{"version":3,"sources":["jsdelivr-header.js","/npm/inferencejs@1.3.0/dist/inference.es.js"],"names":[],"mappings":"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CACb,OAAO,GAAK,EAAE,YAAc,OAAO,UAAU,eAAe,KAAK,EAAG,SAAS,EAAI,EAAE,QAAU,CAC/F,CACA,SAAS,GAAG,EAAG,CACb,GAAI,EAAE,WAAY,OAAO,EACzB,IAAI,EAAI,EAAE,QACV,GAAI,OAAO,GAAK,WAAY,CAC1B,IAAI,EAAI,SAAS,GAAI,CACnB,OAAO,gBAAgB,EAAI,QAAQ,UAAU,EAAG,UAAW,KAAK,WAAW,EAAI,EAAE,MAAM,KAAM,SAAS,CACxG,EACA,EAAE,UAAY,EAAE,SAClB,MAAO,EAAI,CAAA,EACX,OAAO,OAAO,eAAe,EAAG,aAAc,CAAE,MAAO,EAAE,CAAE,EAAG,OAAO,KAAK,CAAC,EAAE,QAAQ,SAAS,EAAG,CAC/F,IAAI,EAAI,OAAO,yBAAyB,EAAG,CAAC,EAC5C,OAAO,eAAe,EAAG,EAAG,EAAE,IAAM,EAAI,CACtC,WAAY,GACZ,IAAK,UAAW,CACd,OAAO,EAAE,CAAC,CACZ,CACN,CAAK,CACH,CAAC,EAAG,CACN,CACA,IAAI,GAAK,GAAI,GAAK,KAClB,GAAI,CACF,GAAK,IAAI,YAAY,SAAS,IAAI,YAAY,OAAO,IAAI,WAAW,CAClE,EACA,GACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,GACA,EACA,GACA,EACA,EACA,IACA,GACA,EACA,IACA,IACA,IACA,IACA,EACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACA,EACA,GACA,EACA,GACA,EACA,GACA,EACA,EACA,IACA,IACA,IACA,EACA,EACA,EACA,IACA,IACA,IACA,GACA,IACA,EACA,EACA,EACA,IACA,IACA,IACA,GACA,IACA,EACA,EACA,EACA,IACA,IACA,IACA,GACA,IACA,EACA,EACA,EACA,IACA,IACA,IACA,GACA,IACA,EACA,EACA,EACA,IACA,IACA,IACA,GACA,IACA,IACA,IACA,IACA,EACA,EACA,GACA,IACA,EACA,EACA,EACA,EACA,GACA,EACA,GACA,GACA,EACA,EACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,IACA,GACA,EACA,GACA,GACA,IACA,IACA,GACA,EACA,GACA,EACA,IACA,GACA,GACA,EACA,EACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,IACA,GACA,EACA,GACA,GACA,IACA,IACA,GACA,EACA,GACA,EACA,IACA,GACA,GACA,EACA,EACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,IACA,GACA,EACA,GACA,GACA,IACA,IACA,GACA,EACA,GACA,EACA,IACA,GACA,GACA,EACA,EACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,IACA,GACA,EACA,GACA,GACA,IACA,IACA,GACA,EACA,GACA,EACA,IACA,GACA,GACA,EACA,EACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,GACA,EACA,IACA,GACA,EACA,IACA,GACA,GACA,IACA,IACA,IACA,GACA,EACA,GACA,GACA,IACA,IACA,GACA,EACA,GACA,EACA,IACA,EACJ,CAAG,CAAC,EAAG,CAAA,CAAE,EAAE,OACX,MAAQ,CACR,CACA,SAAS,GAAG,EAAG,EAAG,EAAG,CACnB,KAAK,IAAM,EAAI,EAAG,KAAK,KAAO,EAAI,EAAG,KAAK,SAAW,CAAC,CAAC,CACzD,CACA,GAAG,UAAU,WACb,OAAO,eAAe,GAAG,UAAW,aAAc,CAAE,MAAO,EAAE,CAAE,EAC/D,SAAS,GAAG,EAAG,CACb,OAAQ,GAAK,EAAE,cAAgB,EACjC,CACA,GAAG,OAAS,GACZ,IAAI,GAAK,CAAA,EAAI,GAAK,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CA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,EACF,EACA,UAAW,KAAK,GACd,GAAG,CAAC,EAiBN,MAAM,GAAK,CAAA,EAAI,GAAK,CAClB,MAAO,GACP,UAAW,GACX,mBAAoB,GACpB,sBAAuB,GACvB,MAAO,GACP,QAAS,GACT,6BAA8B,EAChC,EACA,SAAS,GAAG,EAAG,EAAG,CAChB,GAAG,CAAC,EAAI,CACV,CACA,SAAS,GAAG,EAAG,EAAG,CAChB,GAAI,EAAE,KAAK,KAAO,GAAK,KAAM,CAC3B,MAAM,EAAI,GAAG,EAAG,CAAC,EACjB,GAAI,IAAM,KACR,GAAG,CAAC,EAAI,MAER,QAAO,QAAQ,IAAI,0CAA2C,CAAC,EAAG,IACtE,CACA,MAAM,EAAI,GAAG,CAAC,EACd,OAAO,GAAK,MAAQ,EAAE,cAAa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AAE,MAAO,CAAC,CAAE,CAAE,EACxG,IAAI,EAAI,EACR,GAAI,GAAK,KAAM,CACb,EAAE,KAAK,CAAC,EACR,MAAM,EAAI,GAAG,CAAC,EACd,EAAI,GAAG,CAAE,OAAQ,CAAE,EAAG,CAAC,EAAI,QAAS,EAAG,MAAO,CAAE,KAAM,CAAC,CAAE,CAAE,CAC7D,CACA,OAAO,EAAE,QAAS,GAAM,EAAE,8BAA8B,CAAC,CAAC,EAAG,CAC/D,CACA,MAAM,GAAK,CACT,WAAY,GACZ,YAAa,QACb,WAAY,EACd,EAiBA,MAAM,GAAK,CACT,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,EACF,EACA,UAAW,KAAK,GACd,GAAG,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","file":"/npm/inferencejs@1.3.0/dist/inference.es.js/+esm","sourceRoot":"","sourcesContent":["/**\n * Bundled by jsDelivr using Rollup v4.62.2 and esbuild v0.28.1.\n * Original file: /npm/inferencejs@1.3.0/dist/inference.es.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","var U9 = (I) => {\n  throw TypeError(I);\n};\nvar Hd = (I, l, G) => l.has(I) || U9(\"Cannot \" + G);\nvar uG = (I, l, G) => (Hd(I, l, \"read from private field\"), G ? G.call(I) : l.get(I)), MZ = (I, l, G) => l.has(I) ? U9(\"Cannot add the same private member more than once\") : l instanceof WeakSet ? l.add(I) : l.set(I, G), ib = (I, l, G, Z) => (Hd(I, l, \"write to private field\"), Z ? Z.call(I, G) : l.set(I, G), G), B0 = (I, l, G) => (Hd(I, l, \"access private method\"), G);\nvar mb = (I, l, G, Z) => ({\n  set _(h) {\n    ib(I, l, h, G);\n  },\n  get _() {\n    return uG(I, l, Z);\n  }\n});\nfunction an(I, l) {\n  for (var G = 0; G < l.length; G++) {\n    const Z = l[G];\n    if (typeof Z != \"string\" && !Array.isArray(Z)) {\n      for (const h in Z)\n        if (h !== \"default\" && !(h in I)) {\n          const g = Object.getOwnPropertyDescriptor(Z, h);\n          g && Object.defineProperty(I, h, g.get ? g : {\n            enumerable: !0,\n            get: () => Z[h]\n          });\n        }\n    }\n  }\n  return Object.freeze(Object.defineProperty(I, Symbol.toStringTag, { value: \"Module\" }));\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst mn = 1e-7, Tn = 1e-4;\nclass ti {\n  constructor(l, G) {\n    this.backend = l, this.dataMover = G, this.data = /* @__PURE__ */ new WeakMap(), this.dataIdsCount = 0;\n  }\n  get(l) {\n    return this.data.has(l) || this.dataMover.moveData(this.backend, l), this.data.get(l);\n  }\n  set(l, G) {\n    this.dataIdsCount++, this.data.set(l, G);\n  }\n  has(l) {\n    return this.data.has(l);\n  }\n  delete(l) {\n    return this.dataIdsCount--, this.data.delete(l);\n  }\n  numDataIds() {\n    return this.dataIdsCount;\n  }\n}\nclass wW {\n  refCount(l) {\n    return QG(\"refCount\");\n  }\n  incRef(l) {\n    return QG(\"incRef\");\n  }\n  timerAvailable() {\n    return !0;\n  }\n  time(l) {\n    return QG(\"time\");\n  }\n  read(l) {\n    return QG(\"read\");\n  }\n  readSync(l) {\n    return QG(\"readSync\");\n  }\n  readToGPU(l, G) {\n    return QG(\"readToGPU\");\n  }\n  numDataIds() {\n    return QG(\"numDataIds\");\n  }\n  disposeData(l, G) {\n    return QG(\"disposeData\");\n  }\n  write(l, G, Z) {\n    return QG(\"write\");\n  }\n  move(l, G, Z, h, g) {\n    return QG(\"move\");\n  }\n  createTensorFromGPUData(l, G, Z) {\n    return QG(\"createTensorFromGPUData\");\n  }\n  memory() {\n    return QG(\"memory\");\n  }\n  /** Returns the highest precision for floats in bits (e.g. 16 or 32) */\n  floatPrecision() {\n    return QG(\"floatPrecision\");\n  }\n  /** Returns the smallest representable number.  */\n  epsilon() {\n    return this.floatPrecision() === 32 ? mn : Tn;\n  }\n  dispose() {\n    return QG(\"dispose\");\n  }\n}\nfunction QG(I) {\n  throw new Error(`'${I}' not yet implemented or not found in the registry. This kernel may not be supported by the tfjs backend you have chosen`);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sn(I) {\n  let l = I.length, G = 0;\n  for (; l > 0; )\n    G = Math.random() * l | 0, l--, Eh(I, l, G);\n}\nfunction Zh(I, l, G) {\n  return Math.max(I, Math.min(l, G));\n}\nfunction QW(I) {\n  return I % 2 === 0 ? I : I + 1;\n}\nfunction Eh(I, l, G) {\n  const Z = I[l];\n  I[l] = I[G], I[G] = Z;\n}\nfunction on(I) {\n  let l = 0;\n  for (let G = 0; G < I.length; G++)\n    l += I[G];\n  return l;\n}\nfunction u(I, l) {\n  if (!I)\n    throw new Error(typeof l == \"string\" ? l : l());\n}\nfunction vW(I, l, G = \"\") {\n  u(Nl(I, l), () => G + ` Shapes ${I} and ${l} must match`);\n}\nfunction rW(I) {\n  u(I != null, () => \"The input to the tensor constructor must be a non-null value.\");\n}\nfunction Q(I) {\n  if (I.length === 0)\n    return 1;\n  let l = I[0];\n  for (let G = 1; G < I.length; G++)\n    l *= I[G];\n  return l;\n}\nfunction Nl(I, l) {\n  if (I === l)\n    return !0;\n  if (I == null || l == null || I.length !== l.length)\n    return !1;\n  for (let G = 0; G < I.length; G++)\n    if (I[G] !== l[G])\n      return !1;\n  return !0;\n}\nfunction Mh(I) {\n  return I % 1 === 0;\n}\nfunction GW(I) {\n  const l = Math.ceil(Math.sqrt(I));\n  return [l, Math.ceil(I / l)];\n}\nfunction Kh(I, l) {\n  return l <= I.length ? I : I + \" \".repeat(l - I.length);\n}\nfunction H9(I, l = (h) => 0, G, Z) {\n  return new Promise((h, g) => {\n    let b = 0;\n    const c = () => {\n      if (I()) {\n        h();\n        return;\n      }\n      b++;\n      const d = l(b);\n      if (G != null && b >= G) {\n        g();\n        return;\n      }\n      Z != null ? Z(c, d) : setTimeout(c, d);\n    };\n    c();\n  });\n}\nfunction ui(I, l) {\n  let G = 1, Z = -1;\n  for (let g = 0; g < I.length; ++g)\n    if (I[g] >= 0)\n      G *= I[g];\n    else if (I[g] === -1) {\n      if (Z !== -1)\n        throw Error(`Shapes can only have 1 implicit size. Found -1 at dim ${Z} and dim ${g}`);\n      Z = g;\n    } else if (I[g] < 0)\n      throw Error(`Shapes can not be < 0. Found ${I[g]} at dim ${g}`);\n  if (Z === -1) {\n    if (l > 0 && l !== G)\n      throw Error(`Size(${l}) must match the product of shape ${I}`);\n    return I;\n  }\n  if (G === 0)\n    throw Error(`Cannot infer the missing size in [${I}] when there are 0 elements`);\n  if (l % G !== 0)\n    throw Error(`The implicit shape can't be a fractional number. Got ${l} / ${G}`);\n  const h = I.slice();\n  return h[Z] = l / G, h;\n}\nfunction tl(I, l) {\n  const G = l.length;\n  return I = I == null ? l.map((Z, h) => h) : [].concat(I), u(I.every((Z) => Z >= -G && Z < G), () => `All values in axis param must be in range [-${G}, ${G}) but got axis ${I}`), u(I.every((Z) => Mh(Z)), () => `All values in axis param must be integers but got axis ${I}`), I.map((Z) => Z < 0 ? G + Z : Z);\n}\nfunction PZ(I, l) {\n  const G = [], Z = [], h = l != null && Array.isArray(l) && l.length === 0, g = l == null || h ? null : tl(l, I).sort();\n  let b = 0;\n  for (let c = 0; c < I.length; ++c) {\n    if (g != null) {\n      if (g[b] === c && I[c] !== 1)\n        throw new Error(`Can't squeeze axis ${c} since its dim '${I[c]}' is not 1`);\n      (g[b] == null || g[b] > c) && I[c] === 1 && (G.push(I[c]), Z.push(c)), g[b] <= c && b++;\n    }\n    I[c] !== 1 && (G.push(I[c]), Z.push(c));\n  }\n  return { newShape: G, keptDims: Z };\n}\nfunction eG(I, l) {\n  return $l(I, l);\n}\nfunction $l(I, l) {\n  let G = null;\n  if (I == null || I === \"float32\")\n    G = new Float32Array(l);\n  else if (I === \"int32\")\n    G = new Int32Array(l);\n  else if (I === \"bool\")\n    G = new Uint8Array(l);\n  else if (I === \"string\")\n    G = new Array(l);\n  else\n    throw new Error(`Unknown data type ${I}`);\n  return G;\n}\nfunction Bn(I, l) {\n  for (let G = 0; G < I.length; G++) {\n    const Z = I[G];\n    if (isNaN(Z) || !isFinite(Z))\n      throw Error(`A tensor of type ${l} being uploaded contains ${Z}.`);\n  }\n}\nfunction nn(I) {\n  return I === \"bool\" || I === \"complex64\" || I === \"float32\" || I === \"int32\" || I === \"string\";\n}\nfunction ei(I, l) {\n  return !(l === \"complex64\" || l === \"float32\" && I !== \"complex64\" || l === \"int32\" && I !== \"float32\" && I !== \"complex64\" || l === \"bool\" && I === \"bool\");\n}\nfunction Nb(I) {\n  if (I === \"float32\" || I === \"int32\")\n    return 4;\n  if (I === \"complex64\")\n    return 8;\n  if (I === \"bool\")\n    return 1;\n  throw new Error(`Unknown dtype ${I}`);\n}\nfunction Cn(I) {\n  if (I == null)\n    return 0;\n  let l = 0;\n  return I.forEach((G) => l += G.length), l;\n}\nfunction v0(I) {\n  return typeof I == \"string\" || I instanceof String;\n}\nfunction Xn(I) {\n  return typeof I == \"boolean\";\n}\nfunction IW(I) {\n  return typeof I == \"number\";\n}\nfunction l0(I) {\n  return Array.isArray(I) ? l0(I[0]) : I instanceof Float32Array ? \"float32\" : I instanceof Int32Array || I instanceof Uint8Array || I instanceof Uint8ClampedArray ? \"int32\" : IW(I) ? \"float32\" : v0(I) ? \"string\" : Xn(I) ? \"bool\" : \"float32\";\n}\nfunction ZW(I) {\n  return !!(I && I.constructor && I.call && I.apply);\n}\nfunction hW(I, l) {\n  for (let G = l; G < I; ++G)\n    if (I % G === 0)\n      return G;\n  return I;\n}\nfunction Wl(I) {\n  const l = I.length;\n  if (l < 2)\n    return [];\n  const G = new Array(l - 1);\n  G[l - 2] = I[l - 1];\n  for (let Z = l - 3; Z >= 0; --Z)\n    G[Z] = G[Z + 1] * I[Z + 1];\n  return G;\n}\nfunction Si(I, l, G, Z = !1) {\n  const h = new Array();\n  if (l.length === 1) {\n    const g = l[0] * (Z ? 2 : 1);\n    for (let b = 0; b < g; b++)\n      h[b] = G[I + b];\n  } else {\n    const g = l[0], b = l.slice(1), c = b.reduce((d, W) => d * W) * (Z ? 2 : 1);\n    for (let d = 0; d < g; d++)\n      h[d] = Si(I + d * c, b, G, Z);\n  }\n  return h;\n}\nfunction SI(I, l, G = !1) {\n  if (I.length === 0)\n    return l[0];\n  const Z = I.reduce((h, g) => h * g) * (G ? 2 : 1);\n  if (Z === 0)\n    return [];\n  if (Z !== l.length)\n    throw new Error(`[${I}] does not match the input size ${l.length}${G ? \" for a complex tensor\" : \"\"}.`);\n  return Si(0, I, l, G);\n}\nfunction tn(I, l) {\n  if (Array.isArray(I))\n    return I;\n  if (l === \"float32\")\n    return I instanceof Float32Array ? I : new Float32Array(I);\n  if (l === \"int32\")\n    return I instanceof Int32Array ? I : new Int32Array(I);\n  if (l === \"bool\" || l === \"string\")\n    return Uint8Array.from(new Int32Array(I));\n  throw new Error(`Unknown dtype ${l}`);\n}\nfunction jW(I, l) {\n  const G = SG(I, l);\n  for (let Z = 0; Z < G.length; Z++)\n    G[Z] = 1;\n  return G;\n}\nfunction SG(I, l) {\n  if (l == null || l === \"float32\" || l === \"complex64\")\n    return new Float32Array(I);\n  if (l === \"int32\")\n    return new Int32Array(I);\n  if (l === \"bool\")\n    return new Uint8Array(I);\n  throw new Error(`Unknown data type ${l}`);\n}\nfunction Ri(I, l) {\n  const G = I.reduce((Z, h) => Z * h, 1);\n  if (l == null || l === \"float32\")\n    return SI(I, new Float32Array(G));\n  if (l === \"int32\")\n    return SI(I, new Int32Array(G));\n  if (l === \"bool\")\n    return SI(I, new Uint8Array(G));\n  throw new Error(`Unknown data type ${l}`);\n}\nfunction dZ(I) {\n  I.forEach((l) => {\n    u(Number.isInteger(l) && l >= 0, () => `Tensor must have a shape comprised of positive integers but got shape [${I}].`);\n  });\n}\nfunction zI(I, l, G) {\n  if (l === 0)\n    return 0;\n  if (l === 1)\n    return I[0];\n  let Z = I[I.length - 1];\n  for (let h = 0; h < I.length - 1; ++h)\n    Z += G[h] * I[h];\n  return Z;\n}\nfunction G0(I, l, G) {\n  if (l === 0)\n    return [];\n  if (l === 1)\n    return [I];\n  const Z = new Array(l);\n  for (let h = 0; h < Z.length - 1; ++h)\n    Z[h] = Math.floor(I / G[h]), I -= Z[h] * G[h];\n  return Z[Z.length - 1] = I, Z;\n}\nfunction DW(I) {\n  return I && I.then && typeof I.then == \"function\";\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst K9 = \"tfjsflags\";\nclass un {\n  // tslint:disable-next-line: no-any\n  constructor(l) {\n    this.global = l, this.flags = {}, this.flagRegistry = {}, this.urlFlags = {}, this.getQueryParams = en, this.populateURLFlags();\n  }\n  setPlatform(l, G) {\n    this.platform != null && (A().getBool(\"IS_TEST\") || A().getBool(\"PROD\") || console.warn(`Platform ${this.platformName} has already been set. Overwriting the platform with ${l}.`)), this.platformName = l, this.platform = G;\n  }\n  registerFlag(l, G, Z) {\n    if (this.flagRegistry[l] = { evaluationFn: G, setHook: Z }, this.urlFlags[l] != null) {\n      const h = this.urlFlags[l];\n      A().getBool(\"IS_TEST\") || A().getBool(\"PROD\") || console.warn(`Setting feature override from URL ${l}: ${h}.`), this.set(l, h);\n    }\n  }\n  async getAsync(l) {\n    return l in this.flags ? this.flags[l] : (this.flags[l] = await this.evaluateFlag(l), this.flags[l]);\n  }\n  get(l) {\n    if (l in this.flags)\n      return this.flags[l];\n    const G = this.evaluateFlag(l);\n    if (DW(G))\n      throw new Error(`Flag ${l} cannot be synchronously evaluated. Please use getAsync() instead.`);\n    return this.flags[l] = G, this.flags[l];\n  }\n  getNumber(l) {\n    return this.get(l);\n  }\n  getBool(l) {\n    return this.get(l);\n  }\n  getString(l) {\n    return this.get(l);\n  }\n  getFlags() {\n    return this.flags;\n  }\n  // For backwards compatibility.\n  get features() {\n    return this.flags;\n  }\n  set(l, G) {\n    if (this.flagRegistry[l] == null)\n      throw new Error(`Cannot set flag ${l} as it has not been registered.`);\n    this.flags[l] = G, this.flagRegistry[l].setHook != null && this.flagRegistry[l].setHook(G);\n  }\n  evaluateFlag(l) {\n    if (this.flagRegistry[l] == null)\n      throw new Error(`Cannot evaluate flag '${l}': no evaluation function found.`);\n    return this.flagRegistry[l].evaluationFn();\n  }\n  setFlags(l) {\n    this.flags = Object.assign({}, l);\n  }\n  reset() {\n    this.flags = {}, this.urlFlags = {}, this.populateURLFlags();\n  }\n  populateURLFlags() {\n    if (typeof this.global > \"u\" || typeof this.global.location > \"u\" || typeof this.global.location.search > \"u\")\n      return;\n    const l = this.getQueryParams(this.global.location.search);\n    K9 in l && l[K9].split(\",\").forEach((Z) => {\n      const [h, g] = Z.split(\":\");\n      this.urlFlags[h] = Rn(h, g);\n    });\n  }\n}\nfunction en(I) {\n  const l = {};\n  return I.replace(/[?&]([^=?&]+)(?:=([^&]*))?/g, (G, ...Z) => (Sn(l, Z[0], Z[1]), Z.join(\"=\"))), l;\n}\nfunction Sn(I, l, G) {\n  I[decodeURIComponent(l)] = decodeURIComponent(G || \"\");\n}\nfunction Rn(I, l) {\n  const G = l.toLowerCase();\n  return G === \"true\" || G === \"false\" ? G === \"true\" : `${+G}` === G ? +G : l;\n}\nfunction A() {\n  return pi;\n}\nlet pi = null;\nfunction pn(I) {\n  pi = I;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nlet Kd;\nfunction Fi() {\n  if (Kd == null) {\n    let I;\n    if (typeof window < \"u\")\n      I = window;\n    else if (typeof global < \"u\")\n      I = global;\n    else if (typeof process < \"u\")\n      I = process;\n    else if (typeof self < \"u\")\n      I = self;\n    else\n      throw new Error(\"Could not find a global object\");\n    Kd = I;\n  }\n  return Kd;\n}\nfunction Fn() {\n  const I = Fi();\n  return I._tfGlobals == null && (I._tfGlobals = /* @__PURE__ */ new Map()), I._tfGlobals;\n}\nfunction fW(I, l) {\n  const G = Fn();\n  if (G.has(I))\n    return G.get(I);\n  {\n    const Z = l();\n    return G.set(I, Z), G.get(I);\n  }\n}\nconst bc = \"Abs\", r0 = \"Acos\", j0 = \"Acosh\", I0 = \"Add\", OW = \"AddN\", qW = \"All\", $W = \"Any\", cc = \"ArgMax\", dc = \"ArgMin\", D0 = \"Asin\", f0 = \"Asinh\", O0 = \"Atan\", q0 = \"Atanh\", $0 = \"Atan2\", Wc = \"AvgPool\", _W = \"AvgPoolGrad\", Yc = \"AvgPool3D\", lY = \"AvgPool3DGrad\", Vc = \"BatchMatMul\", ac = \"BatchToSpaceND\", GY = \"Bincount\", IY = \"BitwiseAnd\", yn = \"BroadcastTo\", yi = \"BroadcastArgs\", _0 = \"Cast\", lg = \"Ceil\", Gg = \"ClipByValue\", ZY = \"Complex\", ic = \"ComplexAbs\", mc = \"Concat\", Tc = \"Conv2D\", hY = \"Conv2DBackpropFilter\", sc = \"Conv2DBackpropInput\", oc = \"Conv3D\", gY = \"Conv3DBackpropFilterV2\", bY = \"Conv3DBackpropInputV2\", Ig = \"Cos\", Zg = \"Cosh\", cY = \"Cumprod\", Bc = \"Cumsum\", dY = \"CropAndResize\", WY = \"DenseBincount\", YY = \"DepthToSpace\", nc = \"DepthwiseConv2dNative\", VY = \"DepthwiseConv2dNativeBackpropFilter\", aY = \"DepthwiseConv2dNativeBackpropInput\", Ni = \"Diag\", Cc = \"Dilation2D\", gW = \"Dilation2DBackpropInput\", bW = \"Dilation2DBackpropFilter\", Nn = \"Draw\", hg = \"RealDiv\", iY = \"Einsum\", gg = \"Elu\", mY = \"EluGrad\", bg = \"Erf\", Xc = \"Equal\", cg = \"Exp\", tc = \"ExpandDims\", dg = \"Expm1\", TY = \"FFT\", sY = \"Fill\", oY = \"FlipLeftRight\", Wg = \"Floor\", Yg = \"FloorDiv\", uc = \"FusedBatchNorm\", ec = \"GatherV2\", Pi = \"GatherNd\", Sc = \"Greater\", Vg = \"GreaterEqual\", ag = \"Identity\", BY = \"IFFT\", nY = \"Imag\", ig = \"IsFinite\", mg = \"IsInf\", Tg = \"IsNan\", Rc = \"LeakyRelu\", pc = \"Less\", Fc = \"LessEqual\", Ji = \"LinSpace\", sg = \"Log\", og = \"Log1p\", yc = \"LogicalAnd\", Nc = \"LogicalNot\", Pc = \"LogicalOr\", Pn = \"LogSoftmax\", Jc = \"LRN\", CY = \"LRNGrad\", Ec = \"Max\", Bg = \"Maximum\", xc = \"MaxPool\", XY = \"MaxPoolGrad\", Uc = \"MaxPool3D\", tY = \"MaxPool3DGrad\", Ei = \"MaxPoolWithArgmax\", Hc = \"Mean\", Kc = \"Min\", ng = \"Minimum\", Ac = \"MirrorPad\", Cg = \"Mod\", xi = \"Multinomial\", Xg = \"Multiply\", kc = \"Neg\", zc = \"NotEqual\", uY = \"NonMaxSuppressionV3\", eY = \"NonMaxSuppressionV4\", SY = \"NonMaxSuppressionV5\", Lc = \"OnesLike\", Mc = \"OneHot\", wc = \"Pack\", Qc = \"PadV2\", tg = \"Pow\", vc = \"Prelu\", rc = \"Prod\", Ui = \"RaggedGather\", Hi = \"RaggedRange\", Ki = \"RaggedTensorToTensor\", RY = \"Range\", pY = \"Real\", ug = \"Reciprocal\", eg = \"Relu\", jc = \"Reshape\", Dc = \"ResizeNearestNeighbor\", FY = \"ResizeNearestNeighborGrad\", fc = \"ResizeBilinear\", yY = \"ResizeBilinearGrad\", Sg = \"Relu6\", Oc = \"Reverse\", Rg = \"Round\", pg = \"Rsqrt\", Ai = \"ScatterNd\", ki = \"TensorScatterUpdate\", zi = \"SearchSorted\", qc = \"Select\", Fg = \"Selu\", $c = \"Slice\", yg = \"Sin\", Ng = \"Sinh\", Pg = \"Sign\", Jg = \"Sigmoid\", Eg = \"Softplus\", xg = \"Sqrt\", _c = \"Sum\", ld = \"SpaceToBatchND\", Gd = \"SplitV\", Id = \"Softmax\", Li = \"SparseFillEmptyRows\", Mi = \"SparseReshape\", wi = \"SparseSegmentMean\", Qi = \"SparseSegmentSum\", vi = \"SparseToDense\", Ug = \"SquaredDifference\", NY = \"Square\", PY = \"StaticRegexReplace\", JY = \"StridedSlice\", ri = \"StringNGrams\", ji = \"StringSplit\", Di = \"StringToHashBucketFast\", Hg = \"Sub\", Kg = \"Tan\", Ag = \"Tanh\", kg = \"Tile\", EY = \"TopK\", xY = \"Transform\", Ah = \"Transpose\", UY = \"Unique\", Zd = \"Unpack\", hd = \"UnsortedSegmentSum\", gd = \"ZerosLike\", zg = \"Step\", cW = \"FromPixels\", HY = \"RotateWithOffset\", Pb = \"_FusedMatMul\", Jb = \"FusedConv2D\", fi = \"FusedDepthwiseConv2D\";\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _G(...I) {\n  A().getBool(\"IS_TEST\") || A().getBool(\"PROD\") || console.warn(...I);\n}\nfunction Jn(...I) {\n  A().getBool(\"IS_TEST\") || A().getBool(\"PROD\") || console.log(...I);\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Eb = fW(\"kernelRegistry\", () => /* @__PURE__ */ new Map()), dW = fW(\"gradRegistry\", () => /* @__PURE__ */ new Map());\nfunction WW(I, l) {\n  const G = qi(I, l);\n  return Eb.get(G);\n}\nfunction A9(I) {\n  return dW.get(I);\n}\nfunction k9(I) {\n  const l = Eb.entries(), G = [];\n  for (; ; ) {\n    const { done: Z, value: h } = l.next();\n    if (Z)\n      break;\n    const [g, b] = h, [c] = g.split(\"_\");\n    c === I && G.push(b);\n  }\n  return G;\n}\nfunction Oi(I) {\n  const { kernelName: l, backendName: G } = I, Z = qi(l, G);\n  Eb.has(Z) && _G(`The kernel '${l}' for backend '${G}' is already registered`), Eb.set(Z, I);\n}\nfunction En(I) {\n  const { kernelName: l } = I;\n  dW.has(l) && A().getBool(\"DEBUG\") && _G(`Overriding the gradient for '${l}'`), dW.set(l, I);\n}\nfunction qi(I, l) {\n  return `${l}_${I}`;\n}\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $i(I) {\n  return I instanceof Float32Array || I instanceof Int32Array || I instanceof Uint8Array || I instanceof Uint8ClampedArray;\n}\nvar oh = typeof globalThis < \"u\" ? globalThis : typeof window < \"u\" ? window : typeof global < \"u\" ? global : typeof self < \"u\" ? self : {};\nfunction xn(I) {\n  return I && I.__esModule && Object.prototype.hasOwnProperty.call(I, \"default\") ? I.default : I;\n}\nfunction Un(I) {\n  if (I.__esModule) return I;\n  var l = I.default;\n  if (typeof l == \"function\") {\n    var G = function Z() {\n      return this instanceof Z ? Reflect.construct(l, arguments, this.constructor) : l.apply(this, arguments);\n    };\n    G.prototype = l.prototype;\n  } else G = {};\n  return Object.defineProperty(G, \"__esModule\", { value: !0 }), Object.keys(I).forEach(function(Z) {\n    var h = Object.getOwnPropertyDescriptor(I, Z);\n    Object.defineProperty(G, Z, h.get ? h : {\n      enumerable: !0,\n      get: function() {\n        return I[Z];\n      }\n    });\n  }), G;\n}\nvar _i = wl, WI = null;\ntry {\n  WI = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([\n    0,\n    97,\n    115,\n    109,\n    1,\n    0,\n    0,\n    0,\n    1,\n    13,\n    2,\n    96,\n    0,\n    1,\n    127,\n    96,\n    4,\n    127,\n    127,\n    127,\n    127,\n    1,\n    127,\n    3,\n    7,\n    6,\n    0,\n    1,\n    1,\n    1,\n    1,\n    1,\n    6,\n    6,\n    1,\n    127,\n    1,\n    65,\n    0,\n    11,\n    7,\n    50,\n    6,\n    3,\n    109,\n    117,\n    108,\n    0,\n    1,\n    5,\n    100,\n    105,\n    118,\n    95,\n    115,\n    0,\n    2,\n    5,\n    100,\n    105,\n    118,\n    95,\n    117,\n    0,\n    3,\n    5,\n    114,\n    101,\n    109,\n    95,\n    115,\n    0,\n    4,\n    5,\n    114,\n    101,\n    109,\n    95,\n    117,\n    0,\n    5,\n    8,\n    103,\n    101,\n    116,\n    95,\n    104,\n    105,\n    103,\n    104,\n    0,\n    0,\n    10,\n    191,\n    1,\n    6,\n    4,\n    0,\n    35,\n    0,\n    11,\n    36,\n    1,\n    1,\n    126,\n    32,\n    0,\n    173,\n    32,\n    1,\n    173,\n    66,\n    32,\n    134,\n    132,\n    32,\n    2,\n    173,\n    32,\n    3,\n    173,\n    66,\n    32,\n    134,\n    132,\n    126,\n    34,\n    4,\n    66,\n    32,\n    135,\n    167,\n    36,\n    0,\n    32,\n    4,\n    167,\n    11,\n    36,\n    1,\n    1,\n    126,\n    32,\n    0,\n    173,\n    32,\n    1,\n    173,\n    66,\n    32,\n    134,\n    132,\n    32,\n    2,\n    173,\n    32,\n    3,\n    173,\n    66,\n    32,\n    134,\n    132,\n    127,\n    34,\n    4,\n    66,\n    32,\n    135,\n    167,\n    36,\n    0,\n    32,\n    4,\n    167,\n    11,\n    36,\n    1,\n    1,\n    126,\n    32,\n    0,\n    173,\n    32,\n    1,\n    173,\n    66,\n    32,\n    134,\n    132,\n    32,\n    2,\n    173,\n    32,\n    3,\n    173,\n    66,\n    32,\n    134,\n    132,\n    128,\n    34,\n    4,\n    66,\n    32,\n    135,\n    167,\n    36,\n    0,\n    32,\n    4,\n    167,\n    11,\n    36,\n    1,\n    1,\n    126,\n    32,\n    0,\n    173,\n    32,\n    1,\n    173,\n    66,\n    32,\n    134,\n    132,\n    32,\n    2,\n    173,\n    32,\n    3,\n    173,\n    66,\n    32,\n    134,\n    132,\n    129,\n    34,\n    4,\n    66,\n    32,\n    135,\n    167,\n    36,\n    0,\n    32,\n    4,\n    167,\n    11,\n    36,\n    1,\n    1,\n    126,\n    32,\n    0,\n    173,\n    32,\n    1,\n    173,\n    66,\n    32,\n    134,\n    132,\n    32,\n    2,\n    173,\n    32,\n    3,\n    173,\n    66,\n    32,\n    134,\n    132,\n    130,\n    34,\n    4,\n    66,\n    32,\n    135,\n    167,\n    36,\n    0,\n    32,\n    4,\n    167,\n    11\n  ])), {}).exports;\n} catch {\n}\nfunction wl(I, l, G) {\n  this.low = I | 0, this.high = l | 0, this.unsigned = !!G;\n}\nwl.prototype.__isLong__;\nObject.defineProperty(wl.prototype, \"__isLong__\", { value: !0 });\nfunction qG(I) {\n  return (I && I.__isLong__) === !0;\n}\nwl.isLong = qG;\nvar z9 = {}, L9 = {};\nfunction Bh(I, l) {\n  var G, Z, h;\n  return l ? (I >>>= 0, (h = 0 <= I && I < 256) && (Z = L9[I], Z) ? Z : (G = Ql(I, (I | 0) < 0 ? -1 : 0, !0), h && (L9[I] = G), G)) : (I |= 0, (h = -128 <= I && I < 128) && (Z = z9[I], Z) ? Z : (G = Ql(I, I < 0 ? -1 : 0, !1), h && (z9[I] = G), G));\n}\nwl.fromInt = Bh;\nfunction YI(I, l) {\n  if (isNaN(I))\n    return l ? OZ : VI;\n  if (l) {\n    if (I < 0)\n      return OZ;\n    if (I >= lm)\n      return Zm;\n  } else {\n    if (I <= -w9)\n      return rG;\n    if (I + 1 >= w9)\n      return Im;\n  }\n  return I < 0 ? YI(-I, l).neg() : Ql(I % wh | 0, I / wh | 0, l);\n}\nwl.fromNumber = YI;\nfunction Ql(I, l, G) {\n  return new wl(I, l, G);\n}\nwl.fromBits = Ql;\nvar xb = Math.pow;\nfunction KY(I, l, G) {\n  if (I.length === 0)\n    throw Error(\"empty string\");\n  if (I === \"NaN\" || I === \"Infinity\" || I === \"+Infinity\" || I === \"-Infinity\")\n    return VI;\n  if (typeof l == \"number\" ? (G = l, l = !1) : l = !!l, G = G || 10, G < 2 || 36 < G)\n    throw RangeError(\"radix\");\n  var Z;\n  if ((Z = I.indexOf(\"-\")) > 0)\n    throw Error(\"interior hyphen\");\n  if (Z === 0)\n    return KY(I.substring(1), l, G).neg();\n  for (var h = YI(xb(G, 8)), g = VI, b = 0; b < I.length; b += 8) {\n    var c = Math.min(8, I.length - b), d = parseInt(I.substring(b, b + c), G);\n    if (c < 8) {\n      var W = YI(xb(G, c));\n      g = g.mul(W).add(YI(d));\n    } else\n      g = g.mul(h), g = g.add(YI(d));\n  }\n  return g.unsigned = l, g;\n}\nwl.fromString = KY;\nfunction PI(I, l) {\n  return typeof I == \"number\" ? YI(I, l) : typeof I == \"string\" ? KY(I, l) : Ql(I.low, I.high, typeof l == \"boolean\" ? l : I.unsigned);\n}\nwl.fromValue = PI;\nvar M9 = 65536, Hn = 1 << 24, wh = M9 * M9, lm = wh * wh, w9 = lm / 2, Q9 = Bh(Hn), VI = Bh(0);\nwl.ZERO = VI;\nvar OZ = Bh(0, !0);\nwl.UZERO = OZ;\nvar Hh = Bh(1);\nwl.ONE = Hh;\nvar Gm = Bh(1, !0);\nwl.UONE = Gm;\nvar YW = Bh(-1);\nwl.NEG_ONE = YW;\nvar Im = Ql(-1, 2147483647, !1);\nwl.MAX_VALUE = Im;\nvar Zm = Ql(-1, -1, !0);\nwl.MAX_UNSIGNED_VALUE = Zm;\nvar rG = Ql(0, -2147483648, !1);\nwl.MIN_VALUE = rG;\nvar Gl = wl.prototype;\nGl.toInt = function() {\n  return this.unsigned ? this.low >>> 0 : this.low;\n};\nGl.toNumber = function() {\n  return this.unsigned ? (this.high >>> 0) * wh + (this.low >>> 0) : this.high * wh + (this.low >>> 0);\n};\nGl.toString = function(l) {\n  if (l = l || 10, l < 2 || 36 < l)\n    throw RangeError(\"radix\");\n  if (this.isZero())\n    return \"0\";\n  if (this.isNegative())\n    if (this.eq(rG)) {\n      var G = YI(l), Z = this.div(G), h = Z.mul(G).sub(this);\n      return Z.toString(l) + h.toInt().toString(l);\n    } else\n      return \"-\" + this.neg().toString(l);\n  for (var g = YI(xb(l, 6), this.unsigned), b = this, c = \"\"; ; ) {\n    var d = b.div(g), W = b.sub(d.mul(g)).toInt() >>> 0, Y = W.toString(l);\n    if (b = d, b.isZero())\n      return Y + c;\n    for (; Y.length < 6; )\n      Y = \"0\" + Y;\n    c = \"\" + Y + c;\n  }\n};\nGl.getHighBits = function() {\n  return this.high;\n};\nGl.getHighBitsUnsigned = function() {\n  return this.high >>> 0;\n};\nGl.getLowBits = function() {\n  return this.low;\n};\nGl.getLowBitsUnsigned = function() {\n  return this.low >>> 0;\n};\nGl.getNumBitsAbs = function() {\n  if (this.isNegative())\n    return this.eq(rG) ? 64 : this.neg().getNumBitsAbs();\n  for (var l = this.high != 0 ? this.high : this.low, G = 31; G > 0 && !(l & 1 << G); G--)\n    ;\n  return this.high != 0 ? G + 33 : G + 1;\n};\nGl.isZero = function() {\n  return this.high === 0 && this.low === 0;\n};\nGl.eqz = Gl.isZero;\nGl.isNegative = function() {\n  return !this.unsigned && this.high < 0;\n};\nGl.isPositive = function() {\n  return this.unsigned || this.high >= 0;\n};\nGl.isOdd = function() {\n  return (this.low & 1) === 1;\n};\nGl.isEven = function() {\n  return (this.low & 1) === 0;\n};\nGl.equals = function(l) {\n  return qG(l) || (l = PI(l)), this.unsigned !== l.unsigned && this.high >>> 31 === 1 && l.high >>> 31 === 1 ? !1 : this.high === l.high && this.low === l.low;\n};\nGl.eq = Gl.equals;\nGl.notEquals = function(l) {\n  return !this.eq(\n    /* validates */\n    l\n  );\n};\nGl.neq = Gl.notEquals;\nGl.ne = Gl.notEquals;\nGl.lessThan = function(l) {\n  return this.comp(\n    /* validates */\n    l\n  ) < 0;\n};\nGl.lt = Gl.lessThan;\nGl.lessThanOrEqual = function(l) {\n  return this.comp(\n    /* validates */\n    l\n  ) <= 0;\n};\nGl.lte = Gl.lessThanOrEqual;\nGl.le = Gl.lessThanOrEqual;\nGl.greaterThan = function(l) {\n  return this.comp(\n    /* validates */\n    l\n  ) > 0;\n};\nGl.gt = Gl.greaterThan;\nGl.greaterThanOrEqual = function(l) {\n  return this.comp(\n    /* validates */\n    l\n  ) >= 0;\n};\nGl.gte = Gl.greaterThanOrEqual;\nGl.ge = Gl.greaterThanOrEqual;\nGl.compare = function(l) {\n  if (qG(l) || (l = PI(l)), this.eq(l))\n    return 0;\n  var G = this.isNegative(), Z = l.isNegative();\n  return G && !Z ? -1 : !G && Z ? 1 : this.unsigned ? l.high >>> 0 > this.high >>> 0 || l.high === this.high && l.low >>> 0 > this.low >>> 0 ? -1 : 1 : this.sub(l).isNegative() ? -1 : 1;\n};\nGl.comp = Gl.compare;\nGl.negate = function() {\n  return !this.unsigned && this.eq(rG) ? rG : this.not().add(Hh);\n};\nGl.neg = Gl.negate;\nGl.add = function(l) {\n  qG(l) || (l = PI(l));\n  var G = this.high >>> 16, Z = this.high & 65535, h = this.low >>> 16, g = this.low & 65535, b = l.high >>> 16, c = l.high & 65535, d = l.low >>> 16, W = l.low & 65535, Y = 0, V = 0, a = 0, i = 0;\n  return i += g + W, a += i >>> 16, i &= 65535, a += h + d, V += a >>> 16, a &= 65535, V += Z + c, Y += V >>> 16, V &= 65535, Y += G + b, Y &= 65535, Ql(a << 16 | i, Y << 16 | V, this.unsigned);\n};\nGl.subtract = function(l) {\n  return qG(l) || (l = PI(l)), this.add(l.neg());\n};\nGl.sub = Gl.subtract;\nGl.multiply = function(l) {\n  if (this.isZero())\n    return VI;\n  if (qG(l) || (l = PI(l)), WI) {\n    var G = WI.mul(\n      this.low,\n      this.high,\n      l.low,\n      l.high\n    );\n    return Ql(G, WI.get_high(), this.unsigned);\n  }\n  if (l.isZero())\n    return VI;\n  if (this.eq(rG))\n    return l.isOdd() ? rG : VI;\n  if (l.eq(rG))\n    return this.isOdd() ? rG : VI;\n  if (this.isNegative())\n    return l.isNegative() ? this.neg().mul(l.neg()) : this.neg().mul(l).neg();\n  if (l.isNegative())\n    return this.mul(l.neg()).neg();\n  if (this.lt(Q9) && l.lt(Q9))\n    return YI(this.toNumber() * l.toNumber(), this.unsigned);\n  var Z = this.high >>> 16, h = this.high & 65535, g = this.low >>> 16, b = this.low & 65535, c = l.high >>> 16, d = l.high & 65535, W = l.low >>> 16, Y = l.low & 65535, V = 0, a = 0, i = 0, m = 0;\n  return m += b * Y, i += m >>> 16, m &= 65535, i += g * Y, a += i >>> 16, i &= 65535, i += b * W, a += i >>> 16, i &= 65535, a += h * Y, V += a >>> 16, a &= 65535, a += g * W, V += a >>> 16, a &= 65535, a += b * d, V += a >>> 16, a &= 65535, V += Z * Y + h * W + g * d + b * c, V &= 65535, Ql(i << 16 | m, V << 16 | a, this.unsigned);\n};\nGl.mul = Gl.multiply;\nGl.divide = function(l) {\n  if (qG(l) || (l = PI(l)), l.isZero())\n    throw Error(\"division by zero\");\n  if (WI) {\n    if (!this.unsigned && this.high === -2147483648 && l.low === -1 && l.high === -1)\n      return this;\n    var G = (this.unsigned ? WI.div_u : WI.div_s)(\n      this.low,\n      this.high,\n      l.low,\n      l.high\n    );\n    return Ql(G, WI.get_high(), this.unsigned);\n  }\n  if (this.isZero())\n    return this.unsigned ? OZ : VI;\n  var Z, h, g;\n  if (this.unsigned) {\n    if (l.unsigned || (l = l.toUnsigned()), l.gt(this))\n      return OZ;\n    if (l.gt(this.shru(1)))\n      return Gm;\n    g = OZ;\n  } else {\n    if (this.eq(rG)) {\n      if (l.eq(Hh) || l.eq(YW))\n        return rG;\n      if (l.eq(rG))\n        return Hh;\n      var b = this.shr(1);\n      return Z = b.div(l).shl(1), Z.eq(VI) ? l.isNegative() ? Hh : YW : (h = this.sub(l.mul(Z)), g = Z.add(h.div(l)), g);\n    } else if (l.eq(rG))\n      return this.unsigned ? OZ : VI;\n    if (this.isNegative())\n      return l.isNegative() ? this.neg().div(l.neg()) : this.neg().div(l).neg();\n    if (l.isNegative())\n      return this.div(l.neg()).neg();\n    g = VI;\n  }\n  for (h = this; h.gte(l); ) {\n    Z = Math.max(1, Math.floor(h.toNumber() / l.toNumber()));\n    for (var c = Math.ceil(Math.log(Z) / Math.LN2), d = c <= 48 ? 1 : xb(2, c - 48), W = YI(Z), Y = W.mul(l); Y.isNegative() || Y.gt(h); )\n      Z -= d, W = YI(Z, this.unsigned), Y = W.mul(l);\n    W.isZero() && (W = Hh), g = g.add(W), h = h.sub(Y);\n  }\n  return g;\n};\nGl.div = Gl.divide;\nGl.modulo = function(l) {\n  if (qG(l) || (l = PI(l)), WI) {\n    var G = (this.unsigned ? WI.rem_u : WI.rem_s)(\n      this.low,\n      this.high,\n      l.low,\n      l.high\n    );\n    return Ql(G, WI.get_high(), this.unsigned);\n  }\n  return this.sub(this.div(l).mul(l));\n};\nGl.mod = Gl.modulo;\nGl.rem = Gl.modulo;\nGl.not = function() {\n  return Ql(~this.low, ~this.high, this.unsigned);\n};\nGl.and = function(l) {\n  return qG(l) || (l = PI(l)), Ql(this.low & l.low, this.high & l.high, this.unsigned);\n};\nGl.or = function(l) {\n  return qG(l) || (l = PI(l)), Ql(this.low | l.low, this.high | l.high, this.unsigned);\n};\nGl.xor = function(l) {\n  return qG(l) || (l = PI(l)), Ql(this.low ^ l.low, this.high ^ l.high, this.unsigned);\n};\nGl.shiftLeft = function(l) {\n  return qG(l) && (l = l.toInt()), (l &= 63) === 0 ? this : l < 32 ? Ql(this.low << l, this.high << l | this.low >>> 32 - l, this.unsigned) : Ql(0, this.low << l - 32, this.unsigned);\n};\nGl.shl = Gl.shiftLeft;\nGl.shiftRight = function(l) {\n  return qG(l) && (l = l.toInt()), (l &= 63) === 0 ? this : l < 32 ? Ql(this.low >>> l | this.high << 32 - l, this.high >> l, this.unsigned) : Ql(this.high >> l - 32, this.high >= 0 ? 0 : -1, this.unsigned);\n};\nGl.shr = Gl.shiftRight;\nGl.shiftRightUnsigned = function(l) {\n  if (qG(l) && (l = l.toInt()), l &= 63, l === 0)\n    return this;\n  var G = this.high;\n  if (l < 32) {\n    var Z = this.low;\n    return Ql(Z >>> l | G << 32 - l, G >>> l, this.unsigned);\n  } else return l === 32 ? Ql(G, 0, this.unsigned) : Ql(G >>> l - 32, 0, this.unsigned);\n};\nGl.shru = Gl.shiftRightUnsigned;\nGl.shr_u = Gl.shiftRightUnsigned;\nGl.toSigned = function() {\n  return this.unsigned ? Ql(this.low, this.high, !1) : this;\n};\nGl.toUnsigned = function() {\n  return this.unsigned ? this : Ql(this.low, this.high, !0);\n};\nGl.toBytes = function(l) {\n  return l ? this.toBytesLE() : this.toBytesBE();\n};\nGl.toBytesLE = function() {\n  var l = this.high, G = this.low;\n  return [\n    G & 255,\n    G >>> 8 & 255,\n    G >>> 16 & 255,\n    G >>> 24,\n    l & 255,\n    l >>> 8 & 255,\n    l >>> 16 & 255,\n    l >>> 24\n  ];\n};\nGl.toBytesBE = function() {\n  var l = this.high, G = this.low;\n  return [\n    l >>> 24,\n    l >>> 16 & 255,\n    l >>> 8 & 255,\n    l & 255,\n    G >>> 24,\n    G >>> 16 & 255,\n    G >>> 8 & 255,\n    G & 255\n  ];\n};\nwl.fromBytes = function(l, G, Z) {\n  return Z ? wl.fromBytesLE(l, G) : wl.fromBytesBE(l, G);\n};\nwl.fromBytesLE = function(l, G) {\n  return new wl(\n    l[0] | l[1] << 8 | l[2] << 16 | l[3] << 24,\n    l[4] | l[5] << 8 | l[6] << 16 | l[7] << 24,\n    G\n  );\n};\nwl.fromBytesBE = function(l, G) {\n  return new wl(\n    l[4] << 24 | l[5] << 16 | l[6] << 8 | l[7],\n    l[0] << 24 | l[1] << 16 | l[2] << 8 | l[3],\n    G\n  );\n};\nconst hm = /* @__PURE__ */ xn(_i), Kn = /* @__PURE__ */ an({\n  __proto__: null,\n  default: hm\n}, [_i]);\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst jZ = (\n  // tslint:disable-next-line\n  hm || Kn\n);\nfunction bd(I) {\n  return jZ.fromString(I, !0, 16);\n}\nconst gm = bd(\"c3a5c85c97cb3127\"), rZ = bd(\"b492b66fbe98f273\"), JG = bd(\"9ae16a3b2f90404f\");\nfunction VW(I) {\n  return I.xor(I.shru(47));\n}\nfunction bm(I, l, G) {\n  const Z = I.slice(l, l + G);\n  return jZ.fromBytes(Array.from(Z), !0, !0);\n}\nfunction kl(I, l) {\n  return bm(I, l, 8);\n}\nfunction v9(I, l) {\n  return bm(I, l, 4);\n}\nfunction iG(I, l) {\n  return l === 0 ? I : I.shru(l).or(I.shl(64 - l));\n}\nfunction CZ(I, l, G = bd(\"9ddfea08eb382d69\")) {\n  let Z = I.xor(l).mul(G);\n  Z = Z.xor(Z.shru(47));\n  let h = l.xor(Z).mul(G);\n  return h = h.xor(h.shru(47)), h = h.mul(G), h;\n}\nfunction An(I, l, G, Z, h, g) {\n  h = h.add(I), g = iG(g.add(h).add(Z), 21);\n  const b = h;\n  return h = h.add(l), h = h.add(G), g = g.add(iG(h, 44)), [h.add(Z), g.add(b)];\n}\nfunction Tb(I, l, G, Z) {\n  return An(kl(I, l), kl(I, l + 8), kl(I, l + 16), kl(I, l + 24), G, Z);\n}\nfunction kn(I, l = I.length) {\n  if (l >= 8) {\n    const G = JG.add(l * 2), Z = kl(I, 0).add(JG), h = kl(I, l - 8), g = iG(h, 37).mul(G).add(Z), b = iG(Z, 25).add(h).mul(G);\n    return CZ(g, b, G);\n  }\n  if (l >= 4) {\n    const G = JG.add(l * 2), Z = v9(I, 0);\n    return CZ(Z.shl(3).add(l), v9(I, l - 4), G);\n  }\n  if (l > 0) {\n    const G = I[0], Z = I[l >> 1], h = I[l - 1], g = G + (Z << 8), b = l + (h << 2);\n    return VW(JG.mul(g).xor(gm.mul(b))).mul(JG);\n  }\n  return JG;\n}\nfunction zn(I, l = I.length) {\n  const G = JG.add(l * 2), Z = kl(I, 0).mul(rZ), h = kl(I, 8), g = kl(I, l - 8).mul(G), b = kl(I, l - 16).mul(JG);\n  return CZ(iG(Z.add(h), 43).add(iG(g, 30)).add(b), Z.add(iG(h.add(JG), 18)).add(g), G);\n}\nfunction Ln(I, l = I.length) {\n  const G = JG.add(l * 2), Z = kl(I, 0).mul(JG), h = kl(I, 8), g = kl(I, l - 8).mul(G), b = kl(I, l - 16).mul(JG), c = iG(Z.add(h), 43).add(iG(g, 30)).add(b), d = CZ(c, Z.add(iG(h.add(JG), 18)).add(g), G), W = kl(I, 16).mul(G), Y = kl(I, 24), V = c.add(kl(I, l - 32)).mul(G), a = d.add(kl(I, l - 24)).mul(G);\n  return CZ(iG(W.add(Y), 43).add(iG(V, 30)).add(a), W.add(iG(Y.add(Z), 18)).add(V), G);\n}\nfunction Mn(I, l = I.length) {\n  const G = jZ.fromNumber(81, !0);\n  if (l <= 32)\n    return l <= 16 ? kn(I, l) : zn(I, l);\n  if (l <= 64)\n    return Ln(I, l);\n  let Z = G, h = G.mul(rZ).add(113), g = VW(h.mul(JG).add(113)).mul(JG), b = [jZ.UZERO, jZ.UZERO], c = [jZ.UZERO, jZ.UZERO];\n  Z = Z.mul(JG).add(kl(I, 0));\n  let d = 0;\n  const W = (l - 1 >> 6) * 64, Y = W + (l - 1 & 63) - 63;\n  do\n    Z = iG(Z.add(h).add(b[0]).add(kl(I, d + 8)), 37).mul(rZ), h = iG(h.add(b[1]).add(kl(I, d + 48)), 42).mul(rZ), Z = Z.xor(c[1]), h = h.add(b[0]).add(kl(I, d + 40)), g = iG(g.add(c[0]), 33).mul(rZ), b = Tb(I, d, b[1].mul(rZ), Z.add(c[0])), c = Tb(I, d + 32, g.add(c[1]), h.add(kl(I, d + 16))), [g, Z] = [Z, g], d += 64;\n  while (d !== W);\n  const V = rZ.add(g.and(255).shl(1));\n  return d = Y, c[0] = c[0].add(l - 1 & 63), b[0] = b[0].add(c[0]), c[0] = c[0].add(b[0]), Z = iG(Z.add(h).add(b[0]).add(kl(I, d + 8)), 37).mul(V), h = iG(h.add(b[1]).add(kl(I, d + 48)), 42).mul(V), Z = Z.xor(c[1].mul(9)), h = h.add(b[0].mul(9).add(kl(I, d + 40))), g = iG(g.add(c[0]), 33).mul(V), b = Tb(I, d, b[1].mul(V), Z.add(c[0])), c = Tb(I, d + 32, g.add(c[1]), h.add(kl(I, d + 16))), [g, Z] = [Z, g], CZ(CZ(b[0], c[0], V).add(VW(h).mul(gm)).add(g), CZ(b[1], c[1], V).add(Z), V);\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction JZ(I, l) {\n  return l === \"string\" ? XZ(I) : nh([I], l);\n}\nfunction wn(I, l) {\n  return I instanceof Float32Array && l === \"float32\" || I instanceof Int32Array && l === \"int32\" || I instanceof Uint8Array && l === \"bool\";\n}\nfunction nh(I, l) {\n  if (l === \"string\")\n    throw new Error(\"Cannot convert a string[] to a TypedArray\");\n  if (Array.isArray(I) && (I = hh(I)), A().getBool(\"DEBUG\") && Bn(I, l), wn(I, l))\n    return I;\n  if (l == null || l === \"float32\" || l === \"complex64\")\n    return new Float32Array(I);\n  if (l === \"int32\")\n    return new Int32Array(I);\n  if (l === \"bool\") {\n    const G = new Uint8Array(I.length);\n    for (let Z = 0; Z < G.length; ++Z)\n      Math.round(I[Z]) !== 0 && (G[Z] = 1);\n    return G;\n  } else\n    throw new Error(`Unknown data type ${l}`);\n}\nfunction AG() {\n  return A().platform.now();\n}\nfunction XZ(I, l = \"utf-8\") {\n  return l = l || \"utf-8\", A().platform.encode(I, l);\n}\nfunction eZ(I, l = \"utf-8\") {\n  return l = l || \"utf-8\", A().platform.decode(I, l);\n}\nfunction mI(I) {\n  return A().platform.isTypedArray != null ? A().platform.isTypedArray(I) : $i(I);\n}\nfunction hh(I, l = [], G = !1) {\n  if (l == null && (l = []), typeof I == \"boolean\" || typeof I == \"number\" || typeof I == \"string\" || DW(I) || I == null || mI(I) && G)\n    l.push(I);\n  else if (Array.isArray(I) || mI(I))\n    for (let Z = 0; Z < I.length; ++Z)\n      hh(I[Z], l, G);\n  else {\n    let Z = -1;\n    for (const h of Object.keys(I))\n      /^([1-9]+[0-9]*|0)$/.test(h) && (Z = Math.max(Z, Number(h)));\n    for (let h = 0; h <= Z; h++)\n      hh(I[h], l, G);\n  }\n  return l;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Qn {\n  constructor(l, G) {\n    this.backendTimer = l, this.logger = G, G == null && (this.logger = new rn());\n  }\n  profileKernel(l, G, Z) {\n    let h;\n    const g = () => {\n      h = Z();\n    };\n    let b;\n    const c = AG();\n    if (this.backendTimer.timerAvailable())\n      b = this.backendTimer.time(g);\n    else {\n      g();\n      for (const W of h)\n        W.dataSync();\n      b = Promise.resolve({ kernelMs: AG() - c });\n    }\n    if (A().getBool(\"CHECK_COMPUTATION_FOR_ERRORS\"))\n      for (let W = 0; W < h.length; W++) {\n        const Y = h[W];\n        Y.data().then((V) => {\n          vn(V, Y.dtype, l);\n        });\n      }\n    return {\n      kernelName: l,\n      outputs: h,\n      inputs: G,\n      timeMs: b.then((W) => W.kernelMs),\n      extraInfo: b.then((W) => W.getExtraProfileInfo != null ? W.getExtraProfileInfo() : \"\")\n    };\n  }\n  logKernelProfile(l) {\n    const { kernelName: G, outputs: Z, timeMs: h, inputs: g, extraInfo: b } = l;\n    Z.forEach((c) => {\n      Promise.all([c.data(), h, b]).then((d) => {\n        this.logger.logKernelProfile(G, c, d[0], d[1], g, d[2]);\n      });\n    });\n  }\n}\nfunction vn(I, l, G) {\n  if (l !== \"float32\")\n    return !1;\n  for (let Z = 0; Z < I.length; Z++) {\n    const h = I[Z];\n    if (isNaN(h) || !isFinite(h))\n      return console.warn(`Found ${h} in the result of '${G}'`), !0;\n  }\n  return !1;\n}\nclass rn {\n  logKernelProfile(l, G, Z, h, g, b) {\n    const c = typeof h == \"number\" ? Kh(`${h}ms`, 9) : h.error, d = Kh(l, 25), W = G.rank, Y = G.size, V = Kh(G.shape.toString(), 14);\n    let a = \"\";\n    for (const i in g) {\n      const m = g[i];\n      if (m != null) {\n        const T = m.shape || G.shape, s = T.length;\n        a += `${i}: ${s}D ${s > 0 ? T : \"\"} `;\n      }\n    }\n    console.log(`%c${d}\t%c${c}\t%c${W}D ${V}\t%c${Y}\t%c${a}\t%c${b}`, \"font-weight:bold\", \"color:red\", \"color:blue\", \"color: orange\", \"color: green\", \"color: steelblue\");\n  }\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jn(I, l, G) {\n  const Z = {}, h = {};\n  for (let d = 0; d < l.length; d++)\n    Z[l[d].id] = !0;\n  for (let d = 0; d < I.length; d++) {\n    const W = I[d], Y = W.inputs;\n    for (const V in Y) {\n      const a = Y[V];\n      let i = !1;\n      for (let m = 0; m < l.length; m++)\n        if (Z[a.id]) {\n          W.outputs.forEach((T) => Z[T.id] = !0), i = !0, h[W.id] = !0;\n          break;\n        }\n      if (i)\n        break;\n    }\n  }\n  const g = {};\n  g[G.id] = !0;\n  const b = {};\n  for (let d = I.length - 1; d >= 0; d--) {\n    const W = I[d], Y = W.inputs;\n    for (let V = 0; V < W.outputs.length; V++)\n      if (g[W.outputs[V].id]) {\n        for (const a in Y)\n          g[Y[a].id] = !0, b[W.id] = !0;\n        break;\n      }\n  }\n  const c = [];\n  for (let d = 0; d < I.length; d++) {\n    const W = I[d];\n    if (h[W.id] && b[W.id]) {\n      const Y = {};\n      for (const a in W.inputs) {\n        const i = W.inputs[a];\n        Z[i.id] && (Y[a] = i);\n      }\n      const V = Object.assign({}, W);\n      V.inputs = Y, V.outputs = W.outputs, c.push(V);\n    }\n  }\n  return c;\n}\nfunction Dn(I, l, G, Z) {\n  for (let h = l.length - 1; h >= 0; h--) {\n    const g = l[h], b = [];\n    if (g.outputs.forEach((d) => {\n      const W = I[d.id];\n      W != null ? b.push(W) : b.push(null);\n    }), g.gradient == null)\n      throw new Error(`Cannot compute gradient: gradient function not found for ${g.kernelName}.`);\n    const c = g.gradient(b);\n    for (const d in g.inputs) {\n      if (!(d in c))\n        throw new Error(`Cannot backprop through input ${d}. Available gradients found: ${Object.keys(c)}.`);\n      const W = G(() => c[d]());\n      if (W.dtype !== \"float32\")\n        throw new Error(`Error in gradient for op ${g.kernelName}. The gradient of input ${d} must have 'float32' dtype, but has '${W.dtype}'`);\n      const Y = g.inputs[d];\n      if (!Nl(W.shape, Y.shape))\n        throw new Error(`Error in gradient for op ${g.kernelName}. The gradient of input '${d}' has shape '${W.shape}', which does not match the shape of the input '${Y.shape}'`);\n      if (I[Y.id] == null)\n        I[Y.id] = W;\n      else {\n        const V = I[Y.id];\n        I[Y.id] = Z(V, W), V.dispose();\n      }\n    }\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst r9 = 20, n0 = 3, Ad = 7;\nfunction fn(I, l, G, Z) {\n  const h = Wl(l), g = On(I, l, G, h), b = l.length, c = Fb(I, l, G, h, g), d = [\"Tensor\"];\n  return Z && (d.push(`  dtype: ${G}`), d.push(`  rank: ${b}`), d.push(`  shape: [${l}]`), d.push(\"  values:\")), d.push(c.map((W) => \"    \" + W).join(`\n`)), d.join(`\n`);\n}\nfunction On(I, l, G, Z) {\n  const h = Q(l), g = Z[Z.length - 1], b = new Array(g).fill(0), c = l.length, d = G === \"complex64\" ? e0(I) : I;\n  if (c > 1)\n    for (let W = 0; W < h / g; W++) {\n      const Y = W * g;\n      for (let V = 0; V < g; V++)\n        b[V] = Math.max(b[V], u0(d[Y + V], 0, G).length);\n    }\n  return b;\n}\nfunction u0(I, l, G) {\n  let Z;\n  return Array.isArray(I) ? Z = `${parseFloat(I[0].toFixed(Ad))} + ${parseFloat(I[1].toFixed(Ad))}j` : v0(I) ? Z = `'${I}'` : G === \"bool\" ? Z = cm(I) : Z = parseFloat(I.toFixed(Ad)).toString(), Kh(Z, l);\n}\nfunction cm(I) {\n  return I === 0 ? \"false\" : \"true\";\n}\nfunction Fb(I, l, G, Z, h, g = !0) {\n  const b = G === \"complex64\" ? 2 : 1, c = l[0], d = l.length;\n  if (d === 0) {\n    if (G === \"complex64\") {\n      const T = e0(I);\n      return [u0(T[0], 0, G)];\n    }\n    return G === \"bool\" ? [cm(I[0])] : [I[0].toString()];\n  }\n  if (d === 1) {\n    if (c > r9) {\n      const s = n0 * b;\n      let o = Array.from(I.slice(0, s)), B = Array.from(I.slice((c - n0) * b, c * b));\n      return G === \"complex64\" && (o = e0(o), B = e0(B)), [\n        \"[\" + o.map((C, n) => u0(C, h[n], G)).join(\", \") + \", ..., \" + B.map((C, n) => u0(C, h[c - n0 + n], G)).join(\", \") + \"]\"\n      ];\n    }\n    return [\n      \"[\" + (G === \"complex64\" ? e0(I) : Array.from(I)).map((s, o) => u0(s, h[o], G)).join(\", \") + \"]\"\n    ];\n  }\n  const W = l.slice(1), Y = Z.slice(1), V = Z[0] * b, a = [];\n  if (c > r9) {\n    for (let T = 0; T < n0; T++) {\n      const s = T * V, o = s + V;\n      a.push(...Fb(\n        I.slice(s, o),\n        W,\n        G,\n        Y,\n        h,\n        !1\n        /* isLast */\n      ));\n    }\n    a.push(\"...\");\n    for (let T = c - n0; T < c; T++) {\n      const s = T * V, o = s + V;\n      a.push(...Fb(\n        I.slice(s, o),\n        W,\n        G,\n        Y,\n        h,\n        T === c - 1\n        /* isLast */\n      ));\n    }\n  } else\n    for (let T = 0; T < c; T++) {\n      const s = T * V, o = s + V;\n      a.push(...Fb(\n        I.slice(s, o),\n        W,\n        G,\n        Y,\n        h,\n        T === c - 1\n        /* isLast */\n      ));\n    }\n  const i = d === 2 ? \",\" : \"\";\n  a[0] = \"[\" + (c > 0 ? a[0] + i : \"\");\n  for (let T = 1; T < a.length - 1; T++)\n    a[T] = \" \" + a[T] + i;\n  let m = `,\n`;\n  for (let T = 2; T < d; T++)\n    m += `\n`;\n  return a[a.length - 1] = \" \" + a[a.length - 1] + \"]\" + (g ? \"\" : m), a;\n}\nfunction e0(I) {\n  const l = [];\n  for (let G = 0; G < I.length; G += 2)\n    l.push([I[G], I[G + 1]]);\n  return l;\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass nG {\n  constructor(l, G, Z) {\n    if (this.dtype = G, this.shape = l.slice(), this.size = Q(l), Z != null) {\n      const h = Z.length;\n      u(h === this.size, () => `Length of values '${h}' does not match the size inferred by the shape '${this.size}'.`);\n    }\n    if (G === \"complex64\")\n      throw new Error(\"complex64 dtype TensorBuffers are not supported. Please create a TensorBuffer for the real and imaginary parts separately and call tf.complex(real, imag).\");\n    this.values = Z || $l(G, this.size), this.strides = Wl(l);\n  }\n  /**\n   * Sets a value in the buffer at a given location.\n   *\n   * @param value The value to set.\n   * @param locs  The location indices.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Creation'}\n   */\n  set(l, ...G) {\n    G.length === 0 && (G = [0]), u(G.length === this.rank, () => `The number of provided coordinates (${G.length}) must match the rank (${this.rank})`);\n    const Z = this.locToIndex(G);\n    this.values[Z] = l;\n  }\n  /**\n   * Returns the value in the buffer at the provided location.\n   *\n   * @param locs The location indices.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Creation'}\n   */\n  get(...l) {\n    l.length === 0 && (l = [0]);\n    let G = 0;\n    for (const h of l) {\n      if (h < 0 || h >= this.shape[G]) {\n        const g = `Requested out of range element at ${l}.   Buffer shape=${this.shape}`;\n        throw new Error(g);\n      }\n      G++;\n    }\n    let Z = l[l.length - 1];\n    for (let h = 0; h < l.length - 1; ++h)\n      Z += this.strides[h] * l[h];\n    return this.values[Z];\n  }\n  locToIndex(l) {\n    if (this.rank === 0)\n      return 0;\n    if (this.rank === 1)\n      return l[0];\n    let G = l[l.length - 1];\n    for (let Z = 0; Z < l.length - 1; ++Z)\n      G += this.strides[Z] * l[Z];\n    return G;\n  }\n  indexToLoc(l) {\n    if (this.rank === 0)\n      return [];\n    if (this.rank === 1)\n      return [l];\n    const G = new Array(this.shape.length);\n    for (let Z = 0; Z < G.length - 1; ++Z)\n      G[Z] = Math.floor(l / this.strides[Z]), l -= G[Z] * this.strides[Z];\n    return G[G.length - 1] = l, G;\n  }\n  get rank() {\n    return this.shape.length;\n  }\n  /**\n   * Creates an immutable `tf.Tensor` object from the buffer.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Creation'}\n   */\n  toTensor() {\n    return tI().makeTensor(this.values, this.shape, this.dtype);\n  }\n}\nlet tI = null, xh = null;\nfunction qn(I) {\n  tI = I;\n}\nfunction $n(I) {\n  xh = I;\n}\nclass hG {\n  constructor(l, G, Z, h) {\n    this.kept = !1, this.isDisposedInternal = !1, this.shape = l.slice(), this.dtype = G || \"float32\", this.size = Q(l), this.strides = Wl(l), this.dataId = Z, this.id = h, this.rankType = this.rank < 5 ? this.rank.toString() : \"higher\";\n  }\n  get rank() {\n    return this.shape.length;\n  }\n  /**\n   * Returns a promise of `tf.TensorBuffer` that holds the underlying data.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  async buffer() {\n    const l = await this.data();\n    return xh.buffer(this.shape, this.dtype, l);\n  }\n  /**\n   * Returns a `tf.TensorBuffer` that holds the underlying data.\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  bufferSync() {\n    return xh.buffer(this.shape, this.dtype, this.dataSync());\n  }\n  /**\n   * Returns the tensor data as a nested array. The transfer of data is done\n   * asynchronously.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  async array() {\n    const l = await this.data();\n    return SI(this.shape, l, this.dtype === \"complex64\");\n  }\n  /**\n   * Returns the tensor data as a nested array. The transfer of data is done\n   * synchronously.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  arraySync() {\n    return SI(this.shape, this.dataSync(), this.dtype === \"complex64\");\n  }\n  /**\n   * Asynchronously downloads the values from the `tf.Tensor`. Returns a\n   * promise of `TypedArray` that resolves when the computation has finished.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  async data() {\n    this.throwIfDisposed();\n    const l = tI().read(this.dataId);\n    if (this.dtype === \"string\") {\n      const G = await l;\n      try {\n        return G.map((Z) => eZ(Z));\n      } catch {\n        throw new Error(\"Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().\");\n      }\n    }\n    return l;\n  }\n  /**\n   * Copy the tensor's data to a new GPU resource. Comparing to the `dataSync()`\n   * and `data()`, this method prevents data from being downloaded to CPU.\n   *\n   * For WebGL backend, the data will be stored on a densely packed texture.\n   * This means that the texture will use the RGBA channels to store value.\n   *\n   * For WebGPU backend, the data will be stored on a buffer. There is no\n   * parameter, so can not use a user-defined size to create the buffer.\n   *\n   * @param options:\n   *     For WebGL,\n   *         - customTexShape: Optional. If set, will use the user defined\n   *     texture shape to create the texture.\n   *\n   * @returns For WebGL backend, a GPUData contains the new texture and\n   *     its information.\n   *     {\n   *        tensorRef: The tensor that is associated with this texture,\n   *        texture: WebGLTexture,\n   *        texShape: [number, number] // [height, width]\n   *     }\n   *\n   *     For WebGPU backend, a GPUData contains the new buffer.\n   *     {\n   *        tensorRef: The tensor that is associated with this buffer,\n   *        buffer: GPUBuffer,\n   *     }\n   *\n   *     Remember to dispose the GPUData after it is used by\n   *     `res.tensorRef.dispose()`.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  dataToGPU(l) {\n    return this.throwIfDisposed(), tI().readToGPU(this.dataId, l);\n  }\n  /**\n   * Synchronously downloads the values from the `tf.Tensor`. This blocks the\n   * UI thread until the values are ready, which can cause performance issues.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  dataSync() {\n    this.throwIfDisposed();\n    const l = tI().readSync(this.dataId);\n    if (this.dtype === \"string\")\n      try {\n        return l.map((G) => eZ(G));\n      } catch {\n        throw new Error(\"Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().\");\n      }\n    return l;\n  }\n  /** Returns the underlying bytes of the tensor's data. */\n  async bytes() {\n    this.throwIfDisposed();\n    const l = await tI().read(this.dataId);\n    return this.dtype === \"string\" ? l : new Uint8Array(l.buffer);\n  }\n  /**\n   * Disposes `tf.Tensor` from memory.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  dispose() {\n    this.isDisposed || (this.kerasMask && this.kerasMask.dispose(), tI().disposeTensor(this), this.isDisposedInternal = !0);\n  }\n  get isDisposed() {\n    return this.isDisposedInternal;\n  }\n  throwIfDisposed() {\n    if (this.isDisposed)\n      throw new Error(\"Tensor is disposed.\");\n  }\n  /**\n   * Prints the `tf.Tensor`. See `tf.print` for details.\n   *\n   * @param verbose Whether to print verbose information about the tensor,\n   *    including dtype and size.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  print(l = !1) {\n    return xh.print(this, l);\n  }\n  /**\n   * Returns a copy of the tensor. See `tf.clone` for details.\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  clone() {\n    return this.throwIfDisposed(), xh.clone(this);\n  }\n  /**\n   * Returns a human-readable description of the tensor. Useful for logging.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  toString(l = !1) {\n    const G = this.dataSync();\n    return fn(G, this.shape, this.dtype, l);\n  }\n  cast(l) {\n    return this.throwIfDisposed(), xh.cast(this, l);\n  }\n  variable(l = !0, G, Z) {\n    return this.throwIfDisposed(), tI().makeVariable(this, l, G, Z);\n  }\n}\nObject.defineProperty(hG, Symbol.hasInstance, {\n  value: (I) => !!I && I.data != null && I.dataSync != null && I.throwIfDisposed != null\n});\nfunction M() {\n  return fW(\"Tensor\", () => hG);\n}\nM();\nclass Ub extends hG {\n  constructor(l, G, Z, h) {\n    super(l.shape, l.dtype, l.dataId, h), this.trainable = G, this.name = Z;\n  }\n  /**\n   * Assign a new `tf.Tensor` to this variable. The new `tf.Tensor` must have\n   * the same shape and dtype as the old `tf.Tensor`.\n   *\n   * @param newValue New tensor to be assigned to this variable.\n   *\n   * @doc {heading: 'Tensors', subheading: 'Classes'}\n   */\n  assign(l) {\n    if (l.dtype !== this.dtype)\n      throw new Error(`dtype of the new value (${l.dtype}) and previous value (${this.dtype}) must match`);\n    if (!Nl(l.shape, this.shape))\n      throw new Error(`shape of the new value (${l.shape}) and previous value (${this.shape}) must match`);\n    tI().disposeTensor(this), this.dataId = l.dataId, tI().incRef(\n      this,\n      null\n      /* backend */\n    );\n  }\n  dispose() {\n    tI().disposeVariable(this), this.isDisposedInternal = !0;\n  }\n}\nObject.defineProperty(Ub, Symbol.hasInstance, {\n  value: (I) => I instanceof hG && I.assign != null && I.assign instanceof Function\n});\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nvar j9;\n(function(I) {\n  I.R0 = \"R0\", I.R1 = \"R1\", I.R2 = \"R2\", I.R3 = \"R3\", I.R4 = \"R4\", I.R5 = \"R5\", I.R6 = \"R6\";\n})(j9 || (j9 = {}));\nvar aW;\n(function(I) {\n  I.float32 = \"float32\", I.int32 = \"int32\", I.bool = \"int32\", I.complex64 = \"complex64\";\n})(aW || (aW = {}));\nvar iW;\n(function(I) {\n  I.float32 = \"float32\", I.int32 = \"int32\", I.bool = \"bool\", I.complex64 = \"complex64\";\n})(iW || (iW = {}));\nvar mW;\n(function(I) {\n  I.float32 = \"float32\", I.int32 = \"float32\", I.bool = \"float32\", I.complex64 = \"complex64\";\n})(mW || (mW = {}));\nvar TW;\n(function(I) {\n  I.float32 = \"complex64\", I.int32 = \"complex64\", I.bool = \"complex64\", I.complex64 = \"complex64\";\n})(TW || (TW = {}));\nconst _n = {\n  float32: mW,\n  int32: aW,\n  bool: iW,\n  complex64: TW\n};\nfunction DG(I, l) {\n  if (I === \"string\" || l === \"string\") {\n    if (I === \"string\" && l === \"string\")\n      return \"string\";\n    throw new Error(`Can not upcast ${I} with ${l}`);\n  }\n  return _n[I][l];\n}\nfunction AY(I) {\n  return DG(I, \"int32\");\n}\nfunction dm(I) {\n  return I != null && typeof I == \"object\" && \"texture\" in I && I.texture instanceof WebGLTexture;\n}\nfunction Wm(I) {\n  return typeof GPUBuffer < \"u\" && I != null && typeof I == \"object\" && \"buffer\" in I && I.buffer instanceof GPUBuffer;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lG(I, l) {\n  if (I.dtype === l.dtype)\n    return [I, l];\n  const G = DG(I.dtype, l.dtype);\n  return [I.cast(G), l.cast(G)];\n}\nfunction Ym(I) {\n  const l = [];\n  return Vm(I, l, /* @__PURE__ */ new Set()), l;\n}\nfunction Vm(I, l, G) {\n  if (I == null)\n    return;\n  if (I instanceof hG) {\n    l.push(I);\n    return;\n  }\n  if (!lC(I))\n    return;\n  const Z = I;\n  for (const h in Z) {\n    const g = Z[h];\n    G.has(g) || (G.add(g), Vm(g, l, G));\n  }\n}\nfunction lC(I) {\n  return Array.isArray(I) || typeof I == \"object\";\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kd(I) {\n  return I.kernelName != null;\n}\nclass D9 {\n  constructor() {\n    this.registeredVariables = {}, this.nextTapeNodeId = 0, this.numBytes = 0, this.numTensors = 0, this.numStringTensors = 0, this.numDataBuffers = 0, this.gradientDepth = 0, this.kernelDepth = 0, this.scopeStack = [], this.numDataMovesStack = [], this.nextScopeId = 0, this.tensorInfo = /* @__PURE__ */ new WeakMap(), this.profiling = !1, this.activeProfile = {\n      newBytes: 0,\n      newTensors: 0,\n      peakBytes: 0,\n      kernels: [],\n      result: null,\n      get kernelNames() {\n        return Array.from(new Set(this.kernels.map((l) => l.name)));\n      }\n    };\n  }\n  dispose() {\n    for (const l in this.registeredVariables)\n      this.registeredVariables[l].dispose();\n  }\n}\nclass Qh {\n  constructor(l) {\n    this.ENV = l, this.registry = {}, this.registryFactory = {}, this.pendingBackendInitId = 0, this.state = new D9();\n  }\n  async ready() {\n    if (this.pendingBackendInit != null)\n      return this.pendingBackendInit.then(() => {\n      });\n    if (this.backendInstance != null)\n      return;\n    const l = this.getSortedBackends();\n    for (let G = 0; G < l.length; G++) {\n      const Z = l[G];\n      if (await this.initializeBackend(Z).success) {\n        await this.setBackend(Z);\n        return;\n      }\n    }\n    throw new Error(\"Could not initialize any backends, all backend initializations failed.\");\n  }\n  get backend() {\n    if (this.pendingBackendInit != null)\n      throw new Error(`Backend '${this.backendName}' has not yet been initialized. Make sure to await tf.ready() or await tf.setBackend() before calling other methods`);\n    if (this.backendInstance == null) {\n      const { name: l, asyncInit: G } = this.initializeBackendsAndReturnBest();\n      if (G)\n        throw new Error(`The highest priority backend '${l}' has not yet been initialized. Make sure to await tf.ready() or await tf.setBackend() before calling other methods`);\n      this.setBackend(l);\n    }\n    return this.backendInstance;\n  }\n  backendNames() {\n    return Object.keys(this.registryFactory);\n  }\n  findBackend(l) {\n    if (!(l in this.registry))\n      if (l in this.registryFactory) {\n        const { asyncInit: G } = this.initializeBackend(l);\n        if (G)\n          return null;\n      } else\n        return null;\n    return this.registry[l];\n  }\n  findBackendFactory(l) {\n    return l in this.registryFactory ? this.registryFactory[l].factory : null;\n  }\n  registerBackend(l, G, Z = 1) {\n    return l in this.registryFactory ? (_G(`${l} backend was already registered. Reusing existing backend factory.`), !1) : (this.registryFactory[l] = { factory: G, priority: Z }, !0);\n  }\n  async setBackend(l) {\n    if (this.registryFactory[l] == null)\n      throw new Error(`Backend name '${l}' not found in registry`);\n    if (this.backendName = l, this.registry[l] == null) {\n      this.backendInstance = null;\n      const { success: G, asyncInit: Z } = this.initializeBackend(l);\n      if (!(Z ? await G : G))\n        return !1;\n    }\n    return this.backendInstance = this.registry[l], this.setupRegisteredKernels(), this.profiler = new Qn(this.backendInstance), !0;\n  }\n  setupRegisteredKernels() {\n    k9(this.backendName).forEach((G) => {\n      G.setupFunc != null && G.setupFunc(this.backendInstance);\n    });\n  }\n  disposeRegisteredKernels(l) {\n    k9(l).forEach((Z) => {\n      Z.disposeFunc != null && Z.disposeFunc(this.registry[l]);\n    });\n  }\n  /**\n   * Initializes a backend by looking up the backend name in the factory\n   * registry and calling the factory method. Returns a boolean representing\n   * whether the initialization of the backend suceeded. Throws an error if\n   * there is no backend in the factory registry.\n   */\n  initializeBackend(l) {\n    const G = this.registryFactory[l];\n    if (G == null)\n      throw new Error(`Cannot initialize backend ${l}, no registration found.`);\n    try {\n      const Z = G.factory();\n      if (Z && !(Z instanceof wW) && typeof Z.then == \"function\") {\n        const h = ++this.pendingBackendInitId, g = Z.then((b) => h < this.pendingBackendInitId ? !1 : (this.registry[l] = b, this.pendingBackendInit = null, !0)).catch((b) => (h < this.pendingBackendInitId || (this.pendingBackendInit = null, _G(`Initialization of backend ${l} failed`), _G(b.stack || b.message)), !1));\n        return this.pendingBackendInit = g, { success: g, asyncInit: !0 };\n      } else\n        return this.registry[l] = Z, { success: !0, asyncInit: !1 };\n    } catch (Z) {\n      return _G(`Initialization of backend ${l} failed`), _G(Z.stack || Z.message), { success: !1, asyncInit: !1 };\n    }\n  }\n  removeBackend(l) {\n    if (!(l in this.registryFactory))\n      throw new Error(`${l} backend not found in registry`);\n    this.backendName === l && this.pendingBackendInit != null && this.pendingBackendInitId++, l in this.registry && (this.disposeRegisteredKernels(l), this.registry[l].dispose(), delete this.registry[l]), delete this.registryFactory[l], this.backendName === l && (this.pendingBackendInit = null, this.backendName = null, this.backendInstance = null);\n  }\n  getSortedBackends() {\n    if (Object.keys(this.registryFactory).length === 0)\n      throw new Error(\"No backend found in registry.\");\n    return Object.keys(this.registryFactory).sort((l, G) => this.registryFactory[G].priority - this.registryFactory[l].priority);\n  }\n  initializeBackendsAndReturnBest() {\n    const l = this.getSortedBackends();\n    for (let G = 0; G < l.length; G++) {\n      const Z = l[G], { success: h, asyncInit: g } = this.initializeBackend(Z);\n      if (g || h)\n        return { name: Z, asyncInit: g };\n    }\n    throw new Error(\"Could not initialize any backends, all backend initializations failed.\");\n  }\n  moveData(l, G) {\n    const Z = this.state.tensorInfo.get(G), h = Z.backend, g = this.readSync(G), b = h.refCount(G);\n    h.disposeData(G, !0), Z.backend = l, l.move(G, g, Z.shape, Z.dtype, b), this.shouldCheckForMemLeaks() && this.state.numDataMovesStack[this.state.numDataMovesStack.length - 1]++;\n  }\n  tidy(l, G) {\n    let Z = null;\n    if (G == null) {\n      if (typeof l != \"function\")\n        throw new Error(\"Please provide a function to tidy()\");\n      G = l;\n    } else {\n      if (typeof l != \"string\" && !(l instanceof String))\n        throw new Error(\"When calling with two arguments, the first argument to tidy() must be a string\");\n      if (typeof G != \"function\")\n        throw new Error(\"When calling with two arguments, the 2nd argument to tidy() must be a function\");\n      Z = l;\n    }\n    let h;\n    return this.scopedRun(() => this.startScope(Z), () => this.endScope(h), () => (h = G(), h instanceof Promise && console.error(\"Cannot return a Promise inside of tidy.\"), h));\n  }\n  scopedRun(l, G, Z) {\n    l();\n    try {\n      const h = Z();\n      return G(), h;\n    } catch (h) {\n      throw G(), h;\n    }\n  }\n  nextTensorId() {\n    return Qh.nextTensorId++;\n  }\n  nextVariableId() {\n    return Qh.nextVariableId++;\n  }\n  /**\n   * This method is called instead of the public-facing tensor.clone() when\n   * saving a tensor for backwards pass. It makes sure to add the clone\n   * operation to the tape regardless of being called inside a kernel\n   * execution.\n   */\n  clone(l) {\n    const G = P.runKernel(ag, { x: l }), Z = { x: l }, h = (b) => ({\n      x: () => {\n        const c = \"float32\", d = { x: b }, W = { dtype: c };\n        return P.runKernel(\n          _0,\n          d,\n          // tslint:disable-next-line: no-unnecessary-type-assertion\n          W\n        );\n      }\n    }), g = [];\n    return this.addTapeNode(this.state.activeScope.name, Z, [G], h, g, {}), G;\n  }\n  /**\n   * Execute a kernel with the given name and return the output tensor.\n   *\n   * @param kernelName The name of the kernel to execute.\n   * @param inputs A map of input names to tensors.\n   * @param attrs A map of attribute names to their values. An attribute is a\n   *     primitive (non-tensor) input to the kernel.\n   * @param inputsToSave A list of tensors, inputs to save for the backprop\n   *     computation.\n   * @param outputsToSave A list of booleans, specifying which output to save\n   *     for the backprop computation. These are booleans since the output\n   * tensors are not visible to the user.\n   */\n  runKernel(l, G, Z) {\n    if (this.backendName == null && this.backend, !(WW(l, this.backendName) != null))\n      throw new Error(`Kernel '${l}' not registered for backend '${this.backendName}'`);\n    return this.runKernelFunc({ kernelName: l, inputs: G, attrs: Z });\n  }\n  shouldCheckForMemLeaks() {\n    return this.ENV.getBool(\"IS_TEST\");\n  }\n  checkKernelForMemLeak(l, G, Z) {\n    const h = this.backend.numDataIds();\n    let g = 0;\n    Z.forEach((d) => {\n      g += d.dtype === \"complex64\" ? 3 : 1;\n    });\n    const b = this.state.numDataMovesStack[this.state.numDataMovesStack.length - 1], c = h - G - g - b;\n    if (c > 0)\n      throw new Error(`Backend '${this.backendName}' has an internal memory leak (${c} data ids) after running '${l}'`);\n  }\n  /**\n   * Internal helper method to execute a kernel Func\n   *\n   * Use `runKernel` to execute kernels from outside of engine.\n   */\n  runKernelFunc(l) {\n    let G, Z = [];\n    const h = this.isTapeOn(), g = this.state.numBytes, b = this.state.numTensors;\n    this.shouldCheckForMemLeaks() && this.state.numDataMovesStack.push(0);\n    let c;\n    this.backendName == null && this.backend;\n    let d;\n    const W = kd(l) ? l.kernelName : this.state.activeScope != null ? this.state.activeScope.name : \"\";\n    if (kd(l)) {\n      const { kernelName: m, inputs: T, attrs: s } = l;\n      this.backendName == null && this.backend;\n      const o = WW(m, this.backendName);\n      u(o != null, () => `Cannot find registered kernel '${m}' for backend '${this.backendName}'`), c = () => {\n        const B = this.backend.numDataIds();\n        d = o.kernelFunc({ inputs: T, attrs: s, backend: this.backend });\n        const C = Array.isArray(d) ? d : [d];\n        this.shouldCheckForMemLeaks() && this.checkKernelForMemLeak(m, B, C);\n        const n = C.map((X) => X.rank != null ? X : this.makeTensorFromTensorInfo(X));\n        if (h) {\n          const X = this.getTensorsForGradient(m, T, n);\n          Z = this.saveTensorsForBackwardMode(X);\n        }\n        return n;\n      };\n    } else {\n      const { forwardFunc: m } = l, T = (s) => {\n        h && (Z = s.map((o) => this.keep(this.clone(o))));\n      };\n      c = () => {\n        const s = this.backend.numDataIds();\n        d = this.tidy(() => m(this.backend, T));\n        const o = Array.isArray(d) ? d : [d];\n        return this.shouldCheckForMemLeaks() && this.checkKernelForMemLeak(W, s, o), o;\n      };\n    }\n    const { inputs: Y, attrs: V } = l, a = kd(l) ? null : l.backwardsFunc;\n    let i;\n    return this.scopedRun(\n      // Stop recording to a tape when running a kernel.\n      () => this.state.kernelDepth++,\n      () => this.state.kernelDepth--,\n      () => {\n        !this.ENV.getBool(\"DEBUG\") && !this.state.profiling ? G = c() : (i = this.profiler.profileKernel(W, Y, () => c()), this.ENV.getBool(\"DEBUG\") && this.profiler.logKernelProfile(i), G = i.outputs);\n      }\n    ), h && this.addTapeNode(W, Y, G, a, Z, V), this.state.profiling && this.state.activeProfile.kernels.push({\n      name: W,\n      bytesAdded: this.state.numBytes - g,\n      totalBytesSnapshot: this.state.numBytes,\n      tensorsAdded: this.state.numTensors - b,\n      totalTensorsSnapshot: this.state.numTensors,\n      inputShapes: Object.keys(Y).map((m) => Y[m] != null ? Y[m].shape : null),\n      outputShapes: G.map((m) => m.shape),\n      kernelTimeMs: i.timeMs,\n      extraInfo: i.extraInfo\n    }), Array.isArray(d) ? G : G[0];\n  }\n  /**\n   * Saves tensors used in forward mode for use in backward mode.\n   *\n   * @param tensors the list of tensors to save.\n   */\n  saveTensorsForBackwardMode(l) {\n    return l.map((Z) => this.keep(this.clone(Z)));\n  }\n  /**\n   * Returns a list of tensors to save for a given gradient calculation.\n   *\n   * @param kernelName name of kernel to look up gradient for.\n   * @param inputs a map of input tensors.\n   * @param outputs an array of output tensors from forward mode of kernel.\n   */\n  getTensorsForGradient(l, G, Z) {\n    const h = A9(l);\n    if (h != null) {\n      const g = h.inputsToSave || [], b = h.outputsToSave || [];\n      let c;\n      h.saveAllInputs ? (u(Array.isArray(G), () => \"saveAllInputs is true, expected inputs to be an array.\"), c = Object.keys(G).map((W) => G[W])) : c = g.map((W) => G[W]);\n      const d = Z.filter((W, Y) => b[Y]);\n      return c.concat(d);\n    }\n    return [];\n  }\n  /**\n   * Internal method used by public APIs for tensor creation. Makes a new\n   * tensor with the provided shape, dtype and values. It always\n   * creates a new data id and writes the values to the underlying backend.\n   */\n  makeTensor(l, G, Z, h) {\n    if (l == null)\n      throw new Error(\"Values passed to engine.makeTensor() are null\");\n    Z = Z || \"float32\", h = h || this.backend;\n    let g = l;\n    Z === \"string\" && v0(l[0]) && (g = l.map((d) => XZ(d)));\n    const b = h.write(g, G, Z), c = new hG(G, Z, b, this.nextTensorId());\n    if (this.trackTensor(c, h), Z === \"string\") {\n      const d = this.state.tensorInfo.get(b), W = Cn(g);\n      this.state.numBytes += W - d.bytes, d.bytes = W;\n    }\n    return c;\n  }\n  /**\n   * Internal method used by backends. Makes a new tensor\n   * that is a wrapper around an existing data id. It doesn't create\n   * a new data id, only increments the ref count used in memory tracking.\n   * @deprecated\n   */\n  makeTensorFromDataId(l, G, Z, h) {\n    Z = Z || \"float32\";\n    const g = { dataId: l, shape: G, dtype: Z };\n    return this.makeTensorFromTensorInfo(g, h);\n  }\n  /**\n   * Internal method used by backends. Makes a new tensor that is a wrapper\n   * around an existing data id in TensorInfo. It doesn't create a new data id,\n   * only increments the ref count used in memory tracking.\n   */\n  makeTensorFromTensorInfo(l, G) {\n    const { dataId: Z, shape: h, dtype: g } = l, b = new hG(h, g, Z, this.nextTensorId());\n    return this.trackTensor(b, G), b;\n  }\n  makeVariable(l, G = !0, Z, h) {\n    Z = Z || this.nextVariableId().toString(), h != null && h !== l.dtype && (l = l.cast(h));\n    const g = new Ub(l, G, Z, this.nextTensorId());\n    if (this.state.registeredVariables[g.name] != null)\n      throw new Error(`Variable with name ${g.name} was already registered`);\n    return this.state.registeredVariables[g.name] = g, this.incRef(g, this.backend), g;\n  }\n  trackTensor(l, G) {\n    this.state.numTensors++, l.dtype === \"string\" && this.state.numStringTensors++;\n    let Z = 0;\n    l.dtype !== \"complex64\" && l.dtype !== \"string\" && (Z = l.size * Nb(l.dtype)), this.state.numBytes += Z, this.state.tensorInfo.has(l.dataId) || (this.state.numDataBuffers++, this.state.tensorInfo.set(l.dataId, {\n      backend: G || this.backend,\n      dtype: l.dtype,\n      shape: l.shape,\n      bytes: Z\n    })), l instanceof Ub || this.track(l);\n  }\n  // Track the tensor by dataId and increase the refCount for the dataId in the\n  // backend.\n  // TODO(pyu10055): This is currently used by makeVariable method, to increase\n  // refCount on the backend for the dataId. It can potentially be replaced with\n  // Identity op indead of calling backend directly.\n  incRef(l, G) {\n    this.trackTensor(l, G), this.backend.incRef(l.dataId);\n  }\n  removeDataId(l, G) {\n    this.state.tensorInfo.has(l) && this.state.tensorInfo.get(l).backend === G && (this.state.tensorInfo.delete(l), this.state.numDataBuffers--);\n  }\n  disposeTensor(l) {\n    if (!this.state.tensorInfo.has(l.dataId))\n      return;\n    const G = this.state.tensorInfo.get(l.dataId);\n    if (this.state.numTensors--, l.dtype === \"string\" && (this.state.numStringTensors--, this.state.numBytes -= G.bytes), l.dtype !== \"complex64\" && l.dtype !== \"string\") {\n      const Z = l.size * Nb(l.dtype);\n      this.state.numBytes -= Z;\n    }\n    G.backend.disposeData(l.dataId) && this.removeDataId(l.dataId, G.backend);\n  }\n  disposeVariables() {\n    for (const l in this.state.registeredVariables) {\n      const G = this.state.registeredVariables[l];\n      this.disposeVariable(G);\n    }\n  }\n  disposeVariable(l) {\n    this.disposeTensor(l), this.state.registeredVariables[l.name] != null && delete this.state.registeredVariables[l.name];\n  }\n  memory() {\n    const l = this.backend.memory();\n    return l.numTensors = this.state.numTensors, l.numDataBuffers = this.state.numDataBuffers, l.numBytes = this.state.numBytes, this.state.numStringTensors > 0 && (l.unreliable = !0, l.reasons == null && (l.reasons = []), l.reasons.push(\"Memory usage by string tensors is approximate (2 bytes per character)\")), l;\n  }\n  async profile(l) {\n    this.state.profiling = !0;\n    const G = this.state.numBytes, Z = this.state.numTensors;\n    this.state.activeProfile.kernels = [], this.state.activeProfile.result = await l(), this.state.profiling = !1, this.state.activeProfile.peakBytes = Math.max(...this.state.activeProfile.kernels.map((h) => h.totalBytesSnapshot)), this.state.activeProfile.newBytes = this.state.numBytes - G, this.state.activeProfile.newTensors = this.state.numTensors - Z;\n    for (const h of this.state.activeProfile.kernels)\n      h.kernelTimeMs = await h.kernelTimeMs, h.extraInfo = await h.extraInfo;\n    return this.state.activeProfile;\n  }\n  isTapeOn() {\n    return this.state.gradientDepth > 0 && this.state.kernelDepth === 0;\n  }\n  addTapeNode(l, G, Z, h, g, b) {\n    const c = { id: this.state.nextTapeNodeId++, kernelName: l, inputs: G, outputs: Z, saved: g }, d = A9(l);\n    d != null && (h = d.gradFunc), h != null && (c.gradient = (W) => (W = W.map((Y, V) => {\n      if (Y == null) {\n        const a = Z[V], i = SG(a.size, a.dtype);\n        return this.makeTensor(i, a.shape, a.dtype);\n      }\n      return Y;\n    }), h(W.length > 1 ? W : W[0], g, b))), this.state.activeTape.push(c);\n  }\n  keep(l) {\n    return l.kept = !0, l;\n  }\n  startTape() {\n    this.state.gradientDepth === 0 && (this.state.activeTape = []), this.state.gradientDepth++;\n  }\n  endTape() {\n    this.state.gradientDepth--;\n  }\n  /**\n   * Start a scope. Use this with endScope() to achieve the same functionality\n   * as scope() without the need for a function closure.\n   */\n  startScope(l) {\n    const G = {\n      track: [],\n      name: \"unnamed scope\",\n      id: this.state.nextScopeId++\n    };\n    l && (G.name = l), this.state.scopeStack.push(G), this.state.activeScope = G;\n  }\n  /**\n   * End a scope. Use this with startScope() to achieve the same functionality\n   * as scope() without the need for a function closure.\n   */\n  endScope(l) {\n    const G = Ym(l), Z = new Set(G.map((g) => g.id));\n    for (let g = 0; g < this.state.activeScope.track.length; g++) {\n      const b = this.state.activeScope.track[g];\n      !b.kept && !Z.has(b.id) && b.dispose();\n    }\n    const h = this.state.scopeStack.pop();\n    this.state.activeScope = this.state.scopeStack.length === 0 ? null : this.state.scopeStack[this.state.scopeStack.length - 1], G.forEach((g) => {\n      !g.kept && g.scopeId === h.id && this.track(g);\n    });\n  }\n  /**\n   * Returns gradients of `f` with respect to each of the `xs`. The gradients\n   * returned are of the same length as `xs`, but some might be null if `f`\n   * was not a function of that `x`. It also takes optional dy to multiply the\n   * gradient, which defaults to `1`.\n   */\n  gradients(l, G, Z, h = !1) {\n    if (u(G.length > 0, () => \"gradients() received an empty list of xs.\"), Z != null && Z.dtype !== \"float32\")\n      throw new Error(`dy must have 'float32' dtype, but has '${Z.dtype}'`);\n    const g = this.scopedRun(() => this.startTape(), () => this.endTape(), () => this.tidy(\"forward\", l));\n    u(g instanceof hG, () => \"The result y returned by f() must be a tensor.\");\n    const b = jn(this.state.activeTape, G, g);\n    if (!h && b.length === 0 && G.length > 0)\n      throw new Error(\"Cannot compute gradient of y=f(x) with respect to x. Make sure that the f you passed encloses all operations that lead from x to y.\");\n    return this.tidy(\"backward\", () => {\n      const c = {};\n      c[g.id] = Z ?? GC(g.shape), Dn(\n        c,\n        b,\n        // Pass the tidy function to avoid circular dep with `tape.ts`.\n        (W) => this.tidy(W),\n        // Pass an add function to avoide a circular dep with `tape.ts`.\n        IC\n      );\n      const d = G.map((W) => c[W.id]);\n      return this.state.gradientDepth === 0 && (this.state.activeTape.forEach((W) => {\n        for (const Y of W.saved)\n          Y.dispose();\n      }), this.state.activeTape = null), { value: g, grads: d };\n    });\n  }\n  customGrad(l) {\n    return u(ZW(l), () => \"The f passed in customGrad(f) must be a function.\"), (...G) => {\n      u(G.every((c) => c instanceof hG), () => \"The args passed in customGrad(f)(x1, x2,...) must all be tensors\");\n      let Z;\n      const h = {};\n      G.forEach((c, d) => {\n        h[d] = c;\n      });\n      const g = (c, d) => (Z = l(...G, d), u(Z.value instanceof hG, () => \"The function f passed in customGrad(f) must return an object where `obj.value` is a tensor\"), u(ZW(Z.gradFunc), () => \"The function f passed in customGrad(f) must return an object where `obj.gradFunc` is a function.\"), Z.value), b = (c, d) => {\n        const W = Z.gradFunc(c, d), Y = Array.isArray(W) ? W : [W];\n        u(Y.length === G.length, () => \"The function f passed in customGrad(f) must return an object where `obj.gradFunc` is a function that returns the same number of tensors as inputs passed to f(...).\"), u(Y.every((a) => a instanceof hG), () => \"The function f passed in customGrad(f) must return an object where `obj.gradFunc` is a function that returns a list of only tensors.\");\n        const V = {};\n        return Y.forEach((a, i) => {\n          V[i] = () => a;\n        }), V;\n      };\n      return this.runKernelFunc({\n        forwardFunc: g,\n        backwardsFunc: b,\n        inputs: h\n      });\n    };\n  }\n  readSync(l) {\n    return this.state.tensorInfo.get(l).backend.readSync(l);\n  }\n  read(l) {\n    return this.state.tensorInfo.get(l).backend.read(l);\n  }\n  readToGPU(l, G) {\n    return this.state.tensorInfo.get(l).backend.readToGPU(l, G);\n  }\n  async time(l) {\n    const G = AG(), Z = await this.backend.time(l);\n    return Z.wallMs = AG() - G, Z;\n  }\n  /**\n   * Tracks a Tensor in the current scope to be automatically cleaned up\n   * when the current scope ends, and returns the value.\n   *\n   * @param result The Tensor to track in the current scope.\n   */\n  track(l) {\n    return this.state.activeScope != null && (l.scopeId = this.state.activeScope.id, this.state.activeScope.track.push(l)), l;\n  }\n  get registeredVariables() {\n    return this.state.registeredVariables;\n  }\n  /**\n   * Resets the engine state. Removes all backends but does not remove\n   * registered backend factories.\n   */\n  reset() {\n    this.pendingBackendInitId++, this.state.dispose(), this.ENV.reset(), this.state = new D9();\n    for (const l in this.registry)\n      this.disposeRegisteredKernels(l), this.registry[l].dispose(), delete this.registry[l];\n    this.backendName = null, this.backendInstance = null, this.pendingBackendInit = null;\n  }\n}\nQh.nextTensorId = 0;\nQh.nextVariableId = 0;\nfunction GC(I) {\n  const l = jW(Q(I), \"float32\");\n  return P.makeTensor(l, I, \"float32\");\n}\nfunction am() {\n  const I = Fi();\n  if (I._tfengine == null) {\n    const l = new un(I);\n    I._tfengine = new Qh(l);\n  }\n  return pn(I._tfengine.ENV), qn(() => I._tfengine), I._tfengine;\n}\nconst P = am();\nfunction IC(I, l) {\n  const G = { a: I, b: l };\n  return P.runKernel(I0, G);\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ZC() {\n  return typeof navigator < \"u\" && navigator != null;\n}\nfunction im(I) {\n  if (I || ZC()) {\n    if (I || (I = navigator), I.product === \"ReactNative\")\n      return !0;\n    const l = I.userAgent || I.vendor || // tslint:disable-next-line:no-any\n    (typeof window < \"u\" ? window.opera : \"\");\n    if (!l) {\n      const G = I;\n      return G.userAgentData && G.userAgentData.mobile;\n    }\n    return /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(l) || // tslint:disable-next-line:max-line-length\n    /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(l.substr(0, 4));\n  }\n  return !1;\n}\nfunction mm() {\n  return typeof window < \"u\" && window.document != null || //@ts-ignore\n  typeof WorkerGlobalScope < \"u\";\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst LG = A();\nLG.registerFlag(\"DEBUG\", () => !1, (I) => {\n  I && console.warn(\"Debugging mode is ON. The output of every math call will be downloaded to CPU and checked for NaNs. This significantly impacts performance.\");\n});\nLG.registerFlag(\"IS_BROWSER\", () => mm());\nLG.registerFlag(\"IS_NODE\", () => typeof process < \"u\" && typeof process.versions < \"u\" && typeof process.versions.node < \"u\");\nLG.registerFlag(\"IS_CHROME\", () => typeof navigator < \"u\" && navigator != null && navigator.userAgent != null && /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor));\nLG.registerFlag(\"IS_SAFARI\", () => typeof navigator < \"u\" && navigator != null && navigator.userAgent != null && /Safari/.test(navigator.userAgent) && /Apple/.test(navigator.vendor));\nLG.registerFlag(\"PROD\", () => !1);\nLG.registerFlag(\"TENSORLIKE_CHECK_SHAPE_CONSISTENCY\", () => LG.getBool(\"DEBUG\"));\nLG.registerFlag(\"DEPRECATION_WARNINGS_ENABLED\", () => !0);\nLG.registerFlag(\"IS_TEST\", () => !1);\nLG.registerFlag(\"CHECK_COMPUTATION_FOR_ERRORS\", () => LG.getBool(\"DEBUG\"));\nLG.registerFlag(\"WRAP_TO_IMAGEBITMAP\", () => !1);\nLG.registerFlag(\"CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU\", () => !1);\nLG.registerFlag(\"USE_SETTIMEOUTCUSTOM\", () => !1);\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Lg(I, l) {\n  let G = I;\n  if (mI(I))\n    return l === \"string\" ? [] : [I.length];\n  if (dm(I)) {\n    const h = I.channels || \"RGBA\";\n    return [I.height, I.width * h.length];\n  } else if (Wm(I))\n    return [I.buffer.size / (l == null ? 4 : Nb(l))];\n  if (!Array.isArray(I))\n    return [];\n  const Z = [];\n  for (; Array.isArray(G) || mI(G) && l !== \"string\"; )\n    Z.push(G.length), G = G[0];\n  return Array.isArray(I) && A().getBool(\"TENSORLIKE_CHECK_SHAPE_CONSISTENCY\") && Tm(I, Z, []), Z;\n}\nfunction Tm(I, l, G) {\n  if (G = G || [], !Array.isArray(I) && !mI(I)) {\n    u(l.length === 0, () => `Element arr[${G.join(\"][\")}] is a primitive, but should be an array/TypedArray of ${l[0]} elements`);\n    return;\n  }\n  u(l.length > 0, () => `Element arr[${G.join(\"][\")}] should be a primitive, but is an array of ${I.length} elements`), u(I.length === l[0], () => `Element arr[${G.join(\"][\")}] should have ${l[0]} elements, but has ${I.length} elements`);\n  const Z = l.slice(1);\n  for (let h = 0; h < I.length; ++h)\n    Tm(I[h], Z, G.concat(h));\n}\nfunction f9(I, l, G, Z) {\n  if (I !== \"string_or_numeric\") {\n    if (I == null)\n      throw new Error(\"Expected dtype cannot be null.\");\n    if (I !== \"numeric\" && I !== l || I === \"numeric\" && l === \"string\")\n      throw new Error(`Argument '${G}' passed to '${Z}' must be ${I} tensor, but got ${l} tensor`);\n  }\n}\nfunction R(I, l, G, Z = \"numeric\") {\n  if (I instanceof M())\n    return f9(Z, I.dtype, l, G), I;\n  let h = l0(I);\n  if (h !== \"string\" && [\"bool\", \"int32\", \"float32\"].indexOf(Z) >= 0 && (h = Z), f9(Z, h, l, G), I == null || !mI(I) && !Array.isArray(I) && typeof I != \"number\" && typeof I != \"boolean\" && typeof I != \"string\") {\n    const d = I == null ? \"null\" : I.constructor.name;\n    throw new Error(`Argument '${l}' passed to '${G}' must be a Tensor or TensorLike, but got '${d}'`);\n  }\n  const g = Lg(I, h);\n  !mI(I) && !Array.isArray(I) && (I = [I]);\n  const c = h !== \"string\" ? nh(I, h) : hh(I, [], !0);\n  return P.makeTensor(c, g, h);\n}\nfunction sm(I, l, G, Z = \"numeric\") {\n  if (!Array.isArray(I))\n    throw new Error(`Argument ${l} passed to ${G} must be a \\`Tensor[]\\` or \\`TensorLike[]\\``);\n  return I.map((g, b) => R(g, `${l}[${b}]`, G, Z));\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hC = \"__op\";\nfunction E(I) {\n  const l = Object.keys(I);\n  if (l.length !== 1)\n    throw new Error(`Please provide an object with a single key (operation name) mapping to a function. Got an object with ${l.length} keys.`);\n  let G = l[0];\n  const Z = I[G];\n  G.endsWith(\"_\") && (G = G.substring(0, G.length - 1)), G = G + hC;\n  const h = (...g) => {\n    P.startScope(G);\n    try {\n      const b = Z(...g);\n      return DW(b) && console.error(\"Cannot return a Promise inside of tidy.\"), P.endScope(b), b;\n    } catch (b) {\n      throw P.endScope(null), b;\n    }\n  };\n  return Object.defineProperty(h, \"name\", { value: G, configurable: !0 }), h;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gC(I, l) {\n  const G = R(I, \"real\", \"complex\"), Z = R(l, \"imag\", \"complex\");\n  vW(G.shape, Z.shape, `real and imag shapes, ${G.shape} and ${Z.shape}, must match in call to tf.complex().`);\n  const h = { real: G, imag: Z };\n  return P.runKernel(ZY, h);\n}\nconst vh = /* @__PURE__ */ E({ complex_: gC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Mg(I, l, G, Z) {\n  if (Z == null)\n    Z = l0(I);\n  else if (Z === \"complex64\")\n    throw new Error(\"Cannot construct a complex64 tensor directly. Please use tf.complex(real, imag).\");\n  if (Wm(I) || dm(I)) {\n    if (Z !== \"float32\" && Z !== \"int32\")\n      throw new Error(`Creating tensor from GPU data only supports 'float32'|'int32' dtype, while the dtype is ${Z}.`);\n    return P.backend.createTensorFromGPUData(I, l || G, Z);\n  }\n  if (!mI(I) && !Array.isArray(I) && typeof I != \"number\" && typeof I != \"boolean\" && typeof I != \"string\")\n    throw new Error(\"values passed to tensor(values) must be a number/boolean/string or an array of numbers/booleans/strings, or a TypedArray\");\n  if (l != null) {\n    dZ(l);\n    const h = Q(l), g = Q(G);\n    u(h === g, () => `Based on the provided shape, [${l}], the tensor should have ${h} values but has ${g}`);\n    for (let b = 0; b < G.length; ++b) {\n      const c = G[b], d = b === G.length - 1 ? c !== Q(l.slice(b)) : !0;\n      u(G[b] === l[b] || !d, () => `Error creating a new Tensor. Inferred shape (${G}) does not match the provided shape (${l}). `);\n    }\n  }\n  return !mI(I) && !Array.isArray(I) && (I = [I]), l = l || G, I = Z !== \"string\" ? nh(I, Z) : hh(I, [], !0), P.makeTensor(I, l, Z);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kY(I, l, G) {\n  const Z = Lg(I, G);\n  return Mg(I, l, Z, G);\n}\nclass Z0 {\n  /**\n   * Concatenate a number of ArrayBuffers into one.\n   *\n   * @param buffers An array of ArrayBuffers to concatenate, or a single\n   *     ArrayBuffer.\n   * @returns Result of concatenating `buffers` in order.\n   */\n  static join(l) {\n    return new Z0(l).slice();\n  }\n  constructor(l) {\n    if (this.shards = [], this.previousShardIndex = 0, l == null || (l instanceof Array || (l = [l]), l = l.map((Z) => mI(Z) ? Z.buffer : Z), l.length === 0))\n      return;\n    this.bufferUniformSize = l[0].byteLength;\n    let G = 0;\n    for (let Z = 0; Z < l.length; Z++) {\n      const h = l[Z];\n      Z !== l.length - 1 && h.byteLength !== this.bufferUniformSize && (this.bufferUniformSize = void 0);\n      const g = G + h.byteLength;\n      this.shards.push({ buffer: h, start: G, end: g }), G = g;\n    }\n    this.shards.length === 0 && (this.byteLength = 0), this.byteLength = this.shards[this.shards.length - 1].end;\n  }\n  slice(l = 0, G = this.byteLength) {\n    if (this.shards.length === 0)\n      return new ArrayBuffer(0);\n    if (l = isNaN(Number(l)) ? 0 : l, G = isNaN(Number(G)) ? 0 : G, l = Math.max(0, l), G = Math.min(this.byteLength, G), G <= l)\n      return new ArrayBuffer(0);\n    const Z = this.findShardForByte(l);\n    if (Z === -1)\n      throw new Error(`Could not find start shard for byte ${l}`);\n    const h = G - l, g = new ArrayBuffer(h), b = new Uint8Array(g);\n    let c = 0;\n    for (let d = Z; d < this.shards.length; d++) {\n      const W = this.shards[d], V = l + c - W.start, a = c, m = Math.min(G, W.end) - W.start, T = new Uint8Array(W.buffer, V, m - V);\n      if (b.set(T, a), c += T.length, G < W.end)\n        break;\n    }\n    return g;\n  }\n  /**\n   * Get the index of the shard that contains the byte at `byteIndex`.\n   */\n  findShardForByte(l) {\n    if (this.shards.length === 0 || l < 0 || l >= this.byteLength)\n      return -1;\n    if (this.bufferUniformSize != null)\n      return this.previousShardIndex = Math.floor(l / this.bufferUniformSize), this.previousShardIndex;\n    function G(h) {\n      return l < h.start ? -1 : l >= h.end ? 1 : 0;\n    }\n    if (G(this.shards[this.previousShardIndex]) === 0)\n      return this.previousShardIndex;\n    const Z = bC(this.shards, G);\n    return Z === -1 ? -1 : (this.previousShardIndex = Z, this.previousShardIndex);\n  }\n}\nfunction bC(I, l) {\n  let G = 0, Z = I.length;\n  for (; G <= Z; ) {\n    const h = Math.floor((Z - G) / 2) + G, g = l(I[h]);\n    if (g === 0)\n      return h;\n    g < 0 ? Z = h : G = h + 1;\n  }\n  return -1;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction EI() {\n  return P;\n}\nfunction O9() {\n  return P.memory();\n}\nfunction U(I, l) {\n  return P.tidy(I, l);\n}\nfunction Cl(I) {\n  Ym(I).forEach((G) => G.dispose());\n}\nfunction LI(I) {\n  return P.keep(I);\n}\nfunction om(I, l, G = 1) {\n  return P.registerBackend(I, l, G);\n}\nfunction cC() {\n  return P.backend;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst q9 = 4;\nasync function $9(I, l) {\n  const G = [], Z = [], h = Array.isArray(I) ? I.map((b) => b.name) : Object.keys(I);\n  for (let b = 0; b < h.length; ++b) {\n    const c = h[b], d = Array.isArray(I) ? I[b].tensor : I[c];\n    if (d.dtype !== \"float32\" && d.dtype !== \"int32\" && d.dtype !== \"bool\" && d.dtype !== \"string\" && d.dtype !== \"complex64\")\n      throw new Error(`Unsupported dtype in weight '${c}': ${d.dtype}`);\n    const W = { name: c, shape: d.shape, dtype: d.dtype };\n    if (d.dtype === \"string\") {\n      const Y = new Promise(async (V) => {\n        const a = await d.bytes(), i = a.reduce((s, o) => s + o.length, 0) + q9 * a.length, m = new Uint8Array(i);\n        let T = 0;\n        for (let s = 0; s < a.length; s++) {\n          const o = a[s], B = new Uint8Array(new Uint32Array([o.length]).buffer);\n          m.set(B, T), T += q9, m.set(o, T), T += o.length;\n        }\n        V(m);\n      });\n      Z.push(Y);\n    } else\n      Z.push(d.data());\n    l != null && (W.group = l), G.push(W);\n  }\n  const g = await Promise.all(Z);\n  return { data: dC(g), specs: G };\n}\nfunction dC(I) {\n  if (I === null)\n    throw new Error(`Invalid input value: ${JSON.stringify(I)}`);\n  let l = 0;\n  const G = [];\n  I.forEach((g) => {\n    if (l += g.byteLength, G.push(g.byteLength === g.buffer.byteLength ? g : new g.constructor(g)), !(g instanceof Float32Array || g instanceof Int32Array || g instanceof Uint8Array))\n      throw new Error(`Unsupported TypedArray subtype: ${g.constructor.name}`);\n  });\n  const Z = new Uint8Array(l);\n  let h = 0;\n  return G.forEach((g) => {\n    Z.set(new Uint8Array(g.buffer), h), h += g.byteLength;\n  }), Z.buffer;\n}\nconst zY = typeof Buffer < \"u\" && (typeof Blob > \"u\" || typeof atob > \"u\" || typeof btoa > \"u\");\nfunction _9(I) {\n  return zY ? Buffer.byteLength(I, \"utf8\") : new Blob([I]).size;\n}\nfunction WC(I) {\n  if (zY)\n    return Buffer.from(I).toString(\"base64\");\n  const l = new Uint8Array(I);\n  let G = \"\";\n  for (let Z = 0, h = l.length; Z < h; Z++)\n    G += String.fromCharCode(l[Z]);\n  return btoa(G);\n}\nfunction YC(I) {\n  if (zY) {\n    const Z = Buffer.from(I, \"base64\");\n    return Z.buffer.slice(Z.byteOffset, Z.byteOffset + Z.byteLength);\n  }\n  const l = atob(I), G = new Uint8Array(l.length);\n  for (let Z = 0; Z < l.length; ++Z)\n    G.set([l.charCodeAt(Z)], Z);\n  return G.buffer;\n}\nfunction VC(I) {\n  return Z0.join(I);\n}\nfunction Bm(I) {\n  if (I.modelTopology instanceof ArrayBuffer)\n    throw new Error(\"Expected JSON model topology, received ArrayBuffer.\");\n  return {\n    dateSaved: /* @__PURE__ */ new Date(),\n    modelTopologyType: \"JSON\",\n    modelTopologyBytes: I.modelTopology == null ? 0 : _9(JSON.stringify(I.modelTopology)),\n    weightSpecsBytes: I.weightSpecs == null ? 0 : _9(JSON.stringify(I.weightSpecs)),\n    weightDataBytes: I.weightData == null ? 0 : new Z0(I.weightData).byteLength\n  };\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass NG {\n  constructor() {\n    this.saveRouters = [], this.loadRouters = [];\n  }\n  static getInstance() {\n    return NG.instance == null && (NG.instance = new NG()), NG.instance;\n  }\n  /**\n   * Register a save-handler router.\n   *\n   * @param saveRouter A function that maps a URL-like string onto an instance\n   * of `IOHandler` with the `save` method defined or `null`.\n   */\n  static registerSaveRouter(l) {\n    NG.getInstance().saveRouters.push(l);\n  }\n  /**\n   * Register a load-handler router.\n   *\n   * @param loadRouter A function that maps a URL-like string onto an instance\n   * of `IOHandler` with the `load` method defined or `null`.\n   */\n  static registerLoadRouter(l) {\n    NG.getInstance().loadRouters.push(l);\n  }\n  /**\n   * Look up IOHandler for saving, given a URL-like string.\n   *\n   * @param url\n   * @returns If only one match is found, an instance of IOHandler with the\n   * `save` method defined. If no match is found, `null`.\n   * @throws Error, if more than one match is found.\n   */\n  static getSaveHandlers(l) {\n    return NG.getHandlers(l, \"save\");\n  }\n  /**\n   * Look up IOHandler for loading, given a URL-like string.\n   *\n   * @param url\n   * @param loadOptions Optional, custom load options.\n   * @returns All valid handlers for `url`, given the currently registered\n   *   handler routers.\n   */\n  static getLoadHandlers(l, G) {\n    return NG.getHandlers(l, \"load\", G);\n  }\n  static getHandlers(l, G, Z) {\n    const h = [];\n    return (G === \"load\" ? NG.getInstance().loadRouters : NG.getInstance().saveRouters).forEach((b) => {\n      const c = b(l, Z);\n      c !== null && h.push(c);\n    }), h;\n  }\n}\nconst aC = (I) => NG.getSaveHandlers(I);\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst sW = \"tensorflowjs\", oW = 1, qZ = \"models_store\", oZ = \"model_info_store\";\nfunction nm() {\n  if (!A().getBool(\"IS_BROWSER\"))\n    throw new Error(\"Failed to obtain IndexedDB factory because the current environmentis not a web browser.\");\n  const I = typeof window > \"u\" ? self : window, l = I.indexedDB || I.mozIndexedDB || I.webkitIndexedDB || I.msIndexedDB || I.shimIndexedDB;\n  if (l == null)\n    throw new Error(\"The current browser does not appear to support IndexedDB.\");\n  return l;\n}\nfunction BW(I) {\n  const l = I.result;\n  l.createObjectStore(qZ, { keyPath: \"modelPath\" }), l.createObjectStore(oZ, { keyPath: \"modelPath\" });\n}\nclass gh {\n  constructor(l) {\n    if (this.indexedDB = nm(), l == null || !l)\n      throw new Error(\"For IndexedDB, modelPath must not be null, undefined or empty.\");\n    this.modelPath = l;\n  }\n  async save(l) {\n    if (l.modelTopology instanceof ArrayBuffer)\n      throw new Error(\"BrowserLocalStorage.save() does not support saving model topology in binary formats yet.\");\n    return this.databaseAction(this.modelPath, l);\n  }\n  async load() {\n    return this.databaseAction(this.modelPath);\n  }\n  /**\n   * Perform database action to put model artifacts into or read model artifacts\n   * from IndexedDB object store.\n   *\n   * Whether the action is put or get depends on whether `modelArtifacts` is\n   * specified. If it is specified, the action will be put; otherwise the action\n   * will be get.\n   *\n   * @param modelPath A unique string path for the model.\n   * @param modelArtifacts If specified, it will be the model artifacts to be\n   *   stored in IndexedDB.\n   * @returns A `Promise` of `SaveResult`, if the action is put, or a `Promise`\n   *   of `ModelArtifacts`, if the action is get.\n   */\n  databaseAction(l, G) {\n    return new Promise((Z, h) => {\n      const g = this.indexedDB.open(sW, oW);\n      g.onupgradeneeded = () => BW(g), g.onsuccess = () => {\n        const b = g.result;\n        if (G == null) {\n          const c = b.transaction(qZ, \"readonly\"), W = c.objectStore(qZ).get(this.modelPath);\n          W.onsuccess = () => {\n            if (W.result == null)\n              return b.close(), h(new Error(`Cannot find model with path '${this.modelPath}' in IndexedDB.`));\n            Z(W.result.modelArtifacts);\n          }, W.onerror = (Y) => (b.close(), h(W.error)), c.oncomplete = () => b.close();\n        } else {\n          G.weightData = Z0.join(G.weightData);\n          const c = Bm(G), d = b.transaction(oZ, \"readwrite\");\n          let W = d.objectStore(oZ), Y;\n          try {\n            Y = W.put({ modelPath: this.modelPath, modelArtifactsInfo: c });\n          } catch (a) {\n            return h(a);\n          }\n          let V;\n          Y.onsuccess = () => {\n            V = b.transaction(qZ, \"readwrite\");\n            const a = V.objectStore(qZ);\n            let i;\n            try {\n              i = a.put({\n                modelPath: this.modelPath,\n                modelArtifacts: G,\n                modelArtifactsInfo: c\n              });\n            } catch (m) {\n              return h(m);\n            }\n            i.onsuccess = () => Z({ modelArtifactsInfo: c }), i.onerror = (m) => {\n              W = d.objectStore(oZ);\n              const T = W.delete(this.modelPath);\n              T.onsuccess = () => (b.close(), h(i.error)), T.onerror = (s) => (b.close(), h(i.error));\n            };\n          }, Y.onerror = (a) => (b.close(), h(Y.error)), d.oncomplete = () => {\n            V == null ? b.close() : V.oncomplete = () => b.close();\n          };\n        }\n      }, g.onerror = (b) => h(g.error);\n    });\n  }\n}\ngh.URL_SCHEME = \"indexeddb://\";\nconst Cm = (I) => A().getBool(\"IS_BROWSER\") && !Array.isArray(I) && I.startsWith(gh.URL_SCHEME) ? iC(I.slice(gh.URL_SCHEME.length)) : null;\nNG.registerSaveRouter(Cm);\nNG.registerLoadRouter(Cm);\nfunction iC(I) {\n  return new gh(I);\n}\nfunction mC(I) {\n  return I.startsWith(gh.URL_SCHEME) ? I.slice(gh.URL_SCHEME.length) : I;\n}\nclass TC {\n  constructor() {\n    this.indexedDB = nm();\n  }\n  async listModels() {\n    return new Promise((l, G) => {\n      const Z = this.indexedDB.open(sW, oW);\n      Z.onupgradeneeded = () => BW(Z), Z.onsuccess = () => {\n        const h = Z.result, g = h.transaction(oZ, \"readonly\"), c = g.objectStore(oZ).getAll();\n        c.onsuccess = () => {\n          const d = {};\n          for (const W of c.result)\n            d[W.modelPath] = W.modelArtifactsInfo;\n          l(d);\n        }, c.onerror = (d) => (h.close(), G(c.error)), g.oncomplete = () => h.close();\n      }, Z.onerror = (h) => G(Z.error);\n    });\n  }\n  async removeModel(l) {\n    return l = mC(l), new Promise((G, Z) => {\n      const h = this.indexedDB.open(sW, oW);\n      h.onupgradeneeded = () => BW(h), h.onsuccess = () => {\n        const g = h.result, b = g.transaction(oZ, \"readwrite\"), c = b.objectStore(oZ), d = c.get(l);\n        let W;\n        d.onsuccess = () => {\n          if (d.result == null)\n            return g.close(), Z(new Error(`Cannot find model with path '${l}' in IndexedDB.`));\n          {\n            const Y = c.delete(l), V = () => {\n              W = g.transaction(qZ, \"readwrite\");\n              const i = W.objectStore(qZ).delete(l);\n              i.onsuccess = () => G(d.result.modelArtifactsInfo), i.onerror = (m) => Z(d.error);\n            };\n            Y.onsuccess = V, Y.onerror = (a) => (V(), g.close(), Z(d.error));\n          }\n        }, d.onerror = (Y) => (g.close(), Z(d.error)), b.oncomplete = () => {\n          W == null ? g.close() : W.oncomplete = () => g.close();\n        };\n      }, h.onerror = (g) => Z(h.error);\n    });\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst GZ = \"/\", Uh = \"tensorflowjs_models\", Xm = \"info\", sC = \"model_topology\", oC = \"weight_specs\", BC = \"weight_data\", nC = \"model_metadata\";\nfunction tm(I) {\n  return {\n    info: [Uh, I, Xm].join(GZ),\n    topology: [Uh, I, sC].join(GZ),\n    weightSpecs: [Uh, I, oC].join(GZ),\n    weightData: [Uh, I, BC].join(GZ),\n    modelMetadata: [Uh, I, nC].join(GZ)\n  };\n}\nfunction um(I) {\n  for (const l of Object.values(I))\n    window.localStorage.removeItem(l);\n}\nfunction CC(I) {\n  const l = I.split(GZ);\n  if (l.length < 3)\n    throw new Error(`Invalid key format: ${I}`);\n  return l.slice(1, l.length - 1).join(GZ);\n}\nfunction XC(I) {\n  return I.startsWith(bh.URL_SCHEME) ? I.slice(bh.URL_SCHEME.length) : I;\n}\nclass bh {\n  constructor(l) {\n    if (!A().getBool(\"IS_BROWSER\") || typeof window > \"u\" || typeof window.localStorage > \"u\")\n      throw new Error(\"The current environment does not support local storage.\");\n    if (this.LS = window.localStorage, l == null || !l)\n      throw new Error(\"For local storage, modelPath must not be null, undefined or empty.\");\n    this.modelPath = l, this.keys = tm(this.modelPath);\n  }\n  /**\n   * Save model artifacts to browser local storage.\n   *\n   * See the documentation to `browserLocalStorage` for details on the saved\n   * artifacts.\n   *\n   * @param modelArtifacts The model artifacts to be stored.\n   * @returns An instance of SaveResult.\n   */\n  async save(l) {\n    if (l.modelTopology instanceof ArrayBuffer)\n      throw new Error(\"BrowserLocalStorage.save() does not support saving model topology in binary formats yet.\");\n    {\n      const G = JSON.stringify(l.modelTopology), Z = JSON.stringify(l.weightSpecs), h = Bm(l), g = Z0.join(l.weightData);\n      try {\n        this.LS.setItem(this.keys.info, JSON.stringify(h)), this.LS.setItem(this.keys.topology, G), this.LS.setItem(this.keys.weightSpecs, Z), this.LS.setItem(this.keys.weightData, WC(g));\n        const b = {\n          format: l.format,\n          generatedBy: l.generatedBy,\n          convertedBy: l.convertedBy,\n          signature: l.signature != null ? l.signature : void 0,\n          userDefinedMetadata: l.userDefinedMetadata != null ? l.userDefinedMetadata : void 0,\n          modelInitializer: l.modelInitializer != null ? l.modelInitializer : void 0,\n          initializerSignature: l.initializerSignature != null ? l.initializerSignature : void 0,\n          trainingConfig: l.trainingConfig != null ? l.trainingConfig : void 0\n        };\n        return this.LS.setItem(this.keys.modelMetadata, JSON.stringify(b)), { modelArtifactsInfo: h };\n      } catch {\n        throw um(this.keys), new Error(`Failed to save model '${this.modelPath}' to local storage: size quota being exceeded is a possible cause of this failure: modelTopologyBytes=${h.modelTopologyBytes}, weightSpecsBytes=${h.weightSpecsBytes}, weightDataBytes=${h.weightDataBytes}.`);\n      }\n    }\n  }\n  /**\n   * Load a model from local storage.\n   *\n   * See the documentation to `browserLocalStorage` for details on the saved\n   * artifacts.\n   *\n   * @returns The loaded model (if loading succeeds).\n   */\n  async load() {\n    const l = JSON.parse(this.LS.getItem(this.keys.info));\n    if (l == null)\n      throw new Error(`In local storage, there is no model with name '${this.modelPath}'`);\n    if (l.modelTopologyType !== \"JSON\")\n      throw new Error(\"BrowserLocalStorage does not support loading non-JSON model topology yet.\");\n    const G = {}, Z = JSON.parse(this.LS.getItem(this.keys.topology));\n    if (Z == null)\n      throw new Error(`In local storage, the topology of model '${this.modelPath}' is missing.`);\n    G.modelTopology = Z;\n    const h = JSON.parse(this.LS.getItem(this.keys.weightSpecs));\n    if (h == null)\n      throw new Error(`In local storage, the weight specs of model '${this.modelPath}' are missing.`);\n    G.weightSpecs = h;\n    const g = this.LS.getItem(this.keys.modelMetadata);\n    if (g != null) {\n      const c = JSON.parse(g);\n      G.format = c.format, G.generatedBy = c.generatedBy, G.convertedBy = c.convertedBy, c.signature != null && (G.signature = c.signature), c.userDefinedMetadata != null && (G.userDefinedMetadata = c.userDefinedMetadata), c.modelInitializer != null && (G.modelInitializer = c.modelInitializer), c.initializerSignature != null && (G.initializerSignature = c.initializerSignature), c.trainingConfig != null && (G.trainingConfig = c.trainingConfig);\n    }\n    const b = this.LS.getItem(this.keys.weightData);\n    if (b == null)\n      throw new Error(`In local storage, the binary weight values of model '${this.modelPath}' are missing.`);\n    return G.weightData = YC(b), G;\n  }\n}\nbh.URL_SCHEME = \"localstorage://\";\nconst em = (I) => A().getBool(\"IS_BROWSER\") && !Array.isArray(I) && I.startsWith(bh.URL_SCHEME) ? tC(I.slice(bh.URL_SCHEME.length)) : null;\nNG.registerSaveRouter(em);\nNG.registerLoadRouter(em);\nfunction tC(I) {\n  return new bh(I);\n}\nclass uC {\n  constructor() {\n    u(A().getBool(\"IS_BROWSER\"), () => \"Current environment is not a web browser\"), u(typeof window > \"u\" || typeof window.localStorage < \"u\", () => \"Current browser does not appear to support localStorage\"), this.LS = window.localStorage;\n  }\n  async listModels() {\n    const l = {}, G = Uh + GZ, Z = GZ + Xm;\n    for (let h = 0; h < this.LS.length; ++h) {\n      const g = this.LS.key(h);\n      if (g.startsWith(G) && g.endsWith(Z)) {\n        const b = CC(g);\n        l[b] = JSON.parse(this.LS.getItem(g));\n      }\n    }\n    return l;\n  }\n  async removeModel(l) {\n    l = XC(l);\n    const G = tm(l);\n    if (this.LS.getItem(G.info) == null)\n      throw new Error(`Cannot find model at path '${l}'`);\n    const Z = JSON.parse(this.LS.getItem(G.info));\n    return um(G), Z;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst la = \"://\";\nclass xI {\n  constructor() {\n    this.managers = {};\n  }\n  static getInstance() {\n    return xI.instance == null && (xI.instance = new xI()), xI.instance;\n  }\n  /**\n   * Register a save-handler router.\n   *\n   * @param saveRouter A function that maps a URL-like string onto an instance\n   * of `IOHandler` with the `save` method defined or `null`.\n   */\n  static registerManager(l, G) {\n    u(l != null, () => \"scheme must not be undefined or null.\"), l.endsWith(la) && (l = l.slice(0, l.indexOf(la))), u(l.length > 0, () => \"scheme must not be an empty string.\");\n    const Z = xI.getInstance();\n    u(Z.managers[l] == null, () => `A model store manager is already registered for scheme '${l}'.`), Z.managers[l] = G;\n  }\n  static getManager(l) {\n    const G = xI.getInstance().managers[l];\n    if (G == null)\n      throw new Error(`Cannot find model manager for scheme '${l}'`);\n    return G;\n  }\n  static getSchemes() {\n    return Object.keys(xI.getInstance().managers);\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass eC {\n  constructor() {\n    this.messageName = \"setTimeoutCustom\", this.functionRefs = [], this.handledMessageCount = 0, this.hasEventListener = !1;\n  }\n  fetch(l, G) {\n    return fetch(l, G);\n  }\n  now() {\n    return performance.now();\n  }\n  encode(l, G) {\n    if (G !== \"utf-8\" && G !== \"utf8\")\n      throw new Error(`Browser's encoder only supports utf-8, but got ${G}`);\n    return this.textEncoder == null && (this.textEncoder = new TextEncoder()), this.textEncoder.encode(l);\n  }\n  decode(l, G) {\n    return new TextDecoder(G).decode(l);\n  }\n  // If the setTimeout nesting level is greater than 5 and timeout is less\n  // than 4ms, timeout will be clamped to 4ms, which hurts the perf.\n  // Interleaving window.postMessage and setTimeout will trick the browser and\n  // avoid the clamp.\n  setTimeoutCustom(l, G) {\n    if (typeof window > \"u\" || !A().getBool(\"USE_SETTIMEOUTCUSTOM\")) {\n      setTimeout(l, G);\n      return;\n    }\n    this.functionRefs.push(l), setTimeout(() => {\n      window.postMessage({ name: this.messageName, index: this.functionRefs.length - 1 }, \"*\");\n    }, G), this.hasEventListener || (this.hasEventListener = !0, window.addEventListener(\"message\", (Z) => {\n      if (Z.source === window && Z.data.name === this.messageName) {\n        Z.stopPropagation();\n        const h = this.functionRefs[Z.data.index];\n        h(), this.handledMessageCount++, this.handledMessageCount === this.functionRefs.length && (this.functionRefs = [], this.handledMessageCount = 0);\n      }\n    }, !0));\n  }\n  isTypedArray(l) {\n    return $i(l);\n  }\n}\nif (A().get(\"IS_BROWSER\")) {\n  A().setPlatform(\"browser\", new eC());\n  try {\n    xI.registerManager(bh.URL_SCHEME, new uC());\n  } catch {\n  }\n  try {\n    xI.registerManager(gh.URL_SCHEME, new TC());\n  } catch {\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst SC = {\n  // tslint:disable-next-line:no-require-imports\n  importFetch: () => require(\"node-fetch\")\n};\nlet zd;\nclass RC {\n  constructor() {\n    this.util = require(\"util\"), this.textEncoder = new this.util.TextEncoder();\n  }\n  fetch(l, G) {\n    return A().global.fetch != null ? A().global.fetch(l, G) : (zd == null && (zd = SC.importFetch()), zd(l, G));\n  }\n  now() {\n    const l = process.hrtime();\n    return l[0] * 1e3 + l[1] / 1e6;\n  }\n  encode(l, G) {\n    if (G !== \"utf-8\" && G !== \"utf8\")\n      throw new Error(`Node built-in encoder only supports utf-8, but got ${G}`);\n    return this.textEncoder.encode(l);\n  }\n  decode(l, G) {\n    return l.length === 0 ? \"\" : new this.util.TextDecoder(G).decode(l);\n  }\n  isTypedArray(l) {\n    return this.util.types.isFloat32Array(l) || this.util.types.isInt32Array(l) || this.util.types.isUint8Array(l) || this.util.types.isUint8ClampedArray(l);\n  }\n}\nA().get(\"IS_NODE\") && !A().get(\"IS_BROWSER\") && A().setPlatform(\"node\", new RC());\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Xl(I, l = \"float32\", G) {\n  return l = l || \"float32\", dZ(I), new nG(I, l, G);\n}\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pC(I, l) {\n  const G = R(I, \"x\", \"cast\");\n  if (!nn(l))\n    throw new Error(`Failed to cast to unknown dtype ${l}`);\n  if (l === \"string\" && G.dtype !== \"string\" || l !== \"string\" && G.dtype === \"string\")\n    throw new Error(\"Only strings can be casted to strings\");\n  const Z = { x: G }, h = { dtype: l };\n  return P.runKernel(_0, Z, h);\n}\nconst hl = /* @__PURE__ */ E({ cast_: pC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction FC(I) {\n  const G = { x: R(I, \"x\", \"clone\", \"string_or_numeric\") };\n  return P.runKernel(ag, G);\n}\nconst lh = /* @__PURE__ */ E({ clone_: FC });\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yC(I, l = !1) {\n  console.log(I.toString(l));\n}\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nam();\nconst NC = {\n  buffer: Xl,\n  cast: hl,\n  clone: lh,\n  print: yC\n};\n$n(NC);\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction PC(I, l) {\n  let G = R(I, \"a\", \"add\"), Z = R(l, \"b\", \"add\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel(I0, h);\n}\nconst O = /* @__PURE__ */ E({ add_: PC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction JC(I, l) {\n  let G = R(I, \"a\", \"floorDiv\"), Z = R(l, \"b\", \"floorDiv\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel(Yg, h);\n}\nconst Sm = /* @__PURE__ */ E({ floorDiv_: JC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction EC(I, l) {\n  let G = R(I, \"a\", \"div\"), Z = R(l, \"b\", \"div\");\n  if ([G, Z] = lG(G, Z), G.dtype === \"int32\" && Z.dtype === \"int32\")\n    return Sm(G, Z);\n  const h = { a: G, b: Z }, g = {};\n  return P.runKernel(hg, h, g);\n}\nconst Vl = /* @__PURE__ */ E({ div_: EC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction xC(I, l) {\n  let G = R(I, \"a\", \"mul\"), Z = R(l, \"b\", \"mul\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel(Xg, h);\n}\nconst N = /* @__PURE__ */ E({ mul_: xC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction UC(I) {\n  const l = R(I, \"x\", \"abs\");\n  if (l.dtype === \"complex64\") {\n    const G = { x: l };\n    return P.runKernel(ic, G);\n  } else {\n    const G = { x: l };\n    return P.runKernel(bc, G);\n  }\n}\nconst PG = /* @__PURE__ */ E({ abs_: UC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction HC(I) {\n  const G = { x: R(I, \"x\", \"acos\") };\n  return P.runKernel(r0, G);\n}\nconst KC = /* @__PURE__ */ E({ acos_: HC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction AC(I) {\n  const G = { x: R(I, \"x\", \"acosh\") };\n  return P.runKernel(j0, G);\n}\nconst kC = /* @__PURE__ */ E({ acosh_: AC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zC(I, l = null, G = !1) {\n  const h = { x: R(I, \"x\", \"all\", \"bool\") }, g = { axis: l, keepDims: G };\n  return P.runKernel(qW, h, g);\n}\nconst Rm = /* @__PURE__ */ E({ all_: zC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction LC(I, l = null, G = !1) {\n  const h = { x: R(I, \"x\", \"any\", \"bool\") }, g = { axis: l, keepDims: G };\n  return P.runKernel($W, h, g);\n}\nconst nW = /* @__PURE__ */ E({ any_: LC });\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction MC(I, l = 0) {\n  const Z = { x: R(I, \"x\", \"argMax\") }, h = { axis: l };\n  return P.runKernel(cc, Z, h);\n}\nconst P0 = /* @__PURE__ */ E({ argMax_: MC });\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wC(I, l = 0) {\n  const Z = { x: R(I, \"x\", \"argMin\") }, h = { axis: l };\n  return P.runKernel(dc, Z, h);\n}\nconst QC = /* @__PURE__ */ E({ argMin_: wC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vC(I) {\n  const G = { x: R(I, \"x\", \"asin\") };\n  return P.runKernel(D0, G);\n}\nconst rC = /* @__PURE__ */ E({ asin_: vC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jC(I) {\n  const G = { x: R(I, \"x\", \"asinh\") };\n  return P.runKernel(f0, G);\n}\nconst DC = /* @__PURE__ */ E({ asinh_: jC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction fC(I) {\n  const G = { x: R(I, \"x\", \"atan\") };\n  return P.runKernel(O0, G);\n}\nconst OC = /* @__PURE__ */ E({ atan_: fC });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qC(I, l) {\n  let G = R(I, \"a\", \"atan2\"), Z = R(l, \"b\", \"atan2\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel($0, h);\n}\nconst $C = /* @__PURE__ */ E({ atan2_: qC });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _C(I) {\n  const G = { x: R(I, \"x\", \"atanh\") };\n  return P.runKernel(q0, G);\n}\nconst lX = /* @__PURE__ */ E({ atanh_: _C });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wg(I, l, G, Z, h = \"NHWC\", g) {\n  const b = I[3], c = [...l, b], d = YZ(h);\n  return CG(I, c, G, g, Z, null, null, d);\n}\nfunction sI(I, l, G, Z, h, g, b = \"channelsLast\") {\n  const [c, d] = J0(l);\n  let W;\n  if (b === \"channelsLast\")\n    W = [c, d, I[3], I[3]];\n  else if (b === \"channelsFirst\")\n    W = [c, d, I[1], I[1]];\n  else\n    throw new Error(`Unknown dataFormat ${b}`);\n  return CG(I, W, G, Z, h, g, !1, b);\n}\nfunction WZ(I, l, G, Z, h, g, b = \"NDHWC\") {\n  const [c, d, W] = CW(l);\n  let Y, V;\n  if (b === \"NDHWC\")\n    V = \"channelsLast\", Y = [c, d, W, I[4], I[4]];\n  else if (b === \"NCDHW\")\n    V = \"channelsFirst\", Y = [c, d, W, I[1], I[1]];\n  else\n    throw new Error(`Unknown dataFormat ${b}`);\n  return EZ(I, Y, G, Z, h, !1, V, g);\n}\nfunction CG(I, l, G, Z, h, g, b = !1, c = \"channelsLast\") {\n  let [d, W, Y, V] = [-1, -1, -1, -1];\n  if (c === \"channelsLast\")\n    [d, W, Y, V] = I;\n  else if (c === \"channelsFirst\")\n    [d, V, W, Y] = I;\n  else\n    throw new Error(`Unknown dataFormat ${c}`);\n  const [a, i, , m] = l, [T, s] = J0(G), [o, B] = J0(Z), C = kh(a, o), n = kh(i, B), { padInfo: X, outHeight: t, outWidth: e } = ZX(h, W, Y, T, s, C, n, g, c), S = b ? m * V : m;\n  let p;\n  return c === \"channelsFirst\" ? p = [d, S, t, e] : c === \"channelsLast\" && (p = [d, t, e, S]), {\n    batchSize: d,\n    dataFormat: c,\n    inHeight: W,\n    inWidth: Y,\n    inChannels: V,\n    outHeight: t,\n    outWidth: e,\n    outChannels: S,\n    padInfo: X,\n    strideHeight: T,\n    strideWidth: s,\n    filterHeight: a,\n    filterWidth: i,\n    effectiveFilterHeight: C,\n    effectiveFilterWidth: n,\n    dilationHeight: o,\n    dilationWidth: B,\n    inShape: I,\n    outShape: p,\n    filterShape: l\n  };\n}\nfunction EZ(I, l, G, Z, h, g = !1, b = \"channelsLast\", c) {\n  let [d, W, Y, V, a] = [-1, -1, -1, -1, -1];\n  if (b === \"channelsLast\")\n    [d, W, Y, V, a] = I;\n  else if (b === \"channelsFirst\")\n    [d, a, W, Y, V] = I;\n  else\n    throw new Error(`Unknown dataFormat ${b}`);\n  const [i, m, T, , s] = l, [o, B, C] = CW(G), [n, X, t] = CW(Z), e = kh(i, n), S = kh(m, X), p = kh(T, t), { padInfo: F, outDepth: x, outHeight: H, outWidth: K } = hX(h, W, Y, V, o, B, C, e, S, p, c), z = g ? s * a : s;\n  let k;\n  return b === \"channelsFirst\" ? k = [d, z, x, H, K] : b === \"channelsLast\" && (k = [d, x, H, K, z]), {\n    batchSize: d,\n    dataFormat: b,\n    inDepth: W,\n    inHeight: Y,\n    inWidth: V,\n    inChannels: a,\n    outDepth: x,\n    outHeight: H,\n    outWidth: K,\n    outChannels: z,\n    padInfo: F,\n    strideDepth: o,\n    strideHeight: B,\n    strideWidth: C,\n    filterDepth: i,\n    filterHeight: m,\n    filterWidth: T,\n    effectiveFilterDepth: e,\n    effectiveFilterHeight: S,\n    effectiveFilterWidth: p,\n    dilationDepth: n,\n    dilationHeight: X,\n    dilationWidth: t,\n    inShape: I,\n    outShape: k,\n    filterShape: l\n  };\n}\nfunction GX(I, l, G, Z, h) {\n  Z == null && (Z = LY(I, l, G));\n  const g = I[0], b = I[1], c = E0((g - l + 2 * Z) / G + 1, h), d = E0((b - l + 2 * Z) / G + 1, h);\n  return [c, d];\n}\nfunction IX(I, l, G, Z, h, g) {\n  h == null && (h = LY(I, l[0], Z[0]));\n  const b = [0, 0, 0, G];\n  for (let c = 0; c < 3; c++)\n    I[c] + 2 * h >= l[c] && (b[c] = E0((I[c] - l[c] + 2 * h) / Z[c] + 1, g));\n  return b;\n}\nfunction LY(I, l, G, Z = 1) {\n  const h = kh(l, Z);\n  return Math.floor((I[0] * (G - 1) - G + h) / 2);\n}\nfunction J0(I) {\n  return typeof I == \"number\" ? [I, I, I] : I.length === 2 ? [I[0], I[1], 1] : I;\n}\nfunction CW(I) {\n  return typeof I == \"number\" ? [I, I, I] : I;\n}\nfunction kh(I, l) {\n  return l <= 1 ? I : I + (I - 1) * (l - 1);\n}\nfunction ZX(I, l, G, Z, h, g, b, c, d) {\n  let W, Y, V;\n  if (typeof I == \"number\") {\n    W = { top: I, bottom: I, left: I, right: I, type: I === 0 ? \"VALID\" : \"NUMBER\" };\n    const i = GX([l, G], g, Z, I, c);\n    Y = i[0], V = i[1];\n  } else if (I === \"same\") {\n    Y = Math.ceil(l / Z), V = Math.ceil(G / h);\n    const a = Math.max(0, (Y - 1) * Z + g - l), i = Math.max(0, (V - 1) * h + b - G), m = Math.floor(a / 2), T = a - m, s = Math.floor(i / 2), o = i - s;\n    W = { top: m, bottom: T, left: s, right: o, type: \"SAME\" };\n  } else if (I === \"valid\")\n    W = { top: 0, bottom: 0, left: 0, right: 0, type: \"VALID\" }, Y = Math.ceil((l - g + 1) / Z), V = Math.ceil((G - b + 1) / h);\n  else if (typeof I == \"object\") {\n    const a = d === \"channelsLast\" ? I[1][0] : I[2][0], i = d === \"channelsLast\" ? I[1][1] : I[2][1], m = d === \"channelsLast\" ? I[2][0] : I[3][0], T = d === \"channelsLast\" ? I[2][1] : I[3][1];\n    W = { top: a, bottom: i, left: m, right: T, type: a === 0 && i === 0 && m === 0 && T === 0 ? \"VALID\" : \"EXPLICIT\" }, Y = E0((l - g + a + i) / Z + 1, c), V = E0((G - b + m + T) / h + 1, c);\n  } else\n    throw Error(`Unknown padding parameter: ${I}`);\n  return { padInfo: W, outHeight: Y, outWidth: V };\n}\nfunction hX(I, l, G, Z, h, g, b, c, d, W, Y) {\n  let V, a, i, m;\n  if (I === \"valid\" && (I = 0), typeof I == \"number\") {\n    V = {\n      top: I,\n      bottom: I,\n      left: I,\n      right: I,\n      front: I,\n      back: I,\n      type: I === 0 ? \"VALID\" : \"NUMBER\"\n    };\n    const s = IX([l, G, Z, 1], [c, d, W], 1, [h, g, b], I, Y);\n    a = s[0], i = s[1], m = s[2];\n  } else if (I === \"same\") {\n    a = Math.ceil(l / h), i = Math.ceil(G / g), m = Math.ceil(Z / b);\n    const T = (a - 1) * h + c - l, s = (i - 1) * g + d - G, o = (m - 1) * b + W - Z, B = Math.floor(T / 2), C = T - B, n = Math.floor(s / 2), X = s - n, t = Math.floor(o / 2), e = o - t;\n    V = { top: n, bottom: X, left: t, right: e, front: B, back: C, type: \"SAME\" };\n  } else\n    throw Error(`Unknown padding parameter: ${I}`);\n  return { padInfo: V, outDepth: a, outHeight: i, outWidth: m };\n}\nfunction E0(I, l) {\n  if (!l)\n    return Math.trunc(I);\n  switch (l) {\n    case \"round\":\n      return Math.round(I);\n    case \"ceil\":\n      return Math.ceil(I);\n    case \"floor\":\n      return Math.floor(I);\n    default:\n      throw new Error(`Unknown roundingMode ${l}`);\n  }\n}\nfunction ch(I) {\n  const [l, G, Z] = J0(I);\n  return l === 1 && G === 1 && Z === 1;\n}\nfunction pG(I, l) {\n  return ch(I) || ch(l);\n}\nfunction dh(I) {\n  return J0(I).every((l) => l > 0);\n}\nfunction YZ(I) {\n  if (I === \"NHWC\")\n    return \"channelsLast\";\n  if (I === \"NCHW\")\n    return \"channelsFirst\";\n  throw new Error(`Unknown dataFormat ${I}`);\n}\nfunction wG(I, l, G) {\n  if (G != null) {\n    if (typeof l == \"string\")\n      throw Error(`Error in ${I}: pad must be an integer when using dimRoundingMode ${G} but got pad ${l}.`);\n    if (typeof l == \"number\")\n      u(Mh(l), () => `Error in ${I}: pad must be an integer when using dimRoundingMode ${G} but got pad ${l}.`);\n    else if (typeof l == \"object\")\n      l.forEach((Z) => {\n        Z.forEach((h) => {\n          u(Mh(h), () => `Error in ${I}: pad must be an integer when using dimRoundingMode ${G} but got pad ${h}.`);\n        });\n      });\n    else\n      throw Error(`Error in ${I}: Unknown padding parameter: ${l}`);\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gX(I, l) {\n  const Z = { x: R(I, \"x\", \"reshape\", \"string_or_numeric\") }, h = { shape: l };\n  return P.runKernel(jc, Z, h);\n}\nconst J = /* @__PURE__ */ E({ reshape_: gX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction bX(I, l, G, Z, h) {\n  const g = R(I, \"x\", \"avgPool\", \"float32\"), b = 1;\n  u(pG(G, b), () => `Error in avgPool: Either strides or dilations must be 1. Got strides ${G} and dilations '${b}'`);\n  let c = g, d = !1;\n  g.rank === 3 && (d = !0, c = J(g, [1, g.shape[0], g.shape[1], g.shape[2]])), u(c.rank === 4, () => `Error in avgPool: x must be rank 4 but got rank ${c.rank}.`), wG(\"avgPool\", Z, h);\n  const W = { x: c }, Y = { filterSize: l, strides: G, pad: Z, dimRoundingMode: h };\n  let V = P.runKernel(Wc, W, Y);\n  return V = hl(V, g.dtype), d ? J(V, [V.shape[1], V.shape[2], V.shape[3]]) : V;\n}\nconst MY = /* @__PURE__ */ E({ avgPool_: bX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction cX(I, l, G, Z, h, g = \"NDHWC\") {\n  const b = R(I, \"x\", \"avgPool3d\", \"float32\");\n  let c = b, d = !1;\n  b.rank === 4 && (d = !0, c = J(b, [1, b.shape[0], b.shape[1], b.shape[2], b.shape[3]])), u(c.rank === 5, () => `Error in avgPool3d: x must be rank 5 but got rank ${c.rank}.`), u(g === \"NDHWC\", () => `Error in avgPool3d: Only NDHWC is currently supported, but got dataFormat of ${g}`), u(typeof G == \"number\" && G > 0 || Array.isArray(G) && G[0] > 0 && G[1] > 0 && G[2] > 0, () => `Error in avgPool3d: Stride must be > 0, but got '${G}'`), wG(\"avgPool3d\", Z, h);\n  const W = { x: c }, Y = { filterSize: l, strides: G, pad: Z, dimRoundingMode: h, dataFormat: g };\n  let V = P.runKernel(Yc, W, Y);\n  return V = hl(V, c.dtype), d ? J(V, [V.shape[1], V.shape[2], V.shape[3], V.shape[4]]) : V;\n}\nconst dX = /* @__PURE__ */ E({ avgPool3d_: cX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction WX(I, l = 0) {\n  u(I.length >= 1, () => \"Pass at least one tensor to concat\");\n  const G = sm(I, \"tensors\", \"concat\", \"string_or_numeric\");\n  if (G[0].dtype === \"complex64\" && G.forEach((g) => {\n    if (g.dtype !== \"complex64\")\n      throw new Error(`Cannot concatenate complex64 tensors with a tensor\n          with dtype ${g.dtype}. `);\n  }), G.length === 1)\n    return lh(G[0]);\n  const Z = G, h = { axis: l };\n  return P.runKernel(mc, Z, h);\n}\nconst zG = /* @__PURE__ */ E({ concat_: WX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction YX(I, l, G = !1, Z = !1) {\n  let h = R(I, \"a\", \"matMul\"), g = R(l, \"b\", \"matMul\");\n  [h, g] = lG(h, g);\n  const b = { a: h, b: g }, c = { transposeA: G, transposeB: Z };\n  return P.runKernel(Vc, b, c);\n}\nconst Fl = /* @__PURE__ */ E({ matMul_: YX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction VX(I) {\n  const G = { x: R(I, \"x\", \"sigmoid\", \"float32\") };\n  return P.runKernel(Jg, G);\n}\nconst h0 = /* @__PURE__ */ E({ sigmoid_: VX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction aX(I, l, G) {\n  const Z = R(I, \"x\", \"slice\", \"string_or_numeric\");\n  if (Z.rank === 0)\n    throw new Error(\"Slicing scalar is not possible\");\n  const h = { x: Z }, g = { begin: l, size: G };\n  return P.runKernel($c, h, g);\n}\nconst zl = /* @__PURE__ */ E({ slice_: aX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction iX(I) {\n  const G = { x: R(I, \"x\", \"tanh\", \"float32\") };\n  return P.runKernel(Ag, G);\n}\nconst cd = /* @__PURE__ */ E({ tanh_: iX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mX(I, l, G) {\n  const Z = R(I, \"x\", \"batchToSpaceND\"), h = l.reduce((c, d) => c * d);\n  u(Z.rank >= 1 + l.length, () => `input rank is ${Z.rank} but should be > than blockShape.length ${l.length}`), u(G.length === l.length, () => `crops.length is ${G.length} but should be equal to blockShape.length  ${l.length}`), u(Z.shape[0] % h === 0, () => `input tensor batch is ${Z.shape[0]} but is not divisible by the product of the elements of blockShape ${l.join(\" * \")} === ${h}`);\n  const g = { x: Z }, b = { blockShape: l, crops: G };\n  return P.runKernel(ac, g, b);\n}\nconst wY = /* @__PURE__ */ E({ batchToSpaceND_: mX });\nfunction TX(I) {\n  let l;\n  return I.rank === 0 || I.rank === 1 ? l = J(I, [1, 1, 1, I.size]) : I.rank === 2 ? l = J(I, [1, 1, I.shape[0], I.shape[1]]) : I.rank === 3 ? l = J(I, [1, I.shape[0], I.shape[1], I.shape[2]]) : l = I, l;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sX(I, l, G, Z, h, g) {\n  g == null && (g = 1e-3);\n  const b = R(I, \"x\", \"batchNorm\"), c = R(l, \"mean\", \"batchNorm\"), d = R(G, \"variance\", \"batchNorm\");\n  let W;\n  h != null && (W = R(h, \"scale\", \"batchNorm\"));\n  let Y;\n  Z != null && (Y = R(Z, \"offset\", \"batchNorm\")), u(c.rank === d.rank, () => \"Batch normalization gradient requires mean and variance to have equal ranks.\"), u(Y == null || c.rank === Y.rank, () => \"Batch normalization gradient requires mean and offset to have equal ranks.\"), u(W == null || c.rank === W.rank, () => \"Batch normalization gradient requires mean and scale to have equal ranks.\");\n  const a = {\n    x: TX(b),\n    scale: W,\n    offset: Y,\n    mean: c,\n    variance: d\n  }, i = { varianceEpsilon: g }, m = P.runKernel(uc, a, i);\n  return J(m, b.shape);\n}\nconst dd = /* @__PURE__ */ E({ batchNorm_: sX });\nfunction oX(I, l, G, Z, h, g) {\n  const b = R(I, \"x\", \"batchNorm\"), c = R(l, \"mean\", \"batchNorm\"), d = R(G, \"variance\", \"batchNorm\");\n  let W;\n  h != null && (W = R(h, \"scale\", \"batchNorm\"));\n  let Y;\n  return Z != null && (Y = R(Z, \"offset\", \"batchNorm\")), u(b.rank === 2, () => `Error in batchNorm2D: x must be rank 2 but got rank ${b.rank}.`), u(c.rank === 2 || c.rank === 1, () => `Error in batchNorm2D: mean must be rank 2 or rank 1 but got rank ${c.rank}.`), u(d.rank === 2 || d.rank === 1, () => `Error in batchNorm2D: variance must be rank 2 or rank 1 but got rank ${d.rank}.`), W != null && u(W.rank === 2 || W.rank === 1, () => `Error in batchNorm2D: scale must be rank 2 or rank 1 but got rank ${W.rank}.`), Y != null && u(Y.rank === 2 || Y.rank === 1, () => `Error in batchNorm2D: offset must be rank 2 or rank 1 but got rank ${Y.rank}.`), dd(b, c, d, Y, W, g);\n}\nconst BX = /* @__PURE__ */ E({ batchNorm2d_: oX });\nfunction nX(I, l, G, Z, h, g) {\n  const b = R(I, \"x\", \"batchNorm\"), c = R(l, \"mean\", \"batchNorm\"), d = R(G, \"variance\", \"batchNorm\");\n  let W;\n  h != null && (W = R(h, \"scale\", \"batchNorm\"));\n  let Y;\n  return Z != null && (Y = R(Z, \"offset\", \"batchNorm\")), u(b.rank === 3, () => `Error in batchNorm3D: x must be rank 3 but got rank ${b.rank}.`), u(c.rank === 3 || c.rank === 1, () => `Error in batchNorm3D: mean must be rank 3 or rank 1 but got rank ${c.rank}.`), u(d.rank === 3 || d.rank === 1, () => `Error in batchNorm3D: variance must be rank 3 or rank 1 but got rank ${d.rank}.`), W != null && u(W.rank === 3 || W.rank === 1, () => `Error in batchNorm3D: scale must be rank 3 or rank 1 but got rank ${W.rank}.`), Y != null && u(Y.rank === 3 || Y.rank === 1, () => `Error in batchNorm3D: offset must be rank 3 or rank 1 but got rank ${Y.rank}.`), dd(b, c, d, Y, W, g);\n}\nconst CX = /* @__PURE__ */ E({ batchNorm3d_: nX });\nfunction XX(I, l, G, Z, h, g) {\n  const b = R(I, \"x\", \"batchNorm\"), c = R(l, \"mean\", \"batchNorm\"), d = R(G, \"variance\", \"batchNorm\");\n  let W;\n  h != null && (W = R(h, \"scale\", \"batchNorm\"));\n  let Y;\n  return Z != null && (Y = R(Z, \"offset\", \"batchNorm\")), u(b.rank === 4, () => `Error in batchNorm4D: x must be rank 4 but got rank ${b.rank}.`), u(c.rank === 4 || c.rank === 1, () => `Error in batchNorm4D: mean must be rank 4 or rank 1 but got rank ${c.rank}.`), u(d.rank === 4 || d.rank === 1, () => `Error in batchNorm4D: variance must be rank 4 or rank 1 but got rank ${d.rank}.`), W != null && u(W.rank === 4 || W.rank === 1, () => `Error in batchNorm4D: scale must be rank 4 or rank 1 but got rank ${W.rank}.`), Y != null && u(Y.rank === 4 || Y.rank === 1, () => `Error in batchNorm4D: offset must be rank 4 or rank 1 but got rank ${Y.rank}.`), dd(b, c, d, Y, W, g);\n}\nconst tX = /* @__PURE__ */ E({ batchNorm4d_: XX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction uX(I, l, G) {\n  const Z = R(I, \"x\", \"bincount\"), h = R(l, \"weights\", \"bincount\");\n  u(Z.dtype === \"int32\", () => `Error in bincount: input dtype must be int32, but got ${Z.dtype}`), u(G >= 0, () => `size must be non-negative, but got ${G}.`), u(h.size === Z.size || h.size === 0, () => `Error in bincount: weights must have the same size as input or0-length, but got input shape: ${Z.shape}, weights shape: ${h.shape}.`);\n  const g = { x: Z, weights: h }, b = { size: G };\n  return P.runKernel(GY, g, b);\n}\nconst eX = /* @__PURE__ */ E({ bincount_: uX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction SX(I, l) {\n  let G = R(I, \"broadcastTo\", \"x\");\n  const Z = G.shape;\n  if (dZ(l), l.length < G.rank)\n    throw new Error(`broadcastTo(): shape.length=${l.length} < input.rank=${G.rank}.`);\n  if (l.length > G.rank) {\n    const W = G.shape.slice();\n    for (; W.length < l.length; )\n      W.unshift(1);\n    G = J(G, W);\n  }\n  const h = G.shape, g = Array.from(l);\n  for (let W = l.length - 1; W >= 0; W--)\n    if (h[W] === l[W])\n      g[W] = 1;\n    else if (G.shape[W] !== 1)\n      throw new Error(`broadcastTo(): [${Z}] cannot be broadcast to [${l}].`);\n  if (g.map((W, Y) => W > 1 ? Y : -1).filter((W) => W >= 0).length === 0)\n    return lh(G);\n  const c = { x: G }, d = { reps: g };\n  return P.runKernel(kg, c, d);\n}\nconst y0 = /* @__PURE__ */ E({ broadcastTo_: SX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction RX(I) {\n  const G = { x: R(I, \"x\", \"ceil\", \"float32\") };\n  return P.runKernel(lg, G);\n}\nconst pX = /* @__PURE__ */ E({ ceil_: RX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Wd(I, l, G) {\n  dZ(I), G = G || l0(l);\n  const Z = { shape: I, value: l, dtype: G };\n  return P.runKernel(sY, {}, Z);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction FX(I, l, G) {\n  const Z = R(I, \"x\", \"clipByValue\");\n  if (u(l <= G, () => `Error in clip: min (${l}) must be less than or equal to max (${G}).`), l === G)\n    return Wd(Z.shape, l, Z.dtype);\n  const h = { x: Z }, g = { clipValueMin: l, clipValueMax: G };\n  return P.runKernel(Gg, h, g);\n}\nconst II = /* @__PURE__ */ E({ clipByValue_: FX });\nfunction yX(I) {\n  return zG(\n    I,\n    0\n    /* axis */\n  );\n}\nconst NX = /* @__PURE__ */ E({ concat1d_: yX });\nfunction PX(I, l) {\n  return zG(I, l);\n}\nconst JX = /* @__PURE__ */ E({ concat2d_: PX });\nfunction EX(I, l) {\n  return zG(I, l);\n}\nconst xX = /* @__PURE__ */ E({ concat3d_: EX });\nfunction UX(I, l) {\n  return zG(I, l);\n}\nconst HX = /* @__PURE__ */ E({ concat4d_: UX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction KX(I, l, G, Z, h = \"NHWC\", g = [1, 1], b) {\n  const c = R(I, \"x\", \"conv2d\", \"float32\"), d = R(l, \"filter\", \"conv2d\", \"float32\");\n  let W = c, Y = !1;\n  c.rank === 3 && (Y = !0, W = J(c, [1, c.shape[0], c.shape[1], c.shape[2]])), u(W.rank === 4, () => `Error in conv2d: input must be rank 4, but got rank ${W.rank}.`), u(d.rank === 4, () => `Error in conv2d: filter must be rank 4, but got rank ${d.rank}.`), wG(\"conv2d\", Z, b);\n  const V = h === \"NHWC\" ? W.shape[3] : W.shape[1];\n  u(V === d.shape[2], () => `Error in conv2d: depth of input (${V}) must match input depth for filter ${d.shape[2]}.`), u(pG(G, g), () => `Error in conv2D: Either strides or dilations must be 1. Got strides ${G} and dilations '${g}'`), u(dh(g), () => \"Error in conv2D: Dilated rates should be larger than 0.\"), u(dh(G), () => \"Error in conv2D: Strides should be larger than 0.\");\n  const a = { x: W, filter: d }, i = { strides: G, pad: Z, dataFormat: h, dilations: g, dimRoundingMode: b }, m = P.runKernel(Tc, a, i);\n  return Y ? J(m, [m.shape[1], m.shape[2], m.shape[3]]) : m;\n}\nconst Wh = /* @__PURE__ */ E({ conv2d_: KX });\nfunction AX(I, l, G, Z, h = \"NWC\", g = 1, b) {\n  const c = R(I, \"x\", \"conv1d\"), d = R(l, \"filter\", \"conv1d\");\n  let W = c, Y = !1;\n  c.rank === 2 && (Y = !0, W = J(c, [1, c.shape[0], c.shape[1]])), u(W.rank === 3, () => `Error in conv1d: input must be rank 3, but got rank ${W.rank}.`), u(d.rank === 3, () => `Error in conv1d: filter must be rank 3, but got rank ${d.rank}.`), wG(\"conv1d\", Z, b), u(W.shape[2] === d.shape[1], () => `Error in conv1d: depth of input (${W.shape[2]}) must match input depth for filter ${d.shape[1]}.`), u(pG(G, g), () => `Error in conv1D: Either stride or dilation must be 1. Got stride ${G} and dilation '${g}'`), u(dh(g), () => \"Error in conv1D: Dilated rates should be larger than 0.\"), u(dh(G), () => \"Error in conv1D: Stride should be larger than 0.\"), u(h === \"NWC\", () => `Error in conv1d: got dataFormat of ${h} but only NWC is currently supported.`);\n  const V = J(d, [1, d.shape[0], d.shape[1], d.shape[2]]), a = J(W, [W.shape[0], 1, W.shape[1], W.shape[2]]), s = Wh(a, V, [1, G], Z, \"NHWC\", [1, g], b);\n  return Y ? J(s, [s.shape[2], s.shape[3]]) : J(s, [s.shape[0], s.shape[2], s.shape[3]]);\n}\nconst pm = /* @__PURE__ */ E({ conv1d_: AX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kX(I, l, G, Z, h, g = \"NHWC\", b) {\n  u(I.length === l.rank, () => `Length of inShape (${I.length}) and rank of dy (${l.rank}) must match`);\n  let c = I, d = l, W = !1;\n  l.rank === 3 && (W = !0, d = J(l, [1, l.shape[0], l.shape[1], l.shape[2]]), c = [1, I[0], I[1], I[2]]), u(c.length === 4, () => `Error in conv2dDerInput: inShape must be length 4, but got length ${c.length}.`), u(d.rank === 4, () => `Error in conv2dDerInput: dy must be rank 4, but got rank ${d.rank}`), u(G.rank === 4, () => `Error in conv2dDerInput: filter must be rank 4, but got rank ${G.rank}`);\n  const Y = g === \"NHWC\" ? c[3] : c[1], V = g === \"NHWC\" ? d.shape[3] : d.shape[1];\n  u(Y === G.shape[2], () => `Error in conv2dDerInput: depth of input (${Y}) must match input depth for filter ${G.shape[2]}.`), u(V === G.shape[3], () => `Error in conv2dDerInput: depth of output (${V}) must match output depth for filter ${G.shape[3]}.`), wG(\"conv2dDerInput\", h, b);\n  const a = { dy: d, filter: G }, i = { strides: Z, pad: h, dataFormat: g, dimRoundingMode: b, inputShape: c }, m = P.runKernel(sc, a, i);\n  return W ? J(m, [m.shape[1], m.shape[2], m.shape[3]]) : m;\n}\nconst QY = /* @__PURE__ */ E({ conv2DBackpropInput_: kX });\nfunction zX(I, l, G, Z, h, g) {\n  const b = R(I, \"x\", \"conv2dTranspose\"), c = R(l, \"filter\", \"conv2dTranspose\");\n  return QY(G, b, c, Z, h, \"NHWC\", g);\n}\nconst Fm = /* @__PURE__ */ E({ conv2dTranspose_: zX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction LX(I, l, G, Z, h = \"NDHWC\", g = [1, 1, 1]) {\n  const b = R(I, \"x\", \"conv3d\"), c = R(l, \"filter\", \"conv3d\");\n  let d = b, W = !1;\n  b.rank === 4 && (W = !0, d = J(b, [1, b.shape[0], b.shape[1], b.shape[2], b.shape[3]])), u(d.rank === 5, () => `Error in conv3d: input must be rank 5, but got rank ${d.rank}.`), u(c.rank === 5, () => `Error in conv3d: filter must be rank 5, but got rank ${c.rank}.`), u(d.shape[4] === c.shape[3], () => `Error in conv3d: depth of input (${d.shape[4]}) must match input depth for filter ${c.shape[3]}.`), u(pG(G, g), () => `Error in conv3D: Either strides or dilations must be 1. Got strides ${G} and dilations '${g}'`), u(h === \"NDHWC\", () => `Error in conv3d: got dataFormat of ${h} but only NDHWC is currently supported.`), u(dh(g), () => \"Error in conv3D: Dilated rates should be larger than 0.\"), u(dh(G), () => \"Error in conv3D: Strides should be larger than 0.\");\n  const Y = { x: d, filter: c }, V = { strides: G, pad: Z, dataFormat: h, dilations: g }, a = P.runKernel(oc, Y, V);\n  return W ? J(a, [a.shape[1], a.shape[2], a.shape[3], a.shape[4]]) : a;\n}\nconst MX = /* @__PURE__ */ E({ conv3d_: LX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wX(I, l, G, Z, h) {\n  u(I.length === l.rank, () => `Length of inShape (${I.length}) and rank of dy (${l.rank}) must match`);\n  let g = I, b = l, c = !1;\n  l.rank === 4 && (c = !0, b = J(l, [1, l.shape[0], l.shape[1], l.shape[2], l.shape[3]]), g = [1, I[0], I[1], I[2], I[3]]);\n  const d = g[4], W = b.shape[4];\n  u(g.length === 5, () => `Error in conv3dDerInput: inShape must be length 5, but got length ${g.length}.`), u(b.rank === 5, () => `Error in conv3dDerInput: dy must be rank 5, but got rank ${b.rank}`), u(G.rank === 5, () => `Error in conv3dDerInput: filter must be rank 5, but got rank ${G.rank}`), u(d === G.shape[3], () => `Error in conv3dDerInput: depth of input (${d}) must match input depth for filter ${G.shape[3]}.`), u(W === G.shape[4], () => `Error in conv3dDerInput: depth of output (${W}) must match output depth for filter ${G.shape[4]}.`);\n  const Y = { dy: b, filter: G }, V = { pad: h, strides: Z, inputShape: g }, a = P.runKernel(bY, Y, V);\n  return c ? J(a, [a.shape[1], a.shape[2], a.shape[3], a.shape[4]]) : a;\n}\nconst ym = /* @__PURE__ */ E({ conv3DBackpropInput_: wX });\nfunction QX(I, l, G, Z, h) {\n  const g = R(I, \"x\", \"conv3dTranspose\"), b = R(l, \"filter\", \"conv3dTranspose\");\n  return ym(G, g, b, Z, h);\n}\nconst vX = /* @__PURE__ */ E({ conv3dTranspose_: QX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction rX(I) {\n  const G = { x: R(I, \"x\", \"cos\", \"float32\") };\n  return P.runKernel(Ig, G);\n}\nconst vY = /* @__PURE__ */ E({ cos_: rX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jX(I) {\n  const G = { x: R(I, \"x\", \"cosh\", \"float32\") };\n  return P.runKernel(Zg, G);\n}\nconst Nm = /* @__PURE__ */ E({ cosh_: jX });\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the 'License');\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction DX(I, l = 0, G = !1, Z = !1) {\n  const g = { x: R(I, \"x\", \"cumprod\") }, b = { axis: l, exclusive: G, reverse: Z };\n  return P.runKernel(cY, g, b);\n}\nconst XW = /* @__PURE__ */ E({ cumprod_: DX });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction fX(I, l = 0, G = !1, Z = !1) {\n  const g = { x: R(I, \"x\", \"cumsum\") }, b = { axis: l, exclusive: G, reverse: Z };\n  return P.runKernel(Bc, g, b);\n}\nconst Pm = /* @__PURE__ */ E({ cumsum_: fX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction OX(I, l, G, Z = !1) {\n  const h = R(I, \"x\", \"denseBincount\"), g = R(l, \"weights\", \"denseBincount\");\n  u(h.dtype === \"int32\", () => `Error in denseBincount: input dtype must be int32, but got ${h.dtype}`), u(h.rank <= 2, () => `Error in denseBincount: input must be at most rank 2, but got rank ${h.rank}.`), u(G >= 0, () => `size must be non-negative, but got ${G}.`), u(g.size === h.size || g.size === 0, () => `Error in denseBincount: weights must have the same shape as x or 0-length, but got x shape: ${h.shape}, weights shape: ${g.shape}.`);\n  const b = { x: h, weights: g }, c = { size: G, binaryOutput: Z };\n  return P.runKernel(WY, b, c);\n}\nconst Ga = /* @__PURE__ */ E({ denseBincount_: OX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qX(I, l, G = \"NHWC\") {\n  const Z = R(I, \"x\", \"depthToSpace\", \"float32\"), h = G === \"NHWC\" ? Z.shape[1] : Z.shape[2], g = G === \"NHWC\" ? Z.shape[2] : Z.shape[3], b = G === \"NHWC\" ? Z.shape[3] : Z.shape[1];\n  u(l > 1, () => `blockSize should be > 1 for depthToSpace, but was: ${l}`), u(h * l >= 0, () => `Negative dimension size caused by overflow when multiplying\n    ${h} and ${l}  for depthToSpace with input shape\n    ${Z.shape}`), u(g * l >= 0, () => `Negative dimension size caused by overflow when multiplying\n    ${g} and ${l} for depthToSpace with input shape\n        ${Z.shape}`), u(b % (l * l) === 0, () => `Dimension size must be evenly divisible by ${l * l} but is ${b} for depthToSpace with input shape ${Z.shape}`);\n  const c = { x: Z }, d = { blockSize: l, dataFormat: G };\n  return P.runKernel(YY, c, d);\n}\nconst $X = /* @__PURE__ */ E({ depthToSpace_: qX });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _X(I, l, G, Z, h = \"NHWC\", g = [1, 1], b) {\n  const c = R(I, \"x\", \"depthwiseConv2d\", \"float32\"), d = R(l, \"filter\", \"depthwiseConv2d\", \"float32\");\n  let W = c, Y = !1;\n  c.rank === 3 && (Y = !0, W = J(c, [1, c.shape[0], c.shape[1], c.shape[2]])), u(W.rank === 4, () => `Error in depthwiseConv2d: input must be rank 4, but got rank ${W.rank}.`), u(d.rank === 4, () => `Error in depthwiseConv2d: filter must be rank 4, but got rank ${d.rank}.`);\n  const V = h === \"NHWC\" ? W.shape[3] : W.shape[1];\n  u(V === d.shape[2], () => `Error in depthwiseConv2d: number of input channels (${V}) must match the inChannels dimension in filter ${d.shape[2]}.`), wG(\"depthwiseConv2d\", Z, b);\n  const a = { x: W, filter: d }, i = { strides: G, pad: Z, dataFormat: h, dilations: g, dimRoundingMode: b }, m = P.runKernel(nc, a, i);\n  return Y ? J(m, [m.shape[1], m.shape[2], m.shape[3]]) : m;\n}\nconst rY = /* @__PURE__ */ E({ depthwiseConv2d_: _X });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lt(I, l, G, Z, h = [1, 1], g = \"NHWC\") {\n  const b = R(I, \"x\", \"dilation2d\"), c = R(l, \"filter\", \"dilation2d\");\n  u(b.rank === 3 || b.rank === 4, () => `Error in dilation2d: input must be rank 3 or 4, but got rank ${b.rank}.`), u(c.rank === 3, () => `Error in dilation2d: filter must be rank 3, but got rank ${c.rank}.`), u(g === \"NHWC\", () => `Error in dilation2d: Only NHWC is currently supported, but got dataFormat of ${g}`);\n  let d = b, W = !1;\n  b.rank === 3 && (d = J(b, [1, b.shape[0], b.shape[1], b.shape[2]]), W = !0), u(d.shape[3] === c.shape[2], () => `Error in dilation2d:  input and filter must have the same depth: ${d.shape[3]} vs ${c.shape[2]}`);\n  const Y = { x: d, filter: c }, V = { strides: G, pad: Z, dilations: h }, a = P.runKernel(Cc, Y, V);\n  return W ? J(a, [a.shape[1], a.shape[2], a.shape[3]]) : a;\n}\nconst Gt = /* @__PURE__ */ E({ dilation2d_: lt });\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction rh(I, l) {\n  const G = I.length, Z = [];\n  for (let h = 0; h < G; h++) {\n    const g = G - 1 - h, b = I[g] || 1;\n    (l[l.length - 1 - h] || 1) > 1 && b === 1 && Z.unshift(g);\n  }\n  return Z;\n}\nfunction VG(I, l) {\n  const G = [];\n  for (let Z = 0; Z < l.length; Z++) {\n    const h = I[I.length - Z - 1], g = l.length - Z - 1, b = l[g];\n    (h == null || h === 1 && b > 1) && G.unshift(g);\n  }\n  return G;\n}\nfunction sl(I, l) {\n  const G = Math.max(I.length, l.length), Z = new Array(G);\n  for (let h = 0; h < G; h++) {\n    let g = I[I.length - h - 1];\n    g == null && (g = 1);\n    let b = l[l.length - h - 1];\n    if (b == null && (b = 1), g === 1)\n      Z[G - h - 1] = b;\n    else if (b === 1)\n      Z[G - h - 1] = g;\n    else if (g !== b) {\n      const c = `Operands could not be broadcast together with shapes ${I} and ${l}.`;\n      throw Error(c);\n    } else\n      Z[G - h - 1] = g;\n  }\n  return Z;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction It(I, l) {\n  let G = R(I, \"a\", \"equal\", \"string_or_numeric\"), Z = R(l, \"b\", \"equal\", \"string_or_numeric\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(Xc, h);\n}\nconst vI = /* @__PURE__ */ E({ equal_: It });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Zt(I, l, G) {\n  const Z = R(l, \"a\", \"where\"), h = R(G, \"b\", \"where\"), g = R(I, \"condition\", \"where\", \"bool\"), b = sl(sl(g.shape, Z.shape), h.shape), c = y0(g, b), d = y0(Z, b), W = y0(h, b), Y = {\n    condition: c,\n    t: d,\n    e: W\n  };\n  return P.runKernel(qc, Y);\n}\nconst UG = /* @__PURE__ */ E({ where_: Zt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ht(I) {\n  const G = { x: R(I, \"x\", \"zerosLike\") };\n  return P.runKernel(gd, G);\n}\nconst Sl = /* @__PURE__ */ E({ zerosLike_: ht });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gt(I, l) {\n  let G = R(I, \"a\", \"div\"), Z = R(l, \"b\", \"div\");\n  [G, Z] = lG(G, Z);\n  const h = Vl(G, Z), g = Sl(h), b = vI(Z, g);\n  return UG(b, g, h);\n}\nconst bt = /* @__PURE__ */ E({ divNoNan_: gt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ct(I, l) {\n  const G = R(I, \"t1\", \"dot\"), Z = R(l, \"t2\", \"dot\");\n  u((G.rank === 1 || G.rank === 2) && (Z.rank === 1 || Z.rank === 2), () => `Error in dot: inputs must all be rank 1 or 2, but got ranks ${G.rank} and ${Z.rank}.`);\n  const h = G.rank === 1 ? G.size : G.shape[1], g = Z.rank === 1 ? Z.size : Z.shape[0];\n  if (u(h === g, () => `Error in dot: inner dimensions of inputs must match, but got ${h} and ${g}.`), G.rank === 1 && Z.rank === 1) {\n    const b = J(G, [1, -1]), c = J(Z, [-1, 1]), d = Fl(b, c);\n    return J(d, []);\n  } else if (G.rank === 1 && Z.rank === 2) {\n    const b = J(G, [1, -1]), c = J(Z, [Z.shape[0], Z.shape[1]]), d = Fl(b, c);\n    return J(d, [d.size]);\n  } else if (G.rank === 2 && Z.rank === 1) {\n    const b = J(Z, [-1, 1]), c = Fl(G, b);\n    return J(c, [c.size]);\n  } else {\n    const b = J(Z, [Z.shape[0], Z.shape[1]]);\n    return Fl(G, b);\n  }\n}\nconst dt = /* @__PURE__ */ E({ dot_: ct });\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Wt(I, ...l) {\n  const G = l.map((h, g) => R(h, `tensors${g}`, \"einsum\")), Z = { equation: I };\n  return P.runKernel(iY, G, Z);\n}\nconst C0 = /* @__PURE__ */ E({ einsum_: Wt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Yt(I) {\n  const G = { x: R(I, \"x\", \"elu\", \"float32\") };\n  return P.runKernel(gg, G);\n}\nconst Yd = /* @__PURE__ */ E({ elu_: Yt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Vt(I) {\n  let l = R(I, \"x\", \"erf\");\n  u(l.dtype === \"int32\" || l.dtype === \"float32\", () => \"Input dtype must be `int32` or `float32`.\"), l.dtype === \"int32\" && (l = hl(l, \"float32\"));\n  const G = { x: l };\n  return P.runKernel(bg, G);\n}\nconst Jm = /* @__PURE__ */ E({ erf_: Vt });\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jY(I, l) {\n  for (let G = 0; G < I.length; ++G)\n    if (I[I.length - G - 1] !== l - 1 - G)\n      return !1;\n  return !0;\n}\nfunction Em(I, l, G) {\n  const Z = I.length + l.length, h = [];\n  let g = 0, b = 0;\n  for (let c = 0; c < Z; c++)\n    G.indexOf(c) === -1 ? h.push(I[g++]) : h.push(l[b++]);\n  return h;\n}\nfunction sG(I, l) {\n  const G = [], Z = I.length;\n  for (let g = 0; g < Z; g++)\n    l.indexOf(g) === -1 && G.push(I[g]);\n  const h = l.map((g) => I[g]);\n  return [G, h];\n}\nfunction bG(I, l) {\n  const G = l.map((Z) => 1);\n  return Em(I, G, l);\n}\nfunction XG(I, l, G) {\n  u(jY(l, G), () => `${I} supports only inner-most axes for now. Got axes ${l} and rank-${G} input.`);\n}\nfunction Ol(I, l) {\n  if (jY(I, l))\n    return null;\n  const G = [];\n  for (let Z = 0; Z < l; ++Z)\n    I.indexOf(Z) === -1 && G.push(Z);\n  return I.forEach((Z) => G.push(Z)), G;\n}\nfunction xZ(I) {\n  return I.map((l, G) => [G, l]).sort((l, G) => l[1] - G[1]).map((l) => l[0]);\n}\nfunction GG(I, l) {\n  const G = [];\n  for (let Z = l - I; Z < l; ++Z)\n    G.push(Z);\n  return G;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction at(I, l = null, G = !1) {\n  const h = { x: R(I, \"x\", \"max\") }, g = { reductionIndices: l, keepDims: G };\n  return P.runKernel(Ec, h, g);\n}\nconst RI = /* @__PURE__ */ E({ max_: at });\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction it(I, l = null, G = !1) {\n  const h = { x: R(I, \"x\", \"min\") }, g = { axis: l, keepDims: G };\n  return P.runKernel(Kc, h, g);\n}\nconst Hb = /* @__PURE__ */ E({ min_: it });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mt(I, l) {\n  let G = R(I, \"base\", \"pow\"), Z = R(l, \"exp\", \"pow\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel(tg, h);\n}\nconst Yh = /* @__PURE__ */ E({ pow_: mt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yl(I, l) {\n  if ((mI(I) && l !== \"string\" || Array.isArray(I)) && l !== \"complex64\")\n    throw new Error(\"Error creating a new Scalar: value must be a primitive (number|boolean|string)\");\n  if (l === \"string\" && mI(I) && !(I instanceof Uint8Array))\n    throw new Error(\"When making a scalar from encoded string, the value must be `Uint8Array`.\");\n  return Mg(I, [], [], l);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Tt(I) {\n  const G = { x: R(I, \"x\", \"sqrt\", \"float32\") };\n  return P.runKernel(xg, G);\n}\nconst RG = /* @__PURE__ */ E({ sqrt_: Tt });\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction st(I) {\n  const l = R(I, \"x\", \"square\"), G = {};\n  return P.runKernel(\"Square\", { x: l }, G);\n}\nconst Ml = /* @__PURE__ */ E({ square_: st });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ot(I, l = null, G = !1) {\n  let Z = R(I, \"x\", \"sum\");\n  Z.dtype === \"bool\" && (Z = hl(Z, \"int32\"));\n  const h = { x: Z }, g = { axis: l, keepDims: G };\n  return P.runKernel(_c, h, g);\n}\nconst Yl = /* @__PURE__ */ E({ sum_: ot });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Bt(I, l = \"euclidean\", G = null, Z = !1) {\n  I = R(I, \"x\", \"norm\");\n  const h = xm(I, l, G);\n  let g = h.shape;\n  if (Z) {\n    const b = tl(G, I.shape);\n    g = bG(h.shape, b);\n  }\n  return J(h, g);\n}\nfunction xm(I, l, G = null) {\n  if (I.rank === 0)\n    return PG(I);\n  if (I.rank !== 1 && G === null)\n    return xm(J(I, [-1]), l, G);\n  if (I.rank === 1 || typeof G == \"number\" || Array.isArray(G) && G.length === 1) {\n    if (l === 1)\n      return Yl(PG(I), G);\n    if (l === 1 / 0)\n      return RI(PG(I), G);\n    if (l === -1 / 0)\n      return Hb(PG(I), G);\n    if (l === \"euclidean\" || l === 2)\n      return RG(Yl(Yh(PG(I), yl(2, \"int32\")), G));\n    throw new Error(`Error in norm: invalid ord value: ${l}`);\n  }\n  if (Array.isArray(G) && G.length === 2) {\n    if (l === 1)\n      return RI(Yl(PG(I), G[0]), G[1] - 1);\n    if (l === 1 / 0)\n      return RI(Yl(PG(I), G[1]), G[0]);\n    if (l === -1 / 0)\n      return Hb(Yl(PG(I), G[1]), G[0]);\n    if (l === \"fro\" || l === \"euclidean\")\n      return RG(Yl(Ml(I), G));\n    throw new Error(`Error in norm: invalid ord value: ${l}`);\n  }\n  throw new Error(`Error in norm: invalid axis: ${G}`);\n}\nconst Vd = /* @__PURE__ */ E({ norm_: Bt });\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction nt(I, l = null, G = !1) {\n  return Vd(I, \"euclidean\", l, G);\n}\nconst Ct = /* @__PURE__ */ E({ euclideanNorm_: nt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Xt(I) {\n  const G = { x: R(I, \"x\", \"exp\") };\n  return P.runKernel(cg, G);\n}\nconst rI = /* @__PURE__ */ E({ exp_: Xt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction tt(I, l = 0) {\n  const G = R(I, \"x\", \"expandDims\", \"string_or_numeric\");\n  u(l <= G.rank, () => \"Axis must be <= rank of the tensor\");\n  const Z = { input: G }, h = { dim: l };\n  return P.runKernel(tc, Z, h);\n}\nconst EG = /* @__PURE__ */ E({ expandDims_: tt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ut(I) {\n  const G = { x: R(I, \"x\", \"expm1\") };\n  return P.runKernel(dg, G);\n}\nconst et = /* @__PURE__ */ E({ expm1_: ut });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction St(I, l) {\n  const G = R(I, \"x\", \"tile\", \"string_or_numeric\");\n  u(G.rank === l.length, () => `Error in transpose: rank of input ${G.rank} must match length of reps ${l}.`);\n  const Z = { x: G }, h = { reps: l };\n  return P.runKernel(kg, Z, h);\n}\nconst eI = /* @__PURE__ */ E({ tile_: St });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Rt(I, l, G, Z = \"float32\") {\n  l == null && (l = I);\n  const h = Xl([I, l], Z), g = I <= l ? I : l;\n  for (let c = 0; c < g; ++c)\n    h.set(1, c, c);\n  const b = J(h.toTensor(), [I, l]);\n  if (G == null)\n    return b;\n  if (G.length === 1)\n    return eI(EG(b, 0), [G[0], 1, 1]);\n  if (G.length === 2)\n    return eI(EG(EG(b, 0), 0), [G[0], G[1], 1, 1]);\n  if (G.length === 3)\n    return eI(EG(EG(EG(b, 0), 0), 0), [\n      G[0],\n      G[1],\n      G[2],\n      1,\n      1\n    ]);\n  throw new Error(`eye() currently supports only 1D and 2D batchShapes, but received ${G.length}D.`);\n}\nconst Um = /* @__PURE__ */ E({ eye_: Rt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pt(I) {\n  const G = { x: R(I, \"x\", \"floor\", \"float32\") };\n  return P.runKernel(Wg, G);\n}\nconst ad = /* @__PURE__ */ E({ floor_: pt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ft(I, l, G = 0, Z = 0) {\n  const h = R(I, \"x\", \"gather\"), g = R(l, \"indices\", \"gather\", \"int32\"), b = { x: h, indices: g }, c = { axis: G, batchDims: Z };\n  return P.runKernel(ec, b, c);\n}\nconst DY = /* @__PURE__ */ E({ gather_: Ft });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yt(I, l) {\n  let G = R(I, \"a\", \"greater\", \"string_or_numeric\"), Z = R(l, \"b\", \"greater\", \"string_or_numeric\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(Sc, h);\n}\nconst ZI = /* @__PURE__ */ E({ greater_: yt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Nt(I, l) {\n  let G = R(I, \"a\", \"greaterEqual\", \"string_or_numeric\"), Z = R(l, \"b\", \"greaterEqual\", \"string_or_numeric\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(Vg, h);\n}\nconst Ch = /* @__PURE__ */ E({ greaterEqual_: Nt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Pt(I) {\n  const G = { input: R(I, \"input\", \"imag\") };\n  return P.runKernel(nY, G);\n}\nconst fY = /* @__PURE__ */ E({ imag_: Pt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Jt(I) {\n  const G = { x: R(I, \"x\", \"isFinite\") };\n  return P.runKernel(ig, G);\n}\nconst Et = /* @__PURE__ */ E({ isFinite_: Jt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction xt(I) {\n  const G = { x: R(I, \"x\", \"isInf\") };\n  return P.runKernel(mg, G);\n}\nconst Ut = /* @__PURE__ */ E({ isInf_: xt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ht(I) {\n  const G = { x: R(I, \"x\", \"isNaN\") };\n  return P.runKernel(Tg, G);\n}\nconst Kt = /* @__PURE__ */ E({ isNaN_: Ht });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction At(I, l = 0.2) {\n  const Z = { x: R(I, \"x\", \"leakyRelu\") }, h = { alpha: l };\n  return P.runKernel(Rc, Z, h);\n}\nconst OY = /* @__PURE__ */ E({ leakyRelu_: At });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kt(I, l) {\n  let G = R(I, \"a\", \"less\", \"string_or_numeric\"), Z = R(l, \"b\", \"less\", \"string_or_numeric\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(pc, h);\n}\nconst Kb = /* @__PURE__ */ E({ less_: kt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zt(I, l) {\n  let G = R(I, \"a\", \"lessEqual\", \"string_or_numeric\"), Z = R(l, \"b\", \"lessEqual\", \"string_or_numeric\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(Fc, h);\n}\nconst g0 = /* @__PURE__ */ E({ lessEqual_: zt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Lt(I, l = 5, G = 1, Z = 1, h = 0.5) {\n  const g = R(I, \"x\", \"localResponseNormalization\");\n  u(g.rank === 4 || g.rank === 3, () => `Error in localResponseNormalization: x must be rank 3 or 4 but got\n               rank ${g.rank}.`), u(Mh(l), () => `Error in localResponseNormalization: depthRadius must be an integer but got depthRadius ${l}.`);\n  let b = g, c = !1;\n  g.rank === 3 && (c = !0, b = J(g, [1, g.shape[0], g.shape[1], g.shape[2]]));\n  const d = { x: b }, W = { depthRadius: l, bias: G, alpha: Z, beta: h }, Y = P.runKernel(Jc, d, W);\n  return c ? J(Y, [Y.shape[1], Y.shape[2], Y.shape[3]]) : Y;\n}\nconst Mt = /* @__PURE__ */ E({ localResponseNormalization_: Lt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wt(I) {\n  const G = { x: R(I, \"x\", \"log\", \"float32\") };\n  return P.runKernel(sg, G);\n}\nconst jI = /* @__PURE__ */ E({ log_: wt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Qt(I) {\n  const G = { x: R(I, \"x\", \"log1p\") };\n  return P.runKernel(og, G);\n}\nconst Hm = /* @__PURE__ */ E({ log1p_: Qt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vt(I, l) {\n  u(ZW(I), () => \"The f passed in variableGrads(f) must be a function\"), u(l == null || Array.isArray(l) && l.every((W) => W instanceof Ub), () => \"The varList passed in variableGrads(f, varList) must be an array of variables\");\n  const G = l != null;\n  if (!G) {\n    l = [];\n    for (const W in P.registeredVariables)\n      l.push(P.registeredVariables[W]);\n  }\n  const Z = G ? l.filter((W) => !W.trainable) : null, h = l.length;\n  l = l.filter((W) => W.trainable), u(l.length > 0, () => `variableGrads() expects at least one of the input variables to be trainable, but none of the ${h} variables is trainable.`);\n  const g = !0, { value: b, grads: c } = P.gradients(I, l, null, g);\n  u(c.some((W) => W != null), () => \"Cannot find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize().\"), u(b.rank === 0, () => `The f passed in variableGrads(f) must return a scalar, but it returned a rank-${b.rank} tensor`);\n  const d = {};\n  return l.forEach((W, Y) => {\n    c[Y] != null && (d[W.name] = c[Y]);\n  }), Z != null && Z.forEach((W) => d[W.name] = null), { value: b, grads: d };\n}\nfunction jh(I) {\n  return P.customGrad(I);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction rt(I) {\n  const G = { x: R(I, \"x\", \"neg\") };\n  return P.runKernel(kc, G);\n}\nconst _l = /* @__PURE__ */ E({ neg_: rt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jt(I) {\n  const G = { x: R(I, \"x\", \"softplus\") };\n  return P.runKernel(Eg, G);\n}\nconst Qg = /* @__PURE__ */ E({ softplus_: jt });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Dt(I) {\n  const l = R(I, \"x\", \"logSigmoid\");\n  return jh((Z) => ({ value: _l(Qg(_l(Z))), gradFunc: (b) => N(b, h0(_l(Z))) }))(l);\n}\nconst ft = /* @__PURE__ */ E({ logSigmoid_: Dt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ot(I, l) {\n  let G = R(I, \"a\", \"sub\"), Z = R(l, \"b\", \"sub\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel(Hg, h);\n}\nconst ml = /* @__PURE__ */ E({ sub_: Ot });\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qt(I, l = -1) {\n  const G = R(I, \"logits\", \"logSoftmax\");\n  if (l === -1 && (l = G.rank - 1), l !== G.rank - 1)\n    throw Error(`Log Softmax along a non-last dimension is not yet supported. Logits was rank ${G.rank} and axis was ${l}`);\n  return jh((h, g) => {\n    const c = RI(h, l, !0), d = ml(h, c), W = ml(hl(d, \"float32\"), jI(Yl(rI(d), l, !0)));\n    return g([W]), { value: W, gradFunc: (V, a) => {\n      const [i] = a, m = !0, T = rI(i);\n      return ml(V, N(Yl(V, l, m), T));\n    } };\n  })(G);\n}\nconst Km = /* @__PURE__ */ E({ logSoftmax_: qt });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $t(I, l = null, G = !1) {\n  const Z = R(I, \"x\", \"logSumExp\"), h = tl(l, Z.shape), g = RI(\n    Z,\n    h,\n    !0\n    /* keepDims */\n  ), b = ml(Z, g), c = rI(b), d = Yl(c, h), W = jI(d), Y = O(J(g, W.shape), W);\n  if (G) {\n    const V = bG(Y.shape, h);\n    return J(Y, V);\n  }\n  return Y;\n}\nconst Am = /* @__PURE__ */ E({ logSumExp_: $t });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _t(I, l) {\n  const G = R(I, \"a\", \"logicalAnd\", \"bool\"), Z = R(l, \"b\", \"logicalAnd\", \"bool\");\n  sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(yc, h);\n}\nconst hZ = /* @__PURE__ */ E({ logicalAnd_: _t });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lu(I) {\n  const G = { x: R(I, \"x\", \"logicalNot\", \"bool\") };\n  return P.runKernel(Nc, G);\n}\nconst qY = /* @__PURE__ */ E({ logicalNot_: lu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Gu(I, l) {\n  const G = R(I, \"a\", \"logicalOr\", \"bool\"), Z = R(l, \"b\", \"logicalOr\", \"bool\");\n  sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(Pc, h);\n}\nconst km = /* @__PURE__ */ E({ logicalOr_: Gu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Iu(I, l) {\n  const G = R(I, \"a\", \"logicalXor\", \"bool\"), Z = R(l, \"b\", \"logicalXor\", \"bool\");\n  return sl(G.shape, Z.shape), hZ(km(I, l), qY(hZ(I, l)));\n}\nconst Zu = /* @__PURE__ */ E({ logicalXor_: Iu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction hu(I, l, G, Z, h) {\n  const g = R(I, \"x\", \"maxPool\"), b = 1;\n  let c = g, d = !1;\n  g.rank === 3 && (d = !0, c = J(g, [1, g.shape[0], g.shape[1], g.shape[2]])), u(c.rank === 4, () => `Error in maxPool: input must be rank 4 but got rank ${c.rank}.`), u(pG(G, b), () => `Error in maxPool: Either strides or dilations must be 1. Got strides ${G} and dilations '${b}'`), wG(\"maxPool\", Z, h);\n  const W = { x: c }, Y = { filterSize: l, strides: G, pad: Z, dimRoundingMode: h }, V = P.runKernel(xc, W, Y);\n  return d ? J(V, [V.shape[1], V.shape[2], V.shape[3]]) : V;\n}\nconst $Y = /* @__PURE__ */ E({ maxPool_: hu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gu(I, l = [1, 1, 1], G, Z, h, g = \"NDHWC\") {\n  const b = R(I, \"x\", \"maxPool3d\");\n  let c = b, d = !1;\n  b.rank === 4 && (d = !0, c = J(b, [1, b.shape[0], b.shape[1], b.shape[2], b.shape[3]])), u(c.rank === 5, () => `Error in maxPool3d: x must be rank 5 but got rank ${c.rank}.`), u(g === \"NDHWC\", () => `Error in maxPool3d: Only NDHWC is currently supported, but got dataFormat of ${g}`), wG(\"maxPool3d\", Z, h);\n  const W = { x: c }, Y = { filterSize: l, strides: G, pad: Z, dimRoundingMode: h, dataFormat: g }, V = P.runKernel(Uc, W, Y);\n  return d ? J(V, [V.shape[1], V.shape[2], V.shape[3], V.shape[4]]) : V;\n}\nconst bu = /* @__PURE__ */ E({ maxPool3d_: gu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction cu(I, l) {\n  let G = R(I, \"a\", \"maximum\"), Z = R(l, \"b\", \"maximum\");\n  [G, Z] = lG(G, Z), G.dtype === \"bool\" && (G = hl(G, \"int32\"), Z = hl(Z, \"int32\")), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(Bg, h);\n}\nconst UZ = /* @__PURE__ */ E({ maximum_: cu });\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction du(I, l = null, G = !1) {\n  const h = { x: R(I, \"x\", \"mean\") }, g = { axis: l, keepDims: G };\n  return P.runKernel(Hc, h, g);\n}\nconst gG = /* @__PURE__ */ E({ mean_: du });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mG(I, l = \"float32\") {\n  if (dZ(I), l === \"complex64\") {\n    const Z = mG(I, \"float32\"), h = mG(I, \"float32\");\n    return vh(Z, h);\n  }\n  const G = SG(Q(I), l);\n  return P.makeTensor(G, I, l);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction HZ(I, l = \"float32\") {\n  if (dZ(I), l === \"complex64\") {\n    const Z = HZ(I, \"float32\"), h = mG(I, \"float32\");\n    return vh(Z, h);\n  }\n  const G = jW(Q(I), l);\n  return P.makeTensor(G, I, l);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Wu(I, l) {\n  let G = R(I, \"a\", \"minimum\"), Z = R(l, \"b\", \"minimum\");\n  [G, Z] = lG(G, Z), G.dtype === \"bool\" && (G = hl(G, \"int32\"), Z = hl(Z, \"int32\")), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(ng, h);\n}\nconst x0 = /* @__PURE__ */ E({ minimum_: Wu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Yu(I, l, G) {\n  u(G === \"reflect\" || G === \"symmetric\", () => `Invalid mode. Mode must be either reflect or symmetric. Got ${G}.`);\n  const Z = R(I, \"x\", \"mirrorPad\");\n  if (Z.rank === 0)\n    throw new Error(\"mirrorPad(scalar) is not defined. Pass non-scalar to mirrorPad\");\n  u(l.length === Z.rank, () => `Padding doesn't match input. Must be ${Z.rank}. Got ${l.length}.`);\n  const h = G === \"reflect\" ? 1 : 0;\n  for (let c = 0; c < Z.rank; c++)\n    u(l[c].length === 2, () => \"Invalid number of paddings. Must be length of 2 each.\"), u(l[c][0] >= 0 && l[c][0] <= Z.shape[c] - h && l[c][1] >= 0 && l[c][1] <= Z.shape[c] - h, () => `Padding in dimension ${c} cannot be greater than or equal to ${Z.shape[c] - h} or less than 0 for input of shape ${Z.shape}`);\n  const g = { paddings: l, mode: G }, b = { x: Z };\n  return P.runKernel(Ac, b, g);\n}\nconst Vu = /* @__PURE__ */ E({ mirrorPad_: Yu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction au(I, l) {\n  let G = R(I, \"a\", \"mod\"), Z = R(l, \"b\", \"mod\");\n  [G, Z] = lG(G, Z);\n  const h = { a: G, b: Z };\n  return P.runKernel(Cg, h);\n}\nconst iu = /* @__PURE__ */ E({ mod_: au });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mu(I, l = null, G = !1) {\n  I = R(I, \"x\", \"moments\");\n  const Z = tl(l, I.shape), h = gG(I, Z, G);\n  let g = h.shape;\n  G || (g = bG(h.shape, Z));\n  const b = Ml(ml(hl(I, \"float32\"), J(h, g))), c = gG(b, Z, G);\n  return { mean: h, variance: c };\n}\nconst _Y = /* @__PURE__ */ E({ moments_: mu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Tu(I, l) {\n  let G = R(I, \"a\", \"notEqual\", \"string_or_numeric\"), Z = R(l, \"b\", \"notEqual\", \"string_or_numeric\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z };\n  return P.runKernel(zc, h);\n}\nconst Ab = /* @__PURE__ */ E({ notEqual_: Tu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction su(I, l, G = 1, Z = 0, h = \"int32\") {\n  if (l < 2)\n    throw new Error(`Error in oneHot: depth must be >=2, but it is ${l}`);\n  const b = { indices: R(I, \"indices\", \"oneHot\", \"int32\") }, c = { dtype: h, depth: l, onValue: G, offValue: Z };\n  return P.runKernel(Mc, b, c);\n}\nconst zm = /* @__PURE__ */ E({ oneHot_: su });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ou(I) {\n  const G = { x: R(I, \"x\", \"onesLike\") };\n  return P.runKernel(Lc, G);\n}\nconst TI = /* @__PURE__ */ E({ onesLike_: ou });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Bu(I, l, G = 0) {\n  const Z = R(I, \"x\", \"pad\");\n  if (Z.rank === 0)\n    throw new Error(\"pad(scalar) is not defined. Pass non-scalar to pad\");\n  const h = { paddings: l, constantValue: G }, g = { x: Z };\n  return P.runKernel(Qc, g, h);\n}\nconst lV = /* @__PURE__ */ E({ pad_: Bu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction nu(I, l, G) {\n  const Z = R(I, \"x\", \"spaceToBatchND\");\n  u(Z.rank >= 1 + l.length, () => `input rank ${Z.rank} should be > than [blockShape] ${l.length}`), u(G.length === l.length, () => `paddings.shape[0] ${G.length} must be equal to [blockShape] ${l.length}`), u(Z.shape.reduce((b, c, d) => d > 0 && d <= l.length ? b && (c + G[d - 1][0] + G[d - 1][1]) % l[d - 1] === 0 : b, !0), () => `input spatial dimensions ${Z.shape.slice(1)} with paddings ${G.toString()} must be divisible by blockShapes ${l.toString()}`);\n  const h = { x: Z }, g = { blockShape: l, paddings: G };\n  return P.runKernel(ld, h, g);\n}\nconst GV = /* @__PURE__ */ E({ spaceToBatchND_: nu });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Cu(I, l, G, Z, h, g, b) {\n  h == null && (h = [1, 1]), g == null && (g = 1), Z === 0 && (Z = \"valid\");\n  const c = R(I, \"x\", \"maxPool\");\n  let d = c, W = !1;\n  c.rank === 3 && (W = !0, d = J(c, [1, c.shape[0], c.shape[1], c.shape[2]])), u(pG(g, h), () => `Error in pool: Either strides or dilations must be 1. Got strides ${g} and dilations '${h}'`);\n  const Y = sI(d.shape, l, g, h, Z), V = [Y.dilationHeight, Y.dilationWidth];\n  let a;\n  Z === \"same\" ? a = tu([Y.filterHeight, Y.filterWidth], V) : a = [[0, 0], [0, 0]];\n  const i = V[0] === 1 && V[1] === 1, [m, T] = Xu([Y.inHeight, Y.inWidth], V, a), s = i ? Z : \"valid\", o = i ? d : GV(d, V, m), C = (G === \"avg\" ? () => MY(o, l, g, s, b) : () => $Y(o, l, g, s, b))(), n = i ? C : wY(C, V, T);\n  return W ? J(n, [n.shape[1], n.shape[2], n.shape[3]]) : n;\n}\nfunction Xu(I, l, G) {\n  const Z = G.map((Y) => Y[0]), h = G.map((Y) => Y[1]), g = I.concat(Z, h), b = l.map((Y, V) => (Y - g[V] % Y) % Y), c = h.map((Y, V) => Y + b[V]), d = l.map((Y, V) => [Z[V], c[V]]), W = l.map((Y, V) => [0, b[V]]);\n  return [d, W];\n}\nfunction tu(I, l) {\n  const Z = I.map((b, c) => b + (b - 1) * (l[c] - 1)).map((b) => b - 1), h = Z.map((b) => Math.floor(b / 2)), g = Z.map((b, c) => b - h[c]);\n  return Z.map((b, c) => [h[c], g[c]]);\n}\nconst uu = /* @__PURE__ */ E({ pool_: Cu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction eu(I, l) {\n  const G = R(I, \"x\", \"prelu\"), Z = R(l, \"alpha\", \"prelu\"), h = { x: G, alpha: Z };\n  return P.runKernel(vc, h);\n}\nconst IV = /* @__PURE__ */ E({ prelu_: eu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Su(I, l = null, G = !1) {\n  let Z = R(I, \"x\", \"prod\");\n  Z.dtype === \"bool\" && (Z = hl(Z, \"int32\"));\n  const h = { x: Z }, g = { axis: l, keepDims: G };\n  return P.runKernel(rc, h, g);\n}\nconst Ru = /* @__PURE__ */ E({ prod_: Su });\nvar ZV = { exports: {} };\nZV.exports;\n(function(I) {\n  (function(l, G, Z) {\n    function h(d) {\n      var W = this, Y = c();\n      W.next = function() {\n        var V = 2091639 * W.s0 + W.c * 23283064365386963e-26;\n        return W.s0 = W.s1, W.s1 = W.s2, W.s2 = V - (W.c = V | 0);\n      }, W.c = 1, W.s0 = Y(\" \"), W.s1 = Y(\" \"), W.s2 = Y(\" \"), W.s0 -= Y(d), W.s0 < 0 && (W.s0 += 1), W.s1 -= Y(d), W.s1 < 0 && (W.s1 += 1), W.s2 -= Y(d), W.s2 < 0 && (W.s2 += 1), Y = null;\n    }\n    function g(d, W) {\n      return W.c = d.c, W.s0 = d.s0, W.s1 = d.s1, W.s2 = d.s2, W;\n    }\n    function b(d, W) {\n      var Y = new h(d), V = W && W.state, a = Y.next;\n      return a.int32 = function() {\n        return Y.next() * 4294967296 | 0;\n      }, a.double = function() {\n        return a() + (a() * 2097152 | 0) * 11102230246251565e-32;\n      }, a.quick = a, V && (typeof V == \"object\" && g(V, Y), a.state = function() {\n        return g(Y, {});\n      }), a;\n    }\n    function c() {\n      var d = 4022871197, W = function(Y) {\n        Y = String(Y);\n        for (var V = 0; V < Y.length; V++) {\n          d += Y.charCodeAt(V);\n          var a = 0.02519603282416938 * d;\n          d = a >>> 0, a -= d, a *= d, d = a >>> 0, a -= d, d += a * 4294967296;\n        }\n        return (d >>> 0) * 23283064365386963e-26;\n      };\n      return W;\n    }\n    G && G.exports ? G.exports = b : this.alea = b;\n  })(\n    oh,\n    I\n  );\n})(ZV);\nvar pu = ZV.exports, hV = { exports: {} };\nhV.exports;\n(function(I) {\n  (function(l, G, Z) {\n    function h(c) {\n      var d = this, W = \"\";\n      d.x = 0, d.y = 0, d.z = 0, d.w = 0, d.next = function() {\n        var V = d.x ^ d.x << 11;\n        return d.x = d.y, d.y = d.z, d.z = d.w, d.w ^= d.w >>> 19 ^ V ^ V >>> 8;\n      }, c === (c | 0) ? d.x = c : W += c;\n      for (var Y = 0; Y < W.length + 64; Y++)\n        d.x ^= W.charCodeAt(Y) | 0, d.next();\n    }\n    function g(c, d) {\n      return d.x = c.x, d.y = c.y, d.z = c.z, d.w = c.w, d;\n    }\n    function b(c, d) {\n      var W = new h(c), Y = d && d.state, V = function() {\n        return (W.next() >>> 0) / 4294967296;\n      };\n      return V.double = function() {\n        do\n          var a = W.next() >>> 11, i = (W.next() >>> 0) / 4294967296, m = (a + i) / (1 << 21);\n        while (m === 0);\n        return m;\n      }, V.int32 = W.next, V.quick = V, Y && (typeof Y == \"object\" && g(Y, W), V.state = function() {\n        return g(W, {});\n      }), V;\n    }\n    G && G.exports ? G.exports = b : this.xor128 = b;\n  })(\n    oh,\n    I\n  );\n})(hV);\nvar Fu = hV.exports, gV = { exports: {} };\ngV.exports;\n(function(I) {\n  (function(l, G, Z) {\n    function h(c) {\n      var d = this, W = \"\";\n      d.next = function() {\n        var V = d.x ^ d.x >>> 2;\n        return d.x = d.y, d.y = d.z, d.z = d.w, d.w = d.v, (d.d = d.d + 362437 | 0) + (d.v = d.v ^ d.v << 4 ^ (V ^ V << 1)) | 0;\n      }, d.x = 0, d.y = 0, d.z = 0, d.w = 0, d.v = 0, c === (c | 0) ? d.x = c : W += c;\n      for (var Y = 0; Y < W.length + 64; Y++)\n        d.x ^= W.charCodeAt(Y) | 0, Y == W.length && (d.d = d.x << 10 ^ d.x >>> 4), d.next();\n    }\n    function g(c, d) {\n      return d.x = c.x, d.y = c.y, d.z = c.z, d.w = c.w, d.v = c.v, d.d = c.d, d;\n    }\n    function b(c, d) {\n      var W = new h(c), Y = d && d.state, V = function() {\n        return (W.next() >>> 0) / 4294967296;\n      };\n      return V.double = function() {\n        do\n          var a = W.next() >>> 11, i = (W.next() >>> 0) / 4294967296, m = (a + i) / (1 << 21);\n        while (m === 0);\n        return m;\n      }, V.int32 = W.next, V.quick = V, Y && (typeof Y == \"object\" && g(Y, W), V.state = function() {\n        return g(W, {});\n      }), V;\n    }\n    G && G.exports ? G.exports = b : this.xorwow = b;\n  })(\n    oh,\n    I\n  );\n})(gV);\nvar yu = gV.exports, bV = { exports: {} };\nbV.exports;\n(function(I) {\n  (function(l, G, Z) {\n    function h(c) {\n      var d = this;\n      d.next = function() {\n        var Y = d.x, V = d.i, a, i;\n        return a = Y[V], a ^= a >>> 7, i = a ^ a << 24, a = Y[V + 1 & 7], i ^= a ^ a >>> 10, a = Y[V + 3 & 7], i ^= a ^ a >>> 3, a = Y[V + 4 & 7], i ^= a ^ a << 7, a = Y[V + 7 & 7], a = a ^ a << 13, i ^= a ^ a << 9, Y[V] = i, d.i = V + 1 & 7, i;\n      };\n      function W(Y, V) {\n        var a, i = [];\n        if (V === (V | 0))\n          i[0] = V;\n        else\n          for (V = \"\" + V, a = 0; a < V.length; ++a)\n            i[a & 7] = i[a & 7] << 15 ^ V.charCodeAt(a) + i[a + 1 & 7] << 13;\n        for (; i.length < 8; ) i.push(0);\n        for (a = 0; a < 8 && i[a] === 0; ++a) ;\n        for (a == 8 ? i[7] = -1 : i[a], Y.x = i, Y.i = 0, a = 256; a > 0; --a)\n          Y.next();\n      }\n      W(d, c);\n    }\n    function g(c, d) {\n      return d.x = c.x.slice(), d.i = c.i, d;\n    }\n    function b(c, d) {\n      c == null && (c = +/* @__PURE__ */ new Date());\n      var W = new h(c), Y = d && d.state, V = function() {\n        return (W.next() >>> 0) / 4294967296;\n      };\n      return V.double = function() {\n        do\n          var a = W.next() >>> 11, i = (W.next() >>> 0) / 4294967296, m = (a + i) / (1 << 21);\n        while (m === 0);\n        return m;\n      }, V.int32 = W.next, V.quick = V, Y && (Y.x && g(Y, W), V.state = function() {\n        return g(W, {});\n      }), V;\n    }\n    G && G.exports ? G.exports = b : this.xorshift7 = b;\n  })(\n    oh,\n    I\n  );\n})(bV);\nvar Nu = bV.exports, cV = { exports: {} };\ncV.exports;\n(function(I) {\n  (function(l, G, Z) {\n    function h(c) {\n      var d = this;\n      d.next = function() {\n        var Y = d.w, V = d.X, a = d.i, i, m;\n        return d.w = Y = Y + 1640531527 | 0, m = V[a + 34 & 127], i = V[a = a + 1 & 127], m ^= m << 13, i ^= i << 17, m ^= m >>> 15, i ^= i >>> 12, m = V[a] = m ^ i, d.i = a, m + (Y ^ Y >>> 16) | 0;\n      };\n      function W(Y, V) {\n        var a, i, m, T, s, o = [], B = 128;\n        for (V === (V | 0) ? (i = V, V = null) : (V = V + \"\\0\", i = 0, B = Math.max(B, V.length)), m = 0, T = -32; T < B; ++T)\n          V && (i ^= V.charCodeAt((T + 32) % V.length)), T === 0 && (s = i), i ^= i << 10, i ^= i >>> 15, i ^= i << 4, i ^= i >>> 13, T >= 0 && (s = s + 1640531527 | 0, a = o[T & 127] ^= i + s, m = a == 0 ? m + 1 : 0);\n        for (m >= 128 && (o[(V && V.length || 0) & 127] = -1), m = 127, T = 4 * 128; T > 0; --T)\n          i = o[m + 34 & 127], a = o[m = m + 1 & 127], i ^= i << 13, a ^= a << 17, i ^= i >>> 15, a ^= a >>> 12, o[m] = i ^ a;\n        Y.w = s, Y.X = o, Y.i = m;\n      }\n      W(d, c);\n    }\n    function g(c, d) {\n      return d.i = c.i, d.w = c.w, d.X = c.X.slice(), d;\n    }\n    function b(c, d) {\n      c == null && (c = +/* @__PURE__ */ new Date());\n      var W = new h(c), Y = d && d.state, V = function() {\n        return (W.next() >>> 0) / 4294967296;\n      };\n      return V.double = function() {\n        do\n          var a = W.next() >>> 11, i = (W.next() >>> 0) / 4294967296, m = (a + i) / (1 << 21);\n        while (m === 0);\n        return m;\n      }, V.int32 = W.next, V.quick = V, Y && (Y.X && g(Y, W), V.state = function() {\n        return g(W, {});\n      }), V;\n    }\n    G && G.exports ? G.exports = b : this.xor4096 = b;\n  })(\n    oh,\n    // window object or global\n    I\n  );\n})(cV);\nvar Pu = cV.exports, dV = { exports: {} };\ndV.exports;\n(function(I) {\n  (function(l, G, Z) {\n    function h(c) {\n      var d = this, W = \"\";\n      d.next = function() {\n        var V = d.b, a = d.c, i = d.d, m = d.a;\n        return V = V << 25 ^ V >>> 7 ^ a, a = a - i | 0, i = i << 24 ^ i >>> 8 ^ m, m = m - V | 0, d.b = V = V << 20 ^ V >>> 12 ^ a, d.c = a = a - i | 0, d.d = i << 16 ^ a >>> 16 ^ m, d.a = m - V | 0;\n      }, d.a = 0, d.b = 0, d.c = -1640531527, d.d = 1367130551, c === Math.floor(c) ? (d.a = c / 4294967296 | 0, d.b = c | 0) : W += c;\n      for (var Y = 0; Y < W.length + 20; Y++)\n        d.b ^= W.charCodeAt(Y) | 0, d.next();\n    }\n    function g(c, d) {\n      return d.a = c.a, d.b = c.b, d.c = c.c, d.d = c.d, d;\n    }\n    function b(c, d) {\n      var W = new h(c), Y = d && d.state, V = function() {\n        return (W.next() >>> 0) / 4294967296;\n      };\n      return V.double = function() {\n        do\n          var a = W.next() >>> 11, i = (W.next() >>> 0) / 4294967296, m = (a + i) / (1 << 21);\n        while (m === 0);\n        return m;\n      }, V.int32 = W.next, V.quick = V, Y && (typeof Y == \"object\" && g(Y, W), V.state = function() {\n        return g(W, {});\n      }), V;\n    }\n    G && G.exports ? G.exports = b : this.tychei = b;\n  })(\n    oh,\n    I\n  );\n})(dV);\nvar Ju = dV.exports, Lm = { exports: {} };\nconst Eu = {}, xu = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  default: Eu\n}, Symbol.toStringTag, { value: \"Module\" })), Uu = /* @__PURE__ */ Un(xu);\n(function(I) {\n  (function(l, G, Z) {\n    var h = 256, g = 6, b = 52, c = \"random\", d = Z.pow(h, g), W = Z.pow(2, b), Y = W * 2, V = h - 1, a;\n    function i(n, X, t) {\n      var e = [];\n      X = X == !0 ? { entropy: !0 } : X || {};\n      var S = o(s(\n        X.entropy ? [n, C(G)] : n ?? B(),\n        3\n      ), e), p = new m(e), F = function() {\n        for (var x = p.g(g), H = d, K = 0; x < W; )\n          x = (x + K) * h, H *= h, K = p.g(1);\n        for (; x >= Y; )\n          x /= 2, H /= 2, K >>>= 1;\n        return (x + K) / H;\n      };\n      return F.int32 = function() {\n        return p.g(4) | 0;\n      }, F.quick = function() {\n        return p.g(4) / 4294967296;\n      }, F.double = F, o(C(p.S), G), (X.pass || t || function(x, H, K, z) {\n        return z && (z.S && T(z, p), x.state = function() {\n          return T(p, {});\n        }), K ? (Z[c] = x, H) : x;\n      })(\n        F,\n        S,\n        \"global\" in X ? X.global : this == Z,\n        X.state\n      );\n    }\n    function m(n) {\n      var X, t = n.length, e = this, S = 0, p = e.i = e.j = 0, F = e.S = [];\n      for (t || (n = [t++]); S < h; )\n        F[S] = S++;\n      for (S = 0; S < h; S++)\n        F[S] = F[p = V & p + n[S % t] + (X = F[S])], F[p] = X;\n      (e.g = function(x) {\n        for (var H, K = 0, z = e.i, k = e.j, L = e.S; x--; )\n          H = L[z = V & z + 1], K = K * h + L[V & (L[z] = L[k = V & k + H]) + (L[k] = H)];\n        return e.i = z, e.j = k, K;\n      })(h);\n    }\n    function T(n, X) {\n      return X.i = n.i, X.j = n.j, X.S = n.S.slice(), X;\n    }\n    function s(n, X) {\n      var t = [], e = typeof n, S;\n      if (X && e == \"object\")\n        for (S in n)\n          try {\n            t.push(s(n[S], X - 1));\n          } catch {\n          }\n      return t.length ? t : e == \"string\" ? n : n + \"\\0\";\n    }\n    function o(n, X) {\n      for (var t = n + \"\", e, S = 0; S < t.length; )\n        X[V & S] = V & (e ^= X[V & S] * 19) + t.charCodeAt(S++);\n      return C(X);\n    }\n    function B() {\n      try {\n        var n;\n        return a && (n = a.randomBytes) ? n = n(h) : (n = new Uint8Array(h), (l.crypto || l.msCrypto).getRandomValues(n)), C(n);\n      } catch {\n        var X = l.navigator, t = X && X.plugins;\n        return [+/* @__PURE__ */ new Date(), l, t, l.screen, C(G)];\n      }\n    }\n    function C(n) {\n      return String.fromCharCode.apply(0, n);\n    }\n    if (o(Z.random(), G), I.exports) {\n      I.exports = i;\n      try {\n        a = Uu;\n      } catch {\n      }\n    } else\n      Z[\"seed\" + c] = i;\n  })(\n    // global: `self` in browsers (including strict mode and web workers),\n    // otherwise `this` in Node and other environments\n    typeof self < \"u\" ? self : oh,\n    [],\n    // pool: entropy pool starts empty\n    Math\n    // math: package containing random, pow, and seedrandom\n  );\n})(Lm);\nvar Hu = Lm.exports, Ku = pu, Au = Fu, ku = yu, zu = Nu, Lu = Pu, Mu = Ju, Xh = Hu;\nXh.alea = Ku;\nXh.xor128 = Au;\nXh.xorwow = ku;\nXh.xorshift7 = zu;\nXh.xor4096 = Lu;\nXh.tychei = Mu;\nvar WV = Xh;\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Mm {\n  constructor(l, G, Z, h, g) {\n    this.mean = l, this.stdDev = G, this.dtype = Z, this.nextVal = NaN, this.truncated = h, this.truncated && (this.upper = this.mean + this.stdDev * 2, this.lower = this.mean - this.stdDev * 2);\n    const b = g || Math.random();\n    this.random = WV.alea(b.toString());\n  }\n  /** Returns next sample from a Gaussian distribution. */\n  nextValue() {\n    if (!isNaN(this.nextVal)) {\n      const h = this.nextVal;\n      return this.nextVal = NaN, h;\n    }\n    let l, G, Z = !1;\n    for (; !Z; ) {\n      let h, g, b;\n      do\n        h = 2 * this.random() - 1, g = 2 * this.random() - 1, b = h * h + g * g;\n      while (b >= 1 || b === 0);\n      const c = Math.sqrt(-2 * Math.log(b) / b);\n      l = this.mean + this.stdDev * h * c, G = this.mean + this.stdDev * g * c, (!this.truncated || this.isValidTruncated(l)) && (Z = !0);\n    }\n    return (!this.truncated || this.isValidTruncated(G)) && (this.nextVal = this.convertValue(G)), this.convertValue(l);\n  }\n  /** Handles proper rounding for non-floating-point numbers. */\n  convertValue(l) {\n    return this.dtype == null || this.dtype === \"float32\" ? l : Math.round(l);\n  }\n  /** Returns true if less than 2-standard-deviations from the mean. */\n  isValidTruncated(l) {\n    return l <= this.upper && l >= this.lower;\n  }\n}\nclass wu {\n  constructor(l = 0, G = 1, Z, h) {\n    if (this.canReturnFloat = () => this.dtype == null || this.dtype === \"float32\", this.min = l, this.range = G - l, this.dtype = Z, h == null && (h = Math.random()), typeof h == \"number\" && (h = h.toString()), !this.canReturnFloat() && this.range <= 1)\n      throw new Error(`The difference between ${l} - ${G} <= 1 and dtype is not float`);\n    this.random = WV.alea(h);\n  }\n  convertValue(l) {\n    return this.canReturnFloat() ? l : Math.round(l);\n  }\n  nextValue() {\n    return this.convertValue(this.min + this.range * this.random());\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Qu(I, l = 0, G = 1, Z, h) {\n  if (dZ(I), Z != null && Z === \"bool\")\n    throw new Error(`Unsupported data type ${Z}`);\n  const g = new Mm(l, G, Z, !1, h), b = Xl(I, Z);\n  for (let c = 0; c < b.values.length; c++)\n    b.values[c] = g.nextValue();\n  return b.toTensor();\n}\nconst vu = /* @__PURE__ */ E({ randomNormal_: Qu });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ru(I, l = 0, G = 1, Z = \"float32\", h) {\n  dZ(I);\n  const g = Xl(I, Z), b = new wu(l, G, null, h);\n  for (let c = 0; c < g.values.length; c++)\n    g.values[c] = b.nextValue();\n  return g.toTensor();\n}\nconst vg = /* @__PURE__ */ E({ randomUniform_: ru });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction U0(I, l, G = 1, Z = \"float32\") {\n  if (G === 0)\n    throw new Error(\"Cannot have a step of zero\");\n  const h = { start: I, stop: l, step: G, dtype: Z };\n  return P.runKernel(RY, {}, h);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ju(I) {\n  const G = { input: R(I, \"input\", \"real\") };\n  return P.runKernel(pY, G);\n}\nconst kb = /* @__PURE__ */ E({ real_: ju });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Du(I) {\n  const G = { x: R(I, \"x\", \"reciprocal\") };\n  return P.runKernel(ug, G);\n}\nconst fu = /* @__PURE__ */ E({ reciprocal_: Du });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ou(I) {\n  const G = { x: R(I, \"x\", \"relu\") };\n  return P.runKernel(eg, G);\n}\nconst th = /* @__PURE__ */ E({ relu_: Ou });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qu(I) {\n  const G = { x: R(I, \"x\", \"relu6\") };\n  return P.runKernel(Sg, G);\n}\nconst wm = /* @__PURE__ */ E({ relu6_: qu });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $u(I, l) {\n  const Z = { x: R(I, \"x\", \"reverse\") }, h = { dims: l };\n  return P.runKernel(Oc, Z, h);\n}\nconst Vh = /* @__PURE__ */ E({ reverse_: $u });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _u(I) {\n  const G = { x: R(I, \"x\", \"round\") };\n  return P.runKernel(Rg, G);\n}\nconst Qm = /* @__PURE__ */ E({ round_: _u });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction le(I) {\n  const G = { x: R(I, \"x\", \"rsqrt\", \"float32\") };\n  return P.runKernel(pg, G);\n}\nconst vm = /* @__PURE__ */ E({ rsqrt_: le });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ge(I) {\n  const G = { x: R(I, \"x\", \"selu\") };\n  return P.runKernel(Fg, G);\n}\nconst rm = /* @__PURE__ */ E({ selu_: Ge });\nfunction Ie(I, l, G, Z, h, g = [1, 1], b = \"NHWC\") {\n  const c = R(I, \"x\", \"separableConv2d\"), d = R(l, \"depthwiseFilter\", \"separableConv2d\"), W = R(G, \"pointwiseFilter\", \"separableConv2d\");\n  let Y = c, V = !1;\n  if (c.rank === 3 && (V = !0, Y = J(c, [1, c.shape[0], c.shape[1], c.shape[2]])), b === \"NCHW\")\n    throw new Error(\"separableConv2d currently does not support dataFormat NCHW; only NHWC is supported\");\n  u(Y.rank === 4, () => `Error in separableConv2d: input must be rank 4, but got rank ${Y.rank}.`), u(d.rank === 4, () => `Error in separableConv2d: depthwise filter must be rank 4, but got rank ${d.rank}.`), u(W.rank === 4, () => `Error in separableConv2d: pointwise filter must be rank 4, but got rank ${d.rank}.`), u(W.shape[0] === 1, () => `Error in separableConv2d: the first dimension of pointwise filter  must be 1, but got ${W.shape[0]}.`), u(W.shape[1] === 1, () => `Error in separableConv2d: the second dimension of pointwise filter must be 1, but got ${W.shape[1]}.`);\n  const a = d.shape[2], i = d.shape[3];\n  u(W.shape[2] === a * i, () => `Error in separableConv2d: the third dimension of pointwise filter must be ${a * i}, but got ${W.shape[2]}.`);\n  const m = rY(Y, d, Z, h, b, g), s = Wh(m, W, 1, \"valid\", b);\n  return V ? J(s, [s.shape[1], s.shape[2], s.shape[3]]) : s;\n}\nconst jm = /* @__PURE__ */ E({ separableConv2d_: Ie });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ze(I) {\n  const G = { x: R(I, \"x\", \"sign\") };\n  return P.runKernel(Pg, G);\n}\nconst he = /* @__PURE__ */ E({ sign_: Ze });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ge(I) {\n  const G = { x: R(I, \"x\", \"sin\", \"float32\") };\n  return P.runKernel(yg, G);\n}\nconst Dm = /* @__PURE__ */ E({ sin_: ge });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction be(I) {\n  const G = { x: R(I, \"x\", \"sinh\") };\n  return P.runKernel(Ng, G);\n}\nconst fm = /* @__PURE__ */ E({ sinh_: be });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ce(I, l, G) {\n  const Z = R(I, \"x\", \"slice1d\");\n  return u(Z.rank === 1, () => `slice1d expects a rank-1 tensor, but got a rank-${Z.rank} tensor`), zl(Z, [l], [G]);\n}\nconst YV = /* @__PURE__ */ E({ slice1d_: ce });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction de(I, l, G) {\n  const Z = R(I, \"x\", \"slice2d\");\n  return u(Z.rank === 2, () => `slice2d expects a rank-2 tensor, but got a rank-${Z.rank} tensor`), zl(Z, l, G);\n}\nconst Om = /* @__PURE__ */ E({ slice2d_: de });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction We(I, l, G) {\n  const Z = R(I, \"x\", \"slice3d\");\n  return u(Z.rank === 3, () => `slice3d expects a rank-3 tensor, but got a rank-${Z.rank} tensor`), zl(Z, l, G);\n}\nconst VV = /* @__PURE__ */ E({ slice3d_: We });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ye(I, l, G) {\n  const Z = R(I, \"x\", \"slice4d\");\n  return u(Z.rank === 4, () => `slice4d expects a rank-4 tensor, but got a rank-${Z.rank} tensor`), zl(Z, l, G);\n}\nconst zb = /* @__PURE__ */ E({ slice4d_: Ye });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ve(I, l = -1) {\n  const G = R(I, \"logits\", \"softmax\", \"float32\");\n  if (l === -1 && (l = G.rank - 1), l !== G.rank - 1)\n    throw Error(`Softmax along a non-last dimension is not yet supported. Logits was rank ${G.rank} and dim was ${l}`);\n  const Z = { logits: G }, h = { dim: l };\n  return P.runKernel(Id, Z, h);\n}\nconst aV = /* @__PURE__ */ E({ softmax_: Ve });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ae(I) {\n  u(I.dtype === \"complex64\", () => `The dtype for tf.spectral.fft() must be complex64 but got ${I.dtype}.`);\n  const l = { input: I };\n  return P.runKernel(TY, l);\n}\nconst qm = /* @__PURE__ */ E({ fft_: ae });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ie(I) {\n  u(I.dtype === \"complex64\", () => `The dtype for tf.spectral.ifft() must be complex64 but got ${I.dtype}.`);\n  const l = { input: I };\n  return P.runKernel(BY, l);\n}\nconst tW = /* @__PURE__ */ E({ ifft_: ie });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction me(I) {\n  const l = I.shape[I.shape.length - 1], G = I.size / l;\n  let Z;\n  if (l <= 2) {\n    const h = J(I, [G, l]);\n    Z = tW(h);\n  } else {\n    const h = [G, 2 * (l - 1)], g = J(kb(I), [G, l]), b = J(fY(I), [G, l]), c = Vh(zl(g, [0, 1], [G, l - 2]), 1), d = N(Vh(zl(b, [0, 1], [G, l - 2]), 1), yl(-1)), W = zG([g, c], 1), Y = zG([b, d], 1), V = J(vh(W, Y), [h[0], h[1]]);\n    Z = tW(V);\n  }\n  if (Z = kb(Z), I.rank === 3 && I.shape[0] !== 0) {\n    const h = Z, g = I.shape[0];\n    Z = J(Z, [g, Z.shape[0] / g, Z.shape[1]]), h.dispose();\n  }\n  return Z;\n}\nconst Te = /* @__PURE__ */ E({ irfft_: me });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction se(I, l, G = 0) {\n  const h = { x: R(I, \"x\", \"split\") }, g = { numOrSizeSplits: l, axis: G };\n  return P.runKernel(Gd, h, g);\n}\nconst GI = /* @__PURE__ */ E({ split_: se });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction oe(I, l) {\n  u(I.dtype === \"float32\", () => `The dtype for rfft() must be real value but got ${I.dtype}`);\n  let G = I.shape[I.shape.length - 1];\n  const Z = I.size / G;\n  let h;\n  if (l != null && l < G) {\n    const m = I.shape.map((s) => 0), T = I.shape.map((s) => s);\n    T[I.shape.length - 1] = l, h = zl(I, m, T), G = l;\n  } else if (l != null && l > G) {\n    const m = I.shape.map((T) => T);\n    m[I.shape.length - 1] = l - G, h = zG([I, mG(m)], I.shape.length - 1), G = l;\n  } else\n    h = I;\n  const g = Sl(h), b = J(vh(h, g), [Z, G]), c = qm(b), d = Math.floor(G / 2) + 1, W = kb(c), Y = fY(c), V = GI(W, [d, G - d], W.shape.length - 1), a = GI(Y, [d, G - d], Y.shape.length - 1), i = h.shape.slice();\n  return i[h.shape.length - 1] = d, J(vh(V[0], a[0]), i);\n}\nconst Be = /* @__PURE__ */ E({ rfft_: oe });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ne(I, l) {\n  let G = R(I, \"a\", \"squaredDifference\"), Z = R(l, \"b\", \"squaredDifference\");\n  [G, Z] = lG(G, Z), sl(G.shape, Z.shape);\n  const h = { a: G, b: Z }, g = {};\n  return P.runKernel(Ug, h, g);\n}\nconst Ce = /* @__PURE__ */ E({ squaredDifference_: ne });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Xe(I, l) {\n  const G = R(I, \"x\", \"squeeze\", \"string_or_numeric\");\n  return J(G, PZ(G.shape, l).newShape);\n}\nconst rg = /* @__PURE__ */ E({ squeeze_: Xe });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction te(I, l = 0) {\n  const G = sm(I, \"tensors\", \"stack\", \"string_or_numeric\");\n  u(G.length >= 1, () => \"Pass at least one tensor to tf.stack\"), G.length > 0 && u(l <= G[0].rank, () => \"Axis must be <= rank of the tensor\");\n  const Z = G, h = { axis: l };\n  return P.runKernel(wc, Z, h);\n}\nconst gZ = /* @__PURE__ */ E({ stack_: te });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ue(I, l = 0) {\n  const Z = { x: R(I, \"x\", \"step\") }, h = { alpha: l };\n  return P.runKernel(zg, Z, h);\n}\nconst jg = /* @__PURE__ */ E({ step_: ue });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ee(I, l, G, Z, h = 0, g = 0, b = 0, c = 0, d = 0) {\n  const Y = { x: R(I, \"x\", \"stridedSlice\", \"string_or_numeric\") }, V = {\n    begin: l,\n    end: G,\n    strides: Z,\n    beginMask: h,\n    endMask: g,\n    ellipsisMask: b,\n    newAxisMask: c,\n    shrinkAxisMask: d\n  };\n  return P.runKernel(JY, Y, V);\n}\nconst Se = /* @__PURE__ */ E({ stridedSlice_: ee });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Re(I) {\n  const G = { x: R(I, \"x\", \"tan\", \"float32\") };\n  return P.runKernel(Kg, G);\n}\nconst pe = /* @__PURE__ */ E({ tan_: Re });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jG(I, l) {\n  rW(I);\n  const G = Lg(I, l);\n  if (G.length !== 1)\n    throw new Error(\"tensor1d() requires values to be a flat/TypedArray\");\n  return Mg(I, null, G, l);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ld(I, l, G) {\n  if (rW(I), l != null && l.length !== 2)\n    throw new Error(\"tensor2d() requires shape to have two numbers\");\n  const Z = Lg(I, G);\n  if (Z.length !== 2 && Z.length !== 1)\n    throw new Error(\"tensor2d() requires values to be number[][] or flat/TypedArray\");\n  if (Z.length === 1 && l == null)\n    throw new Error(\"tensor2d() requires shape to be provided when `values` are a flat/TypedArray\");\n  return Mg(I, l, Z, G);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Fe(I, l, G) {\n  if (rW(I), l != null && l.length !== 3)\n    throw new Error(\"tensor3d() requires shape to have three numbers\");\n  const Z = Lg(I, G);\n  if (Z.length !== 3 && Z.length !== 1)\n    throw new Error(\"tensor3d() requires values to be number[][][] or flat/TypedArray\");\n  if (Z.length === 1 && l == null)\n    throw new Error(\"tensor3d() requires shape to be provided when `values` are a flat array\");\n  return Mg(I, l, Z, G);\n}\nfunction $m(I, l, G) {\n  const Z = l.rank > 1 ? l.shape[l.rank - 1] : 1, h = l.rank > 1 ? l.rank - 1 : 1, g = `Must have updates.shape = indices.shape[:batchDim] + shape[sliceDim:], got updates.shape: ${G.shape}, indices.shape: ${l.shape}, shape: ${I}, sliceDim: ${Z}, and batchDim: ${h}.`;\n  if (G.rank < h)\n    throw new Error(g + ` update.rank < ${h}. `);\n  if (I.length < Z + (G.rank - h))\n    throw new Error(g + ` Output shape length < ${Z + (G.rank - h)}`);\n  if (G.rank !== h + I.length - Z)\n    throw new Error(g + ` update.rank != ${h + I.length - Z}`);\n  for (let b = 0; b < h; ++b)\n    if (G.shape[b] !== l.shape[b])\n      throw new Error(g + ` updates.shape[${b}] (${G.shape[b]}) != indices.shape[${b}] (${l.shape[b]}).`);\n  for (let b = 0; b < G.rank - h; ++b)\n    if (G.shape[b + h] !== I[b + Z])\n      throw new Error(g + ` updates.shape[${b + h}] (${G.shape[b + h]}) != shape[${b + h}] (${I[b + h]})`);\n}\nfunction ye(I, l, G) {\n  if (l.rank < 1)\n    throw new Error(`tf.scatterND() expects the indices to be rank 1 or higher, but the rank was ${l.rank}.`);\n  if (I.rank < 1)\n    throw new Error(`tf.scatterND() expects the updates to be rank 1 or higher, but the rank was ${I.rank}.`);\n  if (l.dtype !== \"int32\")\n    throw new Error(`The dtype of 'indices' should be int32, but got dtype: ${l.dtype}`);\n  if (G.length < 1)\n    throw new Error(`Output rank must be greater or equal to 1, but got shape: ${G}`);\n  if (G.length === 0) {\n    if (l.size === 0)\n      throw new Error(`Indices specified for empty output. indices shape: ${l.shape}`);\n    if (I.size === 0)\n      throw new Error(`Updates specified for empty output. updates shape: ${I.shape}`);\n  }\n  $m(G, l, I);\n}\nfunction uh(I, l, G) {\n  const Z = l.shape.length, h = Z > 1 ? l.shape[Z - 1] : 1, g = G.length;\n  let b = 1;\n  for (let V = h; V < g; ++V)\n    b *= G[V];\n  const c = h < 1 ? 1 : h, d = Q(l.shape) / c, W = [...Wl(G.slice(0, h)), 1], Y = Q(G);\n  return { sliceRank: h, numUpdates: d, sliceSize: b, strides: W, outputSize: Y };\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ne(I, l = 1, G = !0) {\n  const Z = R(I, \"x\", \"topk\");\n  if (Z.rank === 0)\n    throw new Error(\"topk() expects the input to be of rank 1 or higher\");\n  const h = Z.shape[Z.shape.length - 1];\n  if (l < 0)\n    throw new Error(`'k' passed to topk() must be >= 0 but got ${l}`);\n  if (l > h)\n    throw new Error(`'k' passed to topk() must be <= the last dimension (${h}) but got ${l}`);\n  const g = { x: Z }, b = { k: l, sorted: G }, [c, d] = P.runKernel(EY, g, b);\n  return { values: c, indices: d };\n}\nconst Pe = /* @__PURE__ */ E({ topk_: Ne });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Je(I, l = 0, G = 1, Z, h) {\n  if (dZ(I), Z != null && Z === \"bool\")\n    throw new Error(\"Unsupported data type $ { dtype }\");\n  const g = new Mm(l, G, Z, !0, h), b = Xl(I, Z);\n  for (let c = 0; c < b.values.length; c++)\n    b.values[c] = g.nextValue();\n  return b.toTensor();\n}\nconst _m = /* @__PURE__ */ E({ truncatedNormal_: Je });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ee(I, l = 0) {\n  const G = R(I, \"x\", \"unique\", \"string_or_numeric\");\n  u(G.rank > 0, () => \"The input tensor must be at least 1D\");\n  const Z = { x: G }, h = { axis: l }, [g, b] = P.runKernel(UY, Z, h);\n  return { values: g, indices: b };\n}\nconst xe = /* @__PURE__ */ E({ unique_: Ee });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ue(I, l, G) {\n  const Z = R(I, \"x\", \"unsortedSegmentSum\"), h = R(l, \"segmentIds\", \"unsortedSegmentSum\", \"int32\");\n  u(Mh(G), () => \"numSegments must be of dtype int\");\n  const g = { x: Z, segmentIds: h }, b = { numSegments: G };\n  return P.runKernel(hd, g, b);\n}\nconst lT = /* @__PURE__ */ E({ unsortedSegmentSum_: Ue });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction He(I, l = 0) {\n  const G = R(I, \"x\", \"unstack\", \"string_or_numeric\");\n  u(l >= -G.shape.length && l < G.shape.length, () => `Axis = ${l} is not in [-${G.shape.length}, ${G.shape.length})`);\n  const Z = { value: G }, h = { axis: l };\n  return P.runKernel(Zd, Z, h);\n}\nconst ah = /* @__PURE__ */ E({ unstack_: He });\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ke(I, l = !0, G, Z) {\n  return P.makeVariable(I, l, G, Z);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction GT(I, l) {\n  const G = [];\n  for (let g = 0; g < l.length; g++)\n    l[g] && G.push(g);\n  const Z = Xl(I, \"int32\"), h = Xl([G.length, I.length], \"int32\");\n  for (let g = 0; g < G.length; g++) {\n    const b = Z.indexToLoc(G[g]), c = g * I.length;\n    h.values.set(b, c);\n  }\n  return h.toTensor();\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ae(I, l, G) {\n  const Z = R(I, \"x\", \"transpose\");\n  if (l == null && (l = Z.shape.map((b, c) => c).reverse()), u(Z.rank === l.length, () => `Error in transpose: rank of input ${Z.rank} must match length of perm ${l}.`), l.forEach((b) => {\n    u(b >= 0 && b < Z.rank, () => `All entries in 'perm' must be between 0 and ${Z.rank - 1} but got ${l}`);\n  }), Z.rank <= 1)\n    return Z.clone();\n  const h = { x: Z }, g = { perm: l };\n  return Z.dtype === \"complex64\" ? U(() => {\n    let b = kb(Z), c = fY(Z);\n    return b = P.runKernel(Ah, { x: b }, g), c = P.runKernel(Ah, { x: c }, g), G && (c = _l(c)), vh(b, c);\n  }) : P.runKernel(Ah, h, g);\n}\nconst el = /* @__PURE__ */ E({ transpose_: Ae });\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ke(I, l) {\n  if (l == null)\n    return I.shape.slice();\n  if (Nl(I.shape, l))\n    return l;\n  if (I.shape.length === l.length) {\n    const G = [];\n    for (let Z = 0; Z < I.shape.length; Z++)\n      l[Z] == null && I.shape[Z] != null ? G.push(I.shape[Z]) : G.push(l[Z]);\n    return G;\n  }\n  return l;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ze(I, l, G, Z) {\n  const h = R(I, \"x\", \"dropout\");\n  if (u(h.dtype === \"float32\", () => `x has to be a floating point tensor since it's going to be scaled, but got a ${h.dtype} tensor instead.`), u(l >= 0 && l < 1, () => `rate must be a float in the range [0, 1), but got ${l}.`), l === 0)\n    return I instanceof hG ? h.clone() : h;\n  const g = ke(h, G), b = 1 - l, c = Vl(ad(O(vg(g, 0, 1, \"float32\", Z), b)), b);\n  return N(h, c);\n}\nconst Le = /* @__PURE__ */ E({ dropout_: ze });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Me(I, l, G, Z, h, g = \"NHWC\", b) {\n  let c = I;\n  I.rank === 3 && (c = J(I, [1, I.shape[0], I.shape[1], I.shape[2]]));\n  let d = l;\n  d.rank === 3 && (d = J(l, [1, l.shape[0], l.shape[1], l.shape[2]])), u(c.rank === 4, () => `Error in conv2dDerFilter: input must be rank 4, but got shape ${c.shape}.`), u(d.rank === 4, () => `Error in conv2dDerFilter: dy must be rank 4, but got shape ${d.shape}.`), u(G.length === 4, () => `Error in conv2dDerFilter: filterShape must be length 4, but got ${G}.`);\n  const W = g === \"NHWC\" ? c.shape[3] : c.shape[1], Y = g === \"NHWC\" ? d.shape[3] : d.shape[1];\n  u(W === G[2], () => `Error in conv2dDerFilter: depth of input ${W}) must match input depth in filter (${G[2]}.`), u(Y === G[3], () => `Error in conv2dDerFilter: depth of dy (${Y}) must match output depth for filter (${G[3]}).`), wG(\"conv2dDerFilter\", h, b);\n  const V = { x: c, dy: d }, a = { strides: Z, pad: h, dataFormat: g, dimRoundingMode: b, filterShape: G };\n  return P.runKernel(hY, V, a);\n}\nconst iV = /* @__PURE__ */ E({ conv2DBackpropFilter_: Me });\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mV(I, l, G) {\n  if (G == null || G === \"linear\")\n    return I;\n  if (G === \"relu\")\n    return N(I, jg(l));\n  throw new Error(`Cannot compute gradient for fused activation ${G}.`);\n}\nfunction TV(I, l) {\n  let G = l;\n  const Z = VG(I.shape, l.shape);\n  return Z.length > 0 && (G = Yl(G, Z)), J(G, I.shape);\n}\nfunction sV(I, l, G, Z) {\n  if (l === \"linear\")\n    return I;\n  if (l === \"relu\")\n    return th(I);\n  if (l === \"elu\")\n    return Yd(I);\n  if (l === \"relu6\")\n    return wm(I);\n  if (l === \"prelu\")\n    return IV(I, G);\n  if (l === \"leakyrelu\")\n    return OY(I, Z);\n  if (l === \"sigmoid\")\n    return h0(I);\n  throw new Error(`Unknown fused activation ${l}.`);\n}\nconst oV = (I, l) => !(I > 0) || l === \"linear\";\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction we({ x: I, filter: l, strides: G, pad: Z, dataFormat: h = \"NHWC\", dilations: g = [1, 1], dimRoundingMode: b, bias: c, activation: d = \"linear\", preluActivationWeights: W, leakyreluAlpha: Y }) {\n  if (d = d || \"linear\", oV(P.state.gradientDepth, d) === !1) {\n    u(h === \"NHWC\", () => `Error in fused conv2d: got dataFormat of ${h} but only NHWC is currently supported for the case of gradient depth is 0 and the activation is not linear.`);\n    let t = Wh(I, l, G, Z, h, g, b);\n    return c != null && (t = O(t, c)), sV(t, d, W, Y);\n  }\n  const V = R(I, \"x\", \"conv2d\", \"float32\"), a = R(l, \"filter\", \"conv2d\", \"float32\");\n  let i = V, m = !1;\n  V.rank === 3 && (m = !0, i = J(V, [1, V.shape[0], V.shape[1], V.shape[2]])), u(i.rank === 4, () => `Error in fused conv2d: input must be rank 4, but got rank ${i.rank}.`), u(a.rank === 4, () => `Error in fused conv2d: filter must be rank 4, but got rank ${a.rank}.`), wG(\"fused conv2d\", Z, b);\n  const T = h === \"NHWC\" ? i.shape[3] : i.shape[1];\n  u(a.shape[2] === T, () => `Error in conv2d: depth of input (${T}) must match input depth for filter ${a.shape[2]}.`), u(pG(G, g), () => `Error in conv2D: Either strides or dilations must be 1. Got strides ${G} and dilations '${g}'`);\n  const s = CG(i.shape, a.shape, G, g, Z, b);\n  let o;\n  c != null && (o = R(c, \"bias\", \"fused conv2d\"), [o] = lG(o, V), h === \"NHWC\" ? sl(s.outShape, o.shape) : (u(o.shape.length <= 1, () => `Error in fused conv2d: only supports scalar or 1-D Tensor bias for NCHW format but got the bias of rank-${o.shape.length}.`), u(o.shape.length === 0 || o.shape[0] === s.outChannels || o.shape[0] === 1, () => `Error in fused conv2d: bias shape (${o.shape}) is not compatible with the number of output channels (${s.outChannels})`)));\n  let B;\n  if (W != null) {\n    const t = W.shape;\n    if (u(t.length <= 1 || t.length === 3, () => `Error in fused conv2d: only supports scalar, 1-D Tensor or 3-D Tensor PReLU activation weights but got a tensor of rank-${t.length}.`), t.length === 1)\n      u(t[0] === 1 || t[0] === s.outChannels, () => `Error in fused conv2d: PReLU activation weights (${t}) is not compatible with the number of output channels (${s.outChannels}).`);\n    else if (t.length === 3)\n      try {\n        sl(t, s.outShape);\n      } catch {\n        const S = `Error in fused conv2d: PReLU activation weights (${t}) is not compatible with the output shape of the conv2d (${s.outShape}).`;\n        throw Error(S);\n      }\n    B = R(W, \"prelu weights\", \"fused conv2d\");\n  }\n  const C = (t, e) => {\n    u(h === \"NHWC\", () => `Error in gradient of fused conv2D: got dataFormat of ${h} but only NHWC is currently supported.`);\n    const [S, p, F, x] = e, H = mV(t, F, d);\n    u(ch(g), () => `Error in gradient of fused conv2D: dilation rates greater than 1 are not yet supported in gradients. Got dilations '${g}'`);\n    const K = QY(p.shape, H, S, G, Z), z = iV(p, H, S.shape, G, Z), k = [K, z];\n    if (x != null) {\n      const L = TV(x, H);\n      k.push(L);\n    }\n    return k;\n  }, n = {\n    x: i,\n    filter: a,\n    bias: o,\n    preluActivationWeights: B\n  }, X = {\n    strides: G,\n    pad: Z,\n    dataFormat: h,\n    dilations: g,\n    dimRoundingMode: b,\n    activation: d,\n    leakyreluAlpha: Y\n  };\n  return c == null ? jh((e, S, p) => {\n    let F = (\n      // tslint:disable-next-line: no-unnecessary-type-assertion\n      P.runKernel(Jb, n, X)\n    );\n    return p([S, e, F]), m && (F = J(F, [F.shape[1], F.shape[2], F.shape[3]])), { value: F, gradFunc: C };\n  })(i, a) : jh((e, S, p, F) => {\n    let x = P.runKernel(Jb, n, X);\n    return F([S, e, x, p]), m && (x = J(x, [x.shape[1], x.shape[2], x.shape[3]])), { value: x, gradFunc: C };\n  })(i, a, o);\n}\nconst Qe = /* @__PURE__ */ E({ fusedConv2d_: we });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ve(I, l, G, Z, h, g = [1, 1], b) {\n  let c = I;\n  I.rank === 3 && (c = J(I, [1, I.shape[0], I.shape[1], I.shape[2]]));\n  let d = l;\n  d.rank === 3 && (d = J(l, [1, l.shape[0], l.shape[1], l.shape[2]]));\n  const W = { x: c, dy: d }, Y = { strides: Z, pad: h, dimRoundingMode: b, dilations: g, filterShape: G };\n  return P.runKernel(VY, W, Y);\n}\nconst re = E({ depthwiseConv2dNativeBackpropFilter_: ve });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction je(I, l, G, Z, h, g = [1, 1], b) {\n  let c = l, d = !1;\n  l.rank === 3 && (d = !0, c = J(l, [1, l.shape[0], l.shape[1], l.shape[2]]));\n  const W = { dy: c, filter: G }, Y = { strides: Z, pad: h, dimRoundingMode: b, dilations: g, inputShape: I }, V = (\n    // tslint:disable-next-line: no-unnecessary-type-assertion\n    P.runKernel(aY, W, Y)\n  );\n  return d ? J(V, [V.shape[1], V.shape[2], V.shape[3]]) : V;\n}\nconst De = E({ depthwiseConv2dNativeBackpropInput_: je });\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction fe({ a: I, b: l, transposeA: G = !1, transposeB: Z = !1, bias: h, activation: g = \"linear\", preluActivationWeights: b, leakyreluAlpha: c = 0.2 }) {\n  if (oV(P.state.gradientDepth, g) === !1) {\n    let x = Fl(I, l, G, Z);\n    return h != null && (x = O(x, h)), sV(x, g, b, c);\n  }\n  let d = R(I, \"a\", \"fused matMul\"), W = R(l, \"b\", \"fused matMul\");\n  [d, W] = lG(d, W);\n  const Y = G ? d.shape[d.rank - 2] : d.shape[d.rank - 1], V = Z ? W.shape[W.rank - 1] : W.shape[W.rank - 2], a = G ? d.shape[d.rank - 1] : d.shape[d.rank - 2], i = Z ? W.shape[W.rank - 2] : W.shape[W.rank - 1], m = d.shape.slice(0, -2), T = W.shape.slice(0, -2), s = Q(m), o = Q(T);\n  u(Y === V, () => `Error in fused matMul: inner shapes (${Y}) and (${V}) of Tensors with shapes ${d.shape} and ${W.shape} and transposeA=${G} and transposeB=${Z} must match.`);\n  const C = sl(d.shape.slice(0, -2), W.shape.slice(0, -2)).concat([a, i]), n = G ? J(d, [s, Y, a]) : J(d, [s, a, Y]), X = Z ? J(W, [o, i, V]) : J(W, [o, V, i]);\n  let t;\n  h != null && (t = R(h, \"bias\", \"fused matMul\"), [t] = lG(t, d), sl(C, t.shape));\n  let e;\n  b != null && (e = R(b, \"prelu weights\", \"fused matMul\"));\n  const S = (x, H) => {\n    const [K, z, k, L] = H, v = mV(J(x, k.shape), k, g);\n    let w, r;\n    if (!G && !Z ? (w = Fl(v, z, !1, !0), r = Fl(K, v, !0, !1)) : !G && Z ? (w = Fl(v, z, !1, !1), r = Fl(v, K, !0, !1)) : G && !Z ? (w = Fl(z, v, !1, !0), r = Fl(K, v, !1, !1)) : (w = Fl(z, v, !0, !0), r = Fl(v, K, !0, !0)), h != null) {\n      const D = TV(L, v);\n      return [w, r, D];\n    } else\n      return [w, r];\n  }, p = {\n    a: n,\n    b: X,\n    bias: t,\n    preluActivationWeights: e\n  }, F = { transposeA: G, transposeB: Z, activation: g, leakyreluAlpha: c };\n  return h == null ? jh((H, K, z) => {\n    const k = (\n      // tslint:disable-next-line: no-unnecessary-type-assertion\n      P.runKernel(Pb, p, F)\n    );\n    return z([H, K, k]), { value: J(k, C), gradFunc: S };\n  })(n, X) : jh((H, K, z, k) => {\n    const L = (\n      // tslint:disable-next-line: no-unnecessary-type-assertion\n      P.runKernel(Pb, p, F)\n    );\n    return k([H, K, L, z]), { value: J(L, C), gradFunc: S };\n  })(n, X, t);\n}\nconst Ia = /* @__PURE__ */ E({ fusedMatMul_: fe });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Oe(I, l, G, Z, h = \"bilinear\", g = 0) {\n  const b = R(I, \"image\", \"cropAndResize\"), c = R(l, \"boxes\", \"cropAndResize\", \"float32\"), d = R(G, \"boxInd\", \"cropAndResize\", \"int32\"), W = c.shape[0];\n  u(b.rank === 4, () => `Error in cropAndResize: image must be rank 4,but got rank ${b.rank}.`), u(c.rank === 2 && c.shape[1] === 4, () => `Error in cropAndResize: boxes must be have size [${W},4] but had shape ${c.shape}.`), u(d.rank === 1 && d.shape[0] === W, () => `Error in cropAndResize: boxInd must be have size [${W}] but had shape ${c.shape}.`), u(Z.length === 2, () => `Error in cropAndResize: cropSize must be of length 2, but got length ${Z.length}.`), u(Z[0] >= 1 && Z[1] >= 1, () => `cropSize must be atleast [1,1], but was ${Z}`), u(h === \"bilinear\" || h === \"nearest\", () => `method must be bilinear or nearest, but was ${h}`);\n  const Y = { image: b, boxes: c, boxInd: d }, V = { method: h, extrapolationValue: g, cropSize: Z };\n  return P.runKernel(dY, Y, V);\n}\nconst qe = /* @__PURE__ */ E({ cropAndResize_: Oe });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $e(I) {\n  const l = R(I, \"image\", \"flipLeftRight\", \"float32\");\n  u(l.rank === 4, () => `Error in flipLeftRight: image must be rank 4,but got rank ${l.rank}.`);\n  const G = { image: l };\n  return P.runKernel(oY, G, {});\n}\nconst _e = /* @__PURE__ */ E({ flipLeftRight_: $e });\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lS(I) {\n  const l = R(I, \"image\", \"grayscaleToRGB\"), G = l.rank - 1, Z = l.shape[G];\n  u(l.rank >= 2, () => `Error in grayscaleToRGB: images must be at least rank 2, but got rank ${l.rank}.`), u(Z === 1, () => `Error in grayscaleToRGB: last dimension of a grayscale image should be size 1, but got size ${Z}.`);\n  const h = new Array(l.rank);\n  return h.fill(1, 0, G), h[G] = 3, eI(l, h);\n}\nconst GS = /* @__PURE__ */ E({ grayscaleToRGB_: lS });\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction IS(I) {\n  const l = R(I, \"image\", \"RGBToGrayscale\"), G = l.rank - 1, Z = l.shape[G];\n  u(l.rank >= 2, () => `Error in RGBToGrayscale: images must be at least rank 2, but got rank ${l.rank}.`), u(Z === 3, () => `Error in RGBToGrayscale: last dimension of an RGB image should be size 3, but got size ${Z}.`);\n  const h = l.dtype, g = hl(l, \"float32\"), b = jG([0.2989, 0.587, 0.114]);\n  let c;\n  switch (l.rank) {\n    case 2:\n      c = C0(\"ij,j->i\", g, b);\n      break;\n    case 3:\n      c = C0(\"ijk,k->ij\", g, b);\n      break;\n    case 4:\n      c = C0(\"ijkl,l->ijk\", g, b);\n      break;\n    case 5:\n      c = C0(\"ijklm,m->ijkl\", g, b);\n      break;\n    case 6:\n      c = C0(\"ijklmn,n->ijklm\", g, b);\n      break;\n    default:\n      throw new Error(\"Not a valid tensor rank.\");\n  }\n  return c = EG(c, -1), hl(c, h);\n}\nconst ZS = /* @__PURE__ */ E({ rgbToGrayscale_: IS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction hS(I, l, G = 0, Z = 0.5) {\n  const h = R(I, \"image\", \"rotateWithOffset\", \"float32\");\n  u(h.rank === 4, () => `Error in rotateWithOffset: image must be rank 4,but got rank ${h.rank}.`);\n  const g = { image: h }, b = { radians: l, fillValue: G, center: Z };\n  return P.runKernel(HY, g, b);\n}\nconst gS = /* @__PURE__ */ E({ rotateWithOffset_: hS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction b0(I, l, G, Z, h, g) {\n  Z == null && (Z = 0.5), h == null && (h = Number.NEGATIVE_INFINITY), g == null && (g = 0);\n  const b = I.shape[0];\n  return G = Math.min(G, b), u(0 <= Z && Z <= 1, () => `iouThreshold must be in [0, 1], but was '${Z}'`), u(I.rank === 2, () => `boxes must be a 2D tensor, but was of rank '${I.rank}'`), u(I.shape[1] === 4, () => `boxes must have 4 columns, but 2nd dimension was ${I.shape[1]}`), u(l.rank === 1, () => \"scores must be a 1D tensor\"), u(l.shape[0] === b, () => `scores has incompatible shape with boxes. Expected ${b}, but was ${l.shape[0]}`), u(0 <= g && g <= 1, () => `softNmsSigma must be in [0, 1], but was '${g}'`), { maxOutputSize: G, iouThreshold: Z, scoreThreshold: h, softNmsSigma: g };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction bS(I, l, G, Z = 0.5, h = Number.NEGATIVE_INFINITY) {\n  const g = R(I, \"boxes\", \"nonMaxSuppression\", \"float32\"), b = R(l, \"scores\", \"nonMaxSuppression\", \"float32\"), c = b0(g, b, G, Z, h);\n  G = c.maxOutputSize, Z = c.iouThreshold, h = c.scoreThreshold;\n  const d = { maxOutputSize: G, iouThreshold: Z, scoreThreshold: h };\n  return P.runKernel(uY, { boxes: g, scores: b }, d);\n}\nconst cS = /* @__PURE__ */ E({ nonMaxSuppression_: bS });\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction dS(I, l, G) {\n  const Z = WS(I, l, G), h = Z < 0 ? -(Z + 1) : Z;\n  I.splice(h, 0, l);\n}\nfunction WS(I, l, G) {\n  return VS(I, l, G || YS);\n}\nfunction YS(I, l) {\n  return I > l ? 1 : I < l ? -1 : 0;\n}\nfunction VS(I, l, G) {\n  let Z = 0, h = I.length, g = 0, b = !1;\n  for (; Z < h; ) {\n    g = Z + (h - Z >>> 1);\n    const c = G(l, I[g]);\n    c > 0 ? Z = g + 1 : (h = g, b = !c);\n  }\n  return b ? Z : -Z - 1;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction BV(I, l, G, Z, h) {\n  return XV(\n    I,\n    l,\n    G,\n    Z,\n    h,\n    0\n    /* softNmsSigma */\n  );\n}\nfunction nV(I, l, G, Z, h, g) {\n  return XV(\n    I,\n    l,\n    G,\n    Z,\n    h,\n    0,\n    !1,\n    g,\n    !0\n    /* returnValidOutputs */\n  );\n}\nfunction CV(I, l, G, Z, h, g) {\n  return XV(\n    I,\n    l,\n    G,\n    Z,\n    h,\n    g,\n    !0\n    /* returnScoresTensor */\n  );\n}\nfunction XV(I, l, G, Z, h, g, b = !1, c = !1, d = !1) {\n  const W = [];\n  for (let s = 0; s < l.length; s++)\n    l[s] > h && W.push({ score: l[s], boxIndex: s, suppressBeginIndex: 0 });\n  W.sort(Za);\n  const Y = g > 0 ? -0.5 / g : 0, V = [], a = [];\n  for (; V.length < G && W.length > 0; ) {\n    const s = W.pop(), { score: o, boxIndex: B, suppressBeginIndex: C } = s;\n    if (o < h)\n      break;\n    let n = !1;\n    for (let X = V.length - 1; X >= C; --X) {\n      const t = aS(I, B, V[X]);\n      if (t >= Z) {\n        n = !0;\n        break;\n      }\n      if (s.score = s.score * iS(Z, Y, t), s.score <= h)\n        break;\n    }\n    s.suppressBeginIndex = V.length, n || (s.score === o ? (V.push(B), a.push(s.score)) : s.score > h && dS(W, s, Za));\n  }\n  const i = V.length, m = G - i;\n  c && m > 0 && (V.push(...new Array(m).fill(0)), a.push(...new Array(m).fill(0)));\n  const T = { selectedIndices: V };\n  return b && (T.selectedScores = a), d && (T.validOutputs = i), T;\n}\nfunction aS(I, l, G) {\n  const Z = I.subarray(l * 4, l * 4 + 4), h = I.subarray(G * 4, G * 4 + 4), g = Math.min(Z[0], Z[2]), b = Math.min(Z[1], Z[3]), c = Math.max(Z[0], Z[2]), d = Math.max(Z[1], Z[3]), W = Math.min(h[0], h[2]), Y = Math.min(h[1], h[3]), V = Math.max(h[0], h[2]), a = Math.max(h[1], h[3]), i = (c - g) * (d - b), m = (V - W) * (a - Y);\n  if (i <= 0 || m <= 0)\n    return 0;\n  const T = Math.max(g, W), s = Math.max(b, Y), o = Math.min(c, V), B = Math.min(d, a), C = Math.max(o - T, 0) * Math.max(B - s, 0);\n  return C / (i + m - C);\n}\nfunction iS(I, l, G) {\n  const Z = Math.exp(l * G * G);\n  return G <= I ? Z : 0;\n}\nfunction Za(I, l) {\n  return I.score - l.score || I.score === l.score && l.boxIndex - I.boxIndex;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nasync function mS(I, l, G, Z = 0.5, h = Number.NEGATIVE_INFINITY) {\n  const g = R(I, \"boxes\", \"nonMaxSuppressionAsync\"), b = R(l, \"scores\", \"nonMaxSuppressionAsync\"), c = b0(g, b, G, Z, h);\n  G = c.maxOutputSize, Z = c.iouThreshold, h = c.scoreThreshold;\n  const d = await Promise.all([g.data(), b.data()]), W = d[0], Y = d[1], { selectedIndices: V } = BV(W, Y, G, Z, h);\n  return g !== I && g.dispose(), b !== l && b.dispose(), jG(V, \"int32\");\n}\nconst TS = mS;\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sS(I, l, G, Z = 0.5, h = Number.NEGATIVE_INFINITY, g = 0) {\n  const b = R(I, \"boxes\", \"nonMaxSuppression\"), c = R(l, \"scores\", \"nonMaxSuppression\"), d = b0(b, c, G, Z, h, g);\n  G = d.maxOutputSize, Z = d.iouThreshold, h = d.scoreThreshold, g = d.softNmsSigma;\n  const W = { boxes: b, scores: c }, Y = { maxOutputSize: G, iouThreshold: Z, scoreThreshold: h, softNmsSigma: g }, V = P.runKernel(SY, W, Y);\n  return { selectedIndices: V[0], selectedScores: V[1] };\n}\nconst oS = /* @__PURE__ */ E({ nonMaxSuppressionWithScore_: sS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nasync function BS(I, l, G, Z = 0.5, h = Number.NEGATIVE_INFINITY, g = 0) {\n  const b = R(I, \"boxes\", \"nonMaxSuppressionAsync\"), c = R(l, \"scores\", \"nonMaxSuppressionAsync\"), d = b0(b, c, G, Z, h, g);\n  G = d.maxOutputSize, Z = d.iouThreshold, h = d.scoreThreshold, g = d.softNmsSigma;\n  const W = await Promise.all([b.data(), c.data()]), Y = W[0], V = W[1], { selectedIndices: a, selectedScores: i } = CV(Y, V, G, Z, h, g);\n  return b !== I && b.dispose(), c !== l && c.dispose(), {\n    selectedIndices: jG(a, \"int32\"),\n    selectedScores: jG(i)\n  };\n}\nconst nS = BS;\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction CS(I, l, G, Z = 0.5, h = Number.NEGATIVE_INFINITY, g = !1) {\n  const b = R(I, \"boxes\", \"nonMaxSuppression\"), c = R(l, \"scores\", \"nonMaxSuppression\"), d = b0(\n    b,\n    c,\n    G,\n    Z,\n    h,\n    null\n    /* softNmsSigma */\n  ), W = d.maxOutputSize, Y = d.iouThreshold, V = d.scoreThreshold, a = { boxes: b, scores: c }, i = {\n    maxOutputSize: W,\n    iouThreshold: Y,\n    scoreThreshold: V,\n    padToMaxOutputSize: g\n  }, m = P.runKernel(eY, a, i);\n  return { selectedIndices: m[0], validOutputs: m[1] };\n}\nconst XS = /* @__PURE__ */ E({ nonMaxSuppressionPadded_: CS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nasync function tS(I, l, G, Z = 0.5, h = Number.NEGATIVE_INFINITY, g = !1) {\n  const b = R(I, \"boxes\", \"nonMaxSuppressionAsync\"), c = R(l, \"scores\", \"nonMaxSuppressionAsync\"), d = b0(\n    b,\n    c,\n    G,\n    Z,\n    h,\n    null\n    /* softNmsSigma */\n  ), W = d.maxOutputSize, Y = d.iouThreshold, V = d.scoreThreshold, [a, i] = await Promise.all([b.data(), c.data()]), { selectedIndices: m, validOutputs: T } = nV(a, i, W, Y, V, g);\n  return b !== I && b.dispose(), c !== l && c.dispose(), {\n    selectedIndices: jG(m, \"int32\"),\n    validOutputs: yl(T, \"int32\")\n  };\n}\nconst uS = tS;\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction eS(I, l, G = !1, Z = !1) {\n  const h = R(I, \"images\", \"resizeBilinear\");\n  u(h.rank === 3 || h.rank === 4, () => `Error in resizeBilinear: x must be rank 3 or 4, but got rank ${h.rank}.`), u(l.length === 2, () => `Error in resizeBilinear: new shape must 2D, but got shape ${l}.`), u(Z === !1 || G === !1, () => \"Error in resizeBilinear: If halfPixelCenters is true, alignCorners must be false.\");\n  let g = h, b = !1;\n  h.rank === 3 && (b = !0, g = J(h, [1, h.shape[0], h.shape[1], h.shape[2]]));\n  const c = { images: g }, d = { alignCorners: G, halfPixelCenters: Z, size: l }, W = P.runKernel(fc, c, d);\n  return b ? J(W, [W.shape[1], W.shape[2], W.shape[3]]) : W;\n}\nconst IT = /* @__PURE__ */ E({ resizeBilinear_: eS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction SS(I, l, G = !1, Z = !1) {\n  const h = R(I, \"images\", \"resizeNearestNeighbor\");\n  u(h.rank === 3 || h.rank === 4, () => `Error in resizeNearestNeighbor: x must be rank 3 or 4, but got rank ${h.rank}.`), u(l.length === 2, () => `Error in resizeNearestNeighbor: new shape must 2D, but got shape ${l}.`), u(h.dtype === \"float32\" || h.dtype === \"int32\", () => \"`images` must have `int32` or `float32` as dtype\"), u(Z === !1 || G === !1, () => \"Error in resizeNearestNeighbor: If halfPixelCenters is true, alignCorners must be false.\");\n  let g = h, b = !1;\n  h.rank === 3 && (b = !0, g = J(h, [1, h.shape[0], h.shape[1], h.shape[2]]));\n  const c = { images: g }, d = { alignCorners: G, halfPixelCenters: Z, size: l }, W = P.runKernel(Dc, c, d);\n  return b ? J(W, [W.shape[1], W.shape[2], W.shape[3]]) : W;\n}\nconst ZT = /* @__PURE__ */ E({ resizeNearestNeighbor_: SS });\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction RS(I, l = \"binary\", G = !1, Z = 0.5) {\n  const h = R(I, \"image\", \"threshold\"), g = 0.2989, b = 0.587, c = 0.114, d = h.shape[0] * h.shape[1];\n  let W = N(jG([Z]), 255), Y, V, a, i;\n  if (u(h.rank === 3, () => `Error in threshold: image must be rank 3,but got rank ${h.rank}.`), u(h.shape[2] === 3 || h.shape[2] === 1, () => `Error in threshold: image color channel must be equal to 3 or 1but got ${h.shape[2]}.`), u(h.dtype === \"int32\" || h.dtype === \"float32\", () => `Error in dtype: image dtype must be int32 or float32,but got dtype ${h.dtype}.`), u(l === \"otsu\" || l === \"binary\", () => `Method must be binary or otsu, but was ${l}`), h.shape[2] === 3) {\n    [Y, V, a] = GI(h, [1, 1, 1], -1);\n    const s = N(Y, g), o = N(V, b), B = N(a, c);\n    i = O(O(s, o), B);\n  } else\n    i = I;\n  if (l === \"otsu\") {\n    const s = eX(hl(Qm(i), \"int32\"), kY([]), 256);\n    W = pS(s, d);\n  }\n  const m = G ? g0(i, W) : ZI(i, W);\n  return hl(N(m, 255), \"int32\");\n}\nfunction pS(I, l) {\n  let G = jG([-1]), Z = jG([0]), h = jG([0]), g, b, c, d, W, Y;\n  for (let V = 0; V < I.size - 1; V++) {\n    g = zl(I, 0, V + 1), b = zl(I, V + 1), W = Vl(Yl(g), l), Y = Vl(Yl(b), l);\n    const a = Yl(N(g, U0(0, g.size)));\n    c = Vl(a, Yl(g));\n    const i = Wd(b.shape, g.size), m = O(U0(0, b.size), i), T = N(b, m);\n    d = Vl(Yl(T), Yl(b));\n    const s = ml(c, d), o = ml(c, d), B = N(W, Y);\n    h = N(N(B, s), o);\n    const C = ZI(h, Z);\n    Z = UG(C, h, Z), G = UG(C, jG([V]), G);\n  }\n  return G;\n}\nconst FS = /* @__PURE__ */ E({ threshold_: RS });\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yS(I, l, G = \"nearest\", Z = \"constant\", h = 0, g) {\n  const b = R(I, \"image\", \"transform\", \"float32\"), c = R(l, \"transforms\", \"transform\", \"float32\");\n  u(b.rank === 4, () => `Error in transform: image must be rank 4,but got rank ${b.rank}.`), u(c.rank === 2 && (c.shape[0] === b.shape[0] || c.shape[0] === 1) && c.shape[1] === 8, () => \"Error in transform: Input transform should be batch x 8 or 1 x 8\"), u(g == null || g.length === 2, () => `Error in transform: outputShape must be [height, width] or null, but got ${g}.`);\n  const d = { image: b, transforms: c }, W = { interpolation: G, fillMode: Z, fillValue: h, outputShape: g };\n  return P.runKernel(xY, d, W);\n}\nconst NS = /* @__PURE__ */ E({ transform_: yS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction PS(I, l, G) {\n  const Z = R(I, \"a\", \"bandPart\");\n  u(Z.rank >= 2, () => `bandPart(): Rank must be at least 2, got ${Z.rank}.`);\n  const h = Z.shape, [g, b] = Z.shape.slice(-2);\n  let c, d;\n  typeof l == \"number\" ? (u(l % 1 === 0, () => `bandPart(): numLower must be an integer, got ${l}.`), u(l <= g, () => `bandPart(): numLower (${l}) must not be greater than the number of rows (${g}).`), c = R(l < 0 ? g : l, \"numLower\", \"bandPart\")) : (u(l.dtype === \"int32\", () => \"bandPart(): numLower's dtype must be an int32.\"), c = UG(Kb(l, 0), g, x0(l, g))), typeof G == \"number\" ? (u(G % 1 === 0, () => `bandPart(): numUpper must be an integer, got ${G}.`), u(G <= b, () => `bandPart(): numUpper (${G}) must not be greater than the number of columns (${b}).`), d = R(G < 0 ? b : G, \"numUpper\", \"bandPart\")) : (u(G.dtype === \"int32\", () => \"bandPart(): numUpper's dtype must be an int32.\"), d = UG(Kb(G, 0), b, x0(G, b)));\n  const W = J(U0(0, g, 1, \"int32\"), [-1, 1]), Y = U0(0, b, 1, \"int32\"), V = ml(W, Y), a = hZ(g0(V, c), Ch(V, _l(d))), i = mG([g, b], Z.dtype);\n  return J(gZ(ah(J(Z, [-1, g, b])).map((m) => UG(a, m, i))), h);\n}\nconst JS = /* @__PURE__ */ E({ bandPart_: PS });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ES(I) {\n  let l;\n  if (Array.isArray(I)) {\n    l = !1, u(I != null && I.length > 0, () => \"Gram-Schmidt process: input must not be null, undefined, or empty\");\n    const h = I[0].shape[0];\n    for (let g = 1; g < I.length; ++g)\n      u(I[g].shape[0] === h, () => `Gram-Schmidt: Non-unique lengths found in the input vectors: (${I[g].shape[0]} vs. ${h})`);\n  } else\n    l = !0, I = GI(I, I.shape[0], 0).map((h) => rg(h, [0]));\n  u(I.length <= I[0].shape[0], () => `Gram-Schmidt: Number of vectors (${I.length}) exceeds number of dimensions (${I[0].shape[0]}).`);\n  const G = [], Z = I;\n  for (let h = 0; h < I.length; ++h)\n    G.push(P.tidy(() => {\n      let g = Z[h];\n      if (h > 0)\n        for (let b = 0; b < h; ++b) {\n          const c = N(Yl(N(G[b], g)), G[b]);\n          g = ml(g, c);\n        }\n      return Vl(g, Vd(g, \"euclidean\"));\n    }));\n  return l ? gZ(G, 0) : G;\n}\nconst xS = /* @__PURE__ */ E({ gramSchmidt_: ES });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction US(I, l = !1) {\n  if (u(I.rank >= 2, () => `qr() requires input tensor to have a rank >= 2, but got rank ${I.rank}`), I.rank === 2)\n    return ha(I, l);\n  {\n    const G = I.shape.slice(0, I.shape.length - 2).reduce((d, W) => d * W), Z = ah(J(I, [\n      G,\n      I.shape[I.shape.length - 2],\n      I.shape[I.shape.length - 1]\n    ]), 0), h = [], g = [];\n    Z.forEach((d) => {\n      const [W, Y] = ha(d, l);\n      h.push(W), g.push(Y);\n    });\n    const b = J(gZ(h, 0), I.shape), c = J(gZ(g, 0), I.shape);\n    return [b, c];\n  }\n}\nfunction ha(I, l = !1) {\n  return P.tidy(() => {\n    u(I.shape.length === 2, () => `qr2d() requires a 2D Tensor, but got a ${I.shape.length}D Tensor.`);\n    const G = I.shape[0], Z = I.shape[1];\n    let h = Um(G), g = lh(I);\n    const b = Ld([[1]], [1, 1]);\n    let c = lh(b);\n    const d = G >= Z ? Z : G;\n    for (let W = 0; W < d; ++W) {\n      const Y = g, V = c, a = h;\n      [c, g, h] = P.tidy(() => {\n        const i = zl(g, [W, W], [G - W, 1]), m = Vd(i), T = zl(g, [W, W], [1, 1]), s = UG(ZI(T, 0), Ld([[-1]]), Ld([[1]])), o = ml(T, N(s, m)), B = Vl(i, o);\n        B.shape[0] === 1 ? c = lh(b) : c = zG([\n          b,\n          zl(B, [1, 0], [B.shape[0] - 1, B.shape[1]])\n        ], 0);\n        const C = _l(Vl(Fl(s, o), m)), n = zl(g, [W, 0], [G - W, Z]), X = N(C, c), t = el(c);\n        if (W === 0)\n          g = ml(n, Fl(X, Fl(t, n)));\n        else {\n          const p = ml(n, Fl(X, Fl(t, n)));\n          g = zG([zl(g, [0, 0], [W, Z]), p], 0);\n        }\n        const e = el(X), S = zl(h, [0, W], [G, h.shape[1] - W]);\n        if (W === 0)\n          h = ml(S, Fl(Fl(S, c), e));\n        else {\n          const p = ml(S, Fl(Fl(S, c), e));\n          h = zG([zl(h, [0, 0], [G, W]), p], 1);\n        }\n        return [c, g, h];\n      }), Cl([Y, V, a]);\n    }\n    return !l && G > Z && (h = zl(h, [0, 0], [G, Z]), g = zl(g, [0, 0], [Z, Z])), [h, g];\n  });\n}\nconst HS = /* @__PURE__ */ E({ qr_: US });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst IZ = {\n  flipLeftRight: _e,\n  grayscaleToRGB: GS,\n  resizeNearestNeighbor: ZT,\n  resizeBilinear: IT,\n  rgbToGrayscale: ZS,\n  rotateWithOffset: gS,\n  cropAndResize: qe,\n  nonMaxSuppression: cS,\n  nonMaxSuppressionAsync: TS,\n  nonMaxSuppressionWithScore: oS,\n  nonMaxSuppressionWithScoreAsync: nS,\n  nonMaxSuppressionPadded: XS,\n  nonMaxSuppressionPaddedAsync: uS,\n  threshold: FS,\n  transform: NS\n}, KS = {\n  bandPart: JS,\n  gramSchmidt: xS,\n  qr: HS\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst AS = /* @__PURE__ */ new Map(), kS = /* @__PURE__ */ new Map();\nclass c0 {\n  /**\n   * Return the class name for this class to use in serialization contexts.\n   *\n   * Generally speaking this will be the same thing that constructor.name\n   * would have returned.  However, the class name needs to be robust\n   * against minification for serialization/deserialization to work properly.\n   *\n   * There's also places such as initializers.VarianceScaling, where\n   * implementation details between different languages led to different\n   * class hierarchies and a non-leaf node is used for serialization purposes.\n   */\n  getClassName() {\n    return this.constructor.className;\n  }\n  /**\n   * Creates an instance of T from a ConfigDict.\n   *\n   * This works for most descendants of serializable.  A few need to\n   * provide special handling.\n   * @param cls A Constructor for the class to instantiate.\n   * @param config The Configuration for the object.\n   */\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G);\n  }\n}\nclass dI {\n  constructor() {\n    this.classNameMap = {};\n  }\n  /**\n   * Returns the singleton instance of the map.\n   */\n  static getMap() {\n    return dI.instance == null && (dI.instance = new dI()), dI.instance;\n  }\n  /**\n   * Registers the class as serializable.\n   */\n  static register(l) {\n    dI.getMap().classNameMap[l.className] = [l, l.fromConfig];\n  }\n}\nfunction j(I, l, G) {\n  u(I.className != null, () => \"Class being registered does not have the static className property defined.\"), u(typeof I.className == \"string\", () => \"className is required to be a string, but got type \" + typeof I.className), u(I.className.length > 0, () => \"Class being registered has an empty-string as its className, which is disallowed.\"), typeof l > \"u\" && (l = \"Custom\"), typeof G > \"u\" && (G = I.className);\n  const Z = G, h = l + \">\" + Z;\n  return dI.register(I), AS.set(h, I), kS.set(I, h), I;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass KZ extends c0 {\n  /**\n   * Executes `f()` and minimizes the scalar output of `f()` by computing\n   * gradients of y with respect to the list of trainable variables provided by\n   * `varList`. If no list is provided, it defaults to all trainable variables.\n   *\n   * @param f The function to execute and whose output to minimize.\n   * @param returnCost Whether to return the scalar cost value produced by\n   * executing `f()`.\n   * @param varList An optional list of variables to update. If specified, only\n   * the trainable variables in varList will be updated by minimize. Defaults to\n   * all trainable variables.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers'}\n   */\n  minimize(l, G = !1, Z) {\n    const { value: h, grads: g } = this.computeGradients(l, Z);\n    if (Z != null) {\n      const b = Z.map((c) => ({ name: c.name, tensor: g[c.name] }));\n      this.applyGradients(b);\n    } else\n      this.applyGradients(g);\n    return Cl(g), G ? h : (h.dispose(), null);\n  }\n  /**\n   * The number of iterations that this optimizer instance has been invoked for.\n   */\n  get iterations() {\n    return this.iterations_ == null && (this.iterations_ = 0), this.iterations_;\n  }\n  incrementIterations() {\n    this.iterations_ = this.iterations + 1;\n  }\n  /**\n   * Executes f() and computes the gradient of the scalar output of f() with\n   * respect to the list of trainable variables provided by `varList`. If no\n   * list is provided, it defaults to all trainable variables.\n   *\n   * @param f The function to execute and whose output to use for computing\n   * gradients with respect to variables.\n   * @param varList An optional list of variables to compute gradients with\n   * respect to. If specified, only the trainable variables in varList will have\n   * gradients computed with respect to. Defaults to all trainable variables.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers'}\n   */\n  computeGradients(l, G) {\n    return vt(l, G);\n  }\n  /**\n   * Dispose the variables (if any) owned by this optimizer instance.\n   */\n  dispose() {\n    this.iterations_ != null && Cl(this.iterations_);\n  }\n  async saveIterations() {\n    return this.iterations_ == null && (this.iterations_ = 0), {\n      name: \"iter\",\n      // TODO(cais): Use 'int64' type when available.\n      tensor: yl(this.iterations_, \"int32\")\n    };\n  }\n  async getWeights() {\n    throw new Error(\"getWeights() is not implemented for this optimizer yet.\");\n  }\n  async setWeights(l) {\n    throw new Error(`setWeights() is not implemented for this optimizer class ${this.getClassName()}`);\n  }\n  /**\n   * Extract the first element of the weight values and set it\n   * as the iterations counter variable of this instance of optimizer.\n   *\n   * @param weightValues\n   * @returns Weight values with the first element consumed and excluded.\n   */\n  async extractIterations(l) {\n    return this.iterations_ = (await l[0].tensor.data())[0], l.slice(1);\n  }\n}\nObject.defineProperty(KZ, Symbol.hasInstance, {\n  value: (I) => I.minimize != null && I.computeGradients != null && I.applyGradients != null\n});\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass hT extends KZ {\n  /** @nocollapse */\n  static get className() {\n    return \"Adadelta\";\n  }\n  constructor(l, G, Z = null) {\n    super(), this.learningRate = l, this.rho = G, this.epsilon = Z, this.accumulatedGrads = [], this.accumulatedUpdates = [], Z == null && (this.epsilon = P.backend.epsilon());\n  }\n  applyGradients(l) {\n    (Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l)).forEach((Z, h) => {\n      const g = P.registeredVariables[Z], b = !1;\n      this.accumulatedGrads[h] == null && (this.accumulatedGrads[h] = {\n        originalName: `${Z}/accum_grad`,\n        variable: U(() => Sl(g).variable(b))\n      }), this.accumulatedUpdates[h] == null && (this.accumulatedUpdates[h] = {\n        originalName: `${Z}/accum_var`,\n        variable: U(() => Sl(g).variable(b))\n      });\n      const c = Array.isArray(l) ? l[h].tensor : l[Z];\n      if (c == null)\n        return;\n      const d = this.accumulatedGrads[h].variable, W = this.accumulatedUpdates[h].variable;\n      U(() => {\n        const Y = O(N(d, this.rho), N(Ml(c), 1 - this.rho)), V = N(Vl(RG(O(W, this.epsilon)), RG(O(d, this.epsilon))), c), a = O(N(W, this.rho), N(Ml(V), 1 - this.rho));\n        d.assign(Y), W.assign(a);\n        const i = O(N(V, -this.learningRate), g);\n        g.assign(i);\n      });\n    }), this.incrementIterations();\n  }\n  dispose() {\n    this.accumulatedUpdates != null && (Cl(this.accumulatedGrads.map((l) => l.variable)), Cl(this.accumulatedUpdates.map((l) => l.variable)));\n  }\n  async getWeights() {\n    const l = [...this.accumulatedGrads, ...this.accumulatedUpdates];\n    return [await this.saveIterations()].concat(l.map((G) => ({ name: G.originalName, tensor: G.variable })));\n  }\n  async setWeights(l) {\n    l = await this.extractIterations(l);\n    const G = l.length / 2, Z = !1;\n    this.accumulatedGrads = l.slice(0, G).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    })), this.accumulatedUpdates = l.slice(G, G * 2).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    }));\n  }\n  getConfig() {\n    return {\n      learningRate: this.learningRate,\n      rho: this.rho,\n      epsilon: this.epsilon\n    };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate, G.rho, G.epsilon);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass gT extends KZ {\n  /** @nocollapse */\n  static get className() {\n    return \"Adagrad\";\n  }\n  constructor(l, G = 0.1) {\n    super(), this.learningRate = l, this.initialAccumulatorValue = G, this.accumulatedGrads = [];\n  }\n  applyGradients(l) {\n    (Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l)).forEach((Z, h) => {\n      const g = P.registeredVariables[Z];\n      this.accumulatedGrads[h] == null && (this.accumulatedGrads[h] = {\n        originalName: `${Z}/accumulator`,\n        variable: U(() => Wd(g.shape, this.initialAccumulatorValue).variable(!1))\n      });\n      const b = Array.isArray(l) ? l[h].tensor : l[Z];\n      if (b == null)\n        return;\n      const c = this.accumulatedGrads[h].variable;\n      U(() => {\n        const d = O(c, Ml(b));\n        c.assign(d);\n        const W = O(N(Vl(b, RG(O(d, P.backend.epsilon()))), -this.learningRate), g);\n        g.assign(W);\n      });\n    }), this.incrementIterations();\n  }\n  dispose() {\n    this.accumulatedGrads != null && Cl(this.accumulatedGrads.map((l) => l.variable));\n  }\n  async getWeights() {\n    return [await this.saveIterations()].concat(this.accumulatedGrads.map((l) => ({ name: l.originalName, tensor: l.variable })));\n  }\n  async setWeights(l) {\n    l = await this.extractIterations(l);\n    const G = !1;\n    this.accumulatedGrads = l.map((Z) => ({ originalName: Z.name, variable: Z.tensor.variable(G) }));\n  }\n  getConfig() {\n    return {\n      learningRate: this.learningRate,\n      initialAccumulatorValue: this.initialAccumulatorValue\n    };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate, G.initialAccumulatorValue);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass bT extends KZ {\n  /** @nocollapse */\n  static get className() {\n    return \"Adam\";\n  }\n  constructor(l, G, Z, h = null) {\n    super(), this.learningRate = l, this.beta1 = G, this.beta2 = Z, this.epsilon = h, this.accumulatedFirstMoment = [], this.accumulatedSecondMoment = [], U(() => {\n      this.accBeta1 = yl(G).variable(), this.accBeta2 = yl(Z).variable();\n    }), h == null && (this.epsilon = P.backend.epsilon());\n  }\n  applyGradients(l) {\n    const G = Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l);\n    U(() => {\n      const Z = ml(1, this.accBeta1), h = ml(1, this.accBeta2);\n      G.forEach((g, b) => {\n        const c = P.registeredVariables[g], d = !1;\n        this.accumulatedFirstMoment[b] == null && (this.accumulatedFirstMoment[b] = {\n          originalName: `${g}/m`,\n          variable: U(() => Sl(c).variable(d))\n        }), this.accumulatedSecondMoment[b] == null && (this.accumulatedSecondMoment[b] = {\n          originalName: `${g}/v`,\n          variable: U(() => Sl(c).variable(d))\n        });\n        const W = Array.isArray(l) ? l[b].tensor : l[g];\n        if (W == null)\n          return;\n        const Y = this.accumulatedFirstMoment[b].variable, V = this.accumulatedSecondMoment[b].variable, a = O(N(Y, this.beta1), N(W, 1 - this.beta1)), i = O(N(V, this.beta2), N(Ml(W), 1 - this.beta2)), m = Vl(a, Z), T = Vl(i, h);\n        Y.assign(a), V.assign(i);\n        const s = O(N(Vl(m, O(RG(T), this.epsilon)), -this.learningRate), c);\n        c.assign(s);\n      }), this.accBeta1.assign(N(this.accBeta1, this.beta1)), this.accBeta2.assign(N(this.accBeta2, this.beta2));\n    }), this.incrementIterations();\n  }\n  dispose() {\n    this.accBeta1.dispose(), this.accBeta2.dispose(), this.accumulatedFirstMoment != null && Cl(this.accumulatedFirstMoment.map((l) => l.variable)), this.accumulatedSecondMoment != null && Cl(this.accumulatedSecondMoment.map((l) => l.variable));\n  }\n  async getWeights() {\n    const l = [...this.accumulatedFirstMoment, ...this.accumulatedSecondMoment];\n    return [await this.saveIterations()].concat(l.map((G) => ({ name: G.originalName, tensor: G.variable })));\n  }\n  async setWeights(l) {\n    l = await this.extractIterations(l), U(() => {\n      this.accBeta1.assign(Yh(this.beta1, this.iterations_ + 1)), this.accBeta2.assign(Yh(this.beta2, this.iterations_ + 1));\n    });\n    const G = l.length / 2, Z = !1;\n    this.accumulatedFirstMoment = l.slice(0, G).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    })), this.accumulatedSecondMoment = l.slice(G, G * 2).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    }));\n  }\n  getConfig() {\n    return {\n      learningRate: this.learningRate,\n      beta1: this.beta1,\n      beta2: this.beta2,\n      epsilon: this.epsilon\n    };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate, G.beta1, G.beta2, G.epsilon);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass cT extends KZ {\n  /** @nocollapse */\n  static get className() {\n    return \"Adamax\";\n  }\n  constructor(l, G, Z, h = null, g = 0) {\n    super(), this.learningRate = l, this.beta1 = G, this.beta2 = Z, this.epsilon = h, this.decay = g, this.accumulatedFirstMoment = [], this.accumulatedWeightedInfNorm = [], U(() => {\n      this.iteration = yl(0).variable(), this.accBeta1 = yl(G).variable();\n    }), h == null && (this.epsilon = P.backend.epsilon());\n  }\n  applyGradients(l) {\n    const G = Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l);\n    U(() => {\n      const Z = ml(1, this.accBeta1), h = Vl(-this.learningRate, O(N(this.iteration, this.decay), 1));\n      G.forEach((g, b) => {\n        const c = P.registeredVariables[g], d = !1;\n        this.accumulatedFirstMoment[b] == null && (this.accumulatedFirstMoment[b] = {\n          originalName: `${g}/m`,\n          variable: Sl(c).variable(d)\n        }), this.accumulatedWeightedInfNorm[b] == null && (this.accumulatedWeightedInfNorm[b] = {\n          originalName: `${g}/v`,\n          variable: Sl(c).variable(d)\n        });\n        const W = Array.isArray(l) ? l[b].tensor : l[g];\n        if (W == null)\n          return;\n        const Y = this.accumulatedFirstMoment[b].variable, V = this.accumulatedWeightedInfNorm[b].variable, a = O(N(Y, this.beta1), N(W, 1 - this.beta1)), i = N(V, this.beta2), m = PG(W), T = UZ(i, m);\n        Y.assign(a), V.assign(T);\n        const s = O(N(Vl(h, Z), Vl(a, O(T, this.epsilon))), c);\n        c.assign(s);\n      }), this.iteration.assign(O(this.iteration, 1)), this.accBeta1.assign(N(this.accBeta1, this.beta1));\n    }), this.incrementIterations();\n  }\n  dispose() {\n    this.accBeta1.dispose(), this.iteration.dispose(), this.accumulatedFirstMoment != null && Cl(this.accumulatedFirstMoment.map((l) => l.variable)), this.accumulatedWeightedInfNorm != null && Cl(this.accumulatedWeightedInfNorm.map((l) => l.variable));\n  }\n  async getWeights() {\n    throw new Error(\"getWeights() is not implemented for Adamax yet.\");\n  }\n  async setWeights(l) {\n    throw new Error(\"setWeights() is not implemented for Adamax yet.\");\n  }\n  getConfig() {\n    return {\n      learningRate: this.learningRate,\n      beta1: this.beta1,\n      beta2: this.beta2,\n      epsilon: this.epsilon,\n      decay: this.decay\n    };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate, G.beta1, G.beta2, G.epsilon, G.decay);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass tV extends KZ {\n  /** @nocollapse */\n  static get className() {\n    return \"SGD\";\n  }\n  constructor(l) {\n    super(), this.learningRate = l, this.setLearningRate(l);\n  }\n  applyGradients(l) {\n    (Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l)).forEach((Z, h) => {\n      const g = Array.isArray(l) ? l[h].tensor : l[Z];\n      if (g == null)\n        return;\n      const b = P.registeredVariables[Z];\n      U(() => {\n        const c = O(N(this.c, g), b);\n        b.assign(c);\n      });\n    }), this.incrementIterations();\n  }\n  /**\n   * Sets the learning rate of the optimizer.\n   */\n  setLearningRate(l) {\n    this.learningRate = l, this.c != null && this.c.dispose(), this.c = LI(yl(-l));\n  }\n  dispose() {\n    this.c.dispose();\n  }\n  async getWeights() {\n    return [await this.saveIterations()];\n  }\n  async setWeights(l) {\n    if (l = await this.extractIterations(l), l.length !== 0)\n      throw new Error(\"SGD optimizer does not have settable weights.\");\n  }\n  getConfig() {\n    return { learningRate: this.learningRate };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass dT extends tV {\n  /** @nocollapse */\n  // Name matters for Python compatibility.\n  static get className() {\n    return \"Momentum\";\n  }\n  constructor(l, G, Z = !1) {\n    super(l), this.learningRate = l, this.momentum = G, this.useNesterov = Z, this.accumulations = [], this.m = yl(this.momentum);\n  }\n  applyGradients(l) {\n    (Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l)).forEach((Z, h) => {\n      const g = P.registeredVariables[Z];\n      this.accumulations[h] == null && (this.accumulations[h] = {\n        originalName: `${Z}/momentum`,\n        variable: U(() => Sl(g).variable(!1))\n      });\n      const b = this.accumulations[h].variable, c = Array.isArray(l) ? l[h].tensor : l[Z];\n      c != null && U(() => {\n        let d;\n        const W = O(N(this.m, b), c);\n        this.useNesterov ? d = O(N(this.c, O(c, N(W, this.m))), g) : d = O(N(this.c, W), g), b.assign(W), g.assign(d);\n      });\n    }), this.incrementIterations();\n  }\n  dispose() {\n    this.m.dispose(), this.accumulations != null && Cl(this.accumulations.map((l) => l.variable));\n  }\n  /**\n   * Sets the momentum of the optimizer.\n   *\n   * @param momentum\n   */\n  setMomentum(l) {\n    this.momentum = l;\n  }\n  async getWeights() {\n    return [await this.saveIterations()].concat(this.accumulations.map((l) => ({ name: l.originalName, tensor: l.variable })));\n  }\n  async setWeights(l) {\n    l = await this.extractIterations(l);\n    const G = !1;\n    this.accumulations = l.map((Z) => ({ originalName: Z.name, variable: Z.tensor.variable(G) }));\n  }\n  getConfig() {\n    return {\n      learningRate: this.learningRate,\n      momentum: this.momentum,\n      useNesterov: this.useNesterov\n    };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate, G.momentum, G.useNesterov);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass WT extends KZ {\n  /** @nocollapse */\n  static get className() {\n    return \"RMSProp\";\n  }\n  constructor(l, G = 0.9, Z = 0, h = null, g = !1) {\n    if (super(), this.learningRate = l, this.decay = G, this.momentum = Z, this.epsilon = h, this.accumulatedMeanSquares = [], this.accumulatedMoments = [], this.accumulatedMeanGrads = [], this.centered = g, h == null && (this.epsilon = P.backend.epsilon()), l == null)\n      throw new Error(\"learningRate for RMSPropOptimizer must be defined.\");\n  }\n  applyGradients(l) {\n    (Array.isArray(l) ? l.map((Z) => Z.name) : Object.keys(l)).forEach((Z, h) => {\n      const g = P.registeredVariables[Z], b = !1;\n      this.accumulatedMeanSquares[h] == null && (this.accumulatedMeanSquares[h] = {\n        originalName: `${Z}/rms`,\n        variable: U(() => Sl(g).variable(b))\n      }), this.accumulatedMoments[h] == null && (this.accumulatedMoments[h] = {\n        originalName: `${Z}/momentum`,\n        variable: U(() => Sl(g).variable(b))\n      }), this.accumulatedMeanGrads[h] == null && this.centered && (this.accumulatedMeanGrads[h] = {\n        originalName: `${Z}/mg`,\n        variable: U(() => Sl(g).variable(b))\n      });\n      const c = Array.isArray(l) ? l[h].tensor : l[Z];\n      if (c == null)\n        return;\n      const d = this.accumulatedMeanSquares[h].variable, W = this.accumulatedMoments[h].variable;\n      U(() => {\n        const Y = O(N(d, this.decay), N(Ml(c), 1 - this.decay));\n        if (this.centered) {\n          const V = this.accumulatedMeanGrads[h].variable, a = O(N(V, this.decay), N(c, 1 - this.decay)), i = Vl(N(c, this.learningRate), RG(ml(Y, O(Ml(a), this.epsilon)))), m = O(N(W, this.momentum), i);\n          d.assign(Y), V.assign(a), W.assign(m);\n          const T = ml(g, m);\n          g.assign(T);\n        } else {\n          const V = O(N(d, this.decay), N(Ml(c), 1 - this.decay)), a = O(N(W, this.momentum), Vl(N(c, this.learningRate), RG(O(V, this.epsilon))));\n          d.assign(V), W.assign(a);\n          const i = ml(g, a);\n          g.assign(i);\n        }\n      });\n    }), this.incrementIterations();\n  }\n  dispose() {\n    this.accumulatedMeanSquares != null && Cl(this.accumulatedMeanSquares.map((l) => l.variable)), this.accumulatedMeanGrads != null && this.centered && Cl(this.accumulatedMeanGrads.map((l) => l.variable)), this.accumulatedMoments != null && Cl(this.accumulatedMoments.map((l) => l.variable));\n  }\n  async getWeights() {\n    const l = [...this.accumulatedMeanSquares, ...this.accumulatedMoments];\n    return this.centered && l.push(...this.accumulatedMeanGrads), [await this.saveIterations()].concat(l.map((G) => ({ name: G.originalName, tensor: G.variable })));\n  }\n  async setWeights(l) {\n    l = await this.extractIterations(l);\n    const G = this.centered ? l.length / 3 : l.length / 2, Z = !1;\n    this.accumulatedMeanSquares = l.slice(0, G).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    })), this.accumulatedMoments = l.slice(G, G * 2).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    })), this.centered && (this.accumulatedMeanGrads = l.slice(G * 2, G * 3).map((h) => ({\n      originalName: h.name,\n      variable: h.tensor.variable(Z)\n    })));\n  }\n  getConfig() {\n    return {\n      learningRate: this.learningRate,\n      decay: this.decay,\n      momentum: this.momentum,\n      epsilon: this.epsilon,\n      centered: this.centered\n    };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G.learningRate, G.decay, G.momentum, G.epsilon, G.centered);\n  }\n}\n/**\n * @license\n * Copyright 2022 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst zS = [\n  hT,\n  gT,\n  bT,\n  cT,\n  dT,\n  WT,\n  tV\n];\nfunction LS() {\n  for (const I of zS)\n    j(I);\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nlet wZ;\nfunction MS(I, l = 3) {\n  if (l > 4)\n    throw new Error(\"Cannot construct Tensor with more than 4 channels from pixels.\");\n  if (I == null)\n    throw new Error(\"pixels passed to tf.browser.fromPixels() can not be null\");\n  let G = !1, Z = !1, h = !1, g = !1, b = !1, c = !1;\n  if (I.data instanceof Uint8Array)\n    G = !0;\n  else if (typeof ImageData < \"u\" && I instanceof ImageData)\n    Z = !0;\n  else if (typeof HTMLVideoElement < \"u\" && I instanceof HTMLVideoElement)\n    h = !0;\n  else if (typeof HTMLImageElement < \"u\" && I instanceof HTMLImageElement)\n    g = !0;\n  else if (I.getContext != null)\n    b = !0;\n  else if (typeof ImageBitmap < \"u\" && I instanceof ImageBitmap)\n    c = !0;\n  else\n    throw new Error(`pixels passed to tf.browser.fromPixels() must be either an HTMLVideoElement, HTMLImageElement, HTMLCanvasElement, ImageData in browser, or OffscreenCanvas, ImageData in webworker or {data: Uint32Array, width: number, height: number}, but was ${I.constructor.name}`);\n  if (WW(cW, P.backendName) != null) {\n    const m = { pixels: I }, T = { numChannels: l };\n    return P.runKernel(cW, m, T);\n  }\n  const [W, Y] = h ? [\n    I.videoWidth,\n    I.videoHeight\n  ] : [I.width, I.height];\n  let V;\n  if (b)\n    V = // tslint:disable-next-line:no-any\n    I.getContext(\"2d\").getImageData(0, 0, W, Y).data;\n  else if (Z || G)\n    V = I.data;\n  else if (g || h || c) {\n    if (wZ == null)\n      if (typeof document > \"u\")\n        if (typeof OffscreenCanvas < \"u\" && typeof OffscreenCanvasRenderingContext2D < \"u\")\n          wZ = new OffscreenCanvas(1, 1).getContext(\"2d\");\n        else\n          throw new Error(\"Cannot parse input in current context. Reason: OffscreenCanvas Context2D rendering is not supported.\");\n      else\n        wZ = document.createElement(\"canvas\").getContext(\"2d\", { willReadFrequently: !0 });\n    wZ.canvas.width = W, wZ.canvas.height = Y, wZ.drawImage(I, 0, 0, W, Y), V = wZ.getImageData(0, 0, W, Y).data;\n  }\n  let a;\n  if (l === 4)\n    a = new Int32Array(V);\n  else {\n    const m = W * Y;\n    a = new Int32Array(m * l);\n    for (let T = 0; T < m; T++)\n      for (let s = 0; s < l; ++s)\n        a[T * l + s] = V[T * 4 + s];\n  }\n  return Fe(a, [Y, W, l], \"int32\");\n}\nconst wS = /* @__PURE__ */ E({ fromPixels_: MS });\nfunction uV(I, l) {\n  const G = I.shape.length, Z = l.shape.length;\n  if (G < 1)\n    throw new Error(`tf.gatherND() expects the input to be rank 1 or higher, but the rank was ${G}.`);\n  if (Z < 1)\n    throw new Error(`tf.gatherND() expects the indices to be rank 1 or higher, but the rank was ${Z}.`);\n  if (l.dtype !== \"int32\")\n    throw new Error(`tf.gatherND() expects the indices to be int32 type, but the dtype was ${l.dtype}.`);\n  if (l.shape[Z - 1] > G)\n    throw new Error(`index innermost dimension length must be <= tensor rank; saw: ${l.shape[Z - 1]} vs. ${G}`);\n  if (Q(I.shape) === 0)\n    throw new Error(`Requested more than 0 entries, but input is empty. Input shape: ${I.shape}.`);\n  const h = l.shape, g = h[h.length - 1];\n  let b = 1;\n  for (let V = 0; V < h.length - 1; ++V)\n    b *= h[V];\n  const c = I.shape, d = h.slice();\n  d.pop();\n  let W = 1;\n  for (let V = g; V < G; ++V)\n    W *= c[V], d.push(c[V]);\n  const Y = [\n    ...Wl(I.shape).map((V) => V / W),\n    1\n  ].slice(0, g);\n  return [d, b, W, Y];\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst uW = -2, QS = -1;\nfunction eV(I, l, G) {\n  const Z = I.shape.length;\n  u(Z === l.length, () => `Error in slice${Z}D: Length of begin ${l} must match the rank of the array (${Z}).`), u(Z === G.length, () => `Error in slice${Z}D: Length of size ${G} must match the rank of the array (${Z}).`);\n  for (let h = 0; h < Z; ++h)\n    u(l[h] + G[h] <= I.shape[h], () => `Error in slice${Z}D: begin[${h}] + size[${h}] (${l[h] + G[h]}) would overflow input.shape[${h}] (${I.shape[h]})`);\n}\nfunction vS(I) {\n  const l = [];\n  let G = 0;\n  for (; I > 0; )\n    I & 1 && l.push(G), I /= 2, G++;\n  return l;\n}\nfunction SV(I, l, G) {\n  const Z = [];\n  for (let h = 0; h < I.length; h++)\n    Z[h] = Math.ceil((l[h] - I[h]) / G[h]);\n  return Z;\n}\nfunction YT(I, l, G, Z) {\n  const h = [...I];\n  for (let g = h.length; g < Z.length; g++)\n    h.push(1);\n  for (let g = 0; g < G; g++)\n    g === 0 ? h[l] = 1 : (h.splice(\n      l,\n      0,\n      1\n      /* element to add */\n    ), h.pop());\n  return h;\n}\nfunction VT(I, l, G) {\n  return G <= I ? G : G - (l - 1);\n}\nfunction aT(I, l) {\n  const G = [];\n  for (let Z = 0; Z < I; Z++)\n    G.push(l + Z);\n  return G;\n}\nfunction rS(I, l, G, Z, h, g, b, c, d) {\n  const W = I.length;\n  let Y = new Array(W), V = new Array(W), a = new Array(W);\n  if (l.length && G > 0) {\n    const i = l[0], m = G + 1;\n    Y = iT(b, i, m, Z, I), V = mT(c, i, m, h, I), a = YT(g, i, m, I);\n  } else\n    for (let i = 0; i < W; i++)\n      Y[i] = sT(b, Z, g, I, i, d), V[i] = oT(c, h, g, I, i, d), a[i] = TT(g, i, d);\n  return {\n    begin: Y,\n    end: V,\n    strides: a\n  };\n}\nfunction iT(I, l, G, Z, h) {\n  const g = [...h], b = aT(G, l);\n  for (let c = 0; c < g.length; c++)\n    if (b.indexOf(c) > -1)\n      g[c] = 0;\n    else {\n      const d = VT(l, G, c);\n      let W = Z[d];\n      I & 1 << d && (W = 0), g[c] = W;\n    }\n  return g;\n}\nfunction mT(I, l, G, Z, h) {\n  const g = [...h], b = aT(G, l);\n  for (let c = 0; c < g.length; c++)\n    if (b.indexOf(c) > -1)\n      g[c] = Number.MAX_SAFE_INTEGER;\n    else {\n      const d = VT(l, G, c);\n      let W = Z[d];\n      I & 1 << d && (W = Number.MAX_SAFE_INTEGER), g[c] = W;\n    }\n  for (let c = 0; c < g.length; c++) {\n    const d = h[c];\n    g[c] < 0 && (g[c] += d), g[c] = Zh(0, g[c], h[c]);\n  }\n  return g;\n}\nfunction TT(I, l, G) {\n  let Z = I[l];\n  return (G & 1 << l || Z == null) && (Z = 1), Z;\n}\nfunction sT(I, l, G, Z, h, g) {\n  let b = l[h];\n  const c = G[h] || 1;\n  (I & 1 << h || g & 1 << h || b == null) && (c > 0 ? b = Number.MIN_SAFE_INTEGER : b = Number.MAX_SAFE_INTEGER);\n  const d = Z[h];\n  return b < 0 && (b += d), b = Zh(0, b, d - 1), b;\n}\nfunction oT(I, l, G, Z, h, g) {\n  let b = l[h];\n  const c = G[h] || 1;\n  (I & 1 << h || g & 1 << h || b == null) && (c > 0 ? b = Number.MAX_SAFE_INTEGER : b = Number.MIN_SAFE_INTEGER);\n  const d = Z[h];\n  return b < 0 && (b += d), c > 0 ? b = Zh(0, b, d) : b = Zh(-1, b, d - 1), b;\n}\nfunction RV(I, l, G) {\n  let Z = G.length;\n  for (let h = 0; h < G.length; h++)\n    if (G[h] > 1) {\n      Z = h;\n      break;\n    }\n  for (let h = Z + 1; h < G.length; h++)\n    if (l[h] > 0 || G[h] !== I[h])\n      return !1;\n  return !0;\n}\nfunction pV(I, l) {\n  let G = I.length > 0 ? I[I.length - 1] : 1;\n  for (let Z = 0; Z < I.length - 1; Z++)\n    G += I[Z] * l[Z];\n  return G;\n}\nfunction id(I, l, G) {\n  let Z;\n  const h = I.shape.length;\n  typeof l == \"number\" ? Z = [l, ...new Array(h - 1).fill(0)] : l.length < h ? Z = l.concat(new Array(h - l.length).fill(0)) : Z = l.slice(), Z.forEach((b) => {\n    u(b !== -1, () => \"slice() does not support negative begin indexing.\");\n  });\n  let g;\n  return G == null ? g = new Array(h).fill(-1) : typeof G == \"number\" ? g = [G, ...new Array(h - 1).fill(-1)] : G.length < h ? g = G.concat(new Array(h - G.length).fill(-1)) : g = G, g = g.map((b, c) => b >= 0 ? b : (u(b === -1, () => `Negative size values should be exactly -1 but got ${b} for the slice() size at index ${c}.`), I.shape[c] - Z[c])), [Z, g];\n}\nfunction FV(I, l, G, Z, h, g, b, c, d) {\n  let W;\n  if (Z == null ? (W = new Array(l.length), W.fill(1)) : W = Z, b != null && b & b - 1)\n    throw new Error(\"Multiple ellipses in slice is not allowed.\");\n  let Y = !1;\n  const V = {\n    dims: W.length,\n    numAddAxisAfterEllipsis: 0,\n    begin: l.slice(),\n    end: G.slice(),\n    strides: W.slice(),\n    beginMask: h,\n    endMask: g,\n    ellipsisMask: b,\n    newAxisMask: c,\n    shrinkAxisMask: d\n  };\n  for (let C = 0; C < V.dims; C++)\n    Y && 1 << C & c && V.numAddAxisAfterEllipsis++, 1 << C & b && (Y = !0);\n  Y || (V.ellipsisMask |= 1 << V.dims, V.dims++);\n  const a = {\n    dims: I.length,\n    beginMask: 0,\n    endMask: 0,\n    beginValid: !1,\n    endValid: !1\n  };\n  jS(V, a);\n  let i = !0, m = !0, T = !0;\n  const s = [], o = [];\n  for (let C = 0; C < I.length; ++C) {\n    if (a.strides[C] === 0)\n      throw Error(`strides[${C}] must be non-zero`);\n    const n = !!(a.shrinkAxisMask & 1 << C), X = I[C];\n    if (X === -1) {\n      s.push(n ? 1 : -1);\n      continue;\n    }\n    const t = [a.beginMask & 1 << C, a.endMask & 1 << C], e = [\n      a.strides[C] > 0 ? 0 : -1,\n      a.strides[C] > 0 ? X : X - 1\n    ];\n    if (n && a.strides[C] <= 0)\n      throw Error(\"only stride 1 allowed on non-range indexing.\");\n    T = T && a.strides[C] === 1;\n    const S = !!(a.beginMask & 1 << C && a.endMask & 1 << C);\n    if (a.beginValid && a.endValid) {\n      if (n) {\n        const H = a.begin[C] < 0 ? X + a.begin[C] : a.begin[C];\n        if (a.begin[C] = H, a.end[C] = a.begin[C] + 1, H < 0 || H >= X)\n          throw Error(`slice index ${a.begin[C]} of dimension ${C} out of bounds.`);\n      } else\n        a.begin[C] = ga(a.begin[C], 0, a.strides[C], X, t, e), a.end[C] = ga(a.end[C], 1, a.strides[C], X, t, e);\n      const x = a.strides[C] === 1 && a.begin[C] === 0 && a.end[C] === X;\n      i = i && x, m = m && (C === 0 && a.strides[C] === 1 || x);\n    } else\n      i = i && a.strides[C] === 1 && S, m = m && (C === 0 && a.strides[C] === 1 || S);\n    let p, F = !1;\n    if (a.beginValid && a.endValid ? (p = a.end[C] - a.begin[C], F = !0) : n ? (p = 1, F = !0) : S && X >= 0 && (a.strides[C] < 0 ? p = -X : p = X, F = !0), F) {\n      let x;\n      p === 0 || p < 0 != a.strides[C] < 0 ? x = 0 : x = Math.trunc(p / a.strides[C]) + (p % a.strides[C] !== 0 ? 1 : 0), s.push(x);\n    } else\n      s.push(-1);\n  }\n  for (let C = 0; C < a.finalShapeGatherIndices.length; ++C) {\n    const n = a.finalShapeGatherIndices[C];\n    n >= 0 ? o.push(s[n]) : n === uW && o.push(1);\n  }\n  return {\n    finalShapeSparse: o.filter((C, n) => a.finalShapeGatherIndices[n] !== uW),\n    finalShape: o,\n    isIdentity: i,\n    sliceDim0: m,\n    isSimpleSlice: T,\n    begin: a.begin,\n    end: a.end,\n    strides: a.strides\n  };\n}\nfunction jS(I, l) {\n  l.beginMask = 0, l.endMask = 0, l.shrinkAxisMask = 0;\n  let G = 0;\n  l.beginValid = I.begin != null, l.endValid = I.end != null, l.begin = new Array(l.dims), l.end = new Array(l.dims), l.strides = new Array(l.dims), l.finalShapeGatherIndices = [], l.finalShapeGatherIndicesSparse = [], l.inputShapeGatherIndicesSparse = new Array(l.dims);\n  for (let Z = 0; Z < I.dims; Z++)\n    if (1 << Z & I.ellipsisMask) {\n      const h = Math.min(l.dims - (I.dims - Z) + 1 + I.numAddAxisAfterEllipsis, l.dims);\n      for (; G < h; G++)\n        l.begin[G] = 0, l.end[G] = 0, l.strides[G] = 1, l.beginMask |= 1 << G, l.endMask |= 1 << G, l.finalShapeGatherIndices.push(G), l.finalShapeGatherIndicesSparse.push(-1), l.inputShapeGatherIndicesSparse[G] = Z;\n    } else if (1 << Z & I.newAxisMask)\n      l.finalShapeGatherIndices.push(uW), l.finalShapeGatherIndicesSparse.push(-1);\n    else {\n      if (G === l.begin.length)\n        throw Error(`Index out of range using input dim ${G}; input has only ${l.dims} dims, ${l.begin.length}.`);\n      I.begin != null && (l.begin[G] = I.begin[Z]), I.end != null && (l.end[G] = I.end[Z]), l.strides[G] = I.strides[Z], I.beginMask & 1 << Z && (l.beginMask |= 1 << G), I.endMask & 1 << Z && (l.endMask |= 1 << G), I.shrinkAxisMask & 1 << Z ? (l.finalShapeGatherIndices.push(QS), l.finalShapeGatherIndicesSparse.push(-1), l.shrinkAxisMask |= 1 << G) : (l.finalShapeGatherIndices.push(G), l.finalShapeGatherIndicesSparse.push(Z)), l.inputShapeGatherIndicesSparse[G] = Z, G++;\n    }\n}\nfunction ga(I, l, G, Z, h, g) {\n  if (h[l])\n    return G > 0 ? g[l] : g[l + 1 & 1];\n  {\n    const b = I < 0 ? Z + I : I;\n    return b < g[0] ? g[0] : b > g[1] ? g[1] : b;\n  }\n}\nconst DS = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  assertParamsValid: eV,\n  computeFlatOffset: pV,\n  computeOutShape: SV,\n  getNormalizedAxes: rS,\n  isSliceContinous: RV,\n  maskToAxes: vS,\n  parseSliceParams: id,\n  sliceInfo: FV,\n  startForAxis: sT,\n  startIndicesWithElidedDims: iT,\n  stopForAxis: oT,\n  stopIndicesWithElidedDims: mT,\n  stridesForAxis: TT,\n  stridesWithElidedDims: YT\n}, Symbol.toStringTag, { value: \"Module\" }));\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass fS {\n  /**\n   * Constructs a `tf.SGDOptimizer` that uses stochastic gradient descent.\n   *\n   * ```js\n   * // Fit a quadratic function by learning the coefficients a, b, c.\n   * const xs = tf.tensor1d([0, 1, 2, 3]);\n   * const ys = tf.tensor1d([1.1, 5.9, 16.8, 33.9]);\n   *\n   * const a = tf.scalar(Math.random()).variable();\n   * const b = tf.scalar(Math.random()).variable();\n   * const c = tf.scalar(Math.random()).variable();\n   *\n   * // y = a * x^2 + b * x + c.\n   * const f = x => a.mul(x.square()).add(b.mul(x)).add(c);\n   * const loss = (pred, label) => pred.sub(label).square().mean();\n   *\n   * const learningRate = 0.01;\n   * const optimizer = tf.train.sgd(learningRate);\n   *\n   * // Train the model.\n   * for (let i = 0; i < 10; i++) {\n   *   optimizer.minimize(() => loss(f(xs), ys));\n   * }\n   *\n   * // Make predictions.\n   * console.log(\n   *     `a: ${a.dataSync()}, b: ${b.dataSync()}, c: ${c.dataSync()}`);\n   * const preds = f(xs).dataSync();\n   * preds.forEach((pred, i) => {\n   *   console.log(`x: ${i}, pred: ${pred}`);\n   * });\n   * ```\n   *\n   * @param learningRate The learning rate to use for the SGD algorithm.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static sgd(l) {\n    return new tV(l);\n  }\n  /**\n   * Constructs a `tf.MomentumOptimizer` that uses momentum gradient\n   * descent.\n   *\n   * See\n   * [http://proceedings.mlr.press/v28/sutskever13.pdf](\n   * http://proceedings.mlr.press/v28/sutskever13.pdf)\n   *\n   * @param learningRate The learning rate to use for the Momentum gradient\n   * descent algorithm.\n   * @param momentum The momentum to use for the momentum gradient descent\n   * algorithm.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static momentum(l, G, Z = !1) {\n    return new dT(l, G, Z);\n  }\n  /**\n   * Constructs a `tf.RMSPropOptimizer` that uses RMSProp gradient\n   * descent. This implementation uses plain momentum and is not centered\n   * version of RMSProp.\n   *\n   * See\n   * [http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf](\n   * http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf)\n   *\n   * @param learningRate The learning rate to use for the RMSProp gradient\n   * descent algorithm.\n   * @param decay The discounting factor for the history/coming gradient.\n   * @param momentum The momentum to use for the RMSProp gradient descent\n   * algorithm.\n   * @param epsilon Small value to avoid zero denominator.\n   * @param centered If true, gradients are normalized by the estimated\n   * variance of the gradient.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static rmsprop(l, G = 0.9, Z = 0, h = null, g = !1) {\n    return new WT(l, G, Z, h, g);\n  }\n  /**\n   * Constructs a `tf.AdamOptimizer` that uses the Adam algorithm.\n   * See [https://arxiv.org/abs/1412.6980](https://arxiv.org/abs/1412.6980)\n   *\n   * @param learningRate The learning rate to use for the Adam gradient\n   * descent algorithm.\n   * @param beta1 The exponential decay rate for the 1st moment estimates.\n   * @param beta2 The exponential decay rate for the 2nd moment estimates.\n   * @param epsilon A small constant for numerical stability.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static adam(l = 1e-3, G = 0.9, Z = 0.999, h = null) {\n    return new bT(l, G, Z, h);\n  }\n  /**\n   * Constructs a `tf.AdadeltaOptimizer` that uses the Adadelta algorithm.\n   * See [https://arxiv.org/abs/1212.5701](https://arxiv.org/abs/1212.5701)\n   *\n   * @param learningRate The learning rate to use for the Adadelta gradient\n   * descent algorithm.\n   * @param rho The learning rate decay over each update.\n   * @param epsilon A constant epsilon used to better condition the grad\n   * update.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static adadelta(l = 1e-3, G = 0.95, Z = null) {\n    return new hT(l, G, Z);\n  }\n  /**\n   * Constructs a `tf.AdamaxOptimizer` that uses the Adamax algorithm.\n   * See [https://arxiv.org/abs/1412.6980](https://arxiv.org/abs/1412.6980)\n   *\n   * @param learningRate The learning rate to use for the Adamax gradient\n   * descent algorithm.\n   * @param beta1 The exponential decay rate for the 1st moment estimates.\n   * @param beta2 The exponential decay rate for the 2nd moment estimates.\n   * @param epsilon A small constant for numerical stability.\n   * @param decay The learning rate decay over each update.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static adamax(l = 2e-3, G = 0.9, Z = 0.999, h = null, g = 0) {\n    return new cT(l, G, Z, h, g);\n  }\n  /**\n   * Constructs a `tf.AdagradOptimizer` that uses the Adagrad algorithm.\n   * See\n   * [http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf](\n   * http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf)\n   * or\n   * [http://ruder.io/optimizing-gradient-descent/index.html#adagrad](\n   * http://ruder.io/optimizing-gradient-descent/index.html#adagrad)\n   *\n   * @param learningRate The learning rate to use for the Adagrad gradient\n   * descent algorithm.\n   * @param initialAccumulatorValue Starting value for the accumulators, must be\n   * positive.\n   *\n   * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'}\n   */\n  static adagrad(l, G = 0.1) {\n    return new gT(l, G);\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Nh = fS;\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst OS = typeof requestAnimationFrame < \"u\" ? requestAnimationFrame : typeof setImmediate < \"u\" ? setImmediate : (I) => I();\nfunction BT() {\n  return new Promise((I) => OS(() => I()));\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yV(I, l) {\n  const G = I[0].length;\n  I.forEach((h, g) => {\n    u(h.length === G, () => `Error in concat${G}D: rank of tensors[${g}] must be the same as the rank of the rest (${G})`);\n  }), u(l >= 0 && l < G, () => `Error in concat${G}D: axis must be between 0 and ${G - 1}.`);\n  const Z = I[0];\n  I.forEach((h, g) => {\n    for (let b = 0; b < G; b++)\n      u(b === l || h[b] === Z[b], () => `Error in concat${G}D: Shape of tensors[${g}] (${h}) does not match the shape of the rest (${Z}) along the non-concatenated axis ${g}.`);\n  });\n}\nfunction MI(I, l) {\n  const G = I[0].slice();\n  for (let Z = 1; Z < I.length; Z++)\n    G[l] += I[Z][l];\n  return G;\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nvar uI;\n(function(I) {\n  I[I.FIRST_DIM_SIZE = 0] = \"FIRST_DIM_SIZE\", I[I.VALUE_ROWIDS = 1] = \"VALUE_ROWIDS\", I[I.ROW_LENGTHS = 2] = \"ROW_LENGTHS\", I[I.ROW_SPLITS = 3] = \"ROW_SPLITS\", I[I.ROW_LIMITS = 4] = \"ROW_LIMITS\", I[I.ROW_STARTS = 5] = \"ROW_STARTS\";\n})(uI || (uI = {}));\nfunction nT(I, l, G) {\n  let Z = new Array();\n  if (G == null && l == null)\n    return Z;\n  if (l == null)\n    for (; Z.length < I + G.length; )\n      Z.push(-1);\n  else\n    Z = l.slice();\n  if (G == null)\n    return Z;\n  if (I + G.length !== Z.length)\n    throw new Error(`rt input.shape and shape=${l} are incompatible: rt input.rank = ${I + G.length}, but shape.rank = ${Z.length}`);\n  for (let h = 1; h < G.length; ++h) {\n    const g = G[h], b = Z[Z.length - G.length + h], c = Z[b];\n    if (g >= 0)\n      if (c >= 0) {\n        if (c !== g)\n          throw new Error(`rt input.shape and shape=${l} are incompatible: rt input.shape[${h + I}] = ${g} but shape[${h + I}] = ${c}`);\n      } else\n        Z[b] = g;\n  }\n  return Z;\n}\nfunction CT(I) {\n  const l = {\n    FIRST_DIM_SIZE: uI.FIRST_DIM_SIZE,\n    VALUE_ROWIDS: uI.VALUE_ROWIDS,\n    ROW_LENGTHS: uI.ROW_LENGTHS,\n    ROW_SPLITS: uI.ROW_SPLITS,\n    ROW_LIMITS: uI.ROW_LIMITS,\n    ROW_STARTS: uI.ROW_STARTS\n  }, G = [];\n  for (const Z of I)\n    if (Z in l)\n      G.push(l[Z]);\n    else\n      break;\n  return G;\n}\nfunction XT(I) {\n  return I.length === 0 ? 0 : I[0] === uI.FIRST_DIM_SIZE ? I.length - 1 : I.length;\n}\nfunction tT(I, l) {\n  if (I == null || l == null)\n    return;\n  const G = I.length, Z = l.length;\n  if (G >= Z)\n    throw new Error(`defaultValue.shape=${I} and ragged tensor flatValues.shape=${l}, are incompatible: defaultValue.rank = ${G} must be less than ragged tensor input flatValues.rank = ${Z})`);\n  for (let h = 0; h < Math.min(G, Z - 1); ++h) {\n    const g = I[h], b = l[h + 1];\n    if (g >= 0 && b >= 0 && g !== 1 && g !== b)\n      throw new Error(`defaultValue.shape=${I}, and ragged tensor input flatValues.shape=${l} are incompatible: defaultValue.shape[${h - I.length}] = ${g} but ragged tensor input.flatValues.shape[${h - I.length}] = ${b}`);\n  }\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst NV = 30;\nfunction md(I) {\n  return I <= NV ? I : hW(I, Math.floor(Math.sqrt(I)));\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction PV(I, l, G) {\n  const Z = G * (typeof I == \"number\" ? I : I[0]), h = l * (typeof I == \"number\" ? I : I[1]);\n  return [Z, h];\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Dg(I, l, G, Z = !0) {\n  let h = [];\n  if (Z)\n    h = h.concat(l.slice(0)), h.push(I[0] / G), h = h.concat(I.slice(1));\n  else {\n    h = h.concat(I[0]);\n    const g = l.length;\n    for (let b = 0; b < g; ++b)\n      h = h.concat([I[b + 1] / l[b], l[b]]);\n    h = h.concat(I.slice(g + 1));\n  }\n  return h;\n}\nfunction fg(I, l, G = !0) {\n  const Z = [];\n  if (G) {\n    Z.push(l);\n    for (let h = l + 1; h < I; ++h)\n      h <= 2 * l ? (Z.push(h), Z.push(h - (l + 1))) : Z.push(h);\n  } else {\n    const h = [], g = [];\n    for (let b = 1; b < I; ++b)\n      b >= l * 2 + 1 || b % 2 === 1 ? g.push(b) : h.push(b);\n    Z.push(...h), Z.push(0), Z.push(...g);\n  }\n  return Z;\n}\nfunction Og(I, l, G, Z = !0) {\n  const h = [];\n  Z ? h.push(I[0] / G) : h.push(I[0] * G);\n  for (let g = 1; g < I.length; ++g)\n    g <= l.length ? Z ? h.push(l[g - 1] * I[g]) : h.push(I[g] / l[g - 1]) : h.push(I[g]);\n  return h;\n}\nfunction JV(I, l) {\n  const G = [0];\n  for (let Z = 0; Z < l; ++Z)\n    G.push(I[Z][0]);\n  return G;\n}\nfunction EV(I, l, G) {\n  const Z = I.slice(0, 1);\n  for (let h = 0; h < G; ++h)\n    Z.push(I[h + 1] - l[h][0] - l[h][1]);\n  return Z;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Td = 1.7580993408473768, sd = 1.0507009873554805;\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst xV = 0.3275911, UV = 0.254829592, HV = -0.284496736, KV = 1.421413741, AV = -1.453152027, kV = 1.061405429;\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction bZ(I, l) {\n  if (I.length !== l.length)\n    throw new Error(`Cannot merge real and imag arrays of different lengths. real:${I.length}, imag: ${l.length}.`);\n  const G = new Float32Array(I.length * 2);\n  for (let Z = 0; Z < G.length; Z += 2)\n    G[Z] = I[Z / 2], G[Z + 1] = l[Z / 2];\n  return G;\n}\nfunction uT(I) {\n  const l = new Float32Array(I.length / 2), G = new Float32Array(I.length / 2);\n  for (let Z = 0; Z < I.length; Z += 2)\n    l[Z / 2] = I[Z], G[Z / 2] = I[Z + 1];\n  return { real: l, imag: G };\n}\nfunction eT(I) {\n  const l = Math.ceil(I.length / 4), G = new Float32Array(l), Z = new Float32Array(l);\n  for (let h = 0; h < I.length; h += 4)\n    G[Math.floor(h / 4)] = I[h], Z[Math.floor(h / 4)] = I[h + 1];\n  return { real: G, imag: Z };\n}\nfunction ST(I) {\n  const l = Math.floor(I.length / 4), G = new Float32Array(l), Z = new Float32Array(l);\n  for (let h = 2; h < I.length; h += 4)\n    G[Math.floor(h / 4)] = I[h], Z[Math.floor(h / 4)] = I[h + 1];\n  return { real: G, imag: Z };\n}\nfunction zV(I, l) {\n  const G = I[l * 2], Z = I[l * 2 + 1];\n  return { real: G, imag: Z };\n}\nfunction RT(I, l, G, Z) {\n  I[Z * 2] = l, I[Z * 2 + 1] = G;\n}\nfunction pT(I, l) {\n  const G = new Float32Array(I / 2), Z = new Float32Array(I / 2);\n  for (let h = 0; h < Math.ceil(I / 2); h++) {\n    const g = (l ? 2 : -2) * Math.PI * (h / I);\n    G[h] = Math.cos(g), Z[h] = Math.sin(g);\n  }\n  return { real: G, imag: Z };\n}\nfunction FT(I, l, G) {\n  const Z = (G ? 2 : -2) * Math.PI * (I / l), h = Math.cos(Z), g = Math.sin(Z);\n  return { real: h, imag: g };\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Md = \"->\", qS = /->/g, ba = \",\", ca = \"...\";\nfunction LV(I, l) {\n  I = I.replace(/\\s/g, \"\");\n  const G = (I.length - I.replace(qS, \"\").length) / Md.length;\n  if (G < 1)\n    throw new Error(\"Equations without an arrow are not supported.\");\n  if (G > 1)\n    throw new Error(`Equation must contain exactly one arrow (\"${Md}\").`);\n  const [Z, h] = I.split(Md);\n  u(Z.indexOf(ca) === -1, () => `The ellipsis notation (\"${ca}\") is not supported yet.`);\n  const g = Z.split(ba), b = g.length;\n  if (l !== b)\n    throw new Error(`Expected ${b} input tensors, received ${l}`);\n  if (b > 2)\n    throw new Error(\"Support for more than 2 input tensors is not implemented yet.\");\n  const c = [];\n  for (let a = 0; a < h.length; ++a) {\n    const i = h[a];\n    if (!g.some((m) => m.indexOf(i) !== -1))\n      throw new Error(`Output subscripts contain the label ${i} not present in the input subscripts.`);\n    c.indexOf(i) === -1 && c.push(i);\n  }\n  for (let a = 0; a < Z.length; ++a) {\n    const i = Z[a];\n    c.indexOf(i) === -1 && i !== ba && c.push(i);\n  }\n  const d = new Array(g.length);\n  for (let a = 0; a < b; ++a) {\n    if (new Set(g[a].split(\"\")).size !== g[a].length)\n      throw new Error(`Found duplicate axes in input component ${g[a]}. Support for duplicate axes in input is not implemented yet.`);\n    d[a] = [];\n    for (let i = 0; i < g[a].length; ++i)\n      d[a].push(c.indexOf(g[a][i]));\n  }\n  const W = c.length, Y = h.length, V = [];\n  for (let a = Y; a < W; ++a)\n    V.push(a);\n  return { allDims: c, summedDims: V, idDims: d };\n}\nfunction MV(I, l) {\n  let G = new Array(I);\n  G.fill(-1);\n  for (let h = 0; h < l.length; ++h)\n    G[l[h]] = h;\n  const Z = [];\n  for (let h = 0; h < I; ++h)\n    G[h] === -1 && Z.push(h);\n  return G = G.filter((h) => h !== -1), { permutationIndices: G, expandDims: Z };\n}\nfunction wV(I, l, G) {\n  const Z = new Array(I);\n  for (let h = 0; h < G.length; ++h) {\n    const g = G[h].shape;\n    for (let b = 0; b < l[h].length; ++b)\n      Z[l[h][b]] === void 0 ? Z[l[h][b]] = g[b] : u(Z[l[h][b]] === g[b], () => `Expected dimension ${Z[l[h][b]]} at axis ${b} of input shaped ${JSON.stringify(g)}, but got dimension ${g[b]}`);\n  }\n}\nfunction QV(I, l) {\n  const G = I, Z = [];\n  let h = 0;\n  I.length === 0 && G.push(-1), h = I.length + 1;\n  for (let b = 0; b < h; ++b)\n    Z.push([]);\n  const g = [];\n  for (let b = 0; b < G.length; ++b) {\n    const c = G[b], d = $S(l, c);\n    for (const W of d)\n      g.indexOf(W) === -1 && (Z[b].push(W), g.push(W));\n  }\n  return { path: G, steps: Z };\n}\nfunction vV(I) {\n  return I.every((l, G) => l === G);\n}\nfunction $S(I, l) {\n  const G = [];\n  for (let Z = 0; Z < I.length; ++Z)\n    (I[Z].length === 0 || I[Z].indexOf(l) !== -1 || l === -1) && G.push(Z);\n  return G;\n}\nfunction rV(I, l, G = 0) {\n  let Z = [];\n  if (typeof l == \"number\")\n    u(I.shape[G] % l === 0, () => \"Number of splits must evenly divide the axis.\"), Z = new Array(l).fill(I.shape[G] / l);\n  else {\n    const h = l.reduce((b, c) => (c === -1 && (b += 1), b), 0);\n    u(h <= 1, () => \"There should be only one negative value in split array.\");\n    const g = l.indexOf(-1);\n    if (g !== -1) {\n      const b = l.reduce((c, d) => d > 0 ? c + d : c);\n      l[g] = I.shape[G] - b;\n    }\n    u(I.shape[G] === l.reduce((b, c) => b + c), () => \"The sum of sizes must match the size of the axis dimension.\"), Z = l;\n  }\n  return Z;\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yT(I) {\n  return `Received SparseTensor with denseShape[0] = 0 but\n  indices.shape[0] = ${I}`;\n}\nfunction NT(I, l) {\n  return `indices(${I}, 0) is invalid: ${l} < 0`;\n}\nfunction PT(I, l, G) {\n  return `indices(${I}, 0) is invalid: ${l} >= ${G}`;\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction JT(I, l) {\n  return `only one output dimension may be -1, not both ${I} and ${l}`;\n}\nfunction ET(I, l) {\n  return `size ${I} must be non-negative, not ${l}`;\n}\nfunction xT() {\n  return \"reshape cannot infer the missing input size for an empty tensor unless all specified input sizes are non-zero\";\n}\nfunction UT(I, l) {\n  const G = Q(I), Z = Q(l);\n  return `Input to reshape is a SparseTensor with ${G}\n  dense values, but the requested shape requires a multiple of ${Z}. inputShape=${I} outputShape= ${l}`;\n}\nfunction HT(I, l) {\n  const G = Q(I), Z = Q(l);\n  return `Input to reshape is a tensor with ${G} dense values, but the requested shape has ${Z}. inputShape=${I} outputShape=${l}`;\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction eW() {\n  return \"segment ids must be >= 0\";\n}\nfunction KT() {\n  return \"segment ids are not increasing\";\n}\nfunction AT(I, l) {\n  return `Segment id ${I} out of range [0, ${l}), possibly because segmentIds input is not sorted.`;\n}\nfunction kT(I, l, G) {\n  return `Bad: indices[${I}] == ${l} out of range [0, ${G})`;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zT(I, l) {\n  let G = !1, Z;\n  for (I <= NV ? (Z = I, G = !0) : Z = hW(I, Math.floor(Math.sqrt(I))); !G; )\n    Z > l || Z === I ? G = !0 : Z = hW(I, Z + 1);\n  return Z;\n}\nfunction LT(I, l, G) {\n  const Z = [], h = I.length;\n  for (let g = 0; g < h; g++)\n    g !== l ? Z.push(I[g]) : Z.push(G);\n  return Z;\n}\nfunction jV(I, l, G, Z) {\n  const h = l.shape.length, g = I.shape.length;\n  if (Z !== 0 && (Z < -h || Z > h))\n    throw new Error(`Expect batchDims in the range of [-${h}, ${h}], but got ${Z}`);\n  if (Z < 0 && (Z += h), Z > g)\n    throw new Error(`batchDims (${Z}) must be less than rank(x) (\n    ${g}).`);\n  if (G < Z)\n    throw new Error(`batchDims (${Z}) must be less than or equal to axis (${G}).`);\n  for (let V = 0; V < Z; ++V)\n    if (I.shape[V] !== l.shape[V])\n      throw new Error(`x.shape[${V}]: ${I.shape[V]} should be equal to indices.shape[${V}]: ${l.shape[V]}.`);\n  const b = I.shape[G], c = [];\n  let d = 1, W = 1, Y = 1;\n  for (let V = 0; V < Z; ++V)\n    c.push(I.shape[V]), d *= I.shape[V];\n  for (let V = Z; V < G; V++)\n    c.push(I.shape[V]), W *= I.shape[V];\n  for (let V = Z; V < h; V++)\n    c.push(l.shape[V]);\n  for (let V = G + 1; V < g; V++)\n    c.push(I.shape[V]), Y *= I.shape[V];\n  return { batchSize: d, sliceSize: Y, outerSize: W, dimSize: b, outputShape: c };\n}\nconst _S = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  collectGatherOpShapeInfo: jV,\n  computeOutShape: LT,\n  segOpComputeOptimalWindowSize: zT\n}, Symbol.toStringTag, { value: \"Module\" }));\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction cZ(I) {\n  try {\n    return I.map((l) => eZ(l));\n  } catch (l) {\n    throw new Error(`Failed to decode encoded string bytes into utf-8, error: ${l}`);\n  }\n}\nfunction MT(I) {\n  return I.map((l) => XZ(l));\n}\nconst lR = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  ERF_A1: UV,\n  ERF_A2: HV,\n  ERF_A3: KV,\n  ERF_A4: AV,\n  ERF_A5: kV,\n  ERF_P: xV,\n  PARALLELIZE_THRESHOLD: NV,\n  get RowPartitionType() {\n    return uI;\n  },\n  SELU_SCALE: sd,\n  SELU_SCALEALPHA: Td,\n  applyActivation: sV,\n  assertAndGetBroadcastShape: sl,\n  assertAxesAreInnerMostDims: XG,\n  assertParamsConsistent: yV,\n  assignToTypedArray: RT,\n  axesAreInnerMostDims: jY,\n  calculateShapes: uh,\n  checkEinsumDimSizes: wV,\n  checkPadOnDimRoundingMode: wG,\n  combineLocations: Em,\n  combineRaggedTensorToTensorShapes: nT,\n  complexWithEvenIndex: eT,\n  complexWithOddIndex: ST,\n  computeConv2DInfo: CG,\n  computeConv3DInfo: EZ,\n  computeDefaultPad: LY,\n  computeDilation2DInfo: wg,\n  computeOptimalWindowSize: md,\n  computeOutAndReduceShapes: sG,\n  computeOutShape: MI,\n  computePool2DInfo: sI,\n  computePool3DInfo: WZ,\n  convertConv2DDataFormat: YZ,\n  decodeEinsumEquation: LV,\n  eitherStridesOrDilationsAreOne: pG,\n  expandShapeToKeepDim: bG,\n  exponent: FT,\n  exponents: pT,\n  fromStringArrayToUint8: MT,\n  fromUint8ToStringArray: cZ,\n  getAxesPermutation: Ol,\n  getBroadcastDims: rh,\n  getComplexWithIndex: zV,\n  getEinsumComputePath: QV,\n  getEinsumPermutation: MV,\n  getFusedBiasGradient: TV,\n  getFusedDyActivation: mV,\n  getImageCenter: PV,\n  getInnerMostAxes: GG,\n  getPermuted: fg,\n  getRaggedRank: XT,\n  getReductionAxes: VG,\n  getReshaped: Dg,\n  getReshapedPermuted: Og,\n  getRowPartitionTypesHelper: CT,\n  getSliceBeginCoords: JV,\n  getSliceSize: EV,\n  getSparseFillEmptyRowsIndicesDenseShapeMismatch: yT,\n  getSparseFillEmptyRowsNegativeIndexErrorMessage: NT,\n  getSparseFillEmptyRowsOutOfRangeIndexErrorMessage: PT,\n  getSparseReshapeEmptyTensorZeroOutputDimErrorMessage: xT,\n  getSparseReshapeInputOutputMismatchErrorMessage: HT,\n  getSparseReshapeInputOutputMultipleErrorMessage: UT,\n  getSparseReshapeMultipleNegativeOneOutputDimErrorMessage: JT,\n  getSparseReshapeNegativeOutputDimErrorMessage: ET,\n  getSparseSegmentReductionIndicesOutOfRangeErrorMessage: kT,\n  getSparseSegmentReductionNegativeSegmentIdsErrorMessage: eW,\n  getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage: KT,\n  getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage: AT,\n  getUndoAxesPermutation: xZ,\n  isIdentityPermutation: vV,\n  log: Jn,\n  mergeRealAndImagArrays: bZ,\n  prepareAndValidate: uV,\n  prepareSplitSize: rV,\n  segment_util: _S,\n  shouldFuse: oV,\n  slice_util: DS,\n  splitRealAndImagArrays: uT,\n  stridesOrDilationsArePositive: dh,\n  tupleValuesAreOne: ch,\n  upcastType: DG,\n  validateDefaultValueShape: tT,\n  validateInput: ye,\n  validateUpdateShape: $m,\n  warn: _G\n}, Symbol.toStringTag, { value: \"Module\" }));\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nLS();\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst wT = {\n  kernelName: bc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, jg(hl(G, \"float32\"), -1)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst GR = {\n  kernelName: r0,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return {\n      x: () => {\n        const Z = Ml(hl(G, \"float32\")), h = RG(ml(yl(1), Z));\n        return _l(Vl(I, h));\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst IR = {\n  kernelName: j0,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return {\n      x: () => {\n        const Z = RG(ml(Ml(hl(G, \"float32\")), 1));\n        return Vl(I, Z);\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ZR = {\n  kernelName: I0,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      let c = I;\n      const d = VG(G.shape, h);\n      return d.length > 0 && (c = Yl(c, d)), J(c, G.shape);\n    }, b: () => {\n      let c = I;\n      const d = VG(Z.shape, h);\n      return d.length > 0 && (c = Yl(c, d)), J(c, Z.shape);\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hR = {\n  kernelName: OW,\n  saveAllInputs: !0,\n  gradFunc: (I, l) => {\n    const G = {};\n    return l.forEach((Z, h) => {\n      G[h] = () => I.clone();\n    }), G;\n  }\n};\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst gR = {\n  kernelName: cc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Sl(G) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bR = {\n  kernelName: dc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Sl(G) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst cR = {\n  kernelName: D0,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, RG(ml(yl(1), Ml(hl(G, \"float32\"))))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst dR = {\n  kernelName: f0,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return {\n      x: () => {\n        const Z = RG(O(yl(1), Ml(hl(G, \"float32\"))));\n        return Vl(I, Z);\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst WR = {\n  kernelName: $0,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      const c = O(Ml(G), Ml(Z));\n      let d = N(I, Vl(Z, c));\n      const W = VG(G.shape, h);\n      return W.length > 0 && (d = Yl(d, W)), J(d, G.shape);\n    }, b: () => {\n      const c = O(Ml(G), Ml(Z));\n      let d = _l(N(I, Vl(G, c)));\n      const W = VG(Z.shape, h);\n      return W.length > 0 && (d = Yl(d, W)), J(d, Z.shape);\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst YR = {\n  kernelName: O0,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, O(Ml(hl(G, \"float32\")), 1)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst VR = {\n  kernelName: q0,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, ml(yl(1), Ml(hl(G, \"float32\")))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction aR(I, l, G, Z, h, g) {\n  const b = R(I, \"dy\", \"avgPool3dGrad\"), c = R(l, \"input\", \"avgPool3dGrad\");\n  let d = b, W = c, Y = !1;\n  c.rank === 4 && (Y = !0, d = J(b, [1, b.shape[0], b.shape[1], b.shape[2], b.shape[3]]), W = J(c, [\n    1,\n    c.shape[0],\n    c.shape[1],\n    c.shape[2],\n    c.shape[3]\n  ])), u(d.rank === 5, () => `Error in avgPool3dGrad: dy must be rank 5 but got rank ${d.rank}.`), u(W.rank === 5, () => `Error in avgPool3dGrad: input must be rank 5 but got rank ${W.rank}.`), wG(\"avgPool3dGrad\", h, g);\n  const V = { dy: d, input: W }, a = { filterSize: G, strides: Z, pad: h, dimRoundingMode: g }, i = P.runKernel(lY, V, a);\n  return Y ? J(i, [i.shape[1], i.shape[2], i.shape[3], i.shape[4]]) : i;\n}\nconst iR = /* @__PURE__ */ E({ avgPool3dGrad_: aR });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst mR = {\n  kernelName: Yc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { filterSize: h, strides: g, pad: b, dimRoundingMode: c } = G;\n    return {\n      x: () => iR(I, Z, h, g, b, c)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction TR(I, l, G, Z, h) {\n  const g = R(I, \"dy\", \"avgPoolGrad\"), b = R(l, \"input\", \"avgPoolGrad\");\n  u(b.rank === g.rank, () => `Rank of input (${b.rank}) does not match rank of dy (${g.rank})`);\n  let c = b, d = g, W = !1;\n  b.rank === 3 && (W = !0, c = J(b, [1, b.shape[0], b.shape[1], b.shape[2]]), d = J(g, [1, g.shape[0], g.shape[1], g.shape[2]])), u(d.rank === 4, () => `Error in avgPoolGrad: dy must be rank 4 but got rank ${d.rank}.`), u(c.rank === 4, () => `Error in avgPoolGrad: input must be rank 4 but got rank ${c.rank}.`);\n  const Y = { dy: d, input: c }, V = { filterSize: G, strides: Z, pad: h }, a = P.runKernel(_W, Y, V);\n  return W ? J(a, [a.shape[1], a.shape[2], a.shape[3]]) : a;\n}\nconst sR = /* @__PURE__ */ E({ avgPoolGrad_: TR });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst oR = {\n  kernelName: Wc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { filterSize: h, strides: g, pad: b } = G;\n    return { x: () => sR(I, Z, h, g, b) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst BR = {\n  kernelName: Vc,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { transposeA: g, transposeB: b } = G;\n    return !g && !b ? {\n      a: () => Fl(I, h, !1, !0),\n      b: () => Fl(Z, I, !0, !1)\n    } : !g && b ? {\n      a: () => Fl(I, h, !1, !1),\n      b: () => Fl(I, Z, !0, !1)\n    } : g && !b ? {\n      a: () => Fl(h, I, !1, !0),\n      b: () => Fl(Z, I, !1, !1)\n    } : {\n      a: () => Fl(h, I, !0, !0),\n      b: () => Fl(I, Z, !0, !0)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst nR = {\n  kernelName: ac,\n  gradFunc: (I, l, G) => {\n    const { blockShape: Z, crops: h } = G;\n    return { x: () => GV(I, Z, h) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst CR = {\n  kernelName: yn,\n  gradFunc: (I, l, G) => {\n    const Z = G, h = Z.inputShape, g = Z.shape, b = Array.from(g);\n    for (let d = h.length - 1; d >= 0; d--)\n      if (h[d] === g[d])\n        b[d] = 1;\n      else if (h[d] !== 1)\n        throw new Error(`broadcastTo(): [${h}] cannot be broadcast to [${g}].`);\n    const c = [];\n    for (let d = 0; d < b.length; d++)\n      b[d] > 1 && c.push(d);\n    return { x: () => Yl(\n      I,\n      c,\n      !0\n      /* keepDims */\n    ) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst XR = {\n  kernelName: _0,\n  gradFunc: (I) => ({ x: () => I.clone() })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst tR = {\n  kernelName: lg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst uR = {\n  kernelName: Gg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { clipValueMin: h, clipValueMax: g } = G;\n    return {\n      x: () => UG(hZ(Ch(Z, h), g0(Z, g)), I, Sl(I))\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst eR = {\n  kernelName: ic,\n  inputsToSave: [\"x\"],\n  gradFunc: wT.gradFunc\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst SR = {\n  kernelName: mc,\n  saveAllInputs: !0,\n  gradFunc: (I, l, G) => {\n    const Z = l.map((d) => d.shape), { axis: h } = G, g = tl(h, l[0].shape)[0], b = Z.map((d) => d[g]);\n    return GI(I, b, g).map((d) => () => d);\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst RR = {\n  kernelName: Tc,\n  inputsToSave: [\"x\", \"filter\"],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { dilations: g, strides: b, pad: c, dataFormat: d } = G;\n    return u(ch(g), () => `Error in gradient of conv2D: dilation rates greater than 1 are not yet supported in gradients. Got dilations '${g}'`), {\n      x: () => QY(Z.shape, I, h, b, c, d),\n      filter: () => iV(Z, I, h.shape, b, c, d)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst pR = {\n  kernelName: sc,\n  inputsToSave: [\"dy\", \"filter\"],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { strides: g, pad: b, dataFormat: c, dimRoundingMode: d } = G;\n    return {\n      dy: () => Wh(I, h, g, b, c, 1, d),\n      filter: () => iV(I, Z, h.shape, g, b, c, d)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction FR(I, l, G, Z, h) {\n  let g = I;\n  I.rank === 4 && (g = J(I, [1, I.shape[0], I.shape[1], I.shape[2], I.shape[3]]));\n  let b = l;\n  b.rank === 4 && (b = J(l, [1, l.shape[0], l.shape[1], l.shape[2], l.shape[3]])), u(g.rank === 5, () => `Error in conv3dDerFilter: input must be rank 5, but got shape ${g.shape}.`), u(b.rank === 5, () => `Error in conv3dDerFilter: dy must be rank 5, but got shape ${b.shape}.`), u(G.length === 5, () => `Error in conv3dDerFilter: filterShape must be length 5, but got ${G}.`), u(g.shape[4] === G[3], () => `Error in conv3dDerFilter: depth of input ${g.shape[4]}) must match input depth in filter (${G[3]}.`), u(b.shape[4] === G[4], () => `Error in conv3dDerFilter: depth of dy (${b.shape[4]}) must match output depth for filter (${G[4]}).`);\n  const c = { x: g, dy: b }, d = { strides: Z, pad: h, filterShape: G };\n  return P.runKernel(gY, c, d);\n}\nconst yR = /* @__PURE__ */ E({ conv3DBackpropFilter_: FR });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst NR = {\n  kernelName: oc,\n  inputsToSave: [\"x\", \"filter\"],\n  gradFunc: (I, l, G) => {\n    const { dilations: Z, strides: h, pad: g } = G;\n    u(ch(Z), () => `Error in gradient of conv3D: dilation rates greater than 1 are not yet supported in gradients. Got dilations '${Z}'`);\n    const [b, c] = l;\n    return {\n      x: () => ym(b.shape, I, c, h, g),\n      filter: () => yR(b, I, c.shape, h, g)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst PR = {\n  kernelName: Ig,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(_l(Dm(hl(G, \"float32\"))), I) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst JR = {\n  kernelName: Zg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(fm(hl(G, \"float32\")), I) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ER = {\n  kernelName: Bc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { axis: h, exclusive: g, reverse: b } = G;\n    return {\n      x: () => {\n        const c = Ol([h], Z.rank);\n        let d = Pm(I, h, g, !b);\n        return c != null && (d = el(d, c)), d;\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst xR = {\n  kernelName: nc,\n  inputsToSave: [\"x\", \"filter\"],\n  gradFunc: (I, l, G) => {\n    const { dilations: Z, strides: h, pad: g, dimRoundingMode: b } = G, c = Z ?? [1, 1];\n    u(ch(c), () => `Error in gradient of depthwiseConv2dNative: dilation rates greater than 1 are not yet supported. Got dilations '${c}'`);\n    const [d, W] = l;\n    return u(d.rank === 4, () => `Error in gradient of depthwiseConv2dNative: input must be rank 4, but got rank ${d.rank}.`), u(W.rank === 4, () => `Error in gradient of depthwiseConv2dNative: filter must be rank 4, but got rank ${W.rank}.`), u(d.shape[3] === W.shape[2], () => `Error in gradient of depthwiseConv2d: number of input channels (${d.shape[3]}) must match the inChannels dimension in filter ${W.shape[2]}.`), u(pG(h, c), () => `Error in gradient of depthwiseConv2d: Either strides or dilations must be  1. Got strides ${h} and dilations '${c}'.`), wG(\"depthwiseConv2d\", g, b), {\n      x: () => De(d.shape, I, W, h, g, c, b),\n      filter: () => re(d, I, W.shape, h, g, c, b)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst UR = {\n  kernelName: Cc,\n  inputsToSave: [\"x\", \"filter\"],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, g = { x: Z, filter: h, dy: I }, b = { x: Z, filter: h, dy: I };\n    return {\n      x: () => P.runKernel(gW, g, G),\n      filter: () => P.runKernel(bW, b, G)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst HR = {\n  kernelName: gg,\n  outputsToSave: [!0],\n  gradFunc: (I, l) => {\n    const [G] = l, Z = { dy: I, y: G };\n    return { x: () => P.runKernel(mY, Z) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst KR = {\n  kernelName: bg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l, Z = N(rI(_l(Ml(G))), 2 / Math.sqrt(Math.PI));\n    return { x: () => N(I, Z) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst AR = {\n  kernelName: cg,\n  outputsToSave: [!0],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, G) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst kR = {\n  kernelName: tc,\n  inputsToSave: [\"input\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { input: () => J(I, G.shape) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst zR = {\n  kernelName: dg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, rI(G)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst LR = {\n  kernelName: Wg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst MR = {\n  kernelName: Yg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      const c = Vl(I, hl(Z, \"float32\")), d = VG(G.shape, h);\n      return d.length > 0 ? J(Yl(c, d), G.shape) : c;\n    }, b: () => {\n      let c = N(I, hl(G, \"float32\"));\n      const d = VG(Z.shape, h);\n      d.length > 0 && (c = J(Yl(c, d), Z.shape));\n      const W = Ml(Z);\n      return _l(Vl(c, hl(W, \"float32\")));\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst wR = {\n  kernelName: uc,\n  inputsToSave: [\"x\", \"mean\", \"variance\", \"scale\"],\n  gradFunc: (I, l, G) => {\n    const { varianceEpsilon: Z } = G, [h, g, b, c] = l, d = c ?? yl(1), W = VG(g.shape, h.shape), Y = [];\n    if (g.rank === 1) {\n      for (let n = 0; n < h.shape.length - 1; ++n)\n        Y.push(h.shape[n]);\n      Y.push(1);\n    }\n    const V = ml(h, g), a = N(I, d), i = vm(O(b, yl(Z))), m = N(N(N(i, i), i), yl(-0.5));\n    return {\n      x: () => g.rank === 1 ? J(N(N(I, eI(J(i, [1, 1, 1, g.shape[0]]), Y)), d), h.shape) : J(N(N(I, i), d), h.shape),\n      mean: () => {\n        let n = N(N(i, yl(-1)), a);\n        return g.rank === 1 && (n = Yl(n, W)), J(n, g.shape);\n      },\n      variance: () => {\n        let n = N(N(m, V), a);\n        return g.rank === 1 && (n = Yl(n, W)), J(n, g.shape);\n      },\n      scale: () => {\n        const n = N(V, i);\n        let X = N(I, n);\n        return g.rank === 1 && (X = Yl(X, W)), J(X, g.shape);\n      },\n      offset: () => {\n        let n = I;\n        return g.rank === 1 && (n = Yl(n, W)), J(n, g.shape);\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst QR = {\n  kernelName: ec,\n  inputsToSave: [\"x\", \"indices\"],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { axis: g, batchDims: b } = G, c = tl(g, Z.shape)[0], d = (W, Y, V) => () => {\n      const a = W.shape, i = Y.size, m = a.slice(0, c), T = m.length, s = a.slice(g, a.length).slice(1), o = s.length, B = da(0, T), C = da(T + 1, T + 1 + o), n = Wa([\n        m,\n        [i],\n        s\n      ]), X = J(V, n), t = J(Y, [i]), e = Wa([[T], B, C]), S = el(X, e);\n      let p = lT(S, t, W.shape[c]);\n      const F = xZ(e);\n      return p = el(p, F), p;\n    };\n    if (b === 1) {\n      const W = Z.shape[0], Y = Z.split(W, 0);\n      return { x: () => gZ(Y.map((i, m) => d(i, h.slice(m, 1), I.slice(m, 1))())).reshape(Z.shape), indices: () => h };\n    } else\n      return { x: d(Z, h, I), indices: () => h };\n  }\n};\nfunction da(I, l) {\n  const G = [];\n  for (let Z = I; Z < l; ++Z)\n    G.push(Z);\n  return G;\n}\nfunction Wa(I) {\n  const l = [];\n  for (let G = 0; G < I.length; ++G)\n    for (let Z = 0; Z < I[G].length; ++Z)\n      l.push(I[G][Z]);\n  return l;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst vR = {\n  kernelName: Vg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l;\n    return { a: () => Sl(G), b: () => Sl(Z) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst rR = {\n  kernelName: ag,\n  gradFunc: (I) => ({ x: () => hl(I, \"float32\") })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst jR = {\n  kernelName: ig,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst DR = {\n  kernelName: mg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fR = {\n  kernelName: Tg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst OR = {\n  kernelName: Rc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { alpha: h } = G, g = ZI(Z, 0);\n    return { x: () => UG(g, I, N(I, h)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst qR = {\n  kernelName: og,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, O(G, 1)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst $R = {\n  kernelName: sg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, hl(G, \"float32\")) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst _R = {\n  kernelName: Pn,\n  inputsToSave: [],\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { axis: h } = G;\n    return {\n      logits: () => {\n        const b = rI(Z);\n        return ml(I, N(Yl(I, h, !0), b));\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lp(I, l, G, Z = 5, h = 1, g = 1, b = 0.5) {\n  const c = { x: I, y: l, dy: G }, d = { depthRadius: Z, bias: h, alpha: g, beta: b };\n  return P.runKernel(CY, c, d);\n}\nconst Gp = E({ localResponseNormalizationBackprop_: lp });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ip = {\n  kernelName: Jc,\n  inputsToSave: [\"x\"],\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { depthRadius: g, bias: b, alpha: c, beta: d } = G;\n    return {\n      x: () => Gp(Z, h, I, g, b, c, d)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction QT(I, l, G, Z) {\n  return l.rank < G.rank && (l = J(l, bG(l.shape, Z))), I.rank < G.rank && (I = J(I, bG(I.shape, Z))), {\n    x: () => N(I, hl(vI(G, l), I.dtype))\n  };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ya = {\n  kernelName: Ec,\n  inputsToSave: [\"x\"],\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const Z = G, { reductionIndices: h } = Z, g = l[0], b = l[1], c = tl(h, g.shape), d = QT(I, b, g, c);\n    return {\n      x: () => d.x()\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Zp = {\n  kernelName: Bg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l;\n    return { a: () => N(I, hl(Ch(G, Z), \"float32\")), b: () => N(I, hl(Kb(G, Z), \"float32\")) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction hp(I, l, G, Z, h, g, b) {\n  const c = R(I, \"dy\", \"maxPool3dGrad\"), d = R(l, \"input\", \"maxPool3dGrad\"), W = R(G, \"output\", \"maxPool3dGrad\");\n  let Y = c, V = d, a = W, i = !1;\n  d.rank === 4 && (i = !0, Y = J(c, [1, c.shape[0], c.shape[1], c.shape[2], c.shape[3]]), V = J(d, [\n    1,\n    d.shape[0],\n    d.shape[1],\n    d.shape[2],\n    d.shape[3]\n  ]), a = J(W, [\n    1,\n    W.shape[0],\n    W.shape[1],\n    W.shape[2],\n    W.shape[3]\n  ])), u(Y.rank === 5, () => `Error in maxPool3dGrad: dy must be rank 5 but got rank ${Y.rank}.`), u(V.rank === 5, () => `Error in maxPool3dGrad: input must be rank 5 but got rank ${V.rank}.`), u(a.rank === 5, () => `Error in maxPool3dGrad: output must be rank 5 but got rank ${a.rank}.`), wG(\"maxPool3dGrad\", g, b);\n  const m = { dy: Y, input: V, output: a }, T = { filterSize: Z, strides: h, pad: g, dimRoundingMode: b }, s = P.runKernel(tY, m, T);\n  return i ? J(s, [s.shape[1], s.shape[2], s.shape[3], s.shape[4]]) : s;\n}\nconst gp = /* @__PURE__ */ E({ maxPool3dGrad_: hp });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bp = {\n  kernelName: Uc,\n  inputsToSave: [\"x\"],\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { filterSize: g, strides: b, pad: c, dimRoundingMode: d } = G;\n    return {\n      x: () => gp(I, Z, h, g, b, c, d)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction cp(I, l, G, Z, h, g, b) {\n  const c = R(I, \"dy\", \"maxPoolGrad\"), d = R(l, \"input\", \"maxPoolGrad\"), W = R(G, \"output\", \"maxPoolGrad\");\n  u(d.rank === c.rank, () => `Rank of input (${d.rank}) does not match rank of dy (${c.rank})`), u(c.rank === 4, () => `Error in maxPoolGrad: dy must be rank 4 but got rank ${c.rank}.`), u(d.rank === 4, () => `Error in maxPoolGrad: input must be rank 4 but got rank ${d.rank}.`), wG(\"maxPoolGrad\", g, b);\n  const Y = { dy: c, input: d, output: W }, V = { filterSize: Z, strides: h, pad: g, dimRoundingMode: b };\n  return P.runKernel(XY, Y, V);\n}\nconst dp = /* @__PURE__ */ E({ maxPoolGrad_: cp });\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Wp = {\n  kernelName: xc,\n  inputsToSave: [\"x\"],\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const [Z, h] = l, { filterSize: g, strides: b, pad: c } = G;\n    return {\n      x: () => dp(I, Z, h, g, b, c)\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Yp = {\n  kernelName: Hc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { axis: h } = G, g = tl(h, Z.shape), c = sG(Z.shape, g)[1], d = Q(c);\n    return { x: () => {\n      const Y = Z.shape.slice();\n      g.forEach((i) => {\n        Y[i] = 1;\n      });\n      const V = J(I, Y);\n      return Vl(N(V, HZ(Z.shape, \"float32\")), d);\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Vp = {\n  kernelName: Kc,\n  inputsToSave: [\"x\"],\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const Z = G, { axis: h } = Z, [g, b] = l, c = tl(h, g.shape), d = QT(I, b, g, c);\n    return {\n      x: () => d.x()\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ap = {\n  kernelName: ng,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l;\n    return { a: () => N(I, hl(g0(G, Z), \"float32\")), b: () => N(I, hl(ZI(G, Z), \"float32\")) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ip = {\n  kernelName: Ac,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const Z = l[0], { paddings: h } = G, g = h.map((b) => b[0]);\n    return { x: () => zl(I, g, Z.shape) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst mp = {\n  kernelName: Cg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      const c = VG(G.shape, h);\n      return c.length > 0 ? J(Yl(I, c), G.shape) : I;\n    }, b: () => {\n      const c = N(I, _l(ad(Vl(G, Z)))), d = VG(Z.shape, h);\n      return d.length > 0 ? J(Yl(c, d), Z.shape) : c;\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Tp = {\n  kernelName: Xg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      const c = N(I, hl(Z, \"float32\")), d = VG(G.shape, h);\n      return d.length > 0 ? J(Yl(c, d), G.shape) : c;\n    }, b: () => {\n      const c = N(I, hl(G, \"float32\")), d = VG(Z.shape, h);\n      return d.length > 0 ? J(Yl(c, d), Z.shape) : c;\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst sp = {\n  kernelName: kc,\n  gradFunc: (I) => ({ x: () => _l(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst op = {\n  kernelName: Mc,\n  inputsToSave: [\"indices\"],\n  gradFunc: (I, l) => {\n    const G = l[0];\n    return { indices: () => mG(G.shape, \"float32\") };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Bp = {\n  kernelName: Lc,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst np = {\n  kernelName: wc,\n  saveAllInputs: !0,\n  gradFunc: (I, l, G) => {\n    const { axis: Z } = G;\n    return ah(I, Z).map((g) => () => g);\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Va = {\n  kernelName: Qc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const Z = l[0], { paddings: h } = G, g = h.map((b) => b[0]);\n    return { x: () => zl(I, g, Z.shape) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Cp = {\n  kernelName: tg,\n  inputsToSave: [\"a\", \"b\"],\n  outputsToSave: [!0],\n  gradFunc: (I, l) => {\n    const [G, Z, h] = l, g = G, b = Z, c = sl(g.shape, b.shape);\n    return { a: () => {\n      const Y = hl(b, \"float32\");\n      let V = N(I, N(Y, Yh(g, ml(Y, yl(1)))));\n      const a = VG(g.shape, c);\n      return a.length > 0 && (V = Yl(V, a)), J(V, g.shape);\n    }, b: () => {\n      const Y = ZI(g, 0), V = UG(Y, jI(g), Sl(g));\n      let a = N(I, N(h, V));\n      const i = VG(b.shape, c);\n      return i.length > 0 && (a = Yl(a, i)), J(a, b.shape);\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Xp = {\n  kernelName: vc,\n  inputsToSave: [\"x\", \"alpha\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = ZI(G, 0);\n    return {\n      x: () => UG(h, I, N(I, Z)),\n      alpha: () => {\n        let g = UG(h, Sl(I), N(I, G));\n        const b = VG(Z.shape, I.shape);\n        return b.length > 0 && (g = Yl(g, b)), J(g, Z.shape);\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2022 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction tp(I, l, G) {\n  const Z = I.shape.slice();\n  Z[G] = 1;\n  const h = J(l, Z), g = XW(I, G, !0, !1), b = XW(I, G, !0, !0), c = N(g, b);\n  return N(h, c);\n}\nfunction up(I, l, G) {\n  const Z = I.shape.length, h = Z - G.length, g = Ol(G, Z);\n  let b = I;\n  g != null && (b = el(I, g));\n  const c = b.shape.slice(), W = c.splice(Z - G.length, G.length).reduce((a, i) => a * i, 1);\n  c.push(W);\n  const Y = b.reshape(c);\n  let V = tp(Y, l, h);\n  if (V = V.reshape(b.shape), g != null) {\n    const a = xZ(g);\n    V = el(V, a);\n  }\n  return V;\n}\nconst ep = {\n  kernelName: rc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { axis: h } = G;\n    let g = [];\n    return h == null ? g = Z.shape.map((b, c) => c) : typeof h == \"number\" ? g = [h] : g = h, { x: () => up(Z, I, g) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Sp = {\n  kernelName: hg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      const c = Vl(I, hl(Z, \"float32\")), d = VG(G.shape, h);\n      return d.length > 0 ? J(Yl(c, d), G.shape) : c;\n    }, b: () => {\n      let c = N(I, hl(G, \"float32\"));\n      const d = VG(Z.shape, h);\n      d.length > 0 && (c = J(Yl(c, d), Z.shape));\n      const W = Ml(Z);\n      return _l(Vl(c, hl(W, \"float32\")));\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Rp = {\n  kernelName: ug,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, _l(Ml(G))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst pp = {\n  kernelName: Sg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l, Z = N(g0(G, 6), jg(G));\n    return { x: () => N(I, hl(Z, \"float32\")) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Fp = {\n  kernelName: eg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, hl(jg(G), \"float32\")) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst yp = {\n  kernelName: jc,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => J(I, G.shape) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Np = {\n  kernelName: fc,\n  inputsToSave: [\"images\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, h = { dy: I, images: Z };\n    return { images: () => (\n      // tslint:disable-next-line: no-unnecessary-type-assertion\n      P.runKernel(yY, h, G)\n    ) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Pp = {\n  kernelName: Dc,\n  inputsToSave: [\"images\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, h = { dy: I, images: Z };\n    return { images: () => (\n      // tslint:disable-next-line: no-unnecessary-type-assertion\n      P.runKernel(FY, h, G)\n    ) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Jp = {\n  kernelName: Oc,\n  gradFunc: (I, l, G) => {\n    const { dims: Z } = G, h = tl(Z, I.shape);\n    return { x: () => Vh(I, h) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ep = {\n  kernelName: Rg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst xp = {\n  kernelName: pg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => _l(Vl(I, N(Yh(G, 1.5), 2))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Up = {\n  kernelName: qc,\n  inputsToSave: [\"condition\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return {\n      // TODO(julianoks): Return null for condition gradient\n      // when backprop supports it.\n      condition: () => hl(Sl(G), \"float32\"),\n      t: () => N(I, hl(G, I.dtype)),\n      e: () => N(I, hl(qY(G), I.dtype))\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Hp = {\n  kernelName: Fg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return {\n      x: () => {\n        const Z = ZI(G, yl(0)), h = yl(Td), g = yl(sd), b = N(I, g), c = N(N(I, h), rI(hl(G, \"float32\")));\n        return UG(Z, b, c);\n      }\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Kp = {\n  kernelName: Jg,\n  outputsToSave: [!0],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, N(G, ml(yl(1), G))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ap = {\n  kernelName: Pg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst kp = {\n  kernelName: yg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(vY(hl(G, \"float32\")), I) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst zp = {\n  kernelName: Ng,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(Nm(hl(G, \"float32\")), I) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Lp = {\n  kernelName: $c,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { begin: h, size: g } = G, b = Z.shape, [c, d] = id(Z, h, g), W = [];\n    for (let Y = 0; Y < I.rank; Y++)\n      W.push([c[Y], b[Y] - c[Y] - d[Y]]);\n    return { x: () => lV(I, W) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Mp = {\n  kernelName: Id,\n  outputsToSave: [!0],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { dim: h } = G, g = !0, b = N(I, Z);\n    return {\n      logits: () => ml(b, N(Yl(b, [h], g), Z))\n    };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst wp = {\n  kernelName: Eg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, h0(G)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst aa = {\n  kernelName: ld,\n  gradFunc: (I, l, G) => {\n    const { blockShape: Z, paddings: h } = G;\n    return { x: () => wY(I, Z, h) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ia = {\n  kernelName: Gd,\n  gradFunc: (I, l, G) => {\n    const { axis: Z } = G;\n    return { x: () => zG(I, Z) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Qp = {\n  kernelName: xg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, N(RG(hl(G, \"float32\")), 2)) };\n  }\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst vp = {\n  kernelName: NY,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(I, N(hl(G, \"float32\"), 2)) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst rp = {\n  kernelName: Ug,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = yl(2);\n    return { a: () => N(I, N(h, ml(G, Z))), b: () => N(I, N(h, ml(Z, G))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst jp = {\n  kernelName: zg,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Dp = {\n  kernelName: Hg,\n  inputsToSave: [\"a\", \"b\"],\n  gradFunc: (I, l) => {\n    const [G, Z] = l, h = sl(G.shape, Z.shape);\n    return { a: () => {\n      let c = I;\n      const d = VG(G.shape, h);\n      return d.length > 0 && (c = Yl(c, d)), J(c, G.shape);\n    }, b: () => {\n      let c = I;\n      const d = VG(Z.shape, h);\n      return d.length > 0 && (c = Yl(c, d)), J(_l(c), Z.shape);\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fp = {\n  kernelName: _c,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, h = Z.shape.slice(), { axis: g } = G;\n    tl(g, Z.shape).forEach((W) => {\n      h[W] = 1;\n    });\n    const c = J(I, h), d = N(c, HZ(Z.shape, \"float32\"));\n    return { x: () => d };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Op = {\n  kernelName: Kg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => Vl(I, Ml(vY(G))) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst qp = {\n  kernelName: Ag,\n  outputsToSave: [!0],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => N(ml(yl(1), Ml(G)), I) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst $p = {\n  kernelName: kg,\n  inputsToSave: [\"x\"],\n  gradFunc: (I, l, G) => {\n    const [Z] = l, { reps: h } = G;\n    return { x: () => {\n      let b = Sl(Z);\n      if (Z.rank === 1)\n        for (let c = 0; c < h[0]; ++c)\n          b = O(b, zl(I, [c * Z.shape[0]], [Z.shape[0]]));\n      else if (Z.rank === 2)\n        for (let c = 0; c < h[0]; ++c)\n          for (let d = 0; d < h[1]; ++d)\n            b = O(b, zl(I, [c * Z.shape[0], d * Z.shape[1]], [\n              Z.shape[0],\n              Z.shape[1]\n            ]));\n      else if (Z.rank === 3)\n        for (let c = 0; c < h[0]; ++c)\n          for (let d = 0; d < h[1]; ++d)\n            for (let W = 0; W < h[2]; ++W)\n              b = O(b, zl(I, [c * Z.shape[0], d * Z.shape[1], W * Z.shape[2]], [Z.shape[0], Z.shape[1], Z.shape[2]]));\n      else if (Z.rank === 4)\n        for (let c = 0; c < h[0]; ++c)\n          for (let d = 0; d < h[1]; ++d)\n            for (let W = 0; W < h[2]; ++W)\n              for (let Y = 0; Y < h[3]; ++Y)\n                b = O(b, zl(I, [\n                  c * Z.shape[0],\n                  d * Z.shape[1],\n                  W * Z.shape[2],\n                  Y * Z.shape[3]\n                ], [Z.shape[0], Z.shape[1], Z.shape[2], Z.shape[3]]));\n      else\n        throw new Error(`Gradient for tile operation is not implemented for rank-${Z.rank} tensors yet.`);\n      return b;\n    } };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst _p = {\n  kernelName: Ah,\n  gradFunc: (I, l, G) => {\n    const Z = G, { perm: h } = Z, g = xZ(h);\n    return { x: () => el(I, g) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst lF = {\n  kernelName: Zd,\n  gradFunc: (I, l, G) => {\n    const Z = G, { axis: h } = Z;\n    return { value: () => gZ(I, h) };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst GF = {\n  kernelName: hd,\n  inputsToSave: [\"segmentIds\"],\n  gradFunc: (I, l) => {\n    const [G] = l;\n    return { x: () => IF(I, G) };\n  }\n};\nfunction IF(I, l) {\n  const G = UZ(l, Sl(l)), Z = DY(I, G);\n  let h = Ch(l, yl(0, \"int32\"));\n  const g = Z.rank - h.rank;\n  for (let c = 0; c < g; ++c)\n    h = EG(h, c + 1);\n  h = hZ(h, HZ(Z.shape, \"bool\"));\n  const b = Sl(Z);\n  return UG(h, Z, b);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ZF = {\n  kernelName: gd,\n  gradFunc: (I) => ({ x: () => Sl(I) })\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hF = [\n  wT,\n  GR,\n  IR,\n  ZR,\n  hR,\n  gR,\n  bR,\n  cR,\n  dR,\n  WR,\n  YR,\n  VR,\n  mR,\n  oR,\n  BR,\n  nR,\n  CR,\n  XR,\n  tR,\n  uR,\n  eR,\n  SR,\n  pR,\n  RR,\n  NR,\n  PR,\n  JR,\n  ER,\n  xR,\n  UR,\n  Sp,\n  HR,\n  KR,\n  AR,\n  kR,\n  zR,\n  MR,\n  LR,\n  wR,\n  QR,\n  vR,\n  rR,\n  jR,\n  DR,\n  fR,\n  OR,\n  qR,\n  $R,\n  _R,\n  Ip,\n  Ya,\n  Ya,\n  Zp,\n  bp,\n  Wp,\n  Yp,\n  Vp,\n  ap,\n  ip,\n  mp,\n  Tp,\n  sp,\n  op,\n  Bp,\n  np,\n  Va,\n  Va,\n  Cp,\n  Xp,\n  ep,\n  Rp,\n  pp,\n  Fp,\n  yp,\n  Np,\n  Pp,\n  Jp,\n  Ep,\n  xp,\n  Up,\n  Hp,\n  Kp,\n  Ap,\n  kp,\n  zp,\n  Lp,\n  Mp,\n  wp,\n  aa,\n  aa,\n  ia,\n  ia,\n  Qp,\n  rp,\n  vp,\n  jp,\n  Dp,\n  fp,\n  Op,\n  qp,\n  $p,\n  _p,\n  lF,\n  GF,\n  ZF\n];\nfor (const I of hF)\n  En(I);\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.abs = function() {\n  return this.throwIfDisposed(), PG(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.acos = function() {\n  return this.throwIfDisposed(), KC(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.acosh = function() {\n  return this.throwIfDisposed(), kC(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.add = function(I) {\n  return this.throwIfDisposed(), O(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.all = function(I, l) {\n  return this.throwIfDisposed(), Rm(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.any = function(I, l) {\n  return this.throwIfDisposed(), nW(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.argMax = function(I) {\n  return this.throwIfDisposed(), P0(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.argMin = function(I) {\n  return this.throwIfDisposed(), QC(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.asScalar = function() {\n  return this.throwIfDisposed(), u(this.size === 1, () => \"The array must have only 1 element.\"), J(this, []);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.asType = function(I) {\n  return this.throwIfDisposed(), hl(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.as1D = function() {\n  return this.throwIfDisposed(), J(this, [this.size]);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.as2D = function(I, l) {\n  return this.throwIfDisposed(), J(this, [I, l]);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.as3D = function(I, l, G) {\n  return this.throwIfDisposed(), J(this, [I, l, G]);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.as4D = function(I, l, G, Z) {\n  return this.throwIfDisposed(), J(this, [I, l, G, Z]);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.as5D = function(I, l, G, Z, h) {\n  return this.throwIfDisposed(), J(this, [I, l, G, Z, h]);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.asin = function() {\n  return this.throwIfDisposed(), rC(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.asinh = function() {\n  return this.throwIfDisposed(), DC(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.atan = function() {\n  return this.throwIfDisposed(), OC(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.atan2 = function(I) {\n  return this.throwIfDisposed(), $C(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.atanh = function() {\n  return this.throwIfDisposed(), lX(this);\n};\nM().prototype.avgPool = function(I, l, G, Z) {\n  return this.throwIfDisposed(), MY(this, I, l, G, Z);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.batchToSpaceND = function(I, l) {\n  return this.throwIfDisposed(), wY(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.batchNorm = function(I, l, G, Z, h) {\n  return this.throwIfDisposed(), dd(this, I, l, G, Z, h);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.broadcastTo = function(I) {\n  return this.throwIfDisposed(), y0(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.cast = function(I) {\n  return this.throwIfDisposed(), hl(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.ceil = function() {\n  return this.throwIfDisposed(), pX(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.clipByValue = function(I, l) {\n  return this.throwIfDisposed(), II(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.concat = function(I, l) {\n  return this.throwIfDisposed(), I instanceof hG && (I = [I]), zG([this, ...I], l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.conv1d = function(I, l, G, Z, h, g) {\n  return this.throwIfDisposed(), pm(this, I, l, G, Z, h, g);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.conv2dTranspose = function(I, l, G, Z, h) {\n  return this.throwIfDisposed(), Fm(this, I, l, G, Z, h);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.conv2d = function(I, l, G, Z, h, g) {\n  return this.throwIfDisposed(), Wh(this, I, l, G, Z, h, g);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.cos = function() {\n  return this.throwIfDisposed(), vY(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.cosh = function() {\n  return this.throwIfDisposed(), Nm(this);\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the 'License');\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.cumprod = function(I, l, G) {\n  return this.throwIfDisposed(), XW(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.cumsum = function(I, l, G) {\n  return this.throwIfDisposed(), Pm(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.depthToSpace = function(I, l) {\n  return this.throwIfDisposed(), $X(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.depthwiseConv2d = function(I, l, G, Z, h, g) {\n  return this.throwIfDisposed(), rY(this, I, l, G, Z, h, g);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.dilation2d = function(I, l, G, Z, h) {\n  return this.throwIfDisposed(), Gt(this, I, l, G, Z, h);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.divNoNan = function(I) {\n  return this.throwIfDisposed(), bt(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.div = function(I) {\n  return this.throwIfDisposed(), Vl(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.dot = function(I) {\n  return this.throwIfDisposed(), dt(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.elu = function() {\n  return this.throwIfDisposed(), Yd(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.equal = function(I) {\n  return this.throwIfDisposed(), vI(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.erf = function() {\n  return this.throwIfDisposed(), Jm(this);\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.euclideanNorm = function(I, l) {\n  return this.throwIfDisposed(), Ct(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.exp = function() {\n  return this.throwIfDisposed(), rI(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.expandDims = function(I) {\n  return this.throwIfDisposed(), EG(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.expm1 = function() {\n  return this.throwIfDisposed(), et(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.fft = function() {\n  return this.throwIfDisposed(), qm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.flatten = function() {\n  return this.throwIfDisposed(), J(this, [this.size]);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.floor = function() {\n  return this.throwIfDisposed(), ad(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.floorDiv = function(I) {\n  return this.throwIfDisposed(), Sm(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.gather = function(I, l, G) {\n  return this.throwIfDisposed(), DY(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.greaterEqual = function(I) {\n  return this.throwIfDisposed(), Ch(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.greater = function(I) {\n  return this.throwIfDisposed(), ZI(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.ifft = function() {\n  return this.throwIfDisposed(), tW(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.irfft = function() {\n  return this.throwIfDisposed(), Te(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.isFinite = function() {\n  return this.throwIfDisposed(), Et(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.isInf = function() {\n  return this.throwIfDisposed(), Ut(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.isNaN = function() {\n  return this.throwIfDisposed(), Kt(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.leakyRelu = function(I) {\n  return this.throwIfDisposed(), OY(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.lessEqual = function(I) {\n  return this.throwIfDisposed(), g0(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.less = function(I) {\n  return this.throwIfDisposed(), Kb(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.localResponseNormalization = function(I, l, G, Z) {\n  return this.throwIfDisposed(), Mt(this, I, l, G, Z);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logSigmoid = function() {\n  return this.throwIfDisposed(), ft(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logSoftmax = function(I) {\n  return this.throwIfDisposed(), Km(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logSumExp = function(I, l) {\n  return this.throwIfDisposed(), Am(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.log = function() {\n  return this.throwIfDisposed(), jI(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.log1p = function() {\n  return this.throwIfDisposed(), Hm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logicalAnd = function(I) {\n  return this.throwIfDisposed(), hZ(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logicalNot = function() {\n  return this.throwIfDisposed(), qY(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logicalOr = function(I) {\n  return this.throwIfDisposed(), km(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.logicalXor = function(I) {\n  return this.throwIfDisposed(), Zu(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.matMul = function(I, l, G) {\n  return this.throwIfDisposed(), Fl(this, I, l, G);\n};\nM().prototype.maxPool = function(I, l, G, Z) {\n  return this.throwIfDisposed(), $Y(this, I, l, G, Z);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.max = function(I, l) {\n  return this.throwIfDisposed(), RI(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.maximum = function(I) {\n  return this.throwIfDisposed(), UZ(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.mean = function(I, l) {\n  return this.throwIfDisposed(), gG(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.min = function(I, l) {\n  return this.throwIfDisposed(), Hb(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.minimum = function(I) {\n  return this.throwIfDisposed(), x0(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.mirrorPad = function(I, l) {\n  return this.throwIfDisposed(), Vu(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.mod = function(I) {\n  return this.throwIfDisposed(), iu(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.mul = function(I) {\n  return this.throwIfDisposed(), N(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.neg = function() {\n  return this.throwIfDisposed(), _l(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.norm = function(I, l, G) {\n  return this.throwIfDisposed(), Vd(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.notEqual = function(I) {\n  return this.throwIfDisposed(), Ab(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.oneHot = function(I, l = 1, G = 0) {\n  return this.throwIfDisposed(), zm(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.onesLike = function() {\n  return this.throwIfDisposed(), TI(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.pad = function(I, l) {\n  return this.throwIfDisposed(), lV(this, I, l);\n};\nM().prototype.pool = function(I, l, G, Z, h, g) {\n  return this.throwIfDisposed(), uu(this, I, l, G, Z, h, g);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.pow = function(I) {\n  return this.throwIfDisposed(), Yh(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.prelu = function(I) {\n  return this.throwIfDisposed(), IV(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.prod = function(I, l) {\n  return this.throwIfDisposed(), Ru(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.reciprocal = function() {\n  return this.throwIfDisposed(), fu(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.relu = function() {\n  return this.throwIfDisposed(), th(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.relu6 = function() {\n  return this.throwIfDisposed(), wm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.reshapeAs = function(I) {\n  return this.throwIfDisposed(), J(this, I.shape);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.reshape = function(I) {\n  return this.throwIfDisposed(), J(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.resizeBilinear = function(I, l, G) {\n  return this.throwIfDisposed(), IT(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.resizeNearestNeighbor = function(I, l, G) {\n  return this.throwIfDisposed(), ZT(this, I, l, G);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.reverse = function(I) {\n  return this.throwIfDisposed(), Vh(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.rfft = function() {\n  return this.throwIfDisposed(), Be(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.round = function() {\n  return this.throwIfDisposed(), Qm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.rsqrt = function() {\n  return this.throwIfDisposed(), vm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.selu = function() {\n  return this.throwIfDisposed(), rm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.separableConv2d = function(I, l, G, Z, h, g) {\n  return this.throwIfDisposed(), jm(this, I, l, G, Z, h, g);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sigmoid = function() {\n  return this.throwIfDisposed(), h0(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sign = function() {\n  return this.throwIfDisposed(), he(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sin = function() {\n  return this.throwIfDisposed(), Dm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sinh = function() {\n  return this.throwIfDisposed(), fm(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.slice = function(I, l) {\n  return this.throwIfDisposed(), zl(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.softmax = function(I) {\n  return this.throwIfDisposed(), aV(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.softplus = function() {\n  return this.throwIfDisposed(), Qg(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.spaceToBatchND = function(I, l) {\n  return this.throwIfDisposed(), GV(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.split = function(I, l) {\n  return this.throwIfDisposed(), GI(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sqrt = function() {\n  return this.throwIfDisposed(), RG(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.square = function() {\n  return this.throwIfDisposed(), Ml(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.squaredDifference = function(I) {\n  return this.throwIfDisposed(), Ce(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.squeeze = function(I) {\n  return this.throwIfDisposed(), rg(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.stack = function(I, l) {\n  this.throwIfDisposed();\n  const G = I instanceof hG ? [this, I] : [this, ...I];\n  return gZ(G, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.step = function(I) {\n  return this.throwIfDisposed(), jg(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.stridedSlice = function(I, l, G, Z, h, g, b, c) {\n  return this.throwIfDisposed(), Se(this, I, l, G, Z, h, g, b, c);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sub = function(I) {\n  return this.throwIfDisposed(), ml(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.sum = function(I, l) {\n  return this.throwIfDisposed(), Yl(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.tan = function() {\n  return this.throwIfDisposed(), pe(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.tanh = function() {\n  return this.throwIfDisposed(), cd(this);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.tile = function(I) {\n  return this.throwIfDisposed(), eI(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.toBool = function() {\n  return this.throwIfDisposed(), hl(this, \"bool\");\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.toFloat = function() {\n  return this.throwIfDisposed(), hl(this, \"float32\");\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.toInt = function() {\n  return this.throwIfDisposed(), hl(this, \"int32\");\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.topk = function(I, l) {\n  return this.throwIfDisposed(), Pe(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.transpose = function(I) {\n  return this.throwIfDisposed(), el(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.unique = function(I) {\n  return this.throwIfDisposed(), xe(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.unsortedSegmentSum = function(I, l) {\n  return this.throwIfDisposed(), lT(this, I, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.unstack = function(I) {\n  return this.throwIfDisposed(), ah(this, I);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.where = function(I, l) {\n  return this.throwIfDisposed(), UG(I, this, l);\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nM().prototype.zerosLike = function() {\n  return this.throwIfDisposed(), Sl(this);\n};\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass HI extends Error {\n  constructor(l) {\n    super(l), Object.setPrototypeOf(this, HI.prototype);\n  }\n}\nclass aI extends Error {\n  constructor(l) {\n    super(l), Object.setPrototypeOf(this, aI.prototype);\n  }\n}\nclass y extends Error {\n  constructor(l) {\n    super(l), Object.setPrototypeOf(this, y.prototype);\n  }\n}\nclass Bl extends Error {\n  constructor(l) {\n    super(l), Object.setPrototypeOf(this, Bl.prototype);\n  }\n}\nclass DV extends Error {\n  constructor(l) {\n    super(l), Object.setPrototypeOf(this, DV.prototype);\n  }\n}\n/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass vT {\n  constructor(l) {\n    this.maxEntries = l || 100, this.cache = /* @__PURE__ */ new Map();\n  }\n  /**\n   * Get the entry for the key and mark it as used recently.\n   */\n  get(l) {\n    let G;\n    return this.cache.has(l) && (G = this.cache.get(l), this.cache.delete(l), this.cache.set(l, G)), G;\n  }\n  /**\n   * Put the entry into the cache. If the key already existed, mark the key as\n   * used recently.\n   */\n  put(l, G) {\n    if (this.cache.has(l))\n      this.cache.delete(l);\n    else if (this.cache.size >= this.maxEntries) {\n      const Z = this.cache.keys().next().value;\n      this.cache.delete(Z);\n    }\n    this.cache.set(l, G);\n  }\n  /**\n   * Get the MaxEntries of the cache.\n   */\n  getMaxEntries() {\n    return this.maxEntries;\n  }\n  /**\n   * Set the MaxEntries of the cache. If the maxEntries is decreased, reduce\n   * entries in the cache.\n   */\n  setMaxEntries(l) {\n    if (l < 0)\n      throw new Error(`The maxEntries of LRU caches must be at least 0, but got ${l}.`);\n    if (this.maxEntries > l)\n      for (let G = 0; G < this.maxEntries - l; G++) {\n        const Z = this.cache.keys().next().value;\n        this.cache.delete(Z);\n      }\n    this.maxEntries = l;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction ih(I, l) {\n  if (Array.isArray(I)) {\n    let G = [];\n    for (let Z = 0; Z < l; Z++)\n      G = G.concat(I);\n    return G;\n  } else {\n    const G = new Array(l);\n    return G.fill(I), G;\n  }\n}\nfunction KI(I, l) {\n  if (!I)\n    throw new DV(l);\n}\nfunction ma(I, l) {\n  let G = 0;\n  for (const Z of I)\n    Z === l && G++;\n  return G;\n}\nfunction kG(I) {\n  return I.length === 1 ? I[0] : I;\n}\nfunction Jl(I) {\n  return Array.isArray(I) ? I : [I];\n}\nfunction _I(I) {\n  const G = I.replace(/(.)([A-Z][a-z0-9]+)/g, \"$1_$2\").replace(/([a-z])([A-Z])/g, \"$1_$2\").toLowerCase();\n  return G[0] !== \"_\" ? G : \"private\" + G;\n}\nfunction DZ(I) {\n  return I.length <= 1 || I.indexOf(\"_\") === -1 ? I : I.replace(/[_]+(\\w|$)/g, (l, G) => G.toUpperCase());\n}\nlet gI = {};\nfunction fV(I) {\n  if (I == null)\n    return null;\n  const l = {};\n  return l.className = I.getClassName(), l.config = I.getConfig(), l;\n}\nfunction SW(I) {\n  if (!(I == null || typeof I != \"object\"))\n    if (Array.isArray(I))\n      I.forEach((l) => SW(l));\n    else {\n      const l = Object.keys(I);\n      for (const G of l) {\n        const Z = I[G];\n        Z != null && typeof Z == \"object\" && (!Array.isArray(Z) && Z.type === \"ndarray\" && typeof Z.value == \"number\" ? I[G] = Z.value : SW(Z));\n      }\n    }\n}\nfunction qg(I, l = {}, G = {}, Z = \"object\", h = !1) {\n  if (typeof I == \"string\") {\n    const g = I;\n    let b;\n    if (g in G)\n      b = G[g];\n    else if (g in gI)\n      b = gI[g];\n    else if (b = l[g], b == null)\n      throw new y(`Unknown ${Z}: ${I}. This may be due to one of the following reasons:\n1. The ${Z} is defined in Python, in which case it needs to be ported to TensorFlow.js or your JavaScript code.\n2. The custom ${Z} is defined in JavaScript, but is not registered properly with tf.serialization.registerClass().`);\n    return b;\n  } else {\n    const g = I;\n    if (g.className == null || g.config == null)\n      throw new y(`${Z}: Improper config format: ${JSON.stringify(g)}.\n'className' and 'config' must set.`);\n    const b = g.className;\n    let c, d;\n    if (b in G ? [c, d] = G[b] : b in gI ? [c, d] = gI.className : b in l && ([c, d] = l[b]), c == null)\n      throw new y(`Unknown ${Z}: ${b}. This may be due to one of the following reasons:\n1. The ${Z} is defined in Python, in which case it needs to be ported to TensorFlow.js or your JavaScript code.\n2. The custom ${Z} is defined in JavaScript, but is not registered properly with tf.serialization.registerClass().`);\n    if (d != null) {\n      const W = {};\n      for (const i of Object.keys(gI))\n        W[i] = gI[i];\n      for (const i of Object.keys(G))\n        W[i] = G[i];\n      const Y = g.config;\n      Y.customObjects = W;\n      const V = Object.assign({}, gI);\n      for (const i of Object.keys(G))\n        gI[i] = G[i];\n      SW(g.config);\n      const a = d(c, g.config, G, h);\n      return gI = Object.assign({}, V), a;\n    } else {\n      const W = Object.assign({}, gI);\n      for (const V of Object.keys(G))\n        gI[V] = G[V];\n      const Y = new c(g.config);\n      return gI = Object.assign({}, W), Y;\n    }\n  }\n}\nfunction gF(I, l) {\n  return I < l ? -1 : I > l ? 1 : 0;\n}\nfunction sb(I, l) {\n  return -1 * gF(I, l);\n}\nfunction tZ(I) {\n  if (I == null)\n    return I;\n  const l = [];\n  for (const G of I)\n    l.indexOf(G) === -1 && l.push(G);\n  return l;\n}\nfunction bF(I) {\n  if (I == null)\n    throw new y(`Invalid value in obj: ${JSON.stringify(I)}`);\n  for (const l in I)\n    if (I.hasOwnProperty(l))\n      return !1;\n  return !0;\n}\nfunction eh(I, l, G) {\n  if (G != null && I.indexOf(G) < 0)\n    throw new y(`${G} is not a valid ${l}.  Valid values are ${I} or null/undefined.`);\n}\nfunction OV(I, l, G = 0, Z = 1 / 0) {\n  return KI(G >= 0), KI(Z >= G), Array.isArray(I) && I.length >= G && I.length <= Z && I.every((h) => typeof h === l);\n}\nfunction TG(I, l) {\n  Array.isArray(I) ? (u(I.length > 0, () => `${l} is unexpectedly an empty array.`), I.forEach((G, Z) => TG(G, `element ${Z + 1} of ${l}`))) : u(Number.isInteger(I) && I > 0, () => `Expected ${l} to be a positive integer, but got ${rT(I)}.`);\n}\nfunction rT(I) {\n  return I === null ? \"null\" : Array.isArray(I) ? \"[\" + I.map((l) => rT(l)).join(\",\") + \"]\" : typeof I == \"string\" ? `\"${I}\"` : `${I}`;\n}\nfunction cF(I, l, G) {\n  let Z = G != null ? G() : AG(), h;\n  return (...b) => {\n    const c = G != null ? G() : AG();\n    return c - Z < l || (Z = c, h = I(...b)), h;\n  };\n}\nfunction jT(I) {\n  return I === \"relu\" ? \"relu\" : I === \"linear\" ? \"linear\" : I === \"elu\" ? \"elu\" : null;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nlet dF = 0;\nfunction DT() {\n  return dF++;\n}\nconst ob = {};\nfunction od(I = \"\") {\n  return I in ob || (ob[I] = 0), ob[I] += 1, I + ob[I].toString();\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst WF = [\"channelsFirst\", \"channelsLast\"], YF = [\"nearest\", \"bilinear\"], VF = [\"valid\", \"same\", \"causal\"], aF = [\"max\", \"avg\"], iF = [\"sum\", \"mul\", \"concat\", \"ave\"];\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst Ph = /* @__PURE__ */ new Map();\nfunction IG(I) {\n  eh(WF, \"DataFormat\", I);\n}\nfunction mF(I) {\n  eh(YF, \"InterpolationFormat\", I);\n}\nfunction hI(I) {\n  eh(VF, \"PaddingMode\", I);\n}\nfunction fT(I) {\n  eh(aF, \"PoolMode\", I);\n}\nconst N0 = [], Ta = \"/\";\nfunction Gh(I, l) {\n  N0.push(I);\n  try {\n    const G = l();\n    return N0.pop(), G;\n  } catch (G) {\n    throw N0.pop(), G;\n  }\n}\nfunction TF() {\n  return N0.length === 0 ? \"\" : N0.join(Ta) + Ta;\n}\nfunction OT(I) {\n  if (!$T(I))\n    throw new Error(\"Not a valid tensor name: '\" + I + \"'\");\n  return TF() + I;\n}\nfunction qT(I) {\n  if (!$T(I))\n    throw new Error(\"Not a valid tensor name: '\" + I + \"'\");\n  Ph.has(I) || Ph.set(I, 0);\n  const l = Ph.get(I);\n  if (Ph.set(I, Ph.get(I) + 1), l > 0) {\n    const G = `${I}_${l}`;\n    return Ph.set(G, 1), G;\n  } else\n    return I;\n}\nconst sF = new RegExp(/^[A-Za-z0-9][-A-Za-z0-9\\._\\/]*$/);\nfunction $T(I) {\n  return !!I.match(sF);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction oF(I) {\n  return I === parseInt(I.toString(), 10);\n}\nfunction uZ(I, l, G) {\n  l == null && (l = 0), G == null && (G = I.length);\n  let Z = 1;\n  for (let h = l; h < G; ++h)\n    Z *= I[h];\n  return Z;\n}\nfunction Dh(I) {\n  if (I.length === 0)\n    return Number.NaN;\n  let l = Number.POSITIVE_INFINITY;\n  for (let G = 0; G < I.length; G++) {\n    const Z = I[G];\n    Z < l && (l = Z);\n  }\n  return l;\n}\nfunction SZ(I) {\n  if (I.length === 0)\n    return Number.NaN;\n  let l = Number.NEGATIVE_INFINITY;\n  for (let G = 0; G < I.length; G++) {\n    const Z = I[G];\n    Z > l && (l = Z);\n  }\n  return l;\n}\nfunction FI(I, l) {\n  if (l < I)\n    throw new y(`end (${l}) < begin (${I}) is forbidden.`);\n  const G = [];\n  for (let Z = I; Z < l; ++Z)\n    G.push(Z);\n  return G;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nlet wd;\nfunction cG() {\n  return wd == null && (wd = cC().epsilon()), wd;\n}\nfunction yI() {\n  return \"channelsLast\";\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction wI(I, l) {\n  return hl(I, l);\n}\nfunction $g(I, l = -1) {\n  const G = I.shape.slice();\n  return l < 0 && (l = G.length + l + 1), G.splice(l, 0, 1), J(I, G);\n}\nfunction BF(I, l) {\n  return U(() => {\n    if (I.shape.length !== 2)\n      throw new y(`repeat() expects a rank-2 tensor, but received a rank-${I.shape.length} tensor.`);\n    const G = $g(I, 1);\n    return RW(G, [1, l, 1]);\n  });\n}\nfunction nF(I) {\n  const l = [uZ(I.shape)];\n  return J(I, l);\n}\nfunction CF(I) {\n  if (I.rank <= 1)\n    throw new y(`batchFlatten requires a minimum rank of 2. Got rank: ${I.rank}.`);\n  const l = [I.shape[0], uZ(I.shape, 1)];\n  return J(I, l);\n}\nfunction Ih(I, l, G) {\n  return U(() => {\n    switch (I.rank) {\n      case 1:\n        return YV(I, l, G);\n      case 2:\n        return Om(I, [l, 0], [G, I.shape[1]]);\n      case 3:\n        return VV(I, [l, 0, 0], [G, I.shape[1], I.shape[2]]);\n      case 4:\n        return zb(I, [l, 0, 0, 0], [G, I.shape[1], I.shape[2], I.shape[3]]);\n      case 5:\n        return zl(I, [l, 0, 0, 0, 0], [\n          G,\n          I.shape[1],\n          I.shape[2],\n          I.shape[3],\n          I.shape[4]\n        ]);\n      case 6:\n        return zl(I, [l, 0, 0, 0, 0, 0], [\n          G,\n          I.shape[1],\n          I.shape[2],\n          I.shape[3],\n          I.shape[4],\n          I.shape[5]\n        ]);\n      default:\n        throw new y(`sliceAlongFirstAxis() received an unsupported tensor rank: ${I.rank}`);\n    }\n  });\n}\nfunction Qd(I, l, G) {\n  return U(() => {\n    switch (I.rank) {\n      case 1:\n        return YV(I, l, G);\n      case 2:\n        return Om(I, [0, l], [I.shape[0], G]);\n      case 3:\n        return VV(I, [0, 0, l], [I.shape[0], I.shape[1], G]);\n      case 4:\n        return zb(I, [0, 0, 0, l], [I.shape[0], I.shape[1], I.shape[2], G]);\n      default:\n        throw new y(`sliceAlongLastAxis() received an unsupported tensor rank: ${I.rank}`);\n    }\n  });\n}\nfunction Bb(I, l, G, Z) {\n  return U(() => {\n    switch (I.rank) {\n      case 1:\n        return YV(I, l, G);\n      case 2:\n        switch (Z) {\n          case 1:\n            return Ih(I, l, G);\n          case 2:\n            return Qd(I, l, G);\n          default:\n            throw new y(`The axis is not within the rank of the tensor ${Z}`);\n        }\n      case 3:\n        switch (Z) {\n          case 1:\n            return Ih(I, l, G);\n          case 2:\n            return VV(I, [0, l, 0], [I.shape[0], G, I.shape[2]]);\n          case 3:\n            return Qd(I, l, G);\n          default:\n            throw new y(`The axis is not within the rank of the tensor ${Z}`);\n        }\n      case 4:\n        switch (Z) {\n          case 1:\n            return Ih(I, l, G);\n          case 2:\n            return zb(I, [0, l, 0, 0], [I.shape[0], G, I.shape[2], I.shape[3]]);\n          case 3:\n            return zb(I, [0, 0, l, 0], [I.shape[0], I.shape[1], G, I.shape[3]]);\n          case 4:\n            return Qd(I, l, G);\n          default:\n            throw new y(`The axis is not within the rank of the tensor ${Z}`);\n        }\n      default:\n        throw new y(`sliceAlongLastAxis() received an unsupported tensor rank: ${I.rank}`);\n    }\n  });\n}\nfunction qV(I, l = -1) {\n  let G;\n  return l < 0 && (G = I[0].rank, G !== 0 ? l = G : l = 0), l === I[0].rank && (l = -1), zG(I, l);\n}\nfunction sa(I, l) {\n  switch (I.rank) {\n    case 1:\n      return NX([I, l]);\n    case 2:\n      return JX([I, l], 0);\n    case 3:\n      return xX([I, l], 0);\n    case 4:\n      return HX([I, l], 0);\n    default:\n      throw new y(`concatAlongFirstAxis() received an unsupported tensor rank: ${I.rank}`);\n  }\n}\nfunction RW(I, l) {\n  if (Array.isArray(l) || (l = [l]), I.rank !== l.length)\n    throw new y(`The length of input n (${l.length}) does not match the number of dimensions in input x (${I.rank})`);\n  return eI(I, l);\n}\nfunction Bd(I, l = 0, G = 1, Z, h) {\n  return vu(I, l, G, Z, h);\n}\nfunction QI(I, l, G, Z) {\n  if (I.rank < 2 || l.rank < 2)\n    throw new Bl(`dot requires both inputs to be rank >= 2 but got x shape = ${I.shape} and y shape = ${l.shape}`);\n  if (l.rank >= 3) {\n    const h = I.shape.slice(-1)[0], g = l.shape.slice(-2)[0];\n    if (h !== g)\n      throw new Bl(`If rank y >= 3, then the second last dim of y must equal the last dim of x but got x shape = ${I.shape} and  y shape = ${l.shape}`);\n  }\n  if (I.rank === 2 && l.rank === 2)\n    return Ia({\n      a: I,\n      b: l,\n      transposeA: !1,\n      transposeB: !1,\n      bias: Z ? pW(I.rank, Z, yI()) : null,\n      activation: G\n    });\n  {\n    const h = I.shape.slice(), g = h.pop();\n    I = J(I, [-1, g]);\n    const b = l.shape.slice(), c = b.pop(), d = b.pop(), W = [...b, c], Y = Array.from({ length: l.rank }, (m, T) => T === 0 ? l.rank - 2 : T <= l.rank - 2 ? T - 1 : T);\n    l = J(el(l, Y), [d, -1]);\n    const V = [...h, ...W];\n    return J(Ia({\n      a: I,\n      b: l,\n      transposeA: !1,\n      transposeB: !1,\n      bias: Z ? pW(I.rank, Z, yI()) : null,\n      activation: G\n    }), V);\n  }\n}\nfunction _T(I, l, G) {\n  return U(() => (Array.isArray(l) ? l = jG(l, \"int32\") : l = hl(l, \"int32\"), DY(I, l, G)));\n}\nfunction _g(I) {\n  return N(I, I);\n}\nfunction pW(I, l, G) {\n  const Z = l.shape;\n  if (l.rank !== 1 && l.rank !== I)\n    throw new y(`Unexpected bias dimensions: ${l.rank}; expected it to be 1 or ${I}`);\n  if (I === 5) {\n    if (G === \"channelsFirst\")\n      return Z.length === 1 ? J(l, [1, Z[0], 1, 1, 1]) : J(l, [1, Z[3], Z[0], Z[1], Z[2]]);\n    if (G === \"channelsLast\")\n      return Z.length === 1 ? J(l, [1, 1, 1, 1, Z[0]]) : J(l, [1].concat(Z));\n  } else if (I === 4) {\n    if (G === \"channelsFirst\")\n      return Z.length === 1 ? J(l, [1, Z[0], 1, 1]) : J(l, [1, Z[2], Z[0], Z[1]]);\n    if (G === \"channelsLast\")\n      return Z.length === 1 ? J(l, [1, 1, 1, Z[0]]) : J(l, [1].concat(Z));\n  } else if (I === 3) {\n    if (G === \"channelsFirst\")\n      return Z.length === 1 ? J(l, [1, Z[0], 1]) : J(l, [1, Z[1], Z[0]]);\n    if (G === \"channelsLast\")\n      return Z.length === 1 ? J(l, [1, 1, Z[0]]) : J(l, [1].concat(Z));\n  } else if (I < 3)\n    return l;\n  throw new y(`Unsupported input rank by biasAdd: ${l.rank}`);\n}\nfunction JI(I, l, G) {\n  return U(() => (G == null && (G = yI()), IG(G), O(I, pW(I.rank, l, G))));\n}\nfunction XF(I, l = 1) {\n  if (l !== 1)\n    throw new Bl(`Support for alpha values other than 1 (${l}) is not implemented yet.`);\n  return Yd(I);\n}\nfunction tF(I) {\n  return U(() => Vl(I, O(PG(I), 1)));\n}\nfunction ls(I, l, G, Z) {\n  return U(() => Le(I, l, G, Z));\n}\nfunction uF(I) {\n  return U(() => {\n    const l = O(0.5, N(0.2, I));\n    return II(l, 0, 1);\n  });\n}\nfunction lb(I, l, G = !1) {\n  return G ? I() : l();\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst eF = [\"fanIn\", \"fanOut\", \"fanAvg\"], SF = [\"normal\", \"uniform\", \"truncatedNormal\"];\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction RF(I) {\n  eh(eF, \"FanMode\", I);\n}\nfunction pF(I) {\n  eh(SF, \"Distribution\", I);\n}\nclass oI extends c0 {\n  fromConfigUsesCustomObjects() {\n    return !1;\n  }\n  getConfig() {\n    return {};\n  }\n}\nclass Gs extends oI {\n  apply(l, G) {\n    return mG(l, G);\n  }\n}\nGs.className = \"Zeros\";\nj(Gs);\nclass $V extends oI {\n  apply(l, G) {\n    return HZ(l, G);\n  }\n}\n$V.className = \"Ones\";\nj($V);\nclass Is extends oI {\n  constructor(l) {\n    if (super(), typeof l != \"object\")\n      throw new y(`Expected argument of type ConstantConfig but got ${l}`);\n    if (l.value === void 0)\n      throw new y(`config must have value set but got ${l}`);\n    this.value = l.value;\n  }\n  apply(l, G) {\n    return U(() => N(yl(this.value), HZ(l, G)));\n  }\n  getConfig() {\n    return {\n      value: this.value\n    };\n  }\n}\nIs.className = \"Constant\";\nj(Is);\nclass Zs extends oI {\n  constructor(l) {\n    super(), this.DEFAULT_MINVAL = -0.05, this.DEFAULT_MAXVAL = 0.05, this.minval = l.minval || this.DEFAULT_MINVAL, this.maxval = l.maxval || this.DEFAULT_MAXVAL, this.seed = l.seed;\n  }\n  apply(l, G) {\n    return vg(l, this.minval, this.maxval, G, this.seed);\n  }\n  getConfig() {\n    return { minval: this.minval, maxval: this.maxval, seed: this.seed };\n  }\n}\nZs.className = \"RandomUniform\";\nj(Zs);\nclass hs extends oI {\n  constructor(l) {\n    super(), this.DEFAULT_MEAN = 0, this.DEFAULT_STDDEV = 0.05, this.mean = l.mean || this.DEFAULT_MEAN, this.stddev = l.stddev || this.DEFAULT_STDDEV, this.seed = l.seed;\n  }\n  apply(l, G) {\n    if (G = G || \"float32\", G !== \"float32\" && G !== \"int32\")\n      throw new Bl(`randomNormal does not support dType ${G}.`);\n    return Bd(l, this.mean, this.stddev, G, this.seed);\n  }\n  getConfig() {\n    return { mean: this.mean, stddev: this.stddev, seed: this.seed };\n  }\n}\nhs.className = \"RandomNormal\";\nj(hs);\nclass gs extends oI {\n  constructor(l) {\n    super(), this.DEFAULT_MEAN = 0, this.DEFAULT_STDDEV = 0.05, this.mean = l.mean || this.DEFAULT_MEAN, this.stddev = l.stddev || this.DEFAULT_STDDEV, this.seed = l.seed;\n  }\n  apply(l, G) {\n    if (G = G || \"float32\", G !== \"float32\" && G !== \"int32\")\n      throw new Bl(`truncatedNormal does not support dType ${G}.`);\n    return _m(l, this.mean, this.stddev, G, this.seed);\n  }\n  getConfig() {\n    return { mean: this.mean, stddev: this.stddev, seed: this.seed };\n  }\n}\ngs.className = \"TruncatedNormal\";\nj(gs);\nclass bs extends oI {\n  constructor(l) {\n    super(), this.gain = l.gain != null ? l.gain : 1;\n  }\n  apply(l, G) {\n    return U(() => {\n      if (l.length !== 2 || l[0] !== l[1])\n        throw new y(\"Identity matrix initializer can only be used for 2D square matrices.\");\n      return N(this.gain, Um(l[0]));\n    });\n  }\n  getConfig() {\n    return { gain: this.gain };\n  }\n}\nbs.className = \"Identity\";\nj(bs);\nfunction FF(I, l = \"channelsLast\") {\n  let G, Z;\n  if (IG(l), I.length === 2)\n    G = I[0], Z = I[1];\n  else if ([3, 4, 5].indexOf(I.length) !== -1) {\n    if (l === \"channelsFirst\") {\n      const h = uZ(I, 2);\n      G = I[1] * h, Z = I[0] * h;\n    } else if (l === \"channelsLast\") {\n      const h = uZ(I, 0, I.length - 2);\n      G = I[I.length - 2] * h, Z = I[I.length - 1] * h;\n    }\n  } else {\n    const h = uZ(I);\n    G = Math.sqrt(h), Z = Math.sqrt(h);\n  }\n  return [G, Z];\n}\nclass fG extends oI {\n  /**\n   * Constructor of VarianceScaling.\n   * @throws ValueError for invalid value in scale.\n   */\n  constructor(l) {\n    if (super(), l.scale < 0)\n      throw new y(`scale must be a positive float. Got: ${l.scale}`);\n    this.scale = l.scale == null ? 1 : l.scale, this.mode = l.mode == null ? \"fanIn\" : l.mode, RF(this.mode), this.distribution = l.distribution == null ? \"normal\" : l.distribution, pF(this.distribution), this.seed = l.seed;\n  }\n  apply(l, G) {\n    const Z = FF(l), h = Z[0], g = Z[1];\n    let b = this.scale;\n    if (this.mode === \"fanIn\" ? b /= Math.max(1, h) : this.mode === \"fanOut\" ? b /= Math.max(1, g) : b /= Math.max(1, (h + g) / 2), this.distribution === \"normal\") {\n      const c = Math.sqrt(b);\n      if (G = G || \"float32\", G !== \"float32\" && G !== \"int32\")\n        throw new Bl(`${this.getClassName()} does not support dType ${G}.`);\n      return _m(l, 0, c, G, this.seed);\n    } else {\n      const c = Math.sqrt(3 * b);\n      return vg(l, -c, c, G, this.seed);\n    }\n  }\n  getConfig() {\n    return {\n      scale: this.scale,\n      mode: this.mode,\n      distribution: this.distribution,\n      seed: this.seed\n    };\n  }\n}\nfG.className = \"VarianceScaling\";\nj(fG);\nclass _V extends fG {\n  /**\n   * Constructor of GlorotUniform\n   * @param scale\n   * @param mode\n   * @param distribution\n   * @param seed\n   */\n  constructor(l) {\n    super({\n      scale: 1,\n      mode: \"fanAvg\",\n      distribution: \"uniform\",\n      seed: l == null ? null : l.seed\n    });\n  }\n  getClassName() {\n    return fG.className;\n  }\n}\n_V.className = \"GlorotUniform\";\nj(_V);\nclass l9 extends fG {\n  /**\n   * Constructor of GlorotNormal.\n   * @param scale\n   * @param mode\n   * @param distribution\n   * @param seed\n   */\n  constructor(l) {\n    super({\n      scale: 1,\n      mode: \"fanAvg\",\n      distribution: \"normal\",\n      seed: l == null ? null : l.seed\n    });\n  }\n  getClassName() {\n    return fG.className;\n  }\n}\nl9.className = \"GlorotNormal\";\nj(l9);\nclass G9 extends fG {\n  constructor(l) {\n    super({\n      scale: 2,\n      mode: \"fanIn\",\n      distribution: \"normal\",\n      seed: l == null ? null : l.seed\n    });\n  }\n  getClassName() {\n    return fG.className;\n  }\n}\nG9.className = \"HeNormal\";\nj(G9);\nclass I9 extends fG {\n  constructor(l) {\n    super({\n      scale: 2,\n      mode: \"fanIn\",\n      distribution: \"uniform\",\n      seed: l == null ? null : l.seed\n    });\n  }\n  getClassName() {\n    return fG.className;\n  }\n}\nI9.className = \"HeUniform\";\nj(I9);\nclass Z9 extends fG {\n  constructor(l) {\n    super({\n      scale: 1,\n      mode: \"fanIn\",\n      distribution: \"normal\",\n      seed: l == null ? null : l.seed\n    });\n  }\n  getClassName() {\n    return fG.className;\n  }\n}\nZ9.className = \"LeCunNormal\";\nj(Z9);\nclass h9 extends fG {\n  constructor(l) {\n    super({\n      scale: 1,\n      mode: \"fanIn\",\n      distribution: \"uniform\",\n      seed: l == null ? null : l.seed\n    });\n  }\n  getClassName() {\n    return fG.className;\n  }\n}\nh9.className = \"LeCunUniform\";\nj(h9);\nclass cs extends oI {\n  constructor(l) {\n    super(), this.DEFAULT_GAIN = 1, this.ELEMENTS_WARN_SLOW = 2e3, this.gain = l.gain == null ? this.DEFAULT_GAIN : l.gain, this.seed = l.seed;\n  }\n  apply(l, G) {\n    return U(() => {\n      if (l.length < 2)\n        throw new Bl(\"Shape must be at least 2D.\");\n      if (G !== \"int32\" && G !== \"float32\" && G !== void 0)\n        throw new TypeError(`Unsupported data type ${G}.`);\n      G = G;\n      const Z = Q(l.slice(0, -1)), h = l[l.length - 1], g = Z * h;\n      g > this.ELEMENTS_WARN_SLOW && console.warn(`Orthogonal initializer is being called on a matrix with more than ${this.ELEMENTS_WARN_SLOW} (${g}) elements: Slowness may result.`);\n      const b = [Math.max(h, Z), Math.min(h, Z)], c = Bd(b, 0, 1, G, this.seed), d = KS.qr(c, !1);\n      let W = d[0];\n      const V = d[1].flatten().stridedSlice([0], [Math.min(h, Z) * Math.min(h, Z)], [Math.min(h, Z) + 1]);\n      return W = N(W, V.sign()), Z < h && (W = W.transpose()), N(yl(this.gain), W.reshape(l));\n    });\n  }\n  getConfig() {\n    return {\n      gain: this.gain,\n      seed: this.seed\n    };\n  }\n}\ncs.className = \"Orthogonal\";\nj(cs);\nconst oa = {\n  constant: \"Constant\",\n  glorotNormal: \"GlorotNormal\",\n  glorotUniform: \"GlorotUniform\",\n  heNormal: \"HeNormal\",\n  heUniform: \"HeUniform\",\n  identity: \"Identity\",\n  leCunNormal: \"LeCunNormal\",\n  leCunUniform: \"LeCunUniform\",\n  ones: \"Ones\",\n  orthogonal: \"Orthogonal\",\n  randomNormal: \"RandomNormal\",\n  randomUniform: \"RandomUniform\",\n  truncatedNormal: \"TruncatedNormal\",\n  varianceScaling: \"VarianceScaling\",\n  zeros: \"Zeros\"\n};\nfunction Ba(I, l = {}) {\n  return qg(I, dI.getMap().classNameMap, l, \"initializer\");\n}\nfunction fl(I) {\n  return fV(I);\n}\nfunction rl(I) {\n  if (typeof I == \"string\") {\n    const l = I in oa ? oa[I] : I;\n    if (l === \"GlorotNormal\")\n      return new l9();\n    if (l === \"GlorotUniform\")\n      return new _V();\n    if (l === \"HeNormal\")\n      return new G9();\n    if (l === \"HeUniform\")\n      return new I9();\n    if (l === \"LeCunNormal\")\n      return new Z9();\n    if (l === \"LeCunUniform\")\n      return new h9();\n    {\n      const G = {};\n      return G.className = l, G.config = {}, Ba(G);\n    }\n  } else return I instanceof oI ? I : Ba(I);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction FW(I) {\n  return Array.isArray(I) && Array.isArray(I[0]);\n}\nfunction Lb(I) {\n  return I.length === 0 ? [] : Array.isArray(I[0]) ? I : [I];\n}\nfunction Tl(I) {\n  let l;\n  if (Array.isArray(I)) {\n    if (I.length !== 1)\n      throw new y(`Expected Tensor length to be 1; got ${I.length}`);\n    l = I[0];\n  } else\n    l = I;\n  return l;\n}\nfunction pl(I) {\n  if (Array.isArray(I) && Array.isArray(I[0])) {\n    if (I.length === 1)\n      return I = I, I[0];\n    throw new y(`Expected exactly 1 Shape; got ${I.length}`);\n  } else\n    return I;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Mb(I) {\n  let l = 0;\n  for (const G of I)\n    G.shape.length === 0 ? l += 1 : l += G.shape.reduce((Z, h) => Z * h);\n  return l;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst na = \"Variable\";\nclass yF {\n  /**\n   * Construct Variable from a `tf.Tensor`.\n   *\n   * If not explicitly named, the Variable will be given a name with the\n   * prefix 'Variable'. Variable names are unique. In the case of name\n   * collision, suffixies '_<num>' will be added to the name.\n   *\n   * @param val Initial value of the Variable.\n   * @param name Name of the variable. If `null` or `undefined` is provided, it\n   *   will default a name with the prefix 'Variable'.\n   * @param constraint Optional, projection function to be applied to the\n   * variable after optimize updates\n   * @throws ValueError if `name` is `null` or `undefined`.\n   */\n  constructor(l, G = \"float32\", Z = na, h = !0, g = null) {\n    this.dtype = G ?? \"float32\", this.shape = l.shape, this.id = DT(), Z = Z ?? na, this.originalName = OT(Z), this.name = qT(this.originalName), this.trainable_ = h, this.constraint = g, this.val = Ke(l, this.trainable_, this.name, this.dtype);\n  }\n  /**\n   * Get a snapshot of the Variable's value.\n   *\n   * The returned value is a snapshot of the Variable's value at the time of\n   * the invocation. Future mutations in the value of the tensor will only\n   * be reflected by future calls to this method.\n   */\n  read() {\n    return this.assertNotDisposed(), this.val;\n  }\n  /**\n   * Update the value of the Variable.\n   *\n   * @param newVal: The new value to update to. Must be consistent with the\n   *   dtype and shape of the Variable.\n   * @return This Variable.\n   */\n  write(l) {\n    return this.assertNotDisposed(), NF(this.val, l), this.val.id !== l.id && (this.val.assign(l), this.constraint != null && this.val.assign(this.constraint.apply(this.val))), this;\n  }\n  /**\n   * Dispose this LayersVariable instance from memory.\n   */\n  dispose() {\n    this.assertNotDisposed(), this.val.dispose();\n  }\n  assertNotDisposed() {\n    if (this.val.isDisposed)\n      throw new Error(`LayersVariable ${this.name} is already disposed.`);\n  }\n  get trainable() {\n    return this.trainable_;\n  }\n  set trainable(l) {\n    this.trainable_ = l, this.val.trainable = l;\n  }\n}\nfunction NF(I, l) {\n  if (I.shape.toString() !== l.shape.toString())\n    throw new Error(\"Shape mismatch: \" + JSON.stringify(I.shape) + \" vs. \" + JSON.stringify(l.shape));\n}\nfunction yW(I) {\n  return I.map((l) => l.read());\n}\nfunction g9(I) {\n  I.forEach((l) => {\n    l[0].write(l[1]);\n  });\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass dG {\n  constructor(l) {\n    this.dtype = l.dtype, this.shape = l.shape, l.shape != null ? this.ndim = l.shape.length : this.ndim = l.ndim, this.maxNDim = l.maxNDim, this.minNDim = l.minNDim, this.axes = l.axes || {};\n  }\n}\nclass DI {\n  /**\n   *\n   * @param dtype\n   * @param shape\n   * @param sourceLayer The Layer that produced this symbolic tensor.\n   * @param inputs The inputs passed to sourceLayer's __call__() method.\n   * @param nodeIndex\n   * @param tensorIndex\n   * @param callArgs The keyword arguments passed to the __call__() method.\n   * @param name\n   * @param outputTensorIndex The index of this tensor in the list of outputs\n   *   returned by apply().\n   */\n  constructor(l, G, Z, h, g, b, c) {\n    this.dtype = l, this.shape = G, this.sourceLayer = Z, this.inputs = h, this.callArgs = g, this.outputTensorIndex = c, this.id = DT(), b != null && (this.originalName = OT(b), this.name = qT(this.originalName)), this.rank = G.length;\n  }\n}\nlet PF = 0;\nclass nd {\n  constructor(l, G) {\n    this.callArgs = G, this.id = PF++, this.outboundLayer = l.outboundLayer, this.inboundLayers = l.inboundLayers, this.nodeIndices = l.nodeIndices, this.tensorIndices = l.tensorIndices, this.inputTensors = l.inputTensors, this.outputTensors = l.outputTensors, this.inputMasks = l.inputMasks, this.outputMasks = l.outputMasks, this.inputShapes = l.inputShapes, this.outputShapes = l.outputShapes;\n    for (const Z of l.inboundLayers)\n      Z != null && Z.outboundNodes.push(this);\n    l.outboundLayer.inboundNodes.push(this);\n  }\n  getConfig() {\n    const l = [];\n    for (const G of this.inboundLayers)\n      G != null ? l.push(G.name) : l.push(null);\n    return {\n      outboundLayer: this.outboundLayer ? this.outboundLayer.name : null,\n      inboundLayers: l,\n      nodeIndices: this.nodeIndices,\n      tensorIndices: this.tensorIndices\n    };\n  }\n}\nlet JF = 0;\nclass ul extends c0 {\n  constructor(l = {}) {\n    super(), this._callHook = null, this._addedWeightNames = [], this._stateful = !1, this.id = JF++, this.activityRegularizer = null, this.inputSpec = null, this.supportsMasking = !1, this._trainableWeights = [], this._nonTrainableWeights = [], this._losses = [], this._updates = [], this._built = !1, this.inboundNodes = [], this.outboundNodes = [];\n    let G = l.name;\n    if (!G) {\n      const Z = this.getClassName();\n      G = _I(Z) + \"_\" + od(Z);\n    }\n    if (this.name = G, this.trainable_ = l.trainable == null ? !0 : l.trainable, l.inputShape != null || l.batchInputShape != null) {\n      let Z;\n      if (l.batchInputShape != null)\n        Z = l.batchInputShape;\n      else if (l.inputShape != null) {\n        let g = null;\n        l.batchSize != null && (g = l.batchSize), Z = [g].concat(l.inputShape);\n      }\n      this.batchInputShape = Z;\n      let h = l.dtype;\n      h == null && (h = l.inputDType), h == null && (h = \"float32\"), this.dtype = h;\n    }\n    l.weights != null ? this.initialWeights = l.weights : this.initialWeights = null, this._refCount = null, this.fastWeightInitDuringBuild = !1;\n  }\n  /**\n   * Converts a layer and its index to a unique (immutable type) name.\n   * This function is used internally with `this.containerNodes`.\n   * @param layer The layer.\n   * @param nodeIndex The layer's position (e.g. via enumerate) in a list of\n   *   nodes.\n   *\n   * @returns The unique name.\n   */\n  static nodeKey(l, G) {\n    return l.name + \"_ib-\" + G.toString();\n  }\n  /**\n   * Returns this.inboundNode at index nodeIndex.\n   *\n   * Porting note: This is a replacement for _get_node_attribute_at_index()\n   * @param nodeIndex\n   * @param attrName The name of the attribute related to request for this node.\n   */\n  getNodeAtIndex(l, G) {\n    if (this.inboundNodes.length === 0)\n      throw new aI(`The layer has never been called and thus has no defined ${G}.`);\n    if (this.inboundNodes.length <= l)\n      throw new y(`Asked to get ${G} at node ${l}, but the layer has only ${this.inboundNodes.length} inbound nodes.`);\n    return this.inboundNodes[l];\n  }\n  /**\n   * Retrieves the input tensor(s) of a layer at a given node.\n   *\n   * @param nodeIndex Integer, index of the node from which to retrieve the\n   *   attribute. E.g. `nodeIndex=0` will correspond to the first time the layer\n   *   was called.\n   *\n   * @return A tensor (or list of tensors if the layer has multiple inputs).\n   */\n  getInputAt(l) {\n    return kG(this.getNodeAtIndex(l, \"input\").inputTensors);\n  }\n  /**\n   * Retrieves the output tensor(s) of a layer at a given node.\n   *\n   * @param nodeIndex Integer, index of the node from which to retrieve the\n   *   attribute. E.g. `nodeIndex=0` will correspond to the first time the layer\n   *   was called.\n   *\n   * @return A tensor (or list of tensors if the layer has multiple outputs).\n   */\n  getOutputAt(l) {\n    return kG(this.getNodeAtIndex(l, \"output\").outputTensors);\n  }\n  // Properties\n  /**\n   * Retrieves the input tensor(s) of a layer.\n   *\n   * Only applicable if the layer has exactly one inbound node,\n   * i.e. if it is connected to one incoming layer.\n   *\n   * @return Input tensor or list of input tensors.\n   *\n   * @exception AttributeError if the layer is connected to more than one\n   *   incoming layers.\n   */\n  get input() {\n    if (this.inboundNodes.length > 1)\n      throw new HI(`Layer ${this.name} has multiple inbound nodes, hence the notion of \"layer input\" is ill-defined. Use \\`getInputAt(nodeIndex)\\` instead.`);\n    if (this.inboundNodes.length === 0)\n      throw new HI(`Layer ${this.name} is not connected, no input to return.`);\n    return kG(this.getNodeAtIndex(0, \"input\").inputTensors);\n  }\n  /**\n   * Retrieves the output tensor(s) of a layer.\n   *\n   * Only applicable if the layer has exactly one inbound node,\n   * i.e. if it is connected to one incoming layer.\n   *\n   * @return Output tensor or list of output tensors.\n   *\n   * @exception AttributeError if the layer is connected to more than one\n   *   incoming layers.\n   */\n  get output() {\n    if (this.inboundNodes.length === 0)\n      throw new HI(`Layer ${this.name} has no inbound nodes.`);\n    if (this.inboundNodes.length > 1)\n      throw new HI(`Layer ${this.name} has multiple inbound nodes, hence the notion of \"layer output\" is ill-defined. Use \\`getOutputAt(nodeIndex)\\` instead.`);\n    return kG(this.getNodeAtIndex(0, \"output\").outputTensors);\n  }\n  get losses() {\n    return this._losses;\n  }\n  /**\n   * Retrieves the Layer's current loss values.\n   *\n   * Used for regularizers during training.\n   */\n  calculateLosses() {\n    return this.losses.map((l) => l());\n  }\n  get updates() {\n    return this._updates;\n  }\n  get built() {\n    return this._built;\n  }\n  set built(l) {\n    this._built = l;\n  }\n  get trainable() {\n    return this.trainable_;\n  }\n  set trainable(l) {\n    this._trainableWeights.forEach((G) => G.trainable = l), this.trainable_ = l;\n  }\n  get trainableWeights() {\n    return this.trainable_ ? this._trainableWeights.filter((l) => l.trainable) : [];\n  }\n  set trainableWeights(l) {\n    this._trainableWeights = l;\n  }\n  get nonTrainableWeights() {\n    return this.trainable ? this._trainableWeights.filter((l) => !l.trainable).concat(this._nonTrainableWeights) : this._trainableWeights.concat(this._nonTrainableWeights);\n  }\n  set nonTrainableWeights(l) {\n    this._nonTrainableWeights = l;\n  }\n  /**\n   * The concatenation of the lists trainableWeights and nonTrainableWeights\n   * (in this order).\n   */\n  get weights() {\n    return this.trainableWeights.concat(this.nonTrainableWeights);\n  }\n  get stateful() {\n    return this._stateful;\n  }\n  /**\n   * Reset the states of the layer.\n   *\n   * This method of the base Layer class is essentially a no-op.\n   * Subclasses that are stateful (e.g., stateful RNNs) should override this\n   * method.\n   */\n  resetStates() {\n    if (!this.stateful)\n      throw new Error(\"Cannot call the resetStates() method of a non-stateful Layer object.\");\n  }\n  /**\n   * Checks compatibility between the layer and provided inputs.\n   *\n   * This checks that the tensor(s) `input`\n   * verify the input assumptions of the layer\n   * (if any). If not, exceptions are raised.\n   *\n   * @param inputs Input tensor or list of input tensors.\n   *\n   * @exception ValueError in case of mismatch between\n   *   the provided inputs and the expectations of the layer.\n   */\n  assertInputCompatibility(l) {\n    const G = Jl(l);\n    if (this.inputSpec == null || this.inputSpec.length === 0)\n      return;\n    const Z = Jl(this.inputSpec);\n    if (G.length !== Z.length)\n      throw new y(`Layer ${this.name} expects ${Z.length} inputs, but it received ${G.length} input tensors. Input received: ${l}`);\n    for (let h = 0; h < G.length; h++) {\n      const g = G[h], b = Z[h];\n      if (b == null)\n        continue;\n      const c = g.rank;\n      if (b.ndim != null && c !== b.ndim)\n        throw new y(`Input ${h} is incompatible with layer ${this.name}: expected ndim=${b.ndim}, found ndim=${c}`);\n      if (b.maxNDim != null && c > b.maxNDim)\n        throw new y(`Input ${h} is incompatible with layer ${this.name}: expected max_ndim=${b.maxNDim}, found ndim=${c}`);\n      if (b.minNDim != null && c < b.minNDim)\n        throw new y(`Input ${h} is incompatible with layer ${this.name}: expected min_ndim=${b.minNDim}, found ndim=${c}.`);\n      if (b.dtype != null && g.dtype !== b.dtype)\n        throw new y(`Input ${h} is incompatible with layer ${this.name} : expected dtype=${b.dtype}, found dtype=${g.dtype}.`);\n      if (b.axes) {\n        const d = g.shape;\n        for (const W in b.axes) {\n          const Y = Number(W), V = b.axes[W], a = Y >= 0 ? d[Y] : d[d.length + Y];\n          if (V != null && [V, null].indexOf(a) === -1)\n            throw new y(`Input ${h} is incompatible with layer ${this.name}: expected axis ${Y} of input shape to have value ${V} but got shape ${d}.`);\n        }\n      }\n      if (b.shape != null)\n        for (let d = 0; d < b.shape.length; ++d) {\n          const W = b.shape[d], Y = g.shape[d];\n          if (W != null && Y != null && W !== Y)\n            throw new y(`Input ${h} is incompatible with layer ${this.name}: expected shape=${b.shape}, found shape=${g.shape}.`);\n        }\n    }\n  }\n  /**\n   * This is where the layer's logic lives.\n   *\n   * @param inputs Input tensor, or list/tuple of input tensors.\n   * @param kwargs Additional keyword arguments.\n   *\n   * @return A tensor or list/tuple of tensors.\n   */\n  call(l, G) {\n    return l;\n  }\n  invokeCallHook(l, G) {\n    this._callHook != null && this._callHook(l, G);\n  }\n  /**\n   * Set call hook.\n   * This is currently used for testing only.\n   * @param callHook\n   */\n  setCallHook(l) {\n    this._callHook = l;\n  }\n  /**\n   * Clear call hook.\n   * This is currently used for testing only.\n   */\n  clearCallHook() {\n    this._callHook = null;\n  }\n  /**\n   * Builds or executes a `Layer`'s logic.\n   *\n   * When called with `tf.Tensor`(s), execute the `Layer`'s computation and\n   * return Tensor(s). For example:\n   *\n   * ```js\n   * const denseLayer = tf.layers.dense({\n   *   units: 1,\n   *   kernelInitializer: 'zeros',\n   *   useBias: false\n   * });\n   *\n   * // Invoke the layer's apply() method with a `tf.Tensor` (with concrete\n   * // numeric values).\n   * const input = tf.ones([2, 2]);\n   * const output = denseLayer.apply(input);\n   *\n   * // The output's value is expected to be [[0], [0]], due to the fact that\n   * // the dense layer has a kernel initialized to all-zeros and does not have\n   * // a bias.\n   * output.print();\n   * ```\n   *\n   * When called with `tf.SymbolicTensor`(s), this will prepare the layer for\n   * future execution.  This entails internal book-keeping on shapes of\n   * expected Tensors, wiring layers together, and initializing weights.\n   *\n   * Calling `apply` with `tf.SymbolicTensor`s are typically used during the\n   * building of non-`tf.Sequential` models. For example:\n   *\n   * ```js\n   * const flattenLayer = tf.layers.flatten();\n   * const denseLayer = tf.layers.dense({units: 1});\n   *\n   * // Use tf.layers.input() to obtain a SymbolicTensor as input to apply().\n   * const input = tf.input({shape: [2, 2]});\n   * const output1 = flattenLayer.apply(input);\n   *\n   * // output1.shape is [null, 4]. The first dimension is the undetermined\n   * // batch size. The second dimension comes from flattening the [2, 2]\n   * // shape.\n   * console.log(JSON.stringify(output1.shape));\n   *\n   * // The output SymbolicTensor of the flatten layer can be used to call\n   * // the apply() of the dense layer:\n   * const output2 = denseLayer.apply(output1);\n   *\n   * // output2.shape is [null, 1]. The first dimension is the undetermined\n   * // batch size. The second dimension matches the number of units of the\n   * // dense layer.\n   * console.log(JSON.stringify(output2.shape));\n   *\n   * // The input and output can be used to construct a model that consists\n   * // of the flatten and dense layers.\n   * const model = tf.model({inputs: input, outputs: output2});\n   * ```\n   *\n   * @param inputs a `tf.Tensor` or `tf.SymbolicTensor` or an Array of them.\n   * @param kwargs Additional keyword arguments to be passed to `call()`.\n   *\n   * @return Output of the layer's `call` method.\n   *\n   * @exception ValueError error in case the layer is missing shape information\n   *   for its `build` call.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  // Porting Note: This is a replacement for __call__() in Python.\n  apply(l, G) {\n    G = G || {}, this.assertNotDisposed();\n    const Z = Jl(l), h = UF(l), g = HF(l);\n    if (h === g)\n      throw new y(\"Arguments to apply() must be all SymbolicTensors or all Tensors\");\n    return Gh(this.name, () => {\n      if (!this.built) {\n        this.assertInputCompatibility(l);\n        const b = [];\n        for (const c of Jl(l))\n          b.push(c.shape);\n        this.build(kG(b)), this.built = !0, this.initialWeights && this.setWeights(this.initialWeights), this._refCount === null && g && (this._refCount = 1);\n      }\n      if (this.assertInputCompatibility(l), g) {\n        let b = this.call(l, G);\n        this.supportsMasking && this.setMaskMetadata(l, b);\n        const c = Jl(b), d = [];\n        for (let W of c)\n          Z.indexOf(W) !== -1 && (W = W.clone()), d.push(W);\n        if (b = kG(d), this.activityRegularizer != null)\n          throw new Bl(\"Layer invocation in the presence of activity regularizer(s) is not supported yet.\");\n        return b;\n      } else {\n        const b = EF(l), c = this.computeOutputShape(b);\n        let d;\n        const W = xF(l);\n        if (this.warnOnIncompatibleInputShape(Array.isArray(l) ? b[0] : b), c != null && c.length > 0 && Array.isArray(c[0]) ? d = c.map((Y, V) => new DI(W, Y, this, Jl(l), G, this.name, V)) : d = new DI(W, c, this, Jl(l), G, this.name), this.addInboundNode(l, d, null, null, b, c, G), this._refCount++, this.activityRegularizer != null)\n          throw new Bl(\"Layer invocation in the presence of activity regularizer(s) is not supported yet.\");\n        return d;\n      }\n    });\n  }\n  /**\n   * Check compatibility between input shape and this layer's batchInputShape.\n   *\n   * Print warning if any incompatibility is found.\n   *\n   * @param inputShape Input shape to be checked.\n   */\n  warnOnIncompatibleInputShape(l) {\n    if (this.batchInputShape != null)\n      if (l.length !== this.batchInputShape.length)\n        console.warn(`The rank of the input tensor provided (shape: ${JSON.stringify(l)}) does not match that of the batchInputShape (${JSON.stringify(this.batchInputShape)}) of the layer ${this.name}`);\n      else {\n        let G = !1;\n        this.batchInputShape.forEach((Z, h) => {\n          Z != null && l[h] != null && l[h] !== Z && (G = !0);\n        }), G && console.warn(`The shape of the input tensor (${JSON.stringify(l)}) does not match the expectation of layer ${this.name}: ${JSON.stringify(this.batchInputShape)}`);\n      }\n  }\n  /**\n   * Retrieves the output shape(s) of a layer.\n   *\n   * Only applicable if the layer has only one inbound node, or if all inbound\n   * nodes have the same output shape.\n   *\n   * @returns Output shape or shapes.\n   * @throws AttributeError: if the layer is connected to more than one incoming\n   *   nodes.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  get outputShape() {\n    if (this.inboundNodes == null || this.inboundNodes.length === 0)\n      throw new HI(`The layer ${this.name} has never been called and thus has no defined output shape.`);\n    const l = [];\n    for (const G of this.inboundNodes) {\n      const Z = JSON.stringify(G.outputShapes);\n      l.indexOf(Z) === -1 && l.push(Z);\n    }\n    if (l.length === 1) {\n      const G = this.inboundNodes[0].outputShapes;\n      return Array.isArray(G) && Array.isArray(G[0]) && G.length === 1 ? G[0] : G;\n    } else\n      throw new HI(`The layer ${this.name} has multiple inbound nodes with different output shapes. Hence the notion of \"output shape\" is ill-defined for the layer.`);\n  }\n  /**\n   * Counts the total number of numbers (e.g., float32, int32) in the\n   * weights.\n   *\n   * @returns An integer count.\n   * @throws RuntimeError: If the layer is not built yet (in which case its\n   *   weights are not defined yet.)\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  countParams() {\n    if (!this.built)\n      throw new aI(`You tried to call countParams() on ${this.name}, but the layer is not built yet. Build it first by calling build(batchInputShape).`);\n    return Mb(this.weights);\n  }\n  /**\n   * Creates the layer weights.\n   *\n   * Must be implemented on all layers that have weights.\n   *\n   * Called when apply() is called to construct the weights.\n   *\n   * @param inputShape A `Shape` or array of `Shape` (unused).\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  build(l) {\n    this.built = !0;\n  }\n  /**\n   * Returns the current values of the weights of the layer.\n   *\n   * @param trainableOnly Whether to get the values of only trainable weights.\n   * @returns Weight values as an `Array` of `tf.Tensor`s.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  getWeights(l = !1) {\n    return yW(l ? this.trainableWeights : this.weights);\n  }\n  /**\n   * Sets the weights of the layer, from Tensors.\n   *\n   * @param weights a list of Tensors. The number of arrays and their shape\n   *   must match number of the dimensions of the weights of the layer (i.e.\n   *   it should match the output of `getWeights`).\n   *\n   * @exception ValueError If the provided weights list does not match the\n   *   layer's specifications.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  setWeights(l) {\n    U(() => {\n      const G = this.weights;\n      if (G.length !== l.length)\n        throw new y(`You called setWeights(weights) on layer \"${this.name}\" with a weight list of length ${l.length}, but the layer was expecting ${G.length} weights. Provided weights: ${l}...`);\n      if (G.length === 0)\n        return;\n      const Z = [], h = yW(G);\n      for (let g = 0; g < h.length; ++g) {\n        const b = h[g], c = G[g], d = l[g];\n        if (!Nl(b.shape, d.shape))\n          throw new y(`Layer weight shape ${b.shape} not compatible with provided weight shape ${d.shape}`);\n        Z.push([c, d]);\n      }\n      g9(Z);\n    });\n  }\n  /**\n   * Adds a weight variable to the layer.\n   *\n   * @param name Name of the new weight variable.\n   * @param shape The shape of the weight.\n   * @param dtype The dtype of the weight.\n   * @param initializer An initializer instance.\n   * @param regularizer A regularizer instance.\n   * @param trainable Whether the weight should be trained via backprop or not\n   *   (assuming that the layer itself is also trainable).\n   * @param constraint An optional trainable.\n   * @return The created weight variable.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  addWeight(l, G, Z, h, g, b, c, d) {\n    if (this._addedWeightNames.indexOf(l) !== -1)\n      throw new y(`Duplicate weight name ${l} for layer ${this.name}`);\n    this._addedWeightNames.push(l), Z == null && (Z = \"float32\"), this.fastWeightInitDuringBuild && (h = d != null ? d() : rl(\"zeros\"));\n    const W = h.apply(G, Z), Y = new yF(W, Z, l, b, c);\n    return W.dispose(), g != null && this.addLoss(() => g.apply(Y.read())), b == null && (b = !0), b ? this._trainableWeights.push(Y) : this._nonTrainableWeights.push(Y), Y;\n  }\n  /**\n   * Set the fast-weight-initialization flag.\n   *\n   * In cases where the initialized weight values will be immediately\n   * overwritten by loaded weight values during model loading, setting\n   * the flag to `true` saves unnecessary calls to potentially expensive\n   * initializers and speeds up the loading process.\n   *\n   * @param value Target value of the flag.\n   */\n  setFastWeightInitDuringBuild(l) {\n    this.fastWeightInitDuringBuild = l;\n  }\n  /**\n   * Add losses to the layer.\n   *\n   * The loss may potentially be conditional on some inputs tensors,\n   * for instance activity losses are conditional on the layer's inputs.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  addLoss(l) {\n    l == null || Array.isArray(l) && l.length === 0 || (l = Jl(l), this._losses !== void 0 && this._losses !== null && this.losses.push(...l));\n  }\n  /**\n   * Computes the output shape of the layer.\n   *\n   * Assumes that the layer will be built to match that input shape provided.\n   *\n   * @param inputShape A shape (tuple of integers) or a list of shape tuples\n   *   (one per output tensor of the layer). Shape tuples can include null for\n   *   free dimensions, instead of an integer.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  computeOutputShape(l) {\n    return l;\n  }\n  /**\n   * Computes an output mask tensor.\n   *\n   * @param inputs Tensor or list of tensors.\n   * @param mask Tensor or list of tensors.\n   *\n   * @return null or a tensor (or list of tensors, one per output tensor of the\n   * layer).\n   */\n  computeMask(l, G) {\n    if (!this.supportsMasking) {\n      if (G != null)\n        if (Array.isArray(G))\n          G.forEach((Z) => {\n            if (Z != null)\n              throw new TypeError(`Layer ${this.name} does not support masking, but was passed an inputMask.`);\n          });\n        else\n          throw new TypeError(`Layer ${this.name} does not support masking, but was passed an inputMask.`);\n      return null;\n    }\n    return G;\n  }\n  setMaskMetadata(l, G, Z) {\n    if (!this.supportsMasking)\n      return;\n    const h = this.computeMask(l, Z), g = Jl(G), b = Jl(h);\n    if (g.length !== b.length)\n      throw new Error(`${this.name} outputs ${g.length} tensors but ${g.length} masks for those tensors`);\n    for (let c = 0; c < g.length; c++)\n      g[c].kerasMask = b[c];\n  }\n  /**\n   * Internal method to create an inbound node for the layer.\n   *\n   * @param inputTensors List of input tensors.\n   * @param outputTensors List of output tensors.\n   * @param inputMasks List of input masks (a mask can be a tensor, or null).\n   * @param outputMasks List of output masks (a mask can be a tensor, or null).\n   * @param inputShapes List of input shape tuples.\n   * @param outputShapes List of output shape tuples.\n   * @param kwargs Dictionary of keyword arguments that were passed to the\n   *   `call` method of the layer at the call that created the node.\n   */\n  addInboundNode(l, G, Z, h, g, b, c = null) {\n    const d = Jl(l);\n    G = Jl(G), Z = Jl(Z), h = Jl(h), g = Lb(g), b = Lb(b);\n    const W = [], Y = [], V = [];\n    for (const a of d)\n      W.push(a.sourceLayer), Y.push(a.nodeIndex), V.push(a.tensorIndex);\n    new nd({\n      outboundLayer: this,\n      inboundLayers: W,\n      nodeIndices: Y,\n      tensorIndices: V,\n      inputTensors: d,\n      outputTensors: G,\n      inputMasks: Z,\n      outputMasks: h,\n      inputShapes: g,\n      outputShapes: b\n    }, c);\n    for (let a = 0; a < G.length; a++)\n      G[a].sourceLayer = this, G[a].nodeIndex = this.inboundNodes.length - 1, G[a].tensorIndex = a;\n  }\n  /**\n   * Returns the config of the layer.\n   *\n   * A layer config is a TS dictionary (serializable)\n   * containing the configuration of a layer.\n   * The same layer can be reinstantiated later\n   * (without its trained weights) from this configuration.\n   *\n   * The config of a layer does not include connectivity\n   * information, nor the layer class name.  These are handled\n   * by 'Container' (one layer of abstraction above).\n   *\n   * Porting Note: The TS dictionary follows TS naming standards for\n   * keys, and uses tfjs-layers type-safe Enums.  Serialization methods\n   * should use a helper function to convert to the pythonic storage\n   * standard. (see serialization_utils.convertTsToPythonic)\n   *\n   * @returns TS dictionary of configuration.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  getConfig() {\n    const l = { name: this.name, trainable: this.trainable };\n    return this.batchInputShape != null && (l.batchInputShape = this.batchInputShape), this.dtype != null && (l.dtype = this.dtype), l;\n  }\n  /**\n   * Dispose the weight variables that this Layer instance holds.\n   *\n   * @returns {number} Number of disposed variables.\n   */\n  disposeWeights() {\n    return this.weights.forEach((l) => l.dispose()), this.weights.length;\n  }\n  assertNotDisposed() {\n    if (this._refCount === 0)\n      throw new Error(`Layer '${this.name}' is already disposed.`);\n  }\n  /**\n   * Attempt to dispose layer's weights.\n   *\n   * This method decreases the reference count of the Layer object by 1.\n   *\n   * A Layer is reference-counted. Its reference count is incremented by 1\n   * the first item its `apply()` method is called and when it becomes a part\n   * of a new `Node` (through calling the `apply()` method on a\n   * `tf.SymbolicTensor`).\n   *\n   * If the reference count of a Layer becomes 0, all the weights will be\n   * disposed and the underlying memory (e.g., the textures allocated in WebGL)\n   * will be freed.\n   *\n   * Note: If the reference count is greater than 0 after the decrement, the\n   * weights of the Layer will *not* be disposed.\n   *\n   * After a Layer is disposed, it cannot be used in calls such as `apply()`,\n   * `getWeights()` or `setWeights()` anymore.\n   *\n   * @returns A DisposeResult Object with the following fields:\n   *   - refCountAfterDispose: The reference count of the Container after this\n   *     `dispose()` call.\n   *   - numDisposedVariables: Number of `tf.Variable`s (i.e., weights) disposed\n   *     during this `dispose()` call.\n   * @throws {Error} If the layer is not built yet, or if the layer has already\n   *   been disposed.\n   *\n   * @doc {heading: 'Models', 'subheading': 'Classes'}\n   */\n  dispose() {\n    if (!this.built)\n      throw new Error(`Cannot dispose Layer ${this.name} because it has not been built yet.`);\n    if (this._refCount === null)\n      throw new Error(`Cannot dispose Layer ${this.name} because it has not been used yet.`);\n    this.assertNotDisposed();\n    let l = 0;\n    return --this._refCount === 0 && (l = this.disposeWeights()), { refCountAfterDispose: this._refCount, numDisposedVariables: l };\n  }\n}\nfunction EF(I) {\n  I = Jl(I);\n  const l = [];\n  for (const G of I)\n    l.push(G.shape);\n  return kG(l);\n}\nfunction xF(I) {\n  return \"float32\";\n}\nfunction ds(I, l, G) {\n  if ((l == null || G != null && G > 0) && (l = I.sourceLayer, G = I.nodeIndex), l.inboundNodes.length === 0)\n    return [I];\n  {\n    const Z = l.inboundNodes[G];\n    if (Z.inboundLayers.length === 0)\n      return Z.inputTensors;\n    {\n      const h = [];\n      for (let g = 0; g < Z.inboundLayers.length; g++) {\n        const b = Z.inputTensors[g], c = Z.inboundLayers[g], d = Z.nodeIndices[g], W = ds(b, c, d);\n        for (const Y of W)\n          h.indexOf(Y) === -1 && h.push(Y);\n      }\n      return h;\n    }\n  }\n}\nfunction UF(I) {\n  let l = !0;\n  for (const G of Jl(I))\n    if (!(G instanceof DI)) {\n      l = !1;\n      break;\n    }\n  return l;\n}\nfunction HF(I) {\n  let l = !0;\n  for (const G of Jl(I))\n    if (G instanceof DI) {\n      l = !1;\n      break;\n    }\n  return l;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass Gb extends ul {\n  constructor(l) {\n    if (super({\n      dtype: l.dtype,\n      name: l.name != null ? l.name : od(\"input\").toString()\n    }), l.batchSize == null && (l.batchSize = null), l.sparse == null && (l.sparse = !1), this.trainable = !1, this.built = !0, this.sparse = l.sparse, l.inputShape != null && l.batchInputShape != null)\n      throw new y(\"Only provide the inputShape OR batchInputShape argument to inputLayer, not both at the same time.\");\n    let G = l.batchInputShape;\n    if (G == null) {\n      if (l.inputShape == null)\n        throw new y(\"An InputLayer should be passed either a `batchInputShape` or an `inputShape`.\");\n      G = [l.batchSize].concat(l.inputShape);\n    } else if (l.batchSize != null)\n      throw new y(\"Cannot specify batchSize if batchInputShape is specified when creating an InputLayer.\");\n    const Z = l.dtype || \"float32\";\n    this.batchInputShape = G, this.dtype = Z, this.inputSpec = [{ shape: G }];\n    const h = new DI(this.dtype, this.batchInputShape, this, [], {}, this.name);\n    h.nodeIndex = 0, h.tensorIndex = 0, new nd({\n      outboundLayer: this,\n      inboundLayers: [],\n      nodeIndices: [],\n      tensorIndices: [],\n      inputTensors: [h],\n      outputTensors: [h],\n      inputMasks: [null],\n      outputMasks: [null],\n      inputShapes: [G],\n      outputShapes: [G]\n    });\n  }\n  apply(l, G) {\n    throw new y(`Cannot pass any input to an InputLayer's apply() method. InputLayer name: ${this.name}`);\n  }\n  dispose() {\n    return { refCountAfterDispose: this._refCount, numDisposedVariables: 0 };\n  }\n  getConfig() {\n    return {\n      batchInputShape: this.batchInputShape,\n      dtype: this.dtype,\n      sparse: this.sparse,\n      name: this.name\n    };\n  }\n}\nGb.className = \"InputLayer\";\nj(Gb);\nfunction KF(I) {\n  if (I.batchShape == null && I.shape == null)\n    throw new Error(\"Please provide to Input either a `shape` or a `batchShape` argument. Note that `shape` does not include the batch dimension.\");\n  if (I.batchShape != null && I.shape != null)\n    throw new y(\"Please provide either a `shape` or `batchShape` argument to Input, but not both.\");\n  let l = I.batchShape;\n  I.shape != null && l == null && (l = [null].concat(I.shape));\n  let G = I.dtype;\n  return G == null && (G = \"float32\"), new Gb({\n    batchInputShape: l,\n    name: I.name,\n    dtype: G,\n    sparse: I.sparse\n  }).inboundNodes[0].outputTensors[0];\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction AF(I, l) {\n  if (I.dtype == null || I.dtype === l.dtype)\n    return l;\n  try {\n    return hl(l, I.dtype);\n  } catch {\n    throw new y(`The dtype of the feed (${l.dtype}) can not be cast to the dtype of the key '${I.name}' (${I.dtype}).`);\n  }\n}\nclass BZ {\n  /**\n   * Constructor, optionally does copy-construction.\n   * @param feeds An Array of `Feed`s, or another `FeedDict`, in which case\n   *   copy-construction will be performed.\n   */\n  constructor(l) {\n    if (this.id2Value = {}, this.id2Mask = {}, this.name2Id = {}, l instanceof BZ)\n      for (const G in l.id2Value)\n        this.id2Value[G] = l.id2Value[G], G in l.id2Mask && (this.id2Mask[G] = l.id2Mask[G]);\n    else {\n      if (l == null)\n        return;\n      for (const G of l)\n        this.add(G.key, G.value);\n    }\n  }\n  /**\n   * Add a key-value pair to the FeedDict.\n   *\n   * @param key The key of the feed.\n   * @param value The value of the tensor feed.\n   * @param mask The value of the mask feed (optional).\n   * @returns This `FeedDict`.\n   * @throws ValueError: If the key `SymbolicTensor` already exists in the\n   *   `FeedDict`.\n   */\n  add(l, G, Z) {\n    if (this.id2Value[l.id] == null)\n      this.id2Value[l.id] = AF(l, G), this.name2Id[l.name] = l.id, Z != null && (this.id2Mask[l.id] = Z);\n    else\n      throw new y(`Duplicate key: name=${l.name}, id=${l.id}`);\n    return this;\n  }\n  /**\n   * Add a Feed to the FeedDict.\n   * @param feed The new `Feed` to add.\n   * @returns This `FeedDict`.\n   */\n  addFeed(l) {\n    this.add(l.key, l.value);\n  }\n  /**\n   * Probe whether a key already exists in the FeedDict.\n   * @param key\n   */\n  hasKey(l) {\n    return this.id2Value[l.id] != null;\n  }\n  /**\n   * Get all the SymbolicTensor available in this FeedDict.\n   */\n  names() {\n    return Object.keys(this.name2Id);\n  }\n  /**\n   * Get the feed value for given key.\n   * @param key The SymbolicTensor, or its name (as a string), of which the\n   *     value is sought.\n   * @returns If `key` exists, the corresponding feed value.\n   * @throws ValueError: If `key` does not exist in this `FeedDict`.\n   */\n  getValue(l) {\n    if (l instanceof DI) {\n      if (this.id2Value[l.id] == null)\n        throw new y(`Nonexistent key: ${l.name}`);\n      return this.id2Value[l.id];\n    } else {\n      const G = this.name2Id[l];\n      if (G == null)\n        throw new y(`Feed dict has no SymbolicTensor name: ${l}`);\n      return this.id2Value[G];\n    }\n  }\n  /**\n   * Get the feed mask for given key.\n   * @param key The SymbolicTensor, or its name (as a string), of which the\n   *     value is sought.\n   * @returns If `key` exists, the corresponding feed mask.\n   * @throws ValueError: If `key` does not exist in this `FeedDict`.\n   */\n  getMask(l) {\n    if (l instanceof DI) {\n      if (this.id2Value[l.id] == null)\n        throw new y(`Nonexistent key: ${l.name}`);\n      return this.id2Mask[l.id];\n    } else {\n      const G = this.name2Id[l];\n      if (G == null)\n        throw new y(`Feed dict has no SymbolicTensor name: ${l}`);\n      return this.id2Mask[G];\n    }\n  }\n  /** Dispose all mask Tensors held by this object. */\n  disposeMasks() {\n    this.id2Mask != null && Cl(this.id2Mask);\n  }\n}\nconst wb = new vT(), Qb = new vT();\nfunction kF(I) {\n  wb != null && wb.setMaxEntries(I), Qb != null && Qb.setMaxEntries(I);\n}\nfunction S0(I, l, G, Z) {\n  const h = G == null ? !1 : G.training, g = Array.isArray(I), b = g ? I : [I], c = b.map((m) => m.name), d = [], W = l.names();\n  for (const m of c)\n    W.indexOf(m) !== -1 ? d.push(l.getValue(m)) : d.push(null);\n  const Y = c.join(\",\") + \"|\" + l.names().sort().join(\",\");\n  let V = wb.get(Y), a;\n  if (V == null) {\n    const m = zF(b, l);\n    V = m.sorted, a = m.recipientCounts, wb.put(Y, V), Qb.put(Y, a);\n  }\n  a = {}, h || Object.assign(a, Qb.get(Y));\n  const i = new BZ(l);\n  for (let m = 0; m < V.length; ++m) {\n    const T = V[m], s = T.sourceLayer;\n    if (s instanceof Gb)\n      continue;\n    const o = [], B = [], C = [];\n    let n = !1;\n    for (const p of T.inputs) {\n      const F = i.getValue(p), x = i.getMask(p);\n      o.push(F), B.push(x), x != null && (n = !0), h || (a[p.name]--, a[p.name] === 0 && !l.hasKey(p) && c.indexOf(p.name) === -1 && !F.isDisposed && p.sourceLayer.stateful !== !0 && C.push(F));\n    }\n    n && (G = G || {}, G.mask = B[0]);\n    const X = Jl(s.apply(o, G));\n    let t = null;\n    s.supportsMasking && (t = s.computeMask(o, B));\n    const e = MF(T), S = Array.isArray(e) ? e : [e];\n    for (let p = 0; p < S.length; ++p) {\n      i.hasKey(S[p]) || i.add(S[p], X[p], Array.isArray(t) ? t[0] : t);\n      const F = c.indexOf(S[p].name);\n      F !== -1 && (d[F] = X[p]);\n    }\n    h || Cl(C);\n  }\n  return i.disposeMasks(), g ? d : d[0];\n}\nfunction zF(I, l) {\n  u(I != null && I.length > 0, () => \"Expected at least one fetch, got none\");\n  let G = [], Z = {};\n  if (I.length === 1) {\n    const h = Ca(I[0], l);\n    G = h.sorted, Z = h.recipientMap;\n  } else {\n    const h = /* @__PURE__ */ new Set();\n    for (const g of I) {\n      const { sorted: b, recipientMap: c } = Ca(g, l);\n      for (const d of b)\n        h.has(d.name) || (G.push(d), h.add(d.name));\n      for (const d in c)\n        Z[d] == null && (Z[d] = /* @__PURE__ */ new Set()), c[d].forEach((W) => Z[d].add(W));\n    }\n  }\n  return {\n    sorted: G,\n    recipientCounts: LF(Z)\n  };\n}\nfunction LF(I) {\n  const l = {};\n  for (const G in I)\n    l[G] = I[G].size;\n  return l;\n}\nfunction Ca(I, l) {\n  const G = /* @__PURE__ */ new Set(), Z = [], h = {};\n  for (const c of l.names())\n    G.add(c);\n  const g = [], b = [];\n  for (g.push(I); g.length > 0; ) {\n    const c = g[g.length - 1];\n    if (G.has(c.name)) {\n      g.pop();\n      continue;\n    }\n    const d = b[b.length - 1] === g.length - 1;\n    if (c.inputs.length === 0 || d)\n      g.pop(), Z.push(c), G.add(c.name), d && b.pop();\n    else {\n      b.push(g.length - 1);\n      for (const W of c.inputs)\n        h[W.name] == null && (h[W.name] = /* @__PURE__ */ new Set()), h[W.name].add(c.name), !G.has(W.name) && g.push(W);\n    }\n  }\n  return { sorted: Z, recipientMap: h };\n}\nfunction MF(I) {\n  let l;\n  if (I.sourceLayer.inboundNodes.length === 1)\n    l = I.sourceLayer.output;\n  else {\n    let G = null;\n    for (let Z = 0; Z < I.sourceLayer.inboundNodes.length; ++Z)\n      for (const h of I.sourceLayer.inboundNodes[Z].outputTensors)\n        if (h.id === I.id) {\n          G = Z;\n          break;\n        }\n    l = I.sourceLayer.getOutputAt(G);\n  }\n  return l;\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst wF = A();\nwF.registerFlag(\"TOPOLOGICAL_SORT_CACHE_MAX_ENTRIES\", () => 100, kF);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction b9(I, l) {\n  return U(() => RG(Yl(N(I, I), l, !0)));\n}\nclass Ib extends c0 {\n  getConfig() {\n    return {};\n  }\n}\nclass Ws extends Ib {\n  constructor(l) {\n    super(), this.defaultMaxValue = 2, this.defaultAxis = 0, this.maxValue = l.maxValue != null ? l.maxValue : this.defaultMaxValue, this.axis = l.axis != null ? l.axis : this.defaultAxis;\n  }\n  apply(l) {\n    return U(() => {\n      const G = b9(l, this.axis), Z = II(G, 0, this.maxValue);\n      return N(l, Vl(Z, O(cG(), G)));\n    });\n  }\n  getConfig() {\n    return { maxValue: this.maxValue, axis: this.axis };\n  }\n}\nWs.className = \"MaxNorm\";\nj(Ws);\nclass Ys extends Ib {\n  constructor(l) {\n    super(), this.defaultAxis = 0, this.axis = l.axis != null ? l.axis : this.defaultAxis;\n  }\n  apply(l) {\n    return U(() => Vl(l, O(cG(), b9(l, this.axis))));\n  }\n  getConfig() {\n    return { axis: this.axis };\n  }\n}\nYs.className = \"UnitNorm\";\nj(Ys);\nclass Vs extends Ib {\n  apply(l) {\n    return th(l);\n  }\n}\nVs.className = \"NonNeg\";\nj(Vs);\nclass as extends Ib {\n  constructor(l) {\n    super(), this.defaultMinValue = 0, this.defaultMaxValue = 1, this.defaultRate = 1, this.defaultAxis = 0, this.minValue = l.minValue != null ? l.minValue : this.defaultMinValue, this.maxValue = l.maxValue != null ? l.maxValue : this.defaultMaxValue, this.rate = l.rate != null ? l.rate : this.defaultRate, this.axis = l.axis != null ? l.axis : this.defaultAxis;\n  }\n  apply(l) {\n    return U(() => {\n      const G = b9(l, this.axis), Z = O(N(this.rate, II(G, this.minValue, this.maxValue)), N(1 - this.rate, G));\n      return N(l, Vl(Z, O(cG(), G)));\n    });\n  }\n  getConfig() {\n    return {\n      minValue: this.minValue,\n      maxValue: this.maxValue,\n      rate: this.rate,\n      axis: this.axis\n    };\n  }\n}\nas.className = \"MinMaxNorm\";\nj(as);\nconst Xa = {\n  maxNorm: \"MaxNorm\",\n  minMaxNorm: \"MinMaxNorm\",\n  nonNeg: \"NonNeg\",\n  unitNorm: \"UnitNorm\"\n};\nfunction WG(I) {\n  return fV(I);\n}\nfunction ta(I, l = {}) {\n  return qg(I, dI.getMap().classNameMap, l, \"constraint\");\n}\nfunction YG(I) {\n  if (I == null)\n    return null;\n  if (typeof I == \"string\") {\n    const G = { className: I in Xa ? Xa[I] : I, config: {} };\n    return ta(G);\n  } else return I instanceof Ib ? I : ta(I);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nasync function QZ(I) {\n  if (I == null)\n    return;\n  const l = [], G = [], Z = [];\n  for (const h in I) {\n    const g = I[h];\n    if (typeof g != \"number\") {\n      const b = g;\n      l.push(b.data()), G.push(h), Z.push(b);\n    }\n  }\n  if (l.length > 0) {\n    const h = await Promise.all(l);\n    for (let g = 0; g < h.length; ++g)\n      I[G[g]] = h[g][0];\n    Cl(Z);\n  }\n}\nfunction is(I) {\n  if (I != null)\n    for (const l in I) {\n      const G = I[l];\n      typeof G != \"number\" && G.dispose();\n    }\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nvar ua;\n(function(I) {\n  I[I.SILENT = 0] = \"SILENT\", I[I.VERBOSE = 1] = \"VERBOSE\";\n})(ua || (ua = {}));\nconst QF = 125;\nclass H0 {\n  constructor() {\n    this.validationData = null;\n  }\n  setParams(l) {\n    this.params = l;\n  }\n  async onEpochBegin(l, G) {\n  }\n  async onEpochEnd(l, G) {\n  }\n  async onBatchBegin(l, G) {\n  }\n  async onBatchEnd(l, G) {\n  }\n  async onTrainBegin(l) {\n  }\n  async onTrainEnd(l) {\n  }\n  // LayersModel needs to call Callback.setModel(), but cannot actually depend\n  // on Callback because that creates a cyclic dependency.  Providing this no-op\n  // method on BaseCallback breaks the cycle: this way LayersModel can depend on\n  // BaseCallback but not on Callback.  The argument is typed as `Container`\n  // (the superclass of LayersModel) to avoid recapitulating the cycle. Callback\n  // overrides this method and enforces that the argument is really a\n  // LayersModel.\n  setModel(l) {\n  }\n}\nclass vF {\n  // TODO(cais): When the need arises, uncomment the following lines and\n  // implement the queue for time values.\n  // private deltaTBatch: number;\n  // private deltaTsBatchBegin: Array<number>;\n  // private deltaTsBatchEnd: Array<number>;\n  /**\n   * Constructor of CallbackList.\n   * @param callbacks Array of `Callback` instances.\n   * @param queueLength Queue length for keeping running statistics over\n   *   callback execution time.\n   */\n  constructor(l, G = 10) {\n    l == null && (l = []), this.callbacks = l, this.queueLength = G;\n  }\n  append(l) {\n    this.callbacks.push(l);\n  }\n  setParams(l) {\n    for (const G of this.callbacks)\n      G.setParams(l);\n  }\n  setModel(l) {\n    for (const G of this.callbacks)\n      G.setModel(l);\n  }\n  /**\n   * Called at the start of an epoch.\n   * @param epoch Index of epoch.\n   * @param logs Dictionary of logs.\n   */\n  async onEpochBegin(l, G) {\n    G == null && (G = {});\n    for (const Z of this.callbacks)\n      await Z.onEpochBegin(l, G);\n  }\n  /**\n   * Called at the end of an epoch.\n   * @param epoch Index of epoch.\n   * @param logs Dictionary of logs.\n   */\n  async onEpochEnd(l, G) {\n    G == null && (G = {});\n    for (const Z of this.callbacks)\n      await Z.onEpochEnd(l, G);\n  }\n  /**\n   * Called  right before processing a batch.\n   * @param batch Index of batch within the current epoch.\n   * @param logs Dictionary of logs.\n   */\n  async onBatchBegin(l, G) {\n    G == null && (G = {});\n    for (const Z of this.callbacks)\n      await Z.onBatchBegin(l, G);\n  }\n  /**\n   * Called at the end of a batch.\n   * @param batch Index of batch within the current epoch.\n   * @param logs Dictionary of logs.\n   */\n  async onBatchEnd(l, G) {\n    G == null && (G = {});\n    for (const Z of this.callbacks)\n      await Z.onBatchEnd(l, G);\n  }\n  /**\n   * Called at the beginning of training.\n   * @param logs Dictionary of logs.\n   */\n  async onTrainBegin(l) {\n    l == null && (l = {});\n    for (const G of this.callbacks)\n      await G.onTrainBegin(l);\n  }\n  /**\n   * Called at the end of training.\n   * @param logs Dictionary of logs.\n   */\n  async onTrainEnd(l) {\n    l == null && (l = {});\n    for (const G of this.callbacks)\n      await G.onTrainEnd(l);\n  }\n}\nclass rF extends H0 {\n  constructor() {\n    super();\n  }\n  async onEpochBegin(l) {\n    this.seen = 0, this.totals = {};\n  }\n  async onBatchEnd(l, G) {\n    G == null && (G = {});\n    const Z = G.size == null ? 0 : G.size;\n    this.seen += Z;\n    for (const h in G) {\n      const g = G[h];\n      if (typeof g == \"number\")\n        this.totals.hasOwnProperty(h) || (this.totals[h] = 0), this.totals[h] = this.totals[h] + g * Z;\n      else {\n        let b;\n        h in this.totals ? b = this.totals[h] : this.totals[h] = 0;\n        const c = U(() => O(this.totals[h], N(g, Z)));\n        this.totals[h] = c, b != null && b.dispose();\n      }\n    }\n  }\n  async onEpochEnd(l, G) {\n    if (G != null)\n      for (const Z of this.params.metrics)\n        this.totals[Z] != null && (typeof this.totals[Z] == \"number\" ? G[Z] = this.totals[Z] / this.seen : U(() => {\n          const h = N(Vl(1, this.seen), this.totals[Z]);\n          G[Z] = h, this.totals[Z].dispose(), LI(G[Z]);\n        }));\n  }\n}\nclass jF extends H0 {\n  async onTrainBegin(l) {\n    this.epoch = [], this.history = {};\n  }\n  async onEpochEnd(l, G) {\n    G == null && (G = {}), this.epoch.push(l);\n    for (const Z in G)\n      this.history[Z] == null && (this.history[Z] = []), this.history[Z].push(G[Z]);\n  }\n  /**\n   * Await the values of all losses and metrics.\n   */\n  async syncData() {\n    const l = [], G = [], Z = [];\n    for (const g in this.history) {\n      const b = this.history[g];\n      for (let c = 0; c < b.length; ++c)\n        if (typeof b[c] != \"number\") {\n          const d = b[c];\n          l.push(d.data()), G.push(g), Z.push(c);\n        }\n    }\n    const h = await Promise.all(l);\n    for (let g = 0; g < h.length; ++g)\n      this.history[G[g]][Z[g]].dispose(), this.history[G[g]][Z[g]] = h[g][0];\n  }\n}\nclass DF extends H0 {\n  constructor(l, G) {\n    if (super(), this.currentEpoch = 0, this.nowFunc = l.nowFunc, this.nextFrameFunc = l.nextFrameFunc || BT, this.yieldEvery = G || \"auto\", this.yieldEvery === \"auto\" && (this.yieldEvery = QF), this.yieldEvery === \"never\" && l.onYield != null)\n      throw new Error(\"yieldEvery is `never` but you provided an `onYield` callback. Either change `yieldEvery` or remove the callback\");\n    IW(this.yieldEvery) && (this.maybeWait = cF(this.maybeWait.bind(this), this.yieldEvery, this.nowFunc)), this.trainBegin = l.onTrainBegin, this.trainEnd = l.onTrainEnd, this.epochBegin = l.onEpochBegin, this.epochEnd = l.onEpochEnd, this.batchBegin = l.onBatchBegin, this.batchEnd = l.onBatchEnd, this.yield = l.onYield;\n  }\n  async maybeWait(l, G, Z) {\n    const h = [];\n    this.yield != null && (await QZ(Z), h.push(this.yield(l, G, Z))), h.push(this.nextFrameFunc()), await Promise.all(h);\n  }\n  async onEpochBegin(l, G) {\n    this.currentEpoch = l, this.epochBegin != null && (await QZ(G), await this.epochBegin(l, G));\n  }\n  async onEpochEnd(l, G) {\n    const Z = [];\n    this.epochEnd != null && (await QZ(G), Z.push(this.epochEnd(l, G))), this.yieldEvery === \"epoch\" && Z.push(this.nextFrameFunc()), await Promise.all(Z);\n  }\n  async onBatchBegin(l, G) {\n    this.batchBegin != null && (await QZ(G), await this.batchBegin(l, G));\n  }\n  async onBatchEnd(l, G) {\n    const Z = [];\n    this.batchEnd != null && (await QZ(G), Z.push(this.batchEnd(l, G))), this.yieldEvery === \"batch\" ? Z.push(this.nextFrameFunc()) : IW(this.yieldEvery) && Z.push(this.maybeWait(this.currentEpoch, l, G)), await Promise.all(Z);\n  }\n  async onTrainBegin(l) {\n    this.trainBegin != null && (await QZ(l), await this.trainBegin(l));\n  }\n  async onTrainEnd(l) {\n    this.trainEnd != null && (await QZ(l), await this.trainEnd(l));\n  }\n}\nfunction ms(I, l) {\n  return I == null && (I = {}), I instanceof H0 ? [I] : Array.isArray(I) && I[0] instanceof H0 ? I : Jl(I).map((Z) => new DF(Z, l));\n}\nclass cI {\n  /**\n   * Blocks public access to constructor.\n   */\n  constructor() {\n  }\n  /**\n   * Register a tf.LayersModel.fit() callback constructor.\n   *\n   * The registered callback constructor will be used to instantiate\n   * callbacks for every tf.LayersModel.fit() call afterwards.\n   *\n   * @param verbosityLevel Level of verbosity at which the `callbackConstructor`\n   *   is to be reigstered.\n   * @param callbackConstructor A no-arg constructor for `tf.Callback`.\n   * @throws Error, if the same callbackConstructor has been registered before,\n   *   either at the same or a different `verbosityLevel`.\n   */\n  static registerCallbackConstructor(l, G) {\n    u(l >= 0 && Number.isInteger(l), () => `Verbosity level is expected to be an integer >= 0, but got ${l}`), cI.checkForDuplicate(G), cI.constructors[l] == null && (cI.constructors[l] = []), cI.constructors[l].push(G);\n  }\n  static checkForDuplicate(l) {\n    for (const G in cI.constructors)\n      cI.constructors[+G].forEach((h) => {\n        if (h === l)\n          throw new y(\"Duplicate callback constructor.\");\n      });\n  }\n  /**\n   * Clear all registered callback constructors.\n   */\n  static clear() {\n    cI.constructors = {};\n  }\n  /**\n   * Create callbacks using the registered callback constructors.\n   *\n   * Given `verbosityLevel`, all constructors registered at that level or above\n   * will be called and the instantiated callbacks will be used.\n   *\n   * @param verbosityLevel: Level of verbosity.\n   */\n  static createCallbacks(l) {\n    const G = [];\n    for (const Z in cI.constructors) {\n      const h = +Z;\n      l >= h && G.push(...cI.constructors[h]);\n    }\n    return G.map((Z) => new Z());\n  }\n}\ncI.constructors = {};\nfunction Ts(I, l, G, Z, h, g, b, c, d) {\n  const W = new jF(), Y = [\n    new rF(),\n    ...cI.createCallbacks(l)\n  ];\n  I != null && Y.push(...I), Y.push(W);\n  const V = new vF(Y);\n  return V.setParams({\n    epochs: G,\n    initialEpoch: Z,\n    samples: h,\n    steps: g,\n    batchSize: b,\n    verbose: l,\n    doValidation: c,\n    metrics: d\n  }), { callbackList: V, history: W };\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction ZZ(I, l = {}, G = !1) {\n  return qg(I, dI.getMap().classNameMap, l, \"layer\", G);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction vb(I, l) {\n  return U(() => {\n    I.dtype !== \"float32\" && (I = hl(I, \"float32\"));\n    const G = Yl(_g(I), l, !0), Z = Wd(G.shape, cG()), h = RG(UZ(G, Z));\n    return Vl(I, h);\n  });\n}\nfunction Cd(I, l) {\n  return U(() => gG(_g(ml(l, I)), -1));\n}\nfunction c9(I, l) {\n  return U(() => gG(PG(ml(l, I)), -1));\n}\nfunction d9(I, l) {\n  return U(() => {\n    const G = ml(I, l), Z = II(PG(I), cG(), Number.MAX_VALUE), h = PG(Vl(G, Z));\n    return N(100, gG(h, -1));\n  });\n}\nfunction fF(I, l) {\n  return U(() => {\n    const G = II(l, cG(), Number.MAX_VALUE), Z = jI(O(1, G)), h = II(I, cG(), Number.MAX_VALUE), g = jI(O(1, h));\n    return gG(_g(ml(Z, g)), -1);\n  });\n}\nfunction OF(I, l) {\n  return U(() => {\n    const G = UZ(0, ml(1, N(I, l)));\n    return gG(_g(G), -1);\n  });\n}\nfunction qF(I, l) {\n  return U(() => {\n    const G = UZ(0, ml(1, N(I, l)));\n    return gG(G, -1);\n  });\n}\nfunction $F(I, l) {\n  return U(() => {\n    const G = Yl(N(I, l), -1), Z = RI(N(ml(1, I), l), -1);\n    return UZ(0, O(1, ml(Z, G)));\n  });\n}\nfunction _F(I, l) {\n  return U(() => {\n    const G = Math.log(2), Z = ml(l, I), h = ml(O(Z, Qg(N(-2, Z))), G);\n    return gG(h, -1);\n  });\n}\nfunction K0(I, l, G = !1) {\n  return U(() => {\n    if (G)\n      l = aV(l);\n    else {\n      const Z = Yl(l, l.shape.length - 1, !0);\n      l = Vl(l, Z);\n    }\n    return l = II(l, cG(), 1 - cG()), _l(Yl(N(hl(I, \"float32\"), jI(l)), l.shape.length - 1));\n  });\n}\nfunction rb(I, l, G = !1) {\n  return U(() => {\n    const Z = hl(ad(nF(I)), \"int32\");\n    l = II(l, cG(), 1 - cG());\n    const h = l.shape, g = J(zm(Z, h[h.length - 1]), h);\n    return K0(g, l, G);\n  });\n}\nfunction ly(I, l) {\n  if (!Nl(I.shape, l.shape))\n    throw new y(`logits and labels must have the same shape, but got shapes ${JSON.stringify(I.shape)} and ${JSON.stringify(l.shape)}`);\n  return U(() => {\n    const G = th(l), Z = _l(PG(l));\n    return O(ml(G, N(l, I)), Hm(rI(Z)));\n  });\n}\nfunction Xd(I, l) {\n  return U(() => {\n    let G;\n    return G = II(l, cG(), 1 - cG()), G = jI(Vl(G, ml(1, G))), gG(ly(I, G), -1);\n  });\n}\nfunction Gy(I, l) {\n  return U(() => {\n    const G = II(I, cG(), 1), Z = II(l, cG(), 1);\n    return Yl(N(I, jI(Vl(G, Z))), -1);\n  });\n}\nfunction Iy(I, l) {\n  return U(() => {\n    const G = jI(O(cG(), l));\n    return gG(ml(l, N(I, G)), -1);\n  });\n}\nfunction ss(I, l) {\n  return U(() => {\n    const G = vb(I, -1), Z = vb(l, -1), h = N(G, Z);\n    return _l(Yl(h, -1));\n  });\n}\nconst jb = {\n  meanSquaredError: Cd,\n  meanAbsoluteError: c9,\n  meanAbsolutePercentageError: d9,\n  meanSquaredLogarithmicError: fF,\n  squaredHinge: OF,\n  hinge: qF,\n  categoricalHinge: $F,\n  logcosh: _F,\n  categoricalCrossentropy: K0,\n  sparseCategoricalCrossentropy: rb,\n  binaryCrossentropy: Xd,\n  kullbackLeiblerDivergence: Gy,\n  poisson: Iy,\n  cosineProximity: ss\n};\nfunction vd(I) {\n  if (typeof I == \"string\") {\n    if (I in jb)\n      return jb[I];\n    let l = `Unknown loss ${I}`;\n    throw I.toLowerCase().includes(\"softmaxcrossentropy\") && (l = `Unknown loss ${I}. Use \"categoricalCrossentropy\" as the string name for tf.losses.softmaxCrossEntropy`), new y(l);\n  } else\n    return I;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction os(I, l) {\n  return U(() => {\n    const G = N(0.5, TI(l)), Z = wI(ZI(l, G), I.dtype);\n    return gG(vI(I, Z), -1);\n  });\n}\nfunction Bs(I, l) {\n  return U(() => wI(vI(P0(I, -1), P0(l, -1)), \"float32\"));\n}\nfunction Zy(I, l) {\n  return U(() => hl(Yl(hZ(vI(I, 1), vI(l, 1))), \"float32\"));\n}\nfunction hy(I, l) {\n  return U(() => hl(Yl(hZ(vI(I, 0), vI(l, 1))), \"float32\"));\n}\nfunction gy(I, l) {\n  return U(() => {\n    const G = Zy(I, l), Z = hy(I, l), h = O(G, Z);\n    return hl(UG(ZI(h, 0), Vl(G, h), 0), \"float32\");\n  });\n}\nfunction by(I, l) {\n  return Xd(I, l);\n}\nfunction cy(I, l) {\n  return I.rank === l.rank && (I = rg(I, [I.rank - 1])), l = P0(l, -1), l.dtype !== I.dtype && (l = hl(l, I.dtype)), hl(vI(I, l), \"float32\");\n}\nconst dy = Cd, Wy = Cd, Yy = c9, Vy = c9, ay = d9, iy = d9, ns = K0, my = ss, Cs = rb, Db = {\n  binaryAccuracy: os,\n  categoricalAccuracy: Bs,\n  precision: gy,\n  categoricalCrossentropy: ns,\n  sparseCategoricalCrossentropy: Cs,\n  mse: dy,\n  MSE: Wy,\n  mae: Yy,\n  MAE: Vy,\n  mape: ay,\n  MAPE: iy,\n  cosine: my\n};\nfunction Ty(I) {\n  if (typeof I == \"string\" && I in Db)\n    return Db[I];\n  if (typeof I != \"string\" && I != null)\n    return I;\n  throw new y(`Unknown metric ${I}`);\n}\nfunction nb(I) {\n  if (KI(I !== null, `Unknown LossOrMetricFn ${I}`), typeof I == \"string\")\n    return I;\n  {\n    let l;\n    for (const G of Object.keys(jb))\n      if (jb[G] === I) {\n        l = G;\n        break;\n      }\n    if (l !== void 0)\n      return l;\n    for (const G of Object.keys(Db))\n      if (Db[G] === I) {\n        l = G;\n        break;\n      }\n    return l !== void 0 ? l : I.name;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction sy(I) {\n  const l = {\n    Adagrad: () => Nh.adagrad(0.01),\n    Adadelta: () => Nh.adadelta(1, 0.95, cG()),\n    Adam: () => Nh.adam(1e-3, 0.9, 0.999, cG()),\n    Adamax: () => Nh.adamax(2e-3, 0.9, 0.999, cG(), 0),\n    RMSProp: () => Nh.rmsprop(1e-3, 0.9, 0, cG()),\n    SGD: () => Nh.sgd(0.01)\n  };\n  if (l.adagrad = l.Adagrad, l.adadelta = l.Adadelta, l.adam = l.Adam, l.adamax = l.Adamax, l.rmsprop = l.RMSProp, l.sgd = l.SGD, I in l)\n    return l[I]();\n  throw new y(`Unknown Optimizer ${I}`);\n}\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst ea = 1 * 1024 * 1024;\nfunction Sa(I, l, G = !1) {\n  if (I == null || typeof I != \"object\" || Object.getPrototypeOf(I) !== Object.prototype || !NW(I))\n    throw new Error(\"User-defined metadata is expected to be a JSON object, but is not.\");\n  if (G) {\n    const Z = JSON.stringify(I);\n    Z.length > ea && console.warn(`User-defined metadata of model \"${l}\" is too large in size (length=${Z.length} when serialized). It is not recommended to store such large objects in user-defined metadata. Please make sure its serialized length is <= ${ea}.`);\n  }\n}\nfunction NW(I) {\n  if (I === null)\n    return !0;\n  if (typeof I == \"object\")\n    if (Object.getPrototypeOf(I) === Object.prototype) {\n      const l = Object.keys(I);\n      for (const G of l)\n        if (typeof G != \"string\" || !NW(I[G]))\n          return !1;\n      return !0;\n    } else if (Array.isArray(I)) {\n      for (const l of I)\n        if (!NW(l))\n          return !1;\n      return !0;\n    } else\n      return !1;\n  else {\n    const l = typeof I;\n    return l === \"string\" || l === \"number\" || l === \"boolean\";\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction oy(I, l, G, Z = console.log) {\n  const h = ny(I), g = [\"Layer (type)\", \"Input Shape\", \"Output shape\", \"Param #\"];\n  h ? (l = l || 90, G = G || [0.32, 0.61, 0.89, 1]) : (l = l || 115, G = G || [0.24, 0.48, 0.7, 0.8, 1]), G[G.length - 1] <= 1 && (G = G.map((Y) => Math.floor(l * Y)));\n  let b;\n  if (!h) {\n    g.push(\"Receives inputs\"), b = [];\n    for (const Y in I.nodesByDepth)\n      b.push(...I.nodesByDepth[Y]);\n  }\n  Z(\"_\".repeat(l)), fb(g, G, Z), Z(\"=\".repeat(l));\n  const c = I.layers;\n  for (let Y = 0; Y < c.length; ++Y)\n    h ? Cy(c[Y], G, Z) : Xy(c[Y], G, b, Z), Z((Y === c.length - 1 ? \"=\" : \"_\").repeat(l));\n  I.checkTrainableWeightsConsistency();\n  const d = By(I), W = Mb(I.nonTrainableWeights);\n  Z(`Total params: ${d + W}`), Z(`Trainable params: ${d}`), Z(`Non-trainable params: ${W}`), Z(\"_\".repeat(l));\n}\nfunction By(I) {\n  let l;\n  return I.collectedTrainableWeights != null ? l = Mb(I.collectedTrainableWeights) : l = Mb(I.trainableWeights), l;\n}\nfunction ny(I) {\n  let l = !0;\n  const G = [], Z = [];\n  for (const h in I.nodesByDepth)\n    G.push(I.nodesByDepth[h]);\n  for (const h of G) {\n    if (h.length > 1 || h.length === 1 && h[0].inboundLayers.length > 1) {\n      l = !1;\n      break;\n    }\n    Z.push(...h);\n  }\n  if (l)\n    for (const h of I.layers) {\n      let g = !1;\n      for (const b of h.inboundNodes)\n        if (Z.indexOf(b) !== -1)\n          if (g) {\n            l = !1;\n            break;\n          } else\n            g = !0;\n      if (!l)\n        break;\n    }\n  return l;\n}\nfunction fb(I, l, G = console.log) {\n  let Z = \"\";\n  for (let h = 0; h < I.length; ++h)\n    h > 0 && (Z = Z.slice(0, Z.length - 1) + \" \"), Z += I[h], Z = Z.slice(0, l[h]), Z += \" \".repeat(l[h] - Z.length);\n  G(Z);\n}\nfunction Cy(I, l, G) {\n  let Z, h;\n  try {\n    h = I.inboundNodes.map((d) => JSON.stringify(d.inputShapes)).join(\",\");\n  } catch {\n    h = \"multiple\";\n  }\n  try {\n    Z = JSON.stringify(I.outputShape);\n  } catch {\n    Z = \"multiple\";\n  }\n  const g = I.name, b = I.getClassName(), c = [\n    `${g} (${b})`,\n    h,\n    Z,\n    I.countParams().toString()\n  ];\n  fb(c, l, G);\n}\nfunction Xy(I, l, G, Z) {\n  let h, g;\n  try {\n    g = I.inboundNodes.map((V) => JSON.stringify(V.inputShapes)).join(\",\");\n  } catch {\n    g = \"multiple\";\n  }\n  try {\n    h = JSON.stringify(I.outputShape);\n  } catch {\n    h = \"multiple\";\n  }\n  const b = [];\n  for (const V of I.inboundNodes)\n    if (!(G != null && G.length > 0 && G.indexOf(V) === -1))\n      for (let a = 0; a < V.inboundLayers.length; ++a) {\n        const i = V.inboundLayers[a].name, m = V.nodeIndices[a], T = V.tensorIndices[a];\n        b.push(`${i}[${m}][${T}]`);\n      }\n  const c = I.name, d = I.getClassName(), W = b.length === 0 ? \"\" : b[0], Y = [\n    `${c} (${d})`,\n    g,\n    h,\n    I.countParams().toString(),\n    W\n  ];\n  fb(Y, l, Z);\n  for (let V = 1; V < b.length; ++V)\n    fb([\"\", \"\", \"\", \"\", b[V]], l, Z);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Xs(I, l, G) {\n  return (I === \"inboundNodes\" || I === \"outputLayers\" || I === \"inputLayers\") && l === 0 && typeof G == \"string\";\n}\nfunction PW(I, l) {\n  if (I === null)\n    return null;\n  if (typeof I == \"string\")\n    return DZ(I);\n  if (typeof I == \"number\" || typeof I == \"boolean\")\n    return I;\n  if (I instanceof Array) {\n    const G = [], Z = I.length;\n    for (let h = 0; h < Z; ++h) {\n      const g = I[h];\n      Xs(l, h, g) ? G.push(g) : G.push(PW(g, l));\n    }\n    return G;\n  } else {\n    const G = {};\n    for (const Z of Object.keys(I)) {\n      const h = I[Z];\n      if (Z === \"name\" && typeof h == \"string\")\n        G[Z] = h;\n      else {\n        const g = DZ(Z);\n        G[g] = PW(h, g);\n      }\n    }\n    return G;\n  }\n}\nfunction JW(I, l) {\n  if (I == null)\n    return null;\n  if (typeof I == \"string\")\n    return _I(I);\n  if (typeof I == \"number\" || typeof I == \"boolean\")\n    return I;\n  if (I instanceof Array) {\n    const G = [], Z = I.length;\n    for (let h = 0; h < Z; ++h) {\n      const g = I[h];\n      Xs(l, h, g) ? G.push(g) : G.push(JW(g, l));\n    }\n    return G;\n  } else {\n    const G = {};\n    for (const Z of Object.keys(I)) {\n      const h = I[Z], g = _I(Z);\n      (Z === \"name\" || Z === \"className\") && typeof h == \"string\" ? G[g] = h : G[g] = JW(h, Z);\n    }\n    return G;\n  }\n}\n/** @license See the LICENSE file. */\nconst ts = \"4.21.0\";\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst ty = (I) => {\n  const l = Object.keys(I);\n  if (l.length === 0)\n    return !1;\n  const G = l[0].split(\"/\");\n  return !isNaN(parseInt(G[G.length - 1], 10));\n};\nclass XI extends ul {\n  constructor(l) {\n    if (super({}), this.containerNodes = /* @__PURE__ */ new Set(), this.name = l.name, this.name == null) {\n      const B = this.getClassName().toLowerCase();\n      this.name = od(B);\n    }\n    if (this.supportsMasking = !1, this.trainable_ = !0, Array.isArray(l.inputs) ? this.inputs = l.inputs.slice() : this.inputs = [l.inputs], Array.isArray(l.outputs) ? this.outputs = l.outputs.slice() : this.outputs = [l.outputs], tZ(this.inputs).length !== this.inputs.length)\n      throw new y(`The list of inputs passed to the model is redundant. All inputs should only appear once. Found: ${this.inputs.map((B) => B.name)}`);\n    tZ(this.outputs).length !== this.outputs.length && console.warn(`The list of outputs passed to the model is redundant. All outputs should only appear once. Found: ${this.outputs.map((B) => B.name)}`), this.inputLayers = [], this.inputLayersNodeIndices = [], this.inputLayersTensorIndices = [], this.outputLayers = [], this.outputLayersNodeIndices = [], this.outputLayersTensorIndices = [], this.layers = [], this.internalContainerRefs = [];\n    for (const B of this.outputs) {\n      const C = B.sourceLayer, n = B.nodeIndex, X = B.tensorIndex;\n      this.outputLayers.push(C), this.outputLayersNodeIndices.push(n), this.outputLayersTensorIndices.push(X);\n    }\n    for (const B of this.inputs) {\n      const C = B.sourceLayer, n = B.nodeIndex, X = B.tensorIndex;\n      KI(n === 0, \"input layer has >1 nodes\"), KI(X === 0, \"input layer has >1 tensors\"), this.inputLayers.push(C), this.inputLayersNodeIndices.push(n), this.inputLayersTensorIndices.push(X);\n    }\n    this.inputNames = [], this.outputNames = [], this.feedInputShapes = [], this.feedInputNames = [], this.feedOutputNames = [];\n    for (let B = 0; B < this.inputLayers.length; B++) {\n      const C = this.inputLayers[B];\n      if (!(C instanceof Gb))\n        throw new TypeError(`Input layers to a LayersModel must be InputLayer objects. Received inputs: ${l.inputs}. Input ${B} (0-based) originates from layer type ${C.getClassName()}.`);\n      this.inputNames.push(C.name), this.feedInputShapes.push(C.batchInputShape), this.feedInputNames.push(C.name);\n    }\n    for (const B of this.outputLayers)\n      this.outputNames.push(B.name);\n    this.internalInputShapes = this.inputs.map((B) => B.shape), this.internalOutputShapes = this.outputs.map((B) => B.shape);\n    const G = {}, Z = {}, h = {}, g = {}, b = {}, c = [], d = (B, C, n, X, t, e) => {\n      (X == null || t == null || e == null) && (X = B.sourceLayer, t = B.nodeIndex, e = B.tensorIndex);\n      const S = X.inboundNodes[t];\n      if (n.indexOf(S) !== -1)\n        throw new aI(`The tensor ${B.name} at layer \"${X.name}\" is part of a cycle.`);\n      if (C.indexOf(S) !== -1)\n        return;\n      this.containerNodes.add(XI.nodeKey(X, t)), X.id in b || (b[X.id] = Object.keys(b).length), n.indexOf(S) === -1 && n.push(S);\n      const p = S.inboundLayers.length;\n      for (let F = 0; F < p; F++) {\n        const x = S.inputTensors[F], H = S.inboundLayers[F], K = S.nodeIndices[F], z = S.tensorIndices[F];\n        d(x, C, n, H, K, z);\n      }\n      for (C.push(S); n.indexOf(S) >= 0; )\n        n.splice(n.indexOf(S), 1);\n      c.push(S);\n    }, W = [], Y = [];\n    for (const B of this.outputs)\n      d(B, W, Y);\n    const V = c.slice().reverse();\n    for (const B of V) {\n      Z[B.id] = B, B.id in G || (G[B.id] = 0);\n      let C = G[B.id];\n      const n = h[B.outboundLayer.id] == null ? 0 : h[B.outboundLayer.id];\n      C = Math.max(C, n), h[B.outboundLayer.id] = C, g[B.outboundLayer.id] = B.outboundLayer, G[B.id] = C;\n      for (let X = 0; X < B.inboundLayers.length; X++) {\n        const t = B.inboundLayers[X], e = B.nodeIndices[X], S = t.inboundNodes[e], p = G[S.id] == null ? 0 : G[S.id];\n        G[S.id] = Math.max(C + 1, p), Z[S.id] = S;\n      }\n    }\n    const a = {};\n    for (const B in G) {\n      const C = G[B];\n      C in a || (a[C] = []), a[C].push(Z[B]);\n    }\n    const i = {};\n    for (const B in h) {\n      const C = h[B];\n      C in i || (i[C] = []), i[C].push(g[B]);\n    }\n    let m = Object.keys(i).map((B) => parseInt(B, 10)).sort(sb);\n    this.layers = [];\n    for (const B of m) {\n      const C = i[B];\n      C.sort((n, X) => {\n        const t = b[n.id], e = b[X.id];\n        return t < e ? -1 : t > e ? 1 : 0;\n      });\n      for (const n of C)\n        n instanceof XI && this.internalContainerRefs.push(n), this.layers.push(n);\n    }\n    this.layersByDepth = i, m = Object.keys(a).map((B) => parseInt(B, 10)).sort(sb);\n    const T = this.inputs.slice(), s = [];\n    for (const B of m)\n      for (const C of a[B]) {\n        const n = C.outboundLayer;\n        if (n != null) {\n          for (const X of C.inputTensors)\n            if (T.indexOf(X) === -1)\n              throw new aI(`Graph disconnected: cannot obtain value for tensor ${X} at layer \"${n.name}\". The following previous layers were accessed without issue: ${s}`);\n          for (const X of C.outputTensors)\n            T.push(X);\n          s.push(n.name);\n        }\n      }\n    this.nodesByDepth = a;\n    const o = this.layers.map((B) => B.name);\n    for (const B of o) {\n      const C = o.filter((n) => n === B).length;\n      if (C !== 1)\n        throw new aI(`The name \"${B}\" is used ${C} times in the model. All layer names should be unique. Layer names: ` + JSON.stringify(o));\n    }\n    this.outboundNodes = [], this.inboundNodes = [], new nd({\n      outboundLayer: this,\n      inboundLayers: [],\n      nodeIndices: [],\n      tensorIndices: [],\n      inputTensors: this.inputs,\n      outputTensors: this.outputs,\n      inputMasks: this.inputs.map((B) => null),\n      outputMasks: this.outputs.map((B) => null),\n      inputShapes: this.inputs.map((B) => B.shape),\n      outputShapes: this.outputs.map((B) => B.shape)\n    }), this.built = !0, this._refCount = 1;\n  }\n  assertNotDisposed() {\n    if (this._refCount === 0)\n      throw new Error(`Container '${this.name}' is already disposed.`);\n  }\n  /**\n   * Attempt to dispose a LayersModel's weights.\n   *\n   * This method decrease the reference count of the LayersModel object by 1.\n   *\n   * A LayersModel is reference-counted. Its reference count is incremented by 1\n   * when it is first constructed and when it is used as a Layer of another\n   * LayersModel.\n   *\n   * If the reference count of a LayersModel becomes 0, the `dispose` method of\n   * all its constituent `Layer`s will be called.\n   *\n   * Note: If the reference count is greater than 0 after the decrement, the\n   * `dispose` method of its constituent `Layer`s will *not* be called.\n   *\n   * After a LayersModel is disposed, it cannot be used in calls such as\n   * 'predict`, `evaluate` or `fit` anymore.\n   *\n   * @returns A DisposeResult Object with the following fields:\n   *   - refCountAfterDispose: The reference count of the LayersModel after this\n   *     `dispose()` call.\n   *   - numDisposedVariables: Number of `tf.Variable`s (i.e., weights) disposed\n   *     during this `dispose()` call.\n   * @throws {Error} If the layer is not built yet, or if the LayersModel has\n   *   already been disposed.\n   */\n  dispose() {\n    this.assertNotDisposed();\n    const l = { refCountAfterDispose: null, numDisposedVariables: 0 };\n    if (--this._refCount === 0) {\n      for (const G of this.layers)\n        l.numDisposedVariables += G.dispose().numDisposedVariables;\n      for (const G of this.internalContainerRefs)\n        l.numDisposedVariables += G.dispose().numDisposedVariables;\n    }\n    return l.refCountAfterDispose = this._refCount, l;\n  }\n  get trainable() {\n    return this.trainable_;\n  }\n  set trainable(l) {\n    this.layers.forEach((G) => {\n      G._trainableWeights.forEach((Z) => Z.trainable = l);\n    }), this.trainable_ = l;\n  }\n  get trainableWeights() {\n    if (this._trainableWeights.length > 0)\n      throw new y(\"Container instance unexpectedly contains _trainableWeights.The trainable weights of a Container are a union of the trainable weights of its consituent Layers. Its own _trainableWeights must remain an empty Array.\");\n    if (!this.trainable)\n      return [];\n    let l = [];\n    for (const G of this.layers)\n      l = l.concat(G.trainableWeights);\n    return l;\n  }\n  get nonTrainableWeights() {\n    const l = [];\n    for (const G of this.layers)\n      l.push(...G.nonTrainableWeights);\n    if (!this.trainable) {\n      const G = [];\n      for (const Z of this.layers)\n        G.push(...Z.trainableWeights);\n      return G.concat(l);\n    }\n    return l;\n  }\n  get weights() {\n    return this.trainableWeights.concat(this.nonTrainableWeights);\n  }\n  /**\n   * Loads all layer weights from a JSON object.\n   *\n   * Porting Note: HDF5 weight files cannot be directly loaded in JavaScript /\n   *   TypeScript. The utility script at `scripts/pykeras.py` offers means\n   *   to convert them into JSON strings compatible with this method.\n   * Porting Note: TensorFlow.js Layers supports only loading by name currently.\n   *\n   * @param weights A JSON mapping weight names to weight values as nested\n   *   arrays of numbers, or a `NamedTensorMap`, i.e., a JSON mapping weight\n   *   names to `tf.Tensor` objects.\n   * @param strict Require that the provided weights exactly match those\n   *   required by the container.  Default: `true`.  Passing `false` means that\n   *   extra weights and missing weights will be silently ignored.\n   */\n  loadWeights(l, G = !0) {\n    const Z = {};\n    let h = 0;\n    const g = ty(l);\n    g && this.parseWeights(l);\n    for (const c of this.layers)\n      for (const [d, W] of c.weights.entries()) {\n        const Y = g ? `${W.name.split(\"/\").slice(0, -1).join(\"/\") + \"/\"}${d}` : W.originalName;\n        if (Z[Y] != null)\n          throw new y(`Duplicate weight name: ${Y}`);\n        Z[Y] = W, h++;\n      }\n    const b = [];\n    for (const c in l) {\n      let d = c;\n      if (Z[c] == null) {\n        const W = c.split(\"/\");\n        d = W.slice(0, -2).concat([W[W.length - 1]]).join(\"/\");\n      }\n      if (Z[d] != null)\n        b.push([Z[d], l[c]]);\n      else if (G)\n        throw new y(`Provided weight data has no target variable: ${c}`);\n      delete Z[d];\n    }\n    if (G) {\n      const c = [];\n      for (const d in Z)\n        c.push(d);\n      if (c.length > 0)\n        throw new y(`${c.length} of ${h} weights are not set: ${c}`);\n    }\n    g9(b);\n  }\n  parseWeights(l) {\n    for (const G in Object.keys(l)) {\n      const Z = G.split(\"/\"), h = [\"vars\", \"layer_checkpoint_dependencies\"], g = Z.map((b) => b.startsWith(\"_\") ? b.slice(1) : b).filter((b) => !h.includes(b)).join(\"/\");\n      g !== G && (l[g] = l[G], delete l[G]);\n    }\n  }\n  /**\n   * Util shared between different serialization methods.\n   * @returns LayersModel config with Keras version information added.\n   */\n  updatedConfig() {\n    const l = this.getConfig(), G = {};\n    return G.className = this.getClassName(), G.config = l, G.kerasVersion = `tfjs-layers ${ts}`, G.backend = \"TensorFlow.js\", G;\n  }\n  /**\n   * Returns a JSON string containing the network configuration.\n   *\n   * To load a network from a JSON save file, use\n   * models.modelFromJSON(jsonString);\n   * @param extraJsonArgs Unused in tfjs-layers, maintained for PyKeras\n   * @param returnString Whether the return value should be stringified\n   *    (default: `true`).\n   * @returns a JSON string if `returnString` (default), or a JSON object if\n   *   `!returnString`.\n   */\n  // tslint:disable-next-line:no-any\n  toJSON(l, G = !0) {\n    const Z = JW(this.updatedConfig());\n    return G ? JSON.stringify(Z) : Z;\n  }\n  /**\n   * Call the model on new inputs.\n   *\n   * In this case `call` just reapplies all ops in the graph to the new inputs\n   * (e.g. build a new computational graph from the provided inputs).\n   *\n   * @param inputs A tensor or list of tensors.\n   * @param mask A mask or list of masks. A mask can be either a tensor or null\n   *   (no mask).\n   *\n   * @return A tensor if there is a single output, or a list of tensors if there\n   *   are more than one outputs.\n   */\n  call(l, G) {\n    return U(() => {\n      l = Jl(l);\n      const Z = new BZ();\n      for (let h = 0; h < this.inputs.length; ++h)\n        Z.add(this.inputs[h], l[h]);\n      return S0(this.outputs, Z, G);\n    });\n  }\n  /**\n   * Computes an output mask tensor.\n   *\n   * @param inputs Tensor or list of tensors.\n   * @param mask Tensor or list of tensors.\n   *\n   * @return null or a tensor (or list of tensors, one per output tensor of the\n   * layer).\n   */\n  computeMask(l, G) {\n    return U(() => {\n      l = Jl(l);\n      let Z;\n      return G == null ? Z = ih(null, l.length) : Z = Jl(G), this.runInternalGraph(l, Z)[1];\n    });\n  }\n  /**\n   * Computes the output shape of the layer.\n   *\n   * Assumes that the layer will be built to match that input shape provided.\n   *\n   * @param inputShape A shape (tuple of integers) or a list of shape tuples\n   *   (one per output tensor of the layer). Shape tuples can include null for\n   *   free dimensions, instead of an integer.\n   */\n  computeOutputShape(l) {\n    const G = Lb(l);\n    if (G.length !== this.inputLayers.length)\n      throw new y(`Invalid inputShape argument ${l}: model has ${this.inputLayers.length} tensor inputs.`);\n    const Z = {};\n    for (let c = 0; c < G.length; c++) {\n      const d = this.inputLayers[c], W = G[c], Y = d.name + \"_0_0\";\n      Z[Y] = W;\n    }\n    const h = Object.keys(this.nodesByDepth).map((c) => parseInt(c, 10)).sort(sb);\n    if (h.length > 1)\n      for (const c of h) {\n        const d = this.nodesByDepth[c];\n        for (const W of d) {\n          const Y = W.outboundLayer;\n          if (this.inputLayers.map((T) => T.id).indexOf(Y.id) !== -1)\n            continue;\n          const V = [];\n          for (let T = 0; T < W.inboundLayers.length; T++) {\n            const s = W.inboundLayers[T], o = W.nodeIndices[T], B = W.tensorIndices[T], C = `${s.name}_${o}_${B}`, n = Z[C];\n            V.push(n);\n          }\n          const a = Y.computeOutputShape(kG(V)), i = Lb(a), m = Y.inboundNodes.indexOf(W);\n          for (let T = 0; T < i.length; T++) {\n            const s = `${Y.name}_${m}_${T}`;\n            Z[s] = i[T];\n          }\n        }\n      }\n    const g = [], b = [];\n    for (let c = 0; c < this.outputLayers.length; c++) {\n      const d = this.outputLayers[c], W = this.outputLayersNodeIndices[c], Y = this.outputLayersTensorIndices[c], V = `${d.name}_${W}_${Y}`;\n      b.push(V);\n    }\n    for (let c = 0; c < b.length; c++) {\n      const d = b[c];\n      KI(d in Z), g.push(Z[d]);\n    }\n    return kG(g);\n  }\n  /**\n   * Computes output tensors for new inputs.\n   *\n   * Note:\n   *   - Expects `inputs` to be a list (potentially with 1 element).\n   *\n   * @param inputs List of tensors\n   * @param masks List of masks (tensors or null).\n   * @return Three lists: outputTensors, outputMasks, outputShapes\n   */\n  runInternalGraph(l, G) {\n    G == null && (G = ih(null, l.length));\n    const Z = {};\n    for (let d = 0; d < this.inputs.length; ++d) {\n      const W = this.inputs[d], Y = l[d], V = G[d];\n      Z[W.id] = [Y, V];\n    }\n    const h = Object.keys(this.nodesByDepth).map((d) => parseInt(d, 10)).sort(sb);\n    for (const d of h) {\n      const W = this.nodesByDepth[d];\n      for (const Y of W) {\n        const V = Y.outboundLayer, a = Y.inputTensors, i = Y.outputTensors, m = new Array();\n        for (const T of a)\n          T.id in Z && m.push(Z[T.id]);\n        if (m.length === a.length) {\n          let T = {}, s, o, B, C;\n          if (Y.callArgs != null && (T = Y.callArgs), m.length === 1) {\n            const [n, X] = m[0];\n            T.mask == null && (T.mask = X), B = Jl(V.call(n, T)), C = Jl(V.computeMask(n, X)), s = [n], o = [X];\n          } else\n            s = m.map((n) => n[0]), o = m.map((n) => n[1]), T.mask == null && (T.mask = o), B = Jl(V.call(s, T)), C = Jl(V.computeMask(s, o));\n          if (V.activityRegularizer)\n            throw new Bl(\"LayersModel invocation with concrete Tensor value(s) in the presence of activity regularizer(s) is not supported yet.\");\n          for (let n = 0; n < i.length; ++n) {\n            const X = i[n], t = B[n], e = C[n];\n            Z[X.id] = [t, e];\n          }\n        }\n      }\n    }\n    const g = [], b = [], c = [];\n    for (const d of this.outputs) {\n      KI(d.id in Z, `Could not compute output ${d.name} : ${d.id}`);\n      const [W, Y] = Z[d.id];\n      c.push(W.shape), g.push(W), b.push(Y);\n    }\n    return [g, b, c];\n  }\n  /**\n   * Builds a map of internal node keys to node ordering.\n   * Used in serializaion a node orderings may change as unused nodes are\n   * dropped. Porting Note:  This helper method was pulled out of getConfig to\n   * improve readability.\n   * @param layers An array of Layers in the model.\n   * @returns Map of Node Keys to index order within the layer.\n   */\n  buildNodeConversionMap(l) {\n    const G = {};\n    let Z;\n    for (const h of this.layers) {\n      Z = h instanceof XI ? 1 : 0;\n      for (let g = 0; g < h.inboundNodes.length; g++) {\n        const b = XI.nodeKey(h, g);\n        this.containerNodes.has(b) && (G[b] = Z, Z += 1);\n      }\n    }\n    return G;\n  }\n  getLayer(l, G) {\n    if (G != null)\n      return this.findLayer(G);\n    if (l == null)\n      throw new y(\"Provide either a layer name or layer index\");\n    if (typeof l == \"number\")\n      return this.findLayer(l);\n    for (const Z of this.layers)\n      if (Z.name === l)\n        return Z;\n    throw new y(`No such layer: ${l}`);\n  }\n  findLayer(l) {\n    if (this.layers.length <= l)\n      throw new y(`Was asked to retrieve layer at index ${l}, but model only has ${this.layers.length} layer(s).`);\n    return this.layers[l];\n  }\n  /**\n   * Retrieves the Container's current loss values.\n   *\n   * Used for regularizers during training.\n   */\n  calculateLosses() {\n    return U(() => {\n      const l = [];\n      for (const G of this.layers)\n        for (let Z = 0; Z < G.inboundNodes.length; ++Z) {\n          const h = XI.nodeKey(G, Z);\n          this.containerNodes.has(h) && l.push(...G.calculateLosses());\n        }\n      return l;\n    });\n  }\n  getConfig() {\n    const l = { name: this.name }, G = this.buildNodeConversionMap(this.layers), Z = [];\n    for (const b of this.layers) {\n      const c = b.getClassName(), d = b.getConfig(), W = [];\n      for (let V = 0; V < b.inboundNodes.length; V++) {\n        const a = b.inboundNodes[V], i = XI.nodeKey(b, V);\n        let m = {};\n        if (this.containerNodes.has(i)) {\n          if (a.callArgs)\n            try {\n              JSON.stringify(a.callArgs), m = a.callArgs;\n            } catch {\n              console.warn(`Layer ${b.name} was passed non-serializable keyword arguments: ${a.callArgs}. They will not be included in the serialized model (and thus will be missing at deserialization time).`), m = {};\n            }\n          if (a.inboundLayers.length > 0) {\n            const T = [];\n            for (let s = 0; s < a.inboundLayers.length; s++) {\n              const o = a.inboundLayers[s], B = a.nodeIndices[s], C = a.tensorIndices[s], n = XI.nodeKey(o, B);\n              let X = G[n];\n              X == null && (X = 0), T.push([o.name, X, C, m]);\n            }\n            W.push(T);\n          }\n        }\n      }\n      const Y = {};\n      Y.name = b.name, Y.className = c, Y.config = d, Y.inboundNodes = W, Z.push(Y);\n    }\n    l.layers = Z;\n    const h = [];\n    for (let b = 0; b < this.inputLayers.length; b++) {\n      const c = this.inputLayers[b], d = this.inputLayersNodeIndices[b], W = XI.nodeKey(c, d);\n      if (!this.containerNodes.has(W))\n        continue;\n      let Y = G[W];\n      Y == null && (Y = 0);\n      const V = this.inputLayersTensorIndices[b];\n      h.push([c.name, Y, V]);\n    }\n    l.inputLayers = h;\n    const g = [];\n    for (let b = 0; b < this.outputLayers.length; b++) {\n      const c = this.outputLayers[b], d = this.outputLayersNodeIndices[b], W = XI.nodeKey(c, d);\n      if (!this.containerNodes.has(W))\n        continue;\n      let Y = G[W];\n      Y == null && (Y = 0);\n      const V = this.outputLayersTensorIndices[b];\n      g.push([c.name, Y, V]);\n    }\n    return l.outputLayers = g, l;\n  }\n  /**\n   * Instantiates a LayersModel from its config (output of `get_config()`).\n   * @param cls the class to create\n   * @param config LayersModel config dictionary.\n   * @param customObjects An optional dictionary of custom objects.\n   * @param fastWeightInit Optional flag to use fast weight initialization\n   *   during deserialization. This is applicable to cases in which\n   *   the initialization will be immediately overwritten by loaded weight\n   *   values. Default: `false`.\n   * @returns A LayersModel instance.\n   * @throws ValueError: In case of improperly formatted config dict.\n   */\n  /** @nocollapse */\n  static fromConfig(l, G, Z = {}, h = !1) {\n    const g = {}, b = {};\n    function c(s, o) {\n      s.name in b ? b[s.name].push(o) : b[s.name] = [o];\n    }\n    function d(s, o) {\n      const B = [];\n      let C;\n      for (const n of o) {\n        const X = n[0], t = n[1], e = n[2];\n        if (C = n[3] == null ? {} : n[3], !(X in g)) {\n          c(s, o);\n          return;\n        }\n        const S = g[X];\n        if (S.inboundNodes.length <= t) {\n          c(s, o);\n          return;\n        }\n        const p = S.inboundNodes[t];\n        B.push(p.outputTensors[e]);\n      }\n      B.length > 0 && s.apply(kG(B), C);\n    }\n    function W(s) {\n      const o = s.name, B = ZZ(s, G.customObjects != null ? G.customObjects : {});\n      B.setFastWeightInitDuringBuild(h), g[o] = B, s.inboundNodes.forEach((n) => {\n        if (!(n instanceof Array))\n          throw new y(`Corrupted configuration, expected array for nodeData: ${n}`);\n        c(B, n);\n      });\n    }\n    const Y = G.name, V = G.layers;\n    for (const s of V)\n      W(s);\n    for (; !bF(b); )\n      for (const s of V) {\n        const o = g[s.name];\n        if (o.name in b) {\n          const B = b[o.name];\n          delete b[o.name];\n          for (const C of B)\n            d(o, C);\n        }\n      }\n    const a = [], i = [], m = G.inputLayers;\n    for (const s of m) {\n      const o = s[0], B = s[1], C = s[2];\n      KI(o in g);\n      const X = g[o].inboundNodes[B].outputTensors;\n      a.push(X[C]);\n    }\n    const T = G.outputLayers;\n    for (const s of T) {\n      const o = s[0], B = s[1], C = s[2];\n      KI(o in g);\n      const X = g[o].inboundNodes[B].outputTensors;\n      i.push(X[C]);\n    }\n    return new l({ inputs: a, outputs: i, name: Y });\n  }\n  /**\n   * Determine whether the container is stateful.\n   *\n   * Porting Note: this is the equivalent of the stateful @property of\n   *   the Container class in PyKeras.\n   */\n  get stateful() {\n    if (this._stateful)\n      throw new y(\"Container instance unexpectedly has _stateful = true. The statefulness of a Container is determined by the Layers it contains. Its _stateful property must remain the default false.\");\n    for (const l of this.layers)\n      if (l.stateful)\n        return !0;\n    return !1;\n  }\n  /**\n   * Reset the state of all stateful constituent layers (if any).\n   *\n   * Examples of stateful layers include RNN layers whose `stateful` property\n   * is set as `true`.\n   */\n  resetStates() {\n    U(() => {\n      this.layers.forEach((l) => {\n        l.stateful && l.resetStates();\n      });\n    });\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction uy(I, l, G) {\n  const Z = l.length;\n  if (I == null || Array.isArray(I) && I.length === 0)\n    return l.map((h) => null);\n  if (Z === 1)\n    return Array.isArray(I) && I.length === 1 ? I : typeof I == \"object\" && l[0] in I ? [I[l[0]]] : [I];\n  if (Array.isArray(I)) {\n    if (I.length !== Z)\n      throw new Error(`Provided ${G} is an array of ${I.length} element(s), but the model has ${Z} outputs. Make sure a set of weights is provided for each model output.`);\n    return I;\n  } else if (typeof I == \"object\" && Object.keys(I).length > 0 && typeof I[Object.keys(I)[0]] == \"object\") {\n    const h = [];\n    return l.forEach((g) => {\n      g in I ? h.push(I[g]) : h.push(null);\n    }), h;\n  } else\n    throw new Error(`The model has multiple (${Z}) outputs, so ${G} must be either an array with ${Z} elements or an object with ${l} keys. Provided ${G} not understood: ${JSON.stringify(I)}`);\n}\nfunction us(I, l) {\n  return uy(I, l, \"classWeight\");\n}\nasync function es(I, l, G, Z) {\n  if (G != null) {\n    const h = U(() => {\n      if (I.shape.length === 1)\n        return lh(I);\n      if (I.shape.length === 2) {\n        if (I.shape[1] > 1)\n          return P0(I, 1);\n        if (I.shape[1] === 1)\n          return J(I, [I.shape[0]]);\n        throw new Error(`Encountered unexpected last-dimension size (${I.shape[1]}) during handling of class weights. The size is expected to be >= 1.`);\n      } else\n        throw new Error(`Unexpected rank of target (y) tensor (${I.rank}) during handling of class weights. The rank is expected to be 1 or 2.`);\n    }), g = Array.from(await h.data());\n    Cl(h);\n    const b = [];\n    return g.forEach((c) => {\n      if (G[c] == null)\n        throw new Error(`classWeight must contain all classes in the training data. The class ${c} exists in the data but not in classWeight`);\n      b.push(G[c]);\n    }), jG(b, \"float32\");\n  } else\n    return null;\n}\nfunction ey(I, l) {\n  return N(I, l);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst Sy = 32;\nfunction Ss(I, l) {\n  let G, Z;\n  const h = l;\n  G = h.xs, Z = h.ys, u(G != null && Z != null, () => `A Dataset iterator for fitDataset() is expected to generate objects of the form \\`{xs: xVal, ys: yVal}\\`, where the two values may be \\`tf.Tensor\\`, an array of Tensors, or a map of string to Tensor.  The provided Dataset instead generates ${l}`);\n  const g = Ra(\"input\", I.inputNames, G), b = Ra(\"output\", I.outputNames, Z), c = g[0].shape[0];\n  u(g.length === I.inputs.length, () => `LayersModel has ${I.inputs.length} inputs, but the dataset provides ${g.length} inputs.  (Expected input keys: ${JSON.stringify(I.inputNames)})`), u(b.length === I.outputs.length, () => `LayersModel has ${I.outputs.length} outputs, but the dataset provides ${b.length} outputs.  (Expected output keys: ${JSON.stringify(I.outputNames)})`);\n  for (let d = 0; d < g.length; d++)\n    u(g[d].shape[0] === c, () => `Batch size mismatch: input ${I.inputNames[d]} has ${g[d].shape[0]}; expected  ${c} based on input ${I.inputNames[0]}.`);\n  for (let d = 0; d < b.length; d++)\n    u(b[d].shape[0] === c, () => `Batch size mismatch: output ${I.outputNames[d]} has ${b[d].shape[0]}; expected  ${c} based on input ${I.inputNames[0]}.`);\n  return { xs: g, ys: b };\n}\nfunction Ra(I, l, G) {\n  if (G instanceof hG)\n    return [G];\n  if (Array.isArray(G))\n    return u(G.length === l.length, () => `Received an array of ${G.length} Tensors, but expected ${l.length} to match the ${I} keys ${l}.`), G;\n  {\n    const Z = [];\n    for (const h of l) {\n      if (G[h] == null)\n        throw new y(`The feature data generated by the dataset lacks the required ${I} key '${h}'.`);\n      Z.push(G[h]);\n    }\n    return Z;\n  }\n}\nfunction Ry(I) {\n  if (I.length === 3)\n    throw new Bl(\"Validation with sample weights is not implemented yet.\");\n  return { xs: I[0], ys: I[1] };\n}\nasync function py(I, l, G) {\n  const Z = G.batchesPerEpoch != null;\n  if (u(I.optimizer != null, () => \"You must compile a model before training/testing. Use LayersModel.compile(modelCompileConfig).\"), u(G != null, () => \"For fitDataset(), the 2nd argument (config) is required, but it is not provided in this call.\"), u(G.epochs != null && G.epochs > 0 && Number.isInteger(G.epochs), () => `For fitDataset(), config.epochs is expected to be a positive integer, but got ${G.epochs}`), u(!Z || G.batchesPerEpoch > 0 && Number.isInteger(G.batchesPerEpoch), () => `For fitDataset(), config.batchesPerEpoch is expected to be a positive integer if specified, but got ${G.batchesPerEpoch}`), u(\n    // tslint:disable-next-line:no-any\n    G.validationSplit == null,\n    () => \"`validationSplit` is not supported by `fitDataset()`. Use validationData instead.\"\n  ), I.isTraining)\n    throw new Error(\"Cannot start training because another fit() call is ongoing.\");\n  I.isTraining = !0;\n  try {\n    const h = G.validationData != null;\n    let g, b;\n    if (h)\n      if (pa(G.validationData))\n        u(G.validationBatches == null || G.validationBatches > 0 && Number.isInteger(G.validationBatches), () => `For fitDataset() with dataset-based validation, config.validationBatches is expected not to be provided, or to be a positive integer, but got ${G.validationBatches}`);\n      else {\n        const s = Ry(G.validationData);\n        g = s.xs, b = s.ys;\n      }\n    const c = I.makeTrainFunction(), d = I.getDedupedMetricsNames();\n    let W;\n    h ? W = d.slice().concat(d.map((s) => \"val_\" + s)) : W = d.slice();\n    const Y = ms(G.callbacks, G.yieldEvery), V = G.verbose == null ? 1 : G.verbose, { callbackList: a, history: i } = Ts(\n      Y,\n      V,\n      G.epochs,\n      null,\n      null,\n      Fy(l, G),\n      null,\n      // Batch size determined by the dataset itself.\n      h,\n      W\n    );\n    a.setModel(I), I.history = i, await a.onTrainBegin(), I.stopTraining_ = !1;\n    let m = G.initialEpoch == null ? 0 : G.initialEpoch, T = await l.iterator();\n    for (; m < G.epochs; ) {\n      const s = {};\n      await a.onEpochBegin(m);\n      let o = 0, B = 0;\n      for (Z || (T = await l.iterator()); !Z || o < G.batchesPerEpoch; ) {\n        const C = await T.next();\n        if (Z && C.done) {\n          console.warn(`You provided \\`batchesPerEpoch\\` as ${G.batchesPerEpoch}, but your dataset iterator ran out of data after ${o} batches; interrupting training. Make sure that your dataset can generate at least \\`batchesPerEpoch * epochs\\` batches (in this case, ${G.batchesPerEpoch * G.epochs} batches). You may need to use the repeat() function when building your dataset.`);\n          break;\n        }\n        if (C.value != null) {\n          const { xs: n, ys: X } = Ss(I, C.value), t = {};\n          t.batch = B, t.size = n[0].shape[0], await a.onBatchBegin(B, t);\n          const e = [];\n          if (G.classWeight != null) {\n            const F = us(G.classWeight, I.outputNames);\n            for (let x = 0; x < F.length; ++x)\n              e.push(await es(X[x], null, F[x]));\n          }\n          const S = n.concat(X).concat(e), p = c(S);\n          Cl(S);\n          for (let F = 0; F < d.length; ++F) {\n            const x = d[F], H = p[F];\n            t[x] = H, LI(H);\n          }\n          await a.onBatchEnd(B, t), is(t), B++, o++;\n        }\n        if (Z ? o >= G.batchesPerEpoch : C.done) {\n          if (h) {\n            let n;\n            pa(G.validationData) ? n = Jl(await I.evaluateDataset(G.validationData, { batches: G.validationBatches })) : n = Jl(I.evaluate(g, b, {\n              batchSize: G.validationBatchSize == null ? Sy : G.validationBatchSize,\n              verbose: 0\n            }));\n            for (let X = 0; X < I.metricsNames.length; ++X)\n              s[`val_${I.metricsNames[X]}`] = n[X];\n          }\n          break;\n        }\n        if (I.stopTraining_)\n          break;\n      }\n      if (await a.onEpochEnd(m, s), m++, I.stopTraining_)\n        break;\n    }\n    return await a.onTrainEnd(), await I.history.syncData(), I.history;\n  } finally {\n    I.isTraining = !1;\n  }\n}\nfunction Fy(I, l) {\n  let G = null;\n  return l.batchesPerEpoch != null ? G = l.batchesPerEpoch : Number.isFinite(I.size) && (G = I.size), G;\n}\nfunction pa(I) {\n  return typeof I.iterator == \"function\";\n}\nfunction yy(I) {\n  return typeof I.next == \"function\";\n}\nasync function Ny(I, l, G) {\n  G = G || {};\n  const Z = G.batches != null, h = I.testFunction;\n  let g = [];\n  if (G.verbose > 0)\n    throw new Bl(\"Verbose mode is not implemented yet.\");\n  u(!Z || G.batches > 0 && Number.isInteger(G.batches), () => `Test loop expects \\`batches\\` to be a positive integer, but received ${JSON.stringify(G.batches)}`);\n  const b = yy(l) ? l : await l.iterator();\n  let c = 0, d = 0;\n  for (; !Z || d < G.batches; ) {\n    const W = await b.next();\n    if (g = U(() => {\n      if (W.value) {\n        const { xs: Y, ys: V } = Ss(I, W.value), a = Y.concat(V), i = U(() => h(a));\n        if (Cl(a), d === 0)\n          for (let T = 0; T < i.length; ++T)\n            g.push(yl(0));\n        const m = a[0].shape[0];\n        for (let T = 0; T < i.length; ++T) {\n          const s = i[T], o = g[T];\n          g[T] = U(() => O(g[T], N(m, s))), d > 0 && Cl(o);\n        }\n        Cl(i), c += m, ++d;\n      }\n      return g;\n    }), W.done) {\n      Z && console.warn(`Your dataset iterator ran out of data during evaluateDataset(). Interrupting evalution. Make sure that your dataset can generate at least \\`batches\\` batches (in this case, ${G.batches} batches). You may need to use the repeat() function when building your dataset.`);\n      break;\n    }\n  }\n  for (let W = 0; W < g.length; ++W) {\n    const Y = g[W];\n    g[W] = Vl(g[W], c), Cl(Y);\n  }\n  return kG(g);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction rd(I) {\n  u(I > 0 && Number.isInteger(I), () => `batchSize is required to be a positive integer, but got ${I}`);\n}\nfunction X0(I, l, G) {\n  return I == null ? [null] : Array.isArray(I) ? I.map((Z) => Ih(Z, l, G - l)) : Ih(I, l, G - l);\n}\nfunction EW(I, l) {\n  return U(() => I == null ? null : Array.isArray(I) ? I.map((G) => EW(G, l)) : _T(I, l.dtype === \"int32\" ? l : hl(l, \"int32\")));\n}\nfunction jd(I, l) {\n  const G = [];\n  let Z = 0, h = null;\n  for (; Z < I; )\n    h = Z + l, h >= I && (h = I), G.push([Z, h]), Z = h;\n  return G;\n}\nfunction Rs(I) {\n  const l = [];\n  I instanceof hG && (I = [I]);\n  for (let G = 0; G < I.length; ++G) {\n    const Z = I[G];\n    if (Z.rank === 1)\n      l.push($g(Z, 1));\n    else {\n      if (Z.rank === 0)\n        throw new Error(\"Expected tensor to be at least 1D, but received a 0D tensor (scalar).\");\n      l.push(Z);\n    }\n  }\n  return l;\n}\nfunction CI(I, l) {\n  if (I == null)\n    return;\n  const G = [];\n  if (l instanceof hG)\n    G.push(l.id);\n  else if (Array.isArray(l))\n    l.forEach((h) => G.push(h.id));\n  else if (l != null)\n    for (const h in l) {\n      const g = l[h];\n      G.push(g.id);\n    }\n  const Z = [];\n  if (I instanceof hG)\n    G.indexOf(I.id) === -1 && Z.push(I);\n  else if (Array.isArray(I))\n    I.forEach((h) => {\n      G.indexOf(h.id) === -1 && Z.push(h);\n    });\n  else if (I != null)\n    for (const h in I) {\n      const g = I[h];\n      G.indexOf(g.id) === -1 && Z.push(g);\n    }\n  Z.forEach((h) => {\n    h.isDisposed || h.dispose();\n  });\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Py(I) {\n  return I instanceof hG;\n}\nfunction xW(I) {\n  return Array.isArray(I);\n}\nfunction Fa(I) {\n  return !Py(I) && !xW(I);\n}\nfunction ya(I, l, G, Z = !0, h = \"\") {\n  if (l == null || l.length === 0) {\n    if (I != null) {\n      let b = !1;\n      if (xW(I) && I.length > 0)\n        b = !0;\n      else if (Fa(I)) {\n        for (const c in I)\n          if (I.hasOwnProperty(c)) {\n            b = !0;\n            break;\n          }\n      } else\n        b = !0;\n      if (b)\n        throw new y(`Error when checking model ${h} expected no data, but got ${I}`);\n    }\n    return [];\n  }\n  if (I == null)\n    return l.map((b) => null);\n  let g;\n  if (Fa(I)) {\n    I = I, g = [];\n    for (const b of l) {\n      if (I[b] == null)\n        throw new y(`No data provided for \"${b}\". Need data for each key in: ${l}`);\n      g.push(I[b]);\n    }\n  } else if (xW(I)) {\n    if (I = I, I.length !== l.length)\n      throw new y(`Error when checking model ${h}: the Array of Tensors that you are passing to your model is not the size the model expected. Expected to see ${l.length} Tensor(s), but instead got the following list of Tensor(s): ${I}`);\n    g = I;\n  } else {\n    if (I = I, l.length > 1)\n      throw new y(`The model ${h} expects ${l.length} Tensor(s), but only received one Tensor. Found: Tensor with shape ${I.shape}`);\n    g = [I];\n  }\n  if (g = Rs(g), G != null)\n    for (let b = 0; b < l.length; ++b) {\n      if (G[b] == null)\n        continue;\n      const c = g[b];\n      if (c.shape.length !== G[b].length)\n        throw new y(`Error when checking ${h}: expected ${l[b]} to have ${G[b].length} dimension(s). but got array with shape ${c.shape}`);\n      for (let d = 0; d < G[b].length; ++d) {\n        if (d === 0 && !Z)\n          continue;\n        const W = c.shape[d], Y = G[b][d];\n        if (Y != null && Y >= 0 && W !== Y)\n          throw new y(`${h} expected a batch of elements where each example has shape [${G[b].slice(1, G[b].length)}] (i.e.,tensor shape [*,${G[b].slice(1, G[b].length)}]) but the ${h} received an input with ${c.shape[0]} examples, each with shape [${c.shape.slice(1, c.shape.length)}] (tensor shape [${c.shape}])`);\n      }\n    }\n  return g;\n}\nfunction Jy(I, l, G) {\n  const Z = tZ(I.map((g) => g.shape[0]));\n  Z.sort();\n  const h = tZ(l.map((g) => g.shape[0]));\n  if (h.sort(), Z.length > 1)\n    throw new y(`All input Tensors (x) should have the same number of samples. Got array shapes: ${JSON.stringify(I.map((g) => g.shape))}`);\n  if (h.length > 1)\n    throw new y(`All target Tensors (y) should have the same number of samples. Got array shapes: ${JSON.stringify(l.map((g) => g.shape))}`);\n  if (Z.length > 0 && h.length > 0 && !Nl(Z, h))\n    throw new y(`Input Tensors should have the same number of samples as target Tensors. Found ${Z[0]} input sample(s) and ${h[0]} target sample(s).`);\n}\nfunction Ey(I, l, G) {\n  const Z = [\n    Cd,\n    Xd,\n    K0\n  ];\n  for (let h = 0; h < I.length; ++h) {\n    const g = I[h], b = l[h], c = G[h];\n    if (b != null) {\n      if (b === K0 && g.shape[g.shape.length - 1] === 1)\n        throw new y(`You are passing a target array of shape ${g.shape} while using a loss 'categorical_crossentropy'. 'categorical_crossentropy'expects targets to be binary matrices (1s and 0s) of shape [samples, classes].`);\n      if (Z.indexOf(b) !== -1) {\n        const d = g.shape.slice(1), W = c.slice(1);\n        for (let Y = 0; Y < d.length; ++Y) {\n          const V = d[Y], a = W[Y];\n          if (a != null && V !== a)\n            throw new y(`A target Tensor with shape ${g.shape} was passed for an output of shape ${c}, while using a loss function that expects targets to have the same shape as the output.`);\n        }\n      }\n    }\n  }\n}\nfunction Na(I, l, G, Z = !0, h = \"\") {\n  let g;\n  if (Array.isArray(I)) {\n    if (I.length !== l.length)\n      throw new y(`Error when checking model ${h}: the Array of Tensors that you are passing to your model is not the size the the model expected. Expected to see ${l.length} Tensor(s), but instead got ${I.length} Tensors(s).`);\n    g = I;\n  } else {\n    if (l.length > 1)\n      throw new y(`The model expects ${l.length} ${h} Tensors, but only received one Tensor. Found: array with shape ${JSON.stringify(I.shape)}.`);\n    g = [I];\n  }\n  if (G != null)\n    for (let b = 0; b < l.length; ++b) {\n      if (G[b] == null)\n        continue;\n      const c = g[b];\n      if (c.shape.length !== G[b].length)\n        throw new y(`Error when checking ${h}: expected ${l[b]} to have ${G[b].length} dimension(s), but got array with shape ${JSON.stringify(c.shape)}`);\n      for (let d = 0; d < G[b].length; ++d) {\n        if (d === 0 && !Z)\n          continue;\n        const W = c.shape[d], Y = G[b][d];\n        if (Y != null && Y !== W)\n          throw new y(`Error when checking ${h}: expected ${l[b]} to have shape ${JSON.stringify(G[b])} but got array with shape ${JSON.stringify(c.shape)}.`);\n      }\n    }\n}\nfunction xy(I, l) {\n  if (I == null || Array.isArray(I) && I.length === 0)\n    return l.map((Z) => []);\n  let G;\n  if (typeof I == \"string\" || typeof I == \"function\")\n    G = [I];\n  else if (Array.isArray(I) || typeof I == \"object\")\n    G = I;\n  else\n    throw new TypeError(`Type of metrics argument not understood. Expected an string,function, Array, or Object, found: ${I}`);\n  if (Array.isArray(G))\n    return l.map((Z) => G);\n  {\n    const Z = [];\n    for (const h of l) {\n      let g = G.hasOwnProperty(h) ? G[h] : [];\n      Array.isArray(g) || (g = [g]), Z.push(g);\n    }\n    return Z;\n  }\n}\nconst Uy = \"layers-model\";\nclass zh extends XI {\n  constructor(l) {\n    super(l), this.isTraining = !1;\n  }\n  /**\n   * Print a text summary of the model's layers.\n   *\n   * The summary includes\n   * - Name and type of all layers that comprise the model.\n   * - Output shape(s) of the layers\n   * - Number of weight parameters of each layer\n   * - If the model has non-sequential-like topology, the inputs each layer\n   *   receives\n   * - The total number of trainable and non-trainable parameters of the model.\n   *\n   * ```js\n   * const input1 = tf.input({shape: [10]});\n   * const input2 = tf.input({shape: [20]});\n   * const dense1 = tf.layers.dense({units: 4}).apply(input1);\n   * const dense2 = tf.layers.dense({units: 8}).apply(input2);\n   * const concat = tf.layers.concatenate().apply([dense1, dense2]);\n   * const output =\n   *     tf.layers.dense({units: 3, activation: 'softmax'}).apply(concat);\n   *\n   * const model = tf.model({inputs: [input1, input2], outputs: output});\n   * model.summary();\n   * ```\n   *\n   * @param lineLength Custom line length, in number of characters.\n   * @param positions Custom widths of each of the columns, as either\n   *   fractions of `lineLength` (e.g., `[0.5, 0.75, 1]`) or absolute number\n   *   of characters (e.g., `[30, 50, 65]`). Each number corresponds to\n   *   right-most (i.e., ending) position of a column.\n   * @param printFn Custom print function. Can be used to replace the default\n   *   `console.log`. For example, you can use `x => {}` to mute the printed\n   *   messages in the console.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  summary(l, G, Z = console.log) {\n    if (!this.built)\n      throw new y(\"This model has never been called, thus its weights have not been created yet. So no summary can be displayed. Build the model first (e.g., by calling it on some test data).\");\n    oy(this, l, G, Z);\n  }\n  /**\n   * Configures and prepares the model for training and evaluation.  Compiling\n   * outfits the model with an optimizer, loss, and/or metrics.  Calling `fit`\n   * or `evaluate` on an un-compiled model will throw an error.\n   *\n   * @param args a `ModelCompileArgs` specifying the loss, optimizer, and\n   * metrics to be used for fitting and evaluating this model.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  compile(l) {\n    if (l.loss == null && (l.loss = []), this.loss = l.loss, typeof l.optimizer == \"string\")\n      this.optimizer_ = sy(l.optimizer), this.isOptimizerOwned = !0;\n    else {\n      if (!(l.optimizer instanceof KZ))\n        throw new y(\"User-defined optimizer must be an instance of tf.Optimizer.\");\n      this.optimizer_ = l.optimizer, this.isOptimizerOwned = !1;\n    }\n    let G = [];\n    if (!Array.isArray(l.loss) && typeof l.loss != \"string\" && typeof l.loss != \"function\") {\n      l.loss = l.loss;\n      for (const b in l.loss)\n        if (this.outputNames.indexOf(b) === -1)\n          throw new y(`Unknown entry in loss dictionary: \"${b}\". Only expected the following keys: ${this.outputNames}`);\n      for (const b of this.outputNames)\n        l.loss[b] == null && console.warn(`Output \"${b}\" is missing from loss dictionary. We assume this was done on purpose, and we will not be expecting data to be passed to ${b} during training`), G.push(vd(l.loss[b]));\n    } else if (Array.isArray(l.loss)) {\n      if (l.loss.length !== this.outputs.length)\n        throw new y(`When passing an Array as loss, it should have one entry per model output. The model has ${this.outputs.length} output(s), but you passed loss=${l.loss}.`);\n      G = l.loss.map((c) => vd(c));\n    } else {\n      const b = vd(l.loss);\n      this.outputs.forEach((c) => {\n        G.push(b);\n      });\n    }\n    this.lossFunctions = G, this.feedOutputNames = [], this.feedOutputShapes = [], this.feedLossFns = [];\n    for (let b = 0; b < this.outputs.length; ++b) {\n      const c = this.internalOutputShapes[b], d = this.outputNames[b];\n      this.feedOutputNames.push(d), this.feedOutputShapes.push(c), this.feedLossFns.push(this.lossFunctions[b]);\n    }\n    const Z = [];\n    this.metrics = l.metrics, this.metricsNames = [\"loss\"], this.metricsTensors = [], Gh(\"loss\", () => {\n      for (let b = 0; b < this.outputs.length; ++b) {\n        if (Z.indexOf(b) !== -1)\n          continue;\n        const c = this.lossFunctions[b];\n        this.outputs.length > 1 && (this.metricsTensors.push([c, b]), this.metricsNames.push(this.outputNames[b] + \"_loss\"));\n      }\n    });\n    const h = xy(l.metrics, this.outputNames), g = (b, c, d) => {\n      this.outputNames.length > 1 && (c = this.outputNames[b] + \"_\" + c), this.metricsNames.push(c), this.metricsTensors.push([d, b]);\n    };\n    Gh(\"metric\", () => {\n      for (let b = 0; b < this.outputs.length; ++b) {\n        if (Z.indexOf(b) !== -1)\n          continue;\n        const c = h[b];\n        ((W) => {\n          const Y = \"\";\n          let V, a, i;\n          for (const m of W) {\n            if (typeof m == \"string\" && [\"accuracy\", \"acc\", \"crossentropy\", \"ce\"].indexOf(m) !== -1) {\n              const s = this.internalOutputShapes[b];\n              s[s.length - 1] === 1 || this.lossFunctions[b] === Xd ? [\"accuracy\", \"acc\"].indexOf(m) !== -1 ? a = os : [\"crossentropy\", \"ce\"].indexOf(m) !== -1 && (a = by) : this.lossFunctions[b] === rb ? [\"accuracy\", \"acc\"].indexOf(m) !== -1 ? a = cy : [\"crossentropy\", \"ce\"].indexOf(m) !== -1 && (a = Cs) : [\"accuracy\", \"acc\"].indexOf(m) !== -1 ? a = Bs : [\"crossentropy\", \"ce\"].indexOf(m) !== -1 && (a = ns);\n              let o;\n              [\"accuracy\", \"acc\"].indexOf(m) !== -1 ? o = \"acc\" : [\"crossentropy\", \"ce\"].indexOf(m) !== -1 && (o = \"ce\"), i = a, V = Y + o;\n            } else\n              i = Ty(m), V = Y + nb(m);\n            let T;\n            Gh(V, () => {\n              T = i;\n            }), g(b, V, T);\n          }\n        })(c);\n      }\n    }), this.collectedTrainableWeights = this.trainableWeights;\n  }\n  /**\n   * Check trainable weights count consistency.\n   *\n   * This will raise a warning if `this.trainableWeights` and\n   * `this.collectedTrainableWeights` are inconsistent (i.e., have different\n   * numbers of parameters).\n   * Inconsistency will typically arise when one modifies `model.trainable`\n   * without calling `model.compile()` again.\n   */\n  checkTrainableWeightsConsistency() {\n    this.collectedTrainableWeights != null && this.trainableWeights.length !== this.collectedTrainableWeights.length && console.warn(\"Discrepancy between trainableweights and collected trainable weights. Did you set `model.trainable` without calling `model.compile()` afterwards?\");\n  }\n  /**\n   * Returns the loss value & metrics values for the model in test mode.\n   *\n   * Loss and metrics are specified during `compile()`, which needs to happen\n   * before calls to `evaluate()`.\n   *\n   * Computation is done in batches.\n   *\n   * ```js\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});\n   * const result = model.evaluate(\n   *     tf.ones([8, 10]), tf.ones([8, 1]), {batchSize: 4});\n   * result.print();\n   * ```\n   *\n   * @param x `tf.Tensor` of test data, or an `Array` of `tf.Tensor`s if the\n   * model has multiple inputs.\n   * @param y `tf.Tensor` of target data, or an `Array` of `tf.Tensor`s if the\n   * model has multiple outputs.\n   * @param args A `ModelEvaluateArgs`, containing optional fields.\n   *\n   * @return `Scalar` test loss (if the model has a single output and no\n   *   metrics) or `Array` of `Scalar`s (if the model has multiple outputs\n   *   and/or metrics). The attribute `model.metricsNames`\n   *   will give you the display labels for the scalar outputs.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  evaluate(l, G, Z = {}) {\n    const h = Z.batchSize == null ? 32 : Z.batchSize;\n    rd(h);\n    const b = this.standardizeUserDataXY(l, G, !0, h);\n    try {\n      const c = b[0].concat(b[1]);\n      this.makeTestFunction();\n      const d = this.testFunction, W = this.testLoop(d, c, h, Z.verbose, Z.steps);\n      return kG(W);\n    } finally {\n      CI(b[0], l), CI(b[1], G);\n    }\n  }\n  // TODO(cais): Add code snippet below once real dataset objects are\n  //   available.\n  /**\n   * Evaluate model using a dataset object.\n   *\n   * Note: Unlike `evaluate()`, this method is asynchronous (`async`).\n   *\n   * @param dataset A dataset object. Its `iterator()` method is expected\n   *   to generate a dataset iterator object, the `next()` method of which\n   *   is expected to produce data batches for evaluation. The return value\n   *   of the `next()` call ought to contain a boolean `done` field and a\n   *   `value` field. The `value` field is expected to be an array of two\n   *   `tf.Tensor`s or an array of two nested `tf.Tensor` structures. The former\n   *   case is for models with exactly one input and one output (e.g.\n   *   a sequential model). The latter case is for models with multiple\n   *   inputs and/or multiple outputs. Of the two items in the array, the\n   *   first is the input feature(s) and the second is the output target(s).\n   * @param args A configuration object for the dataset-based evaluation.\n   * @returns Loss and metric values as an Array of `Scalar` objects.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async evaluateDataset(l, G) {\n    return this.makeTestFunction(), Ny(this, l, G);\n  }\n  /**\n   * Get number of samples provided for training, evaluation or prediction.\n   *\n   * @param ins Input `tf.Tensor`.\n   * @param batchSize Integer batch size, optional.\n   * @param steps Total number of steps (batches of samples) before\n   * declaring loop finished. Optional.\n   * @param stepsName The public API's parameter name for `steps`.\n   * @returns Number of samples provided.\n   */\n  checkNumSamples(l, G, Z, h = \"steps\") {\n    let g;\n    if (Z != null) {\n      if (g = null, G != null)\n        throw new y(`If ${h} is set, batchSize must be null or undefined.Got batchSize = ${G}`);\n    } else if (l != null)\n      Array.isArray(l) ? g = l[0].shape[0] : g = l.shape[0];\n    else\n      throw new y(`Either the input data should have a defined shape, or ${h} shoud be specified.`);\n    return g;\n  }\n  /**\n   * Execute internal tensors of the model with input data feed.\n   * @param inputs Input data feed. Must match the inputs of the model.\n   * @param outputs Names of the output tensors to be fetched. Must match\n   *   names of the SymbolicTensors that belong to the graph.\n   * @returns Fetched values for `outputs`.\n   */\n  execute(l, G) {\n    if (Array.isArray(G) && G.length === 0)\n      throw new y(\"`outputs` is an empty Array, which is not allowed.\");\n    const Z = Array.isArray(G), h = Z ? G : [G], g = this.retrieveSymbolicTensors(h), b = new BZ();\n    if (l instanceof hG && (l = [l]), Array.isArray(l)) {\n      if (l.length !== this.inputs.length)\n        throw new y(`The number of inputs provided (${l.length}) does not match the number of inputs of this model (${this.inputs.length}).`);\n      for (let d = 0; d < this.inputs.length; ++d)\n        b.add(this.inputs[d], l[d]);\n    } else\n      for (const d of this.inputs) {\n        const W = l[d.name];\n        if (W == null)\n          throw new y(`No value is provided for the model's input ${d.name}`);\n        b.add(d, W);\n      }\n    const c = S0(g, b);\n    return Z ? c : c[0];\n  }\n  /**\n   * Retrieve the model's internal symbolic tensors from symbolic-tensor names.\n   */\n  retrieveSymbolicTensors(l) {\n    const G = ih(null, l.length);\n    let Z = l.length;\n    for (const h of this.layers) {\n      const g = Array.isArray(h.output) ? h.output : [h.output], b = g.map((c) => c.name);\n      for (let c = 0; c < l.length; ++c) {\n        const d = b.indexOf(l[c]);\n        if (d !== -1 && (G[c] = g[d], Z--), Z === 0)\n          break;\n      }\n      if (Z === 0)\n        break;\n    }\n    if (Z > 0) {\n      const h = [];\n      throw G.forEach((g, b) => {\n        g == null && h.push(l[b]);\n      }), new y(`Cannot find SymbolicTensors for output name(s): ${JSON.stringify(h)}`);\n    }\n    return G;\n  }\n  /**\n   * Helper method to loop over some data in batches.\n   *\n   * Porting Note: Not using the functional approach in the Python equivalent\n   *   due to the imperative backend.\n   * Porting Note: Does not support step mode currently.\n   *\n   * @param ins: input data\n   * @param batchSize: integer batch size.\n   * @param verbose: verbosity model\n   * @returns: Predictions as `tf.Tensor` (if a single output) or an `Array` of\n   *   `tf.Tensor` (if multipe outputs).\n   */\n  predictLoop(l, G = 32, Z = !1) {\n    return U(() => {\n      const h = this.checkNumSamples(l);\n      if (Z)\n        throw new Bl(\"Verbose predictLoop() is not implemented yet.\");\n      const g = jd(h, G), b = this.outputs.map((c) => []);\n      for (let c = 0; c < g.length; ++c)\n        U(() => {\n          const W = g[c][0], Y = g[c][1], V = X0(l, W, Y), a = [];\n          if (Array.isArray(V))\n            for (let m = 0; m < V.length; ++m)\n              a.push({ key: this.inputs[m], value: V[m] });\n          else\n            a.push({ key: this.inputs[0], value: V });\n          const i = new BZ(a);\n          return S0(this.outputs, i);\n        }).forEach((W, Y) => b[Y].push(W));\n      return kG(b.map((c) => zG(c, 0)));\n    });\n  }\n  /**\n   * Generates output predictions for the input samples.\n   *\n   * Computation is done in batches.\n   *\n   * Note: the \"step\" mode of predict() is currently not supported.\n   *   This is because the TensorFlow.js core backend is imperative only.\n   *\n   * ```js\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.predict(tf.ones([8, 10]), {batchSize: 4}).print();\n   * ```\n   *\n   * @param x The input data, as a Tensor, or an `Array` of `tf.Tensor`s if\n   *   the model has multiple inputs.\n   * @param args A `ModelPredictArgs` object containing optional fields.\n   *\n   * @return Prediction results as a `tf.Tensor`(s).\n   *\n   * @exception ValueError In case of mismatch between the provided input data\n   *   and the model's expectations, or in case a stateful model receives a\n   *   number of samples that is not a multiple of the batch size.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  predict(l, G = {}) {\n    const Z = Rs(l);\n    Na(Z, this.inputNames, this.feedInputShapes, !1);\n    try {\n      const h = G.batchSize == null ? 32 : G.batchSize;\n      return rd(h), this.predictLoop(Z, h);\n    } finally {\n      CI(Z, l);\n    }\n  }\n  /**\n   * Returns predictions for a single batch of samples.\n   *\n   * ```js\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.predictOnBatch(tf.ones([8, 10])).print();\n   * ```\n   * @param x: Input samples, as a Tensor (for models with exactly one\n   *   input) or an array of Tensors (for models with more than one input).\n   * @return Tensor(s) of predictions\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  predictOnBatch(l) {\n    Na(l, this.inputNames, this.feedInputShapes, !0);\n    const G = (Array.isArray(l) ? l[0] : l).shape[0];\n    return this.predictLoop(l, G);\n  }\n  standardizeUserDataXY(l, G, Z = !0, h) {\n    if (this.optimizer_ == null)\n      throw new aI(\"You must compile a model before training/testing. Use LayersModel.compile(modelCompileArgs).\");\n    const g = [];\n    for (let b = 0; b < this.feedOutputShapes.length; ++b) {\n      const c = this.feedOutputShapes[b];\n      this.feedLossFns[b] === rb ? g.push(c.slice(0, c.length - 1).concat([1])) : g.push(c);\n    }\n    if (l = ya(l, this.feedInputNames, this.feedInputShapes, !1, \"input\"), G = ya(G, this.feedOutputNames, g, !1, \"target\"), Jy(l, G), Ey(G, this.feedLossFns, this.feedOutputShapes), this.stateful && h != null && h > 0 && l[0].shape[0] % h !== 0)\n      throw new y(`In a stateful network, you should only pass inputs with a number of samples that is divisible by the batch size ${h}. Found: ${l[0].shape[0]} sample(s).`);\n    return [l, G];\n  }\n  async standardizeUserData(l, G, Z, h, g = !0, b) {\n    const [c, d] = this.standardizeUserDataXY(l, G, g, b);\n    if (Z != null)\n      throw new Error(\"sample weight is not supported yet.\");\n    let W = null;\n    if (h != null) {\n      const Y = us(h, this.outputNames);\n      W = [];\n      for (let V = 0; V < Y.length; ++V)\n        W.push(await es(d[V], null, Y[V]));\n    }\n    return [c, d, W];\n  }\n  /**\n   * Loop over some test data in batches.\n   * @param f A Function returning a list of tensors.\n   * @param ins Array of tensors to be fed to `f`.\n   * @param batchSize Integer batch size or `null` / `undefined`.\n   * @param verbose verbosity mode.\n   * @param steps Total number of steps (batches of samples) before\n   * declaring test finished. Ignored with the default value of `null` /\n   * `undefined`.\n   * @returns Array of Scalars.\n   */\n  testLoop(l, G, Z, h = 0, g) {\n    return U(() => {\n      const b = this.checkNumSamples(G, Z, g, \"steps\"), c = [];\n      if (h > 0)\n        throw new Bl(\"Verbose mode is not implemented yet.\");\n      if (g != null)\n        throw new Bl(\"steps mode in testLoop() is not implemented yet\");\n      {\n        const d = jd(b, Z), W = jG(FI(0, b));\n        for (let Y = 0; Y < d.length; ++Y) {\n          const V = d[Y][0], a = d[Y][1], i = Ih(W, V, a - V), m = EW(G, i), T = l(m);\n          if (Y === 0)\n            for (let s = 0; s < T.length; ++s)\n              c.push(yl(0));\n          for (let s = 0; s < T.length; ++s) {\n            const o = T[s];\n            c[s] = O(c[s], N(a - V, o));\n          }\n        }\n        for (let Y = 0; Y < c.length; ++Y)\n          c[Y] = Vl(c[Y], b);\n      }\n      return c;\n    });\n  }\n  getDedupedMetricsNames() {\n    const l = this.metricsNames, G = [];\n    for (let Z = 0; Z < l.length; ++Z) {\n      const h = l[Z];\n      let g = h;\n      if (ma(l, h) > 1) {\n        const b = ma(l.slice(0, Z), h);\n        g += `_${b}`;\n      }\n      G.push(g);\n    }\n    return G;\n  }\n  /**\n   * Creates a function that performs the following actions:\n   *\n   * 1. computes the losses\n   * 2. sums them to get the total loss\n   * 3. call the optimizer computes the gradients of the LayersModel's\n   *    trainable weights w.r.t. the total loss and update the variables\n   * 4. calculates the metrics\n   * 5. returns the values of the losses and metrics.\n   */\n  makeTrainFunction() {\n    return (l) => {\n      const G = [], Z = l.slice(0, this.inputs.length), h = l.slice(this.inputs.length, this.inputs.length + this.outputs.length), g = l.slice(this.inputs.length + this.outputs.length, this.inputs.length + this.outputs.length * 2), b = [], c = () => {\n        const V = [];\n        for (let T = 0; T < this.inputs.length; ++T)\n          V.push({ key: this.inputs[T], value: Z[T] });\n        const a = new BZ(V), i = S0(this.outputs, a, { training: !0 });\n        let m;\n        for (let T = 0; T < this.lossFunctions.length; ++T) {\n          const s = this.lossFunctions[T];\n          let o = s(h[T], i[T]);\n          g[T] != null && (o = ey(o, g[T]));\n          const B = gG(o);\n          G.push(B), T === 0 ? m = o : m = O(m, o);\n        }\n        for (let T = 0; T < this.metricsTensors.length; ++T) {\n          let s;\n          if (this.outputs.length > 1 && T < this.outputs.length)\n            s = G[T];\n          else {\n            const o = this.metricsTensors[T][0], B = this.metricsTensors[T][1];\n            s = gG(o(h[B], i[B]));\n          }\n          LI(s), b.push(s);\n        }\n        return m = gG(m), this.calculateLosses().forEach((T) => {\n          m = O(m, T);\n        }), m;\n      }, d = this.collectedTrainableWeights.map((V) => V.read());\n      return [this.optimizer_.minimize(c, !0, d)].concat(b);\n    };\n  }\n  /**\n   * Create a function which, when invoked with an array of `tf.Tensor`s as a\n   * batch of inputs, returns the prespecified loss and metrics of the model\n   * under the batch of input data.\n   */\n  makeTestFunction() {\n    this.testFunction = (l) => U(() => {\n      const G = [];\n      let Z;\n      const h = l.slice(0, this.inputs.length), g = l.slice(this.inputs.length, this.inputs.length + this.outputs.length), b = [];\n      for (let W = 0; W < this.inputs.length; ++W)\n        b.push({ key: this.inputs[W], value: h[W] });\n      const c = new BZ(b), d = S0(this.outputs, c);\n      for (let W = 0; W < this.lossFunctions.length; ++W) {\n        const Y = this.lossFunctions[W], V = gG(Y(g[W], d[W]));\n        W === 0 ? Z = V : Z = O(Z, V), G.push(Z);\n      }\n      for (let W = 0; W < this.metricsTensors.length; ++W) {\n        const Y = this.metricsTensors[W][0], V = this.metricsTensors[W][1], a = gG(Y(g[V], d[V]));\n        G.push(a);\n      }\n      return G;\n    });\n  }\n  /**\n   * Trains the model for a fixed number of epochs (iterations on a\n   * dataset).\n   *\n   * ```js\n   * const model = tf.sequential({\n   *     layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});\n   * for (let i = 1; i < 5 ; ++i) {\n   *   const h = await model.fit(tf.ones([8, 10]), tf.ones([8, 1]), {\n   *       batchSize: 4,\n   *       epochs: 3\n   *   });\n   *   console.log(\"Loss after Epoch \" + i + \" : \" + h.history.loss[0]);\n   * }\n   * ```\n   *\n   * @param x `tf.Tensor` of training data, or an array of `tf.Tensor`s if the\n   * model has multiple inputs. If all inputs in the model are named, you\n   * can also pass a dictionary mapping input names to `tf.Tensor`s.\n   * @param y `tf.Tensor` of target (label) data, or an array of `tf.Tensor`s if\n   * the model has multiple outputs. If all outputs in the model are named,\n   * you can also pass a dictionary mapping output names to `tf.Tensor`s.\n   * @param args A `ModelFitArgs`, containing optional fields.\n   *\n   * @return A `History` instance. Its `history` attribute contains all\n   *   information collected during training.\n   *\n   * @exception ValueError In case of mismatch between the provided input\n   * data and what the model expects.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async fit(l, G, Z = {}) {\n    if (this.isTraining)\n      throw new Error(\"Cannot start training because another fit() call is ongoing.\");\n    this.isTraining = !0;\n    let h, g, b, c, d, W, Y, V, a;\n    try {\n      const i = Z.batchSize == null ? 32 : Z.batchSize;\n      rd(i);\n      const T = await this.standardizeUserData(l, G, Z.sampleWeight, Z.classWeight, !1, i);\n      h = T[0], g = T[1], a = T[2];\n      let s = !1, o;\n      if (Z.validationData != null && Z.validationData.length > 0) {\n        if (s = !0, Z.validationData.length === 2)\n          d = Z.validationData[0], W = Z.validationData[1];\n        else throw Z.validationData.length === 3 ? new Bl(\"validationData including sample weights is not supported yet.\") : new y(`When passing validation data, it must contain 2 (valX, valY) or 3 (valX, valY, valSampleWeight) items; ${Z.validationData} is invalid.`);\n        const F = await this.standardizeUserData(\n          d,\n          W,\n          null,\n          /** Unused sample weights. */\n          null,\n          !0,\n          i\n        );\n        Y = F[0], V = F[1], o = Y.concat(V);\n      } else if (Z.validationSplit != null && Z.validationSplit > 0 && Z.validationSplit < 1) {\n        s = !0;\n        const p = Math.floor(h[0].shape[0] * (1 - Z.validationSplit)), F = h[0].shape[0];\n        Y = X0(h, p, F), b = h, h = X0(h, 0, p), V = X0(g, p, F), c = g, g = X0(g, 0, p), o = Y.concat(V);\n      } else Z.validationSteps != null && (s = !0);\n      const B = h.concat(g).concat(a);\n      this.checkTrainableWeightsConsistency();\n      const C = this.makeTrainFunction(), n = this.getDedupedMetricsNames();\n      let X, t;\n      s ? (this.makeTestFunction(), X = this.testFunction, t = n.slice().concat(n.map((p) => \"val_\" + p))) : (X = null, o = [], t = n.slice());\n      const e = ms(Z.callbacks, Z.yieldEvery);\n      return await this.fitLoop(C, B, n, i, Z.epochs, Z.verbose, e, X, o, Z.shuffle, t, Z.initialEpoch, null, null);\n    } finally {\n      this.isTraining = !1, CI(h, l), CI(g, G), CI(b, l), CI(c, G), CI(Y, d), CI(V, W), a != null && Cl(a);\n    }\n  }\n  /**\n   * Abstract fit function for `f(ins)`.\n   * @param f A Function returning a list of tensors. For training, this\n   *   function is expected to perform the updates to the variables.\n   * @param ins List of tensors to be fed to `f`.\n   * @param outLabels List of strings, display names of the outputs of `f`.\n   * @param batchSize Integer batch size or `== null` if unknown. Default : 32.\n   * @param epochs Number of times to iterate over the data. Default : 1.\n   * @param verbose Verbosity mode: 0, 1, or 2. Default: 1.\n   * @param callbacks List of callbacks to be called during training.\n   * @param valF Function to call for validation.\n   * @param valIns List of tensors to be fed to `valF`.\n   * @param shuffle Whether to shuffle the data at the beginning of every\n   * epoch. Default : true.\n   * @param callbackMetrics List of strings, the display names of the metrics\n   *   passed to the callbacks. They should be the concatenation of the\n   *   display names of the outputs of `f` and the list of display names\n   *   of the outputs of `valF`.\n   * @param initialEpoch Epoch at which to start training (useful for\n   *   resuming a previous training run). Default : 0.\n   * @param stepsPerEpoch Total number of steps (batches on samples) before\n   *   declaring one epoch finished and starting the next epoch. Ignored with\n   *   the default value of `undefined` or `null`.\n   * @param validationSteps Number of steps to run validation for (only if\n   *   doing validation from data tensors). Not applicable for tfjs-layers.\n   * @returns A `History` object.\n   */\n  async fitLoop(l, G, Z, h, g, b, c, d, W, Y, V, a, i, m) {\n    h == null && (h = 32), g == null && (g = 1), Y == null && (Y = !0), a == null && (a = 0);\n    let T = !1;\n    if (d != null && W != null && (T = !0), m != null && (T = !0, i == null))\n      throw new y(\"Can only use `validationSteps` when doing step-wise training, i.e., `stepsPerEpoch` must be set.\");\n    const s = this.checkNumSamples(G, h, i, \"steps_per_epoch\");\n    let o;\n    s != null && (o = FI(0, s)), b == null && (b = 1);\n    const { callbackList: B, history: C } = Ts(c, b, g, a, s, i, h, T, V);\n    B.setModel(this), this.history = C, await B.onTrainBegin(), this.stopTraining_ = !1;\n    for (let n = a; n < g; ++n) {\n      await B.onEpochBegin(n);\n      const X = {};\n      if (i != null)\n        throw new Bl(\"stepsPerEpoch mode is not implemented yet.\");\n      {\n        if (Y === \"batch\")\n          throw new Bl(\"batch shuffling is not implemneted yet\");\n        Y && sn(o);\n        const t = jG(o), e = jd(s, h);\n        for (let S = 0; S < e.length; ++S) {\n          const p = {};\n          if (await B.onBatchBegin(S, p), U(() => {\n            const F = e[S][0], x = e[S][1], H = Ih(t, F, x - F);\n            p.batch = S, p.size = x - F;\n            const K = EW(G, H), z = l(K);\n            for (let k = 0; k < Z.length; ++k) {\n              const L = Z[k], v = z[k];\n              p[L] = v, LI(v);\n            }\n            if (S === e.length - 1 && T) {\n              const k = this.testLoop(d, W, h);\n              for (let L = 0; L < Z.length; ++L) {\n                const v = Z[L], w = k[L];\n                LI(w), X[\"val_\" + v] = w;\n              }\n            }\n          }), await B.onBatchEnd(S, p), is(p), this.stopTraining_)\n            break;\n        }\n        t.dispose();\n      }\n      if (await B.onEpochEnd(n, X), this.stopTraining_)\n        break;\n    }\n    return await B.onTrainEnd(), await this.history.syncData(), this.history;\n  }\n  // TODO(cais): Add code snippet below when it's possible to instantiate\n  //   actual dataset objects.\n  /**\n   * Trains the model using a dataset object.\n   *\n   * @param dataset A dataset object. Its `iterator()` method is expected\n   *   to generate a dataset iterator object, the `next()` method of which\n   *   is expected to produce data batches for training. The return value\n   *   of the `next()` call ought to contain a boolean `done` field and a\n   *   `value` field. The `value` field is expected to be an array of two\n   *   `tf.Tensor`s or an array of two nested `tf.Tensor` structures. The former\n   *   case is for models with exactly one input and one output (e.g.\n   *   a sequential model). The latter case is for models with multiple\n   *   inputs and/or multiple outputs.\n   *   Of the two items in the array, the first is the input feature(s) and\n   *   the second is the output target(s).\n   * @param args A `ModelFitDatasetArgs`, containing optional fields.\n   *\n   * @return A `History` instance. Its `history` attribute contains all\n   *   information collected during training.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async fitDataset(l, G) {\n    return py(this, l, G);\n  }\n  /**\n   * Runs a single gradient update on a single batch of data.\n   *\n   * This method differs from `fit()` and `fitDataset()` in the following\n   * regards:\n   *   - It operates on exactly one batch of data.\n   *   - It returns only the loss and metric values, instead of\n   *     returning the batch-by-batch loss and metric values.\n   *   - It doesn't support fine-grained options such as verbosity and\n   *     callbacks.\n   *\n   * @param x Input data. It could be one of the following:\n   *   - A `tf.Tensor`, or an Array of `tf.Tensor`s (in case the model has\n   *     multiple inputs).\n   *   - An Object mapping input names to corresponding `tf.Tensor` (if the\n   *     model has named inputs).\n   * @param y Target data. It could be either a `tf.Tensor` or multiple\n   *   `tf.Tensor`s. It should be consistent with `x`.\n   * @returns Training loss or losses (in case the model has\n   *   multiple outputs), along with metrics (if any), as numbers.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async trainOnBatch(l, G) {\n    const Z = await this.standardizeUserData(l, G), h = Z[0], g = Z[1], c = this.makeTrainFunction()(h.concat(g)), d = [];\n    for (const W of c) {\n      const Y = await W.data();\n      d.push(Y[0]);\n    }\n    return Cl(c), CI(Z[0], l), CI(Z[1], G), kG(d);\n  }\n  /**\n   * Extract weight values of the model.\n   *\n   * @param config: An instance of `io.SaveConfig`, which specifies\n   * model-saving options such as whether only trainable weights are to be\n   * saved.\n   * @returns A `NamedTensorMap` mapping original weight names (i.e.,\n   *   non-uniqueified weight names) to their values.\n   */\n  getNamedWeights(l) {\n    const G = [], Z = l != null && l.trainableOnly, h = Z ? this.trainableWeights : this.weights, g = this.getWeights(Z);\n    for (let b = 0; b < h.length; ++b)\n      Z && !h[b].trainable || G.push({ name: h[b].originalName, tensor: g[b] });\n    return G;\n  }\n  /**\n   * Setter used for force stopping of LayersModel.fit() (i.e., training).\n   *\n   * Example:\n   *\n   * ```js\n   * const input = tf.input({shape: [10]});\n   * const output = tf.layers.dense({units: 1}).apply(input);\n   * const model = tf.model({inputs: [input], outputs: [output]});\n   * model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});\n   * const xs = tf.ones([8, 10]);\n   * const ys = tf.zeros([8, 1]);\n   *\n   * const history = await model.fit(xs, ys, {\n   *   epochs: 10,\n   *   callbacks: {\n   *     onEpochEnd: async (epoch, logs) => {\n   *       if (epoch === 2) {\n   *         model.stopTraining = true;\n   *       }\n   *     }\n   *   }\n   * });\n   *\n   * // There should be only 3 values in the loss array, instead of 10\n   * values,\n   * // due to the stopping after 3 epochs.\n   * console.log(history.history.loss);\n   * ```\n   */\n  set stopTraining(l) {\n    this.stopTraining_ = l;\n  }\n  get stopTraining() {\n    return this.stopTraining_;\n  }\n  get optimizer() {\n    return this.optimizer_;\n  }\n  set optimizer(l) {\n    this.optimizer_ !== l && (this.optimizer_ = l, this.isOptimizerOwned = !1);\n  }\n  dispose() {\n    const l = super.dispose();\n    if (l.refCountAfterDispose === 0 && this.optimizer != null && this.isOptimizerOwned) {\n      const G = O9().numTensors;\n      this.optimizer_.dispose(), l.numDisposedVariables += G - O9().numTensors;\n    }\n    return l;\n  }\n  getLossIdentifiers() {\n    let l;\n    if (typeof this.loss == \"string\")\n      l = _I(this.loss);\n    else if (Array.isArray(this.loss)) {\n      for (const G of this.loss)\n        if (typeof G != \"string\")\n          throw new Error(\"Serialization of non-string loss is not supported.\");\n      l = this.loss.map((G) => _I(G));\n    } else {\n      const G = Object.keys(this.loss);\n      l = {};\n      const Z = this.loss;\n      for (const h of G)\n        if (typeof Z[h] == \"string\")\n          l[h] = _I(Z[h]);\n        else\n          throw new Error(\"Serialization of non-string loss is not supported.\");\n    }\n    return l;\n  }\n  getMetricIdentifiers() {\n    if (typeof this.metrics == \"string\" || typeof this.metrics == \"function\")\n      return [_I(nb(this.metrics))];\n    if (Array.isArray(this.metrics))\n      return this.metrics.map((l) => _I(nb(l)));\n    {\n      const l = {};\n      for (const G in this.metrics)\n        l[G] = _I(nb(this.metrics[G]));\n      return l;\n    }\n  }\n  getTrainingConfig() {\n    return {\n      loss: this.getLossIdentifiers(),\n      metrics: this.getMetricIdentifiers(),\n      optimizer_config: {\n        class_name: this.optimizer.getClassName(),\n        config: this.optimizer.getConfig()\n      }\n    };\n  }\n  loadTrainingConfig(l) {\n    if (l.weighted_metrics != null)\n      throw new Error(\"Loading weight_metrics is not supported yet.\");\n    if (l.loss_weights != null)\n      throw new Error(\"Loading loss_weights is not supported yet.\");\n    if (l.sample_weight_mode != null)\n      throw new Error(\"Loading sample_weight_mode is not supported yet.\");\n    const G = PW(l.optimizer_config), Z = ZZ(G);\n    let h;\n    if (typeof l.loss == \"string\")\n      h = DZ(l.loss);\n    else if (Array.isArray(l.loss))\n      h = l.loss.map((b) => DZ(b));\n    else if (l.loss != null) {\n      h = {};\n      for (const b in l.loss)\n        h[b] = DZ(l.loss[b]);\n    }\n    let g;\n    if (Array.isArray(l.metrics))\n      g = l.metrics.map((b) => DZ(b));\n    else if (l.metrics != null) {\n      g = {};\n      for (const b in l.metrics)\n        g[b] = DZ(l.metrics[b]);\n    }\n    this.compile({ loss: h, metrics: g, optimizer: Z });\n  }\n  /**\n   * Save the configuration and/or weights of the LayersModel.\n   *\n   * An `IOHandler` is an object that has a `save` method of the proper\n   * signature defined. The `save` method manages the storing or\n   * transmission of serialized data (\"artifacts\") that represent the\n   * model's topology and weights onto or via a specific medium, such as\n   * file downloads, local storage, IndexedDB in the web browser and HTTP\n   * requests to a server. TensorFlow.js provides `IOHandler`\n   * implementations for a number of frequently used saving mediums, such as\n   * `tf.io.browserDownloads` and `tf.io.browserLocalStorage`. See `tf.io`\n   * for more details.\n   *\n   * This method also allows you to refer to certain types of `IOHandler`s\n   * as URL-like string shortcuts, such as 'localstorage://' and\n   * 'indexeddb://'.\n   *\n   * Example 1: Save `model`'s topology and weights to browser [local\n   * storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage);\n   * then load it back.\n   *\n   * ```js\n   * const model = tf.sequential(\n   *     {layers: [tf.layers.dense({units: 1, inputShape: [3]})]});\n   * console.log('Prediction from original model:');\n   * model.predict(tf.ones([1, 3])).print();\n   *\n   * const saveResults = await model.save('localstorage://my-model-1');\n   *\n   * const loadedModel = await tf.loadLayersModel('localstorage://my-model-1');\n   * console.log('Prediction from loaded model:');\n   * loadedModel.predict(tf.ones([1, 3])).print();\n   * ```\n   *\n   * Example 2. Saving `model`'s topology and weights to browser\n   * [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API);\n   * then load it back.\n   *\n   * ```js\n   * const model = tf.sequential(\n   *     {layers: [tf.layers.dense({units: 1, inputShape: [3]})]});\n   * console.log('Prediction from original model:');\n   * model.predict(tf.ones([1, 3])).print();\n   *\n   * const saveResults = await model.save('indexeddb://my-model-1');\n   *\n   * const loadedModel = await tf.loadLayersModel('indexeddb://my-model-1');\n   * console.log('Prediction from loaded model:');\n   * loadedModel.predict(tf.ones([1, 3])).print();\n   * ```\n   *\n   * Example 3. Saving `model`'s topology and weights as two files\n   * (`my-model-1.json` and `my-model-1.weights.bin`) downloaded from\n   * browser.\n   *\n   * ```js\n   * const model = tf.sequential(\n   *     {layers: [tf.layers.dense({units: 1, inputShape: [3]})]});\n   * const saveResults = await model.save('downloads://my-model-1');\n   * ```\n   *\n   * Example 4. Send  `model`'s topology and weights to an HTTP server.\n   * See the documentation of `tf.io.http` for more details\n   * including specifying request parameters and implementation of the\n   * server.\n   *\n   * ```js\n   * const model = tf.sequential(\n   *     {layers: [tf.layers.dense({units: 1, inputShape: [3]})]});\n   * const saveResults = await model.save('http://my-server/model/upload');\n   * ```\n   *\n   * @param handlerOrURL An instance of `IOHandler` or a URL-like,\n   * scheme-based string shortcut for `IOHandler`.\n   * @param config Options for saving the model.\n   * @returns A `Promise` of `SaveResult`, which summarizes the result of\n   * the saving, such as byte sizes of the saved artifacts for the model's\n   *   topology and weight values.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes', ignoreCI: true}\n   */\n  async save(l, G) {\n    if (typeof l == \"string\") {\n      const W = aC(l);\n      if (W.length === 0)\n        throw new y(`Cannot find any save handlers for URL '${l}'`);\n      if (W.length > 1)\n        throw new y(`Found more than one (${W.length}) save handlers for URL '${l}'`);\n      l = W[0];\n    }\n    if (l.save == null)\n      throw new y(\"LayersModel.save() cannot proceed because the IOHandler provided does not have the `save` attribute defined.\");\n    const Z = await $9(this.getNamedWeights(G)), c = {\n      modelTopology: this.toJSON(null, !1),\n      format: Uy,\n      generatedBy: `TensorFlow.js tfjs-layers v${ts}`,\n      convertedBy: null\n    };\n    if ((G == null ? !1 : G.includeOptimizer) && this.optimizer != null) {\n      c.trainingConfig = this.getTrainingConfig();\n      const W = \"optimizer\", { data: Y, specs: V } = await $9(await this.optimizer.getWeights(), W);\n      Z.specs.push(...V), Z.data = VC([Z.data, Y]);\n    }\n    return this.userDefinedMetadata != null && (Sa(this.userDefinedMetadata, this.name, !0), c.userDefinedMetadata = this.userDefinedMetadata), c.weightData = Z.data, c.weightSpecs = Z.specs, l.save(c);\n  }\n  /**\n   * Set user-defined metadata.\n   *\n   * The set metadata will be serialized together with the topology\n   * and weights of the model during `save()` calls.\n   *\n   * @param setUserDefinedMetadata\n   */\n  setUserDefinedMetadata(l) {\n    Sa(l, this.name), this.userDefinedMetadata = l;\n  }\n  /**\n   * Get user-defined metadata.\n   *\n   * The metadata is supplied via one of the two routes:\n   *   1. By calling `setUserDefinedMetadata()`.\n   *   2. Loaded during model loading (if the model is constructed\n   *      via `tf.loadLayersModel()`.)\n   *\n   * If no user-defined metadata is available from either of the\n   * two routes, this function will return `undefined`.\n   */\n  getUserDefinedMetadata() {\n    return this.userDefinedMetadata;\n  }\n}\nzh.className = \"Model\";\nj(zh);\nclass ps extends zh {\n}\nps.className = \"Functional\";\nj(ps);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass A0 extends zh {\n  constructor(l) {\n    if (super({ inputs: [], outputs: [] }), l = l || {}, this.trainable = !0, this.built = !1, this.name = l.name != null ? l.name : od(\"sequential_\"), l.layers != null)\n      for (const G of l.layers)\n        this.add(G);\n  }\n  // Helper function to Sequential.add  Throws if the new output shape will be\n  // invalid.\n  checkShape(l) {\n    if (l.inboundNodes[0].outputTensors[0].shape.some((Z) => Z < 0))\n      throw new y(`Negative dimension size caused by adding layer ${l.name} with input shape [${l.inboundNodes[0].inputTensors[0].shape}]`);\n  }\n  /**\n   * Adds a layer instance on top of the layer stack.\n   *\n   * ```js\n   *  const model = tf.sequential();\n   *  model.add(tf.layers.dense({units: 8, inputShape: [1]}));\n   *  model.add(tf.layers.dense({units: 4, activation: 'relu6'}));\n   *  model.add(tf.layers.dense({units: 1, activation: 'relu6'}));\n   *  // Note that the untrained model is random at this point.\n   *  model.predict(tf.randomNormal([10, 1])).print();\n   * ```\n   * @param layer Layer instance.\n   *\n   * @exception ValueError In case the `layer` argument does not know its\n   * input shape.\n   * @exception ValueError In case the `layer` argument has multiple output\n   *   tensors, or is already connected somewhere else (forbidden in\n   *   `Sequential` models).\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  add(l) {\n    const G = l instanceof A0 || l instanceof zh;\n    let Z;\n    if (G) {\n      if (Z = l, Z.outputs.length !== 1)\n        throw new y(\"All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.\");\n      if (Z.inputs.length !== 1)\n        throw new y(\"All layers in a Sequential model should have a single input tensor. For multi-input layers, use the functional API.\");\n    }\n    if (this.outputs.length === 0) {\n      if (l.inboundNodes.length === 0) {\n        if (l.batchInputShape == null)\n          throw new y(\"The first layer in a Sequential model must get an `inputShape` or `batchInputShape` argument.\");\n        const h = KF({\n          batchShape: l.batchInputShape,\n          dtype: l.dtype,\n          name: l.name + \"_input\"\n        });\n        l.apply(h);\n      }\n      if (G)\n        this.outputs = Z.outputs, this.inputs = Z.inputs;\n      else {\n        if (l.inboundNodes.length !== 1)\n          throw new y(`A layer added to a Sequential model must not already be connected somewhere else. LayersModel received layer ${l.name} which has ${l.inboundNodes.length} pre-existing inbound connections.`);\n        if (l.inboundNodes[0].outputTensors.length !== 1)\n          throw new y(\"All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.\");\n        this.checkShape(l), this.outputs = [l.inboundNodes[0].outputTensors[0]], this.inputs = ds(this.outputs[0]);\n      }\n      this.inboundNodes = [], new nd({\n        outboundLayer: this,\n        inboundLayers: [],\n        nodeIndices: [],\n        tensorIndices: [],\n        inputTensors: this.inputs,\n        outputTensors: this.outputs,\n        // no model-level masking for now\n        inputMasks: ih(null, this.inputs.length),\n        outputMasks: [null],\n        inputShapes: this.inputs.map((h) => h.shape),\n        outputShapes: this.outputs[0].shape\n      });\n    } else {\n      const h = l.apply(this.outputs[0]);\n      if (Array.isArray(h))\n        throw new TypeError(\"All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.\");\n      this.checkShape(l), this.outputs = [h], this.inboundNodes[0].outputTensors = this.outputs, this.inboundNodes[0].outputShapes = [this.outputs[0].shape];\n    }\n    this.layers.push(l), this.built = !1;\n  }\n  /**\n   * Removes the last layer in the model.\n   *\n   * @exception TypeError if there are no layers in the model.\n   */\n  pop() {\n    if (this.layers.length === 0)\n      throw new TypeError(\"There are no layers in the model.\");\n    if (this.layers.pop(), this.layers.length === 0)\n      this.outputs = [], this.inboundNodes = [], this.outboundNodes = [];\n    else {\n      const l = this.layers.length - 1;\n      this.layers[l].outboundNodes = [], this.outputs = [this.layers[l].output], this.inboundNodes[0].outputTensors = this.outputs, this.inboundNodes[0].outputShapes = [this.outputs[0].shape];\n    }\n  }\n  call(l, G) {\n    return this.model == null && this.build(), this.model.call(l, G);\n  }\n  build(l) {\n    if (pl(l), this.inputs.length === 0 || this.outputs.length === 0)\n      throw new TypeError(\"Sequential model cannot be built: model is empty. Add some layers first.\");\n    this.model = new zh({\n      inputs: this.inputs,\n      outputs: this.outputs[0],\n      name: this.name + \"_model\"\n    }), this.model.trainable = this.trainable, this.supportsMasking = this.model.supportsMasking, this.inputLayers = this.model.inputLayers, this.inputLayersNodeIndices = this.model.inputLayersNodeIndices, this.inputLayersTensorIndices = this.model.inputLayersTensorIndices, this.outputLayers = this.model.outputLayers, this.outputLayersNodeIndices = this.model.outputLayersNodeIndices, this.outputLayersTensorIndices = this.model.outputLayersTensorIndices, this.nodesByDepth = this.model.nodesByDepth, this.containerNodes = this.model.containerNodes, this.outputNames = this.model.outputNames, this.inputNames = this.model.inputNames, this.built = !0;\n  }\n  countParams() {\n    return this.built || this.build(), super.countParams();\n  }\n  /**\n   * Print a text summary of the Sequential model's layers.\n   *\n   * The summary includes\n   * - Name and type of all layers that comprise the model.\n   * - Output shape(s) of the layers\n   * - Number of weight parameters of each layer\n   * - The total number of trainable and non-trainable parameters of the\n   * model.\n   *\n   * ```js\n   * const model = tf.sequential();\n   * model.add(\n   *     tf.layers.dense({units: 100, inputShape: [10], activation: 'relu'}));\n   * model.add(tf.layers.dense({units: 1, activation: 'sigmoid'}));\n   *\n   * model.summary();\n   * ```\n   *\n   * @param lineLength Custom line length, in number of characters.\n   * @param positions Custom widths of each of the columns, as either\n   *   fractions of `lineLength` (e.g., `[0.5, 0.75, 1]`) or absolute number\n   *   of characters (e.g., `[30, 50, 65]`). Each number corresponds to\n   *   right-most (i.e., ending) position of a column.\n   * @param printFn Custom print function. Can be used to replace the default\n   *   `console.log`. For example, you can use `x => {}` to mute the printed\n   *   messages in the console.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  summary(l, G, Z = console.log) {\n    this.built || this.build(), super.summary(l, G, Z);\n  }\n  /**\n   * Sets the weights of the model.\n   *\n   * @param weights Should be a list of Tensors with shapes and types matching\n   *   the output of `model.getWeights()`.\n   */\n  setWeights(l) {\n    this.model == null && this.build(), this.model.setWeights(l);\n  }\n  /**\n   * Returns the loss value & metrics values for the model in test mode.\n   *\n   * Loss and metrics are specified during `compile()`, which needs to happen\n   * before calls to `evaluate()`.\n   *\n   * Computation is done in batches.\n   *\n   * ```js\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});\n   * const result = model.evaluate(tf.ones([8, 10]), tf.ones([8, 1]), {\n   *   batchSize: 4,\n   * });\n   * result.print();\n   * ```\n   *\n   * @param x `tf.Tensor` of test data, or an `Array` of `tf.Tensor`s if the\n   * model has multiple inputs.\n   * @param y `tf.Tensor` of target data, or an `Array` of `tf.Tensor`s if the\n   * model has multiple outputs.\n   * @param args A `ModelEvaluateConfig`, containing optional fields.\n   *\n   * @return `Scalar` test loss (if the model has a single output and no\n   *   metrics) or `Array` of `Scalar`s (if the model has multiple outputs\n   *   and/or metrics). The attribute `model.metricsNames`\n   *   will give you the display labels for the scalar outputs.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  evaluate(l, G, Z = {}) {\n    if (!this.built)\n      throw new aI(\"The model needs to be compiled before being used.\");\n    return this.model.evaluate(l, G, Z);\n  }\n  // TODO(cais): Add code snippet below once real dataset objects are\n  //   available.\n  /**\n   * Evaluate model using a dataset object.\n   *\n   * Note: Unlike `evaluate()`, this method is asynchronous (`async`).\n   *\n   * @param dataset A dataset object. Its `iterator()` method is expected\n   *   to generate a dataset iterator object, the `next()` method of which\n   *   is expected to produce data batches for evaluation. The return value\n   *   of the `next()` call ought to contain a boolean `done` field and a\n   *   `value` field. The `value` field is expected to be an array of two\n   *   `tf.Tensor`s or an array of two nested `tf.Tensor` structures. The former\n   *   case is for models with exactly one input and one output (e.g.\n   *   a sequential model). The latter case is for models with multiple\n   *   inputs and/or multiple outputs. Of the two items in the array, the\n   *   first is the input feature(s) and the second is the output target(s).\n   * @param args A configuration object for the dataset-based evaluation.\n   * @returns Loss and metric values as an Array of `Scalar` objects.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async evaluateDataset(l, G) {\n    if (!this.built)\n      throw new aI(\"The model needs to be compiled before being used.\");\n    return this.model.evaluateDataset(l, G);\n  }\n  /**\n   * Generates output predictions for the input samples.\n   *\n   * Computation is done in batches.\n   *\n   * Note: the \"step\" mode of predict() is currently not supported.\n   *   This is because the TensorFlow.js core backend is imperative only.\n   *\n   * ```js\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.predict(tf.ones([2, 10])).print();\n   * ```\n   *\n   * @param x The input data, as a Tensor, or an `Array` of `tf.Tensor`s if\n   *   the model has multiple inputs.\n   * @param conifg A `ModelPredictConfig` object containing optional fields.\n   *\n   * @return `tf.Tensor`(s) of predictions.\n   *\n   * @exception ValueError In case of mismatch between the provided input data\n   *   and the model's expectations, or in case a stateful model receives a\n   *   number of samples that is not a multiple of the batch size.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  predict(l, G = {}) {\n    return this.model == null && this.build(), this.model.predict(l, G);\n  }\n  /**\n   * Returns predictions for a single batch of samples.\n   *\n   * @param x: Input samples, as a Tensor, or list of Tensors (if the model\n   *   has multiple inputs).\n   * @return Tensor(s) of predictions\n   */\n  predictOnBatch(l) {\n    return this.model == null && this.build(), this.model.predictOnBatch(l);\n  }\n  /**\n   * See `LayersModel.compile`.\n   *\n   * @param args\n   */\n  compile(l) {\n    this.build(), this.model.compile(l), this.optimizer_ = this.model.optimizer, this.isOptimizerOwned = this.model.isOptimizerOwned, this.loss = this.model.loss, this.metrics = this.model.metrics, this.metricsTensors = this.model.metricsTensors, this.metricsNames = this.model.metricsNames;\n  }\n  get optimizer() {\n    return this.model == null ? void 0 : this.model.optimizer;\n  }\n  set optimizer(l) {\n    this.model.optimizer = l;\n  }\n  /**\n   * Trains the model for a fixed number of epochs (iterations on a dataset).\n   *\n   * ```js\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [10]})]\n   * });\n   * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});\n   * const history = await model.fit(tf.ones([8, 10]), tf.ones([8, 1]), {\n   *   batchSize: 4,\n   *   epochs: 3\n   * });\n   * console.log(history.history.loss[0]);\n   * ```\n   *\n   * @param x `tf.Tensor` of training data, or an array of `tf.Tensor`s if the\n   * model has multiple inputs. If all inputs in the model are named, you can\n   * also pass a dictionary mapping input names to `tf.Tensor`s.\n   * @param y `tf.Tensor` of target (label) data, or an array of `tf.Tensor`s if\n   * the model has multiple outputs. If all outputs in the model are named, you\n   *  can also pass a dictionary mapping output names to `tf.Tensor`s.\n   * @param args  A `ModelFitConfig`, containing optional fields.\n   *\n   * @return A `History` instance. Its `history` attribute contains all\n   *   information collected during training.\n   *\n   * @exception ValueError In case of mismatch between the provided input data\n   *   and what the model expects.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async fit(l, G, Z = {}) {\n    if (!this.built)\n      throw new aI(\"The model needs to be compiled before being used.\");\n    return this.model.fit(l, G, Z);\n  }\n  /**\n   * Trains the model using a dataset object.\n   *\n   * ```js\n   * const xArray = [\n   *   [1, 1, 1, 1, 1, 1, 1, 1, 1],\n   *   [1, 1, 1, 1, 1, 1, 1, 1, 1],\n   *   [1, 1, 1, 1, 1, 1, 1, 1, 1],\n   *   [1, 1, 1, 1, 1, 1, 1, 1, 1],\n   * ];\n   * const yArray = [1, 1, 1, 1];\n   * // Create a dataset from the JavaScript array.\n   * const xDataset = tf.data.array(xArray);\n   * const yDataset = tf.data.array(yArray);\n   * // Zip combines the `x` and `y` Datasets into a single Dataset, the\n   * // iterator of which will return an object containing of two tensors,\n   * // corresponding to `x` and `y`.  The call to `batch(4)` will bundle\n   * // four such samples into a single object, with the same keys now pointing\n   * // to tensors that hold 4 examples, organized along the batch dimension.\n   * // The call to `shuffle(4)` causes each iteration through the dataset to\n   * // happen in a different order.  The size of the shuffle window is 4.\n   * const xyDataset = tf.data.zip({xs: xDataset, ys: yDataset})\n   *     .batch(4)\n   *     .shuffle(4);\n   * const model = tf.sequential({\n   *   layers: [tf.layers.dense({units: 1, inputShape: [9]})]\n   * });\n   * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});\n   * const history = await model.fitDataset(xyDataset, {\n   *   epochs: 4,\n   *   callbacks: {onEpochEnd: (epoch, logs) => console.log(logs.loss)}\n   * });\n   * ```\n   *\n   * @param dataset A dataset object. Its `iterator()` method is expected to\n   *   generate a dataset iterator object, the `next()` method of which is\n   *   expected to produce data batches for evaluation. The return value of the\n   *   `next()` call ought to contain a boolean `done` field and a `value`\n   *   field.\n   *\n   *   The `value` field is expected to be an object of with fields\n   *   `xs` and `ys`, which point to the feature tensor and the target tensor,\n   *   respectively. This case is for models with exactly one input and one\n   *   output (e.g. a sequential model). For example:\n   *   ```js\n   *   {value: {xs: xsTensor, ys: ysTensor}, done: false}\n   *   ```\n   *\n   *   If the model has multiple inputs, the `xs` field of `value` should\n   *   be an object mapping input names to their respective feature tensors.\n   *   For example:\n   *   ```js\n   *   {\n   *     value: {\n   *       xs: {\n   *         input_1: xsTensor1,\n   *         input_2: xsTensor2\n   *       },\n   *       ys: ysTensor\n   *     },\n   *     done: false\n   *   }\n   *   ```\n   *   If the model has multiple outputs, the `ys` field of `value` should\n   *   be an object mapping output names to their respective target tensors.\n   *   For example:\n   *   ```js\n   *   {\n   *     value: {\n   *       xs: xsTensor,\n   *       ys: {\n   *         output_1: ysTensor1,\n   *         output_2: ysTensor2\n   *       },\n   *     },\n   *     done: false\n   *   }\n   *   ```\n   * @param args A `ModelFitDatasetArgs`, containing optional fields.\n   *\n   * @return A `History` instance. Its `history` attribute contains all\n   *   information collected during training.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes', ignoreCI: true}\n   */\n  async fitDataset(l, G) {\n    if (!this.built)\n      throw new aI(\"The model needs to be compiled before being used.\");\n    return this.model.fitDataset(l, G);\n  }\n  /**\n   * Runs a single gradient update on a single batch of data.\n   *\n   * This method differs from `fit()` and `fitDataset()` in the following\n   * regards:\n   *   - It operates on exactly one batch of data.\n   *   - It returns only the loss and metric values, instead of\n   *     returning the batch-by-batch loss and metric values.\n   *   - It doesn't support fine-grained options such as verbosity and\n   *     callbacks.\n   *\n   * @param x Input data. It could be one of the following:\n   *   - A `tf.Tensor`, or an Array of `tf.Tensor`s (in case the model has\n   *     multiple inputs).\n   *   - An Object mapping input names to corresponding `tf.Tensor` (if the\n   *     model has named inputs).\n   * @param y Target data. It could be either a `tf.Tensor` or multiple\n   *   `tf.Tensor`s. It should be consistent with `x`.\n   * @returns Training loss or losses (in case the model has\n   *   multiple outputs), along with metrics (if any), as numbers.\n   *\n   * @doc {heading: 'Models', subheading: 'Classes'}\n   */\n  async trainOnBatch(l, G) {\n    return this.model.trainOnBatch(l, G);\n  }\n  /* See parent class for JsDoc */\n  /** @nocollapse */\n  static fromConfig(l, G, Z = {}, h = !1) {\n    let g, b = {};\n    if (G instanceof Array) {\n      if (G[0].className == null || G[0].className === \"Merge\")\n        throw new y(\"Legacy serialization format not supported yet.\");\n      g = G;\n    } else\n      u(G.layers != null, () => \"When the config data for a Sequential model is not an Array, it must be an Object that contains the 'layers' field.\"), g = G.layers, delete G.layers, b = G;\n    const c = new l(b);\n    if (!(c instanceof A0))\n      throw new Bl(`Sequential.fromConfig called on non-Sequential input: ${c}`);\n    for (const d of g) {\n      const Y = ZZ(d, void 0, h);\n      h && Y.setFastWeightInitDuringBuild(!0), c.add(Y);\n    }\n    return c;\n  }\n  /**\n   * Setter used for force stopping of LayersModel.fit() (i.e., training).\n   *\n   * Example:\n   *\n   * ```js\n   * const model = tf.sequential();\n   * model.add(tf.layers.dense({units: 1, inputShape: [10]}));\n   * model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});\n   * const xs = tf.ones([8, 10]);\n   * const ys = tf.zeros([8, 1]);\n   *\n   * const history = await model.fit(xs, ys, {\n   *   epochs: 10,\n   *   callbacks: {\n   *     onEpochEnd: async (epoch, logs) => {\n   *       if (epoch === 2) {\n   *         model.stopTraining = true;\n   *       }\n   *     }\n   *   }\n   * });\n   *\n   * // There should be only 3 values in the loss array, instead of 10 values,\n   * // due to the stopping after 3 epochs.\n   * console.log(history.history.loss);\n   * ```\n   */\n  set stopTraining(l) {\n    if (this.model == null)\n      throw new y(\"Cannot set the stopTraining property of a sequential model before it is compiled.\");\n    this.model.stopTraining = l;\n  }\n  get stopTraining() {\n    if (this.model == null)\n      throw new y(\"Cannot get the stopTraining property of a sequential model before it is compiled.\");\n    return this.model.stopTraining;\n  }\n  // TODO(cais): Override get trainableWeights() here\n  // tslint:disable-next-line:no-any\n  getConfig() {\n    const l = [];\n    for (const G of this.layers) {\n      const Z = {};\n      Z.className = G.getClassName(), Z.config = G.getConfig(), l.push(Z);\n    }\n    return { name: this.name, layers: l };\n  }\n}\nA0.className = \"Sequential\";\nj(A0);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nlet FG = class extends c0 {\n  getConfig() {\n    return {};\n  }\n};\nclass Fs extends FG {\n  /**\n   * Calculate the activation function.\n   *\n   * @param x: Input.\n   * @param alpha: Scaling factor the negative section.\n   * @return Output of the ELU activation.\n   */\n  apply(l, G = 1) {\n    return XF(l, G);\n  }\n}\nFs.className = \"elu\";\nj(Fs);\nclass ys extends FG {\n  apply(l) {\n    return rm(l);\n  }\n}\nys.className = \"selu\";\nj(ys);\nclass Ns extends FG {\n  apply(l) {\n    return th(l);\n  }\n}\nNs.className = \"relu\";\nj(Ns);\nclass Ps extends FG {\n  apply(l) {\n    return U(() => x0(6, th(l)));\n  }\n}\nPs.className = \"relu6\";\nj(Ps);\nclass Js extends FG {\n  apply(l) {\n    return l;\n  }\n}\nJs.className = \"linear\";\nj(Js);\nclass Es extends FG {\n  apply(l) {\n    return h0(l);\n  }\n}\nEs.className = \"sigmoid\";\nj(Es);\nclass xs extends FG {\n  apply(l) {\n    return uF(l);\n  }\n}\nxs.className = \"hardSigmoid\";\nj(xs);\nclass Us extends FG {\n  apply(l) {\n    return Qg(l);\n  }\n}\nUs.className = \"softplus\";\nj(Us);\nclass Hs extends FG {\n  apply(l) {\n    return tF(l);\n  }\n}\nHs.className = \"softsign\";\nj(Hs);\nclass Ks extends FG {\n  apply(l) {\n    return cd(l);\n  }\n}\nKs.className = \"tanh\";\nj(Ks);\nlet W9 = class extends FG {\n  /**\n   * Calculate the activation function.\n   *\n   * @param x Tensor.\n   * @param axis Integer, axis along which the softmax normalization is applied.\n   * Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be\n   * an error.\n   *\n   * @returns a Tensor of the same shape as x\n   *\n   * @throws ValueError: In case `dim(x) < 2`.\n   */\n  apply(l, G = -1) {\n    return aV(l, G);\n  }\n};\nW9.className = \"softmax\";\nj(W9);\nclass As extends FG {\n  /**\n   * Calculate the activation function of log softmax:\n   * log( exp(x_i) / sum(exp(x)) )\n   *\n   * @param x Tensor.\n   * @param axis Integer, axis along which the softmax normalization is applied.\n   * Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be\n   * an error.\n   *\n   * @returns a Tensor of the same shape as x\n   *\n   * @throws ValueError: In case `dim(x) < 2`.\n   */\n  apply(l, G = -1) {\n    return Km(l, G);\n  }\n}\nAs.className = \"logSoftmax\";\nj(As);\nclass ks extends FG {\n  /**\n   * Calculate the activation function.\n   *\n   * @param x Tensor.\n   * @returns a Tensor of the same shape as x\n   */\n  apply(l) {\n    return U(() => U(() => {\n      const G = Math.sqrt(2), Z = N(0.5, O(1, Jm(Vl(l, G))));\n      return N(l, Z);\n    }));\n  }\n}\nks.className = \"gelu\";\nj(ks);\nclass zs extends FG {\n  /**\n   * Calculate the activation function.\n   *\n   * @param x Tensor.\n   * @returns a Tensor of the same shape as x\n   */\n  apply(l) {\n    return U(() => N(0.5, N(l, O(1, cd(N(RG(Vl(2, Math.PI)), O(l, N(0.044715, Yh(l, 3)))))))));\n  }\n}\nzs.className = \"gelu_new\";\nj(zs);\nclass Ls extends FG {\n  /**\n   * Calculate the activation function.\n   *\n   * @param x Tensor.\n   * @returns a Tensor of the same shape as x\n   */\n  apply(l) {\n    return U(() => N(l, cd(Qg(l))));\n  }\n}\nLs.className = \"mish\";\nj(Ls);\nclass Ms extends FG {\n  /**\n   * Calculate the activation function.\n   *\n   * @param x Tensor.\n   * @param alpha Scaling factor for the sigmoid function.\n   * @returns a Tensor of the same shape as x\n   */\n  apply(l, G = 1) {\n    return U(() => N(h0(N(l, G)), l));\n  }\n}\nMs.className = \"swish\";\nj(Ms);\nfunction RZ(I) {\n  return I.getClassName();\n}\nfunction Dd(I, l = {}) {\n  return qg(I, dI.getMap().classNameMap, l, \"activation\");\n}\nfunction pZ(I) {\n  if (I == null) {\n    const l = {};\n    return l.className = \"linear\", l.config = {}, Dd(l);\n  }\n  if (typeof I == \"string\") {\n    const l = {};\n    return l.className = I, l.config = {}, Dd(l);\n  } else return I instanceof FG ? I : Dd(I);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Hy(I) {\n  if (I != null && typeof I != \"object\")\n    throw new Error(`Argument to L1L2 regularizer's constructor is expected to be an object, but received: ${I}`);\n}\nclass ws extends c0 {\n}\nclass Qs extends ws {\n  constructor(l) {\n    super(), Hy(l), this.l1 = l == null || l.l1 == null ? 0.01 : l.l1, this.l2 = l == null || l.l2 == null ? 0.01 : l.l2, this.hasL1 = this.l1 !== 0, this.hasL2 = this.l2 !== 0;\n  }\n  /**\n   * Porting note: Renamed from __call__.\n   * @param x Variable of which to calculate the regularization score.\n   */\n  apply(l) {\n    return U(() => {\n      let G = mG([1]);\n      return this.hasL1 && (G = O(G, Yl(N(this.l1, PG(l))))), this.hasL2 && (G = O(G, Yl(N(this.l2, _g(l))))), J(G, []);\n    });\n  }\n  getConfig() {\n    return { l1: this.l1, l2: this.l2 };\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l({ l1: G.l1, l2: G.l2 });\n  }\n}\nQs.className = \"L1L2\";\nj(Qs);\nconst Pa = {\n  l1l2: \"L1L2\"\n};\nfunction Hl(I) {\n  return fV(I);\n}\nfunction Ja(I, l = {}) {\n  return qg(I, dI.getMap().classNameMap, l, \"regularizer\");\n}\nfunction jl(I) {\n  if (I == null)\n    return null;\n  if (typeof I == \"string\") {\n    const G = { className: I in Pa ? Pa[I] : I, config: {} };\n    return Ja(G);\n  } else return I instanceof ws ? I : Ja(I);\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass vs extends ul {\n  constructor(l) {\n    super(l ?? {}), this.supportsMasking = !0, l != null && (this.maxValue = l.maxValue);\n  }\n  call(l, G) {\n    l = Tl(l);\n    let Z = th(l);\n    return this.maxValue != null && (Z = II(Z, 0, this.maxValue)), Z;\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = { maxValue: this.maxValue }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nvs.className = \"ReLU\";\nj(vs);\nclass rs extends ul {\n  constructor(l) {\n    super(l ?? {}), this.DEFAULT_ALPHA = 0.3, l == null && (l = {}), this.alpha = l.alpha == null ? this.DEFAULT_ALPHA : l.alpha;\n  }\n  call(l, G) {\n    const Z = Tl(l);\n    return OY(Z, this.alpha);\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = { alpha: this.alpha }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nrs.className = \"LeakyReLU\";\nj(rs);\nclass js extends ul {\n  constructor(l) {\n    if (super(l ?? {}), this.DEFAULT_ALPHA_INITIALIZER = \"zeros\", l == null && (l = {}), this.supportsMasking = !0, this.alphaInitializer = rl(l.alphaInitializer || this.DEFAULT_ALPHA_INITIALIZER), this.alphaRegularizer = jl(l.alphaRegularizer), this.alphaConstraint = YG(l.alphaConstraint), l.sharedAxes == null)\n      this.sharedAxes = null;\n    else if (Array.isArray(l.sharedAxes))\n      this.sharedAxes = l.sharedAxes;\n    else if (typeof l.sharedAxes == \"number\")\n      this.sharedAxes = [l.sharedAxes];\n    else\n      throw new y(`Expected sharedAxes to be a number or an array of numbers, but got ${l.sharedAxes}`);\n  }\n  build(l) {\n    l = pl(l);\n    const G = l.slice(1);\n    if (this.sharedAxes != null)\n      for (const h of this.sharedAxes)\n        G[h - 1] = 1;\n    this.alpha = this.addWeight(\"alpha\", G, \"float32\", this.alphaInitializer, this.alphaRegularizer, !0, this.alphaConstraint);\n    const Z = {};\n    if (this.sharedAxes != null)\n      for (let h = 1; h < l.length; ++h)\n        Z[h] = l[h];\n    this.inputSpec = [new dG({\n      ndim: l.length,\n      axes: Z\n    })], this.built = !0;\n  }\n  call(l, G) {\n    return l = Tl(l), IV(l, this.alpha.read());\n  }\n  getConfig() {\n    const l = {\n      alphaInitializer: fl(this.alphaInitializer),\n      alphaRegularizer: Hl(this.alphaRegularizer),\n      alphaConstraint: WG(this.alphaConstraint),\n      sharedAxes: this.sharedAxes\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\njs.className = \"PReLU\";\nj(js);\nlet Ds = class extends ul {\n  constructor(l) {\n    if (super(l ?? {}), this.DEFAULT_ALPHA = 1, l == null && (l = {}), l.alpha != null && l.alpha !== this.DEFAULT_ALPHA)\n      throw new Bl(`Non-default alpha value (${l.alpha}) is not supported by the ELU layer yet.`);\n    this.alpha = l.alpha == null ? this.DEFAULT_ALPHA : l.alpha;\n  }\n  call(l, G) {\n    const Z = Tl(l);\n    return Yd(Z);\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = { alpha: this.alpha }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n};\nDs.className = \"ELU\";\nj(Ds);\nclass fs extends ul {\n  constructor(l) {\n    super(l ?? {}), this.DEFAULT_THETA = 1, l == null && (l = {}), this.theta = l.theta == null ? this.DEFAULT_THETA : l.theta;\n  }\n  call(l, G) {\n    const Z = Tl(l);\n    return N(Z, hl(ZI(Z, this.theta), \"float32\"));\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = { theta: this.theta }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nfs.className = \"ThresholdedReLU\";\nj(fs);\nclass Os extends ul {\n  constructor(l) {\n    super(l ?? {}), this.DEFAULT_AXIS = 1, l == null && (l = {}), this.softmax = new W9().apply, this.axis = l.axis == null ? this.DEFAULT_AXIS : l.axis;\n  }\n  call(l, G) {\n    return U(() => {\n      let Z = Tl(l);\n      const h = G.mask;\n      if (h != null) {\n        const g = N(ml(HZ(Z.shape), hl(h, Z.dtype)), yl(-1e9));\n        Z = O(Z, g);\n      }\n      return this.axis instanceof Array ? this.axis.length > 1 ? rI(ml(Z, Am(Z, this.axis, !0))) : this.softmax(Z, this.axis[0]) : this.softmax(Z, this.axis);\n    });\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = { axis: this.axis }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nOs.className = \"Softmax\";\nj(Os);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Lh(I, l, G) {\n  if (typeof I == \"number\")\n    return ih(I, l);\n  if (I.length !== l)\n    throw new y(`The ${G} argument must be an integer or tuple of ${l} integers. Received: ${I.length} elements.`);\n  for (let Z = 0; Z < l; ++Z) {\n    const h = I[Z];\n    if (!oF(h))\n      throw new y(`The ${G} argument must be an integer or tuple of ${l} integers. Received: ${JSON.stringify(I)} including a non-integer number ${h}`);\n  }\n  return I;\n}\nfunction pI(I, l, G, Z, h = 1) {\n  if (I == null)\n    return I;\n  const g = l + (l - 1) * (h - 1);\n  let b;\n  return G === \"same\" ? b = I : b = I - g + 1, Math.floor((b + Z - 1) / Z);\n}\nfunction AI(I, l, G, Z) {\n  if (I == null)\n    return null;\n  if (Z === \"valid\")\n    I = I * l + SZ([G - l, 0]);\n  else if (Z === \"same\")\n    I = I * l;\n  else\n    throw new y(`Unsupport padding mode: ${Z}.`);\n  return I;\n}\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Y9(I, l) {\n  return U(() => (IG(l), l === \"channelsFirst\" ? el(I, [0, 2, 3, 1]) : I));\n}\nfunction qs(I, l) {\n  return U(() => (IG(l), l === \"channelsFirst\" ? el(I, [0, 2, 3, 4, 1]) : I));\n}\nfunction Ky(I, l, G, Z = 1, h = \"valid\", g, b = 1) {\n  return U(() => {\n    if (g == null && (g = yI()), IG(g), I.shape.length !== 3)\n      throw new y(`The input of a conv1dWithBias operation should be 3, but is ${I.shape.length} instead.`);\n    if (l.shape.length !== 3)\n      throw new y(`The kernel for a conv1dWithBias operation should be 3, but is ${l.shape.length} instead`);\n    if (G != null && G.shape.length !== 1)\n      throw new y(`The bias for a conv1dWithBias operation should be 1, but is ${G.shape.length} instead`);\n    if (g === \"channelsFirst\" && (I = el(I, [0, 2, 1])), h === \"causal\")\n      throw new Bl(\"The support for CAUSAL padding mode in conv1dWithBias is not implemented yet.\");\n    let c = pm(I, l, Z, h === \"same\" ? \"same\" : \"valid\", \"NWC\", b);\n    return G != null && (c = JI(c, G)), c;\n  });\n}\nfunction Ea(I, l, G, Z = [1, 1], h = \"valid\", g, b, c = null) {\n  return U(() => {\n    if (g == null && (g = yI()), IG(g), I.rank !== 3 && I.rank !== 4)\n      throw new y(`conv2dWithBiasActivation expects input to be of rank 3 or 4, but received ${I.rank}.`);\n    if (l.rank !== 3 && l.rank !== 4)\n      throw new y(`conv2dWithBiasActivation expects kernel to be of rank 3 or 4, but received ${I.rank}.`);\n    let d = Y9(I, g);\n    if (h === \"causal\")\n      throw new Bl(\"The support for CAUSAL padding mode in conv1dWithBias is not implemented yet.\");\n    return d = Qe({\n      x: d,\n      filter: l,\n      strides: Z,\n      pad: h === \"same\" ? \"same\" : \"valid\",\n      dilations: b,\n      dataFormat: \"NHWC\",\n      bias: G,\n      activation: c\n    }), g === \"channelsFirst\" && (d = el(d, [0, 3, 1, 2])), d;\n  });\n}\nfunction Ay(I, l, G, Z = [1, 1, 1], h = \"valid\", g, b) {\n  return U(() => {\n    if (g == null && (g = yI()), IG(g), I.rank !== 4 && I.rank !== 5)\n      throw new y(`conv3dWithBias expects input to be of rank 4 or 5, but received ${I.rank}.`);\n    if (l.rank !== 4 && l.rank !== 5)\n      throw new y(`conv3dWithBias expects kernel to be of rank 4 or 5, but received ${I.rank}.`);\n    let c = qs(I, g);\n    if (h === \"causal\")\n      throw new Bl(\"The support for CAUSAL padding mode in conv3dWithBias is not implemented yet.\");\n    return c = MX(c, l, Z, h === \"same\" ? \"same\" : \"valid\", \"NDHWC\", b), G != null && (c = JI(c, G)), g === \"channelsFirst\" && (c = el(c, [0, 4, 1, 2, 3])), c;\n  });\n}\nclass td extends ul {\n  constructor(l, G) {\n    if (super(G), this.bias = null, this.DEFAULT_KERNEL_INITIALIZER = \"glorotNormal\", this.DEFAULT_BIAS_INITIALIZER = \"zeros\", td.verifyArgs(G), this.rank = l, TG(this.rank, \"rank\"), this.rank !== 1 && this.rank !== 2 && this.rank !== 3)\n      throw new Bl(`Convolution layer for rank other than 1, 2, or 3 (${this.rank}) is not implemented yet.`);\n    if (this.kernelSize = Lh(G.kernelSize, l, \"kernelSize\"), this.strides = Lh(G.strides == null ? 1 : G.strides, l, \"strides\"), this.padding = G.padding == null ? \"valid\" : G.padding, hI(this.padding), this.dataFormat = G.dataFormat == null ? \"channelsLast\" : G.dataFormat, IG(this.dataFormat), this.activation = pZ(G.activation), this.useBias = G.useBias == null ? !0 : G.useBias, this.biasInitializer = rl(G.biasInitializer || this.DEFAULT_BIAS_INITIALIZER), this.biasConstraint = YG(G.biasConstraint), this.biasRegularizer = jl(G.biasRegularizer), this.activityRegularizer = jl(G.activityRegularizer), this.dilationRate = Lh(G.dilationRate == null ? 1 : G.dilationRate, l, \"dilationRate\"), this.rank === 1 && Array.isArray(this.dilationRate) && this.dilationRate.length !== 1)\n      throw new y(`dilationRate must be a number or an array of a single number for 1D convolution, but received ${JSON.stringify(this.dilationRate)}`);\n    if (this.rank === 2) {\n      if (typeof this.dilationRate == \"number\")\n        this.dilationRate = [this.dilationRate, this.dilationRate];\n      else if (this.dilationRate.length !== 2)\n        throw new y(`dilationRate must be a number or array of two numbers for 2D convolution, but received ${JSON.stringify(this.dilationRate)}`);\n    } else if (this.rank === 3) {\n      if (typeof this.dilationRate == \"number\")\n        this.dilationRate = [this.dilationRate, this.dilationRate, this.dilationRate];\n      else if (this.dilationRate.length !== 3)\n        throw new y(`dilationRate must be a number or array of three numbers for 3D convolution, but received ${JSON.stringify(this.dilationRate)}`);\n    }\n  }\n  static verifyArgs(l) {\n    if (KI(\"kernelSize\" in l, \"required key 'kernelSize' not in config\"), typeof l.kernelSize != \"number\" && !OV(l.kernelSize, \"number\", 1, 3))\n      throw new y(`BaseConv expects config.kernelSize to be number or number[] with length 1, 2, or 3, but received ${JSON.stringify(l.kernelSize)}.`);\n  }\n  getConfig() {\n    const l = {\n      kernelSize: this.kernelSize,\n      strides: this.strides,\n      padding: this.padding,\n      dataFormat: this.dataFormat,\n      dilationRate: this.dilationRate,\n      activation: RZ(this.activation),\n      useBias: this.useBias,\n      biasInitializer: fl(this.biasInitializer),\n      biasRegularizer: Hl(this.biasRegularizer),\n      activityRegularizer: Hl(this.activityRegularizer),\n      biasConstraint: WG(this.biasConstraint)\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nclass d0 extends td {\n  constructor(l, G) {\n    super(l, G), this.kernel = null, d0.verifyArgs(G), this.filters = G.filters, TG(this.filters, \"filters\"), this.kernelInitializer = rl(G.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER), this.kernelConstraint = YG(G.kernelConstraint), this.kernelRegularizer = jl(G.kernelRegularizer);\n  }\n  build(l) {\n    l = pl(l);\n    const G = this.dataFormat === \"channelsFirst\" ? 1 : l.length - 1;\n    if (l[G] == null)\n      throw new y(`The channel dimension of the input should be defined. Found ${l[G]}`);\n    const Z = l[G], h = this.kernelSize.concat([Z, this.filters]);\n    this.kernel = this.addWeight(\"kernel\", h, null, this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.useBias && (this.bias = this.addWeight(\"bias\", [this.filters], null, this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint)), this.inputSpec = [{ ndim: this.rank + 2, axes: { [G]: Z } }], this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      l = Tl(l);\n      let Z;\n      const h = this.bias == null ? null : this.bias.read(), g = jT(this.activation.getClassName());\n      if (g != null && this.rank === 2)\n        Z = Ea(l, this.kernel.read(), h, this.strides, this.padding, this.dataFormat, this.dilationRate, g);\n      else {\n        if (this.rank === 1)\n          Z = Ky(l, this.kernel.read(), h, this.strides[0], this.padding, this.dataFormat, this.dilationRate[0]);\n        else if (this.rank === 2)\n          Z = Ea(l, this.kernel.read(), h, this.strides, this.padding, this.dataFormat, this.dilationRate);\n        else if (this.rank === 3)\n          Z = Ay(l, this.kernel.read(), h, this.strides, this.padding, this.dataFormat, this.dilationRate);\n        else\n          throw new Bl(\"convolutions greater than 3D are not implemented yet.\");\n        this.activation != null && (Z = this.activation.apply(Z));\n      }\n      return Z;\n    });\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = [], Z = this.dataFormat === \"channelsLast\" ? l.slice(1, l.length - 1) : l.slice(2);\n    for (let g = 0; g < Z.length; ++g) {\n      const b = pI(Z[g], this.kernelSize[g], this.padding, this.strides[g], typeof this.dilationRate == \"number\" ? this.dilationRate : this.dilationRate[g]);\n      G.push(b);\n    }\n    let h = [l[0]];\n    return this.dataFormat === \"channelsLast\" ? (h = h.concat(G), h.push(this.filters)) : (h.push(this.filters), h = h.concat(G)), h;\n  }\n  getConfig() {\n    const l = {\n      filters: this.filters,\n      kernelInitializer: fl(this.kernelInitializer),\n      kernelRegularizer: Hl(this.kernelRegularizer),\n      kernelConstraint: WG(this.kernelConstraint)\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  static verifyArgs(l) {\n    if (!(\"filters\" in l) || typeof l.filters != \"number\" || l.filters < 1)\n      throw new y(`Convolution layer expected config.filters to be a 'number' > 0 but got ${JSON.stringify(l.filters)}`);\n  }\n}\nclass Zb extends d0 {\n  constructor(l) {\n    super(2, l), Zb.verifyArgs(l);\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return delete l.rank, l;\n  }\n  static verifyArgs(l) {\n    if (typeof l.kernelSize != \"number\" && !OV(l.kernelSize, \"number\", 1, 2))\n      throw new y(`Conv2D expects config.kernelSize to be number or number[] with length 1 or 2, but received ${JSON.stringify(l.kernelSize)}.`);\n  }\n}\nZb.className = \"Conv2D\";\nj(Zb);\nclass hb extends d0 {\n  constructor(l) {\n    super(3, l), hb.verifyArgs(l);\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return delete l.rank, l;\n  }\n  static verifyArgs(l) {\n    if (typeof l.kernelSize != \"number\" && !(Array.isArray(l.kernelSize) && (l.kernelSize.length === 1 || l.kernelSize.length === 3)))\n      throw new y(`Conv3D expects config.kernelSize to be number or [number, number, number], but received ${JSON.stringify(l.kernelSize)}.`);\n  }\n}\nhb.className = \"Conv3D\";\nj(hb);\nclass $s extends Zb {\n  constructor(l) {\n    if (super(l), this.inputSpec = [new dG({ ndim: 4 })], this.padding !== \"same\" && this.padding !== \"valid\")\n      throw new y(`Conv2DTranspose currently supports only padding modes 'same' and 'valid', but received padding mode ${this.padding}`);\n  }\n  build(l) {\n    if (l = pl(l), l.length !== 4)\n      throw new y(\"Input should have rank 4; Received input shape: \" + JSON.stringify(l));\n    const G = this.dataFormat === \"channelsFirst\" ? 1 : l.length - 1;\n    if (l[G] == null)\n      throw new y(\"The channel dimension of the inputs should be defined. Found `None`.\");\n    const Z = l[G], h = this.kernelSize.concat([this.filters, Z]);\n    this.kernel = this.addWeight(\"kernel\", h, \"float32\", this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.useBias && (this.bias = this.addWeight(\"bias\", [this.filters], \"float32\", this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint)), this.inputSpec = [new dG({ ndim: 4, axes: { [G]: Z } })], this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      let Z = Tl(l);\n      if (Z.shape.length !== 4)\n        throw new y(`Conv2DTranspose.call() expects input tensor to be rank-4, but received a tensor of rank-${Z.shape.length}`);\n      const h = Z.shape, g = h[0];\n      let b, c;\n      this.dataFormat === \"channelsFirst\" ? (b = 2, c = 3) : (b = 1, c = 2);\n      const d = h[b], W = h[c], Y = this.kernelSize[0], V = this.kernelSize[1], a = this.strides[0], i = this.strides[1], m = AI(d, a, Y, this.padding), T = AI(W, i, V, this.padding), s = [g, m, T, this.filters];\n      this.dataFormat !== \"channelsLast\" && (Z = el(Z, [0, 2, 3, 1]));\n      let o = Fm(Z, this.kernel.read(), s, this.strides, this.padding);\n      return this.dataFormat !== \"channelsLast\" && (o = el(o, [0, 3, 1, 2])), this.bias != null && (o = JI(o, this.bias.read(), this.dataFormat)), this.activation != null && (o = this.activation.apply(o)), o;\n    });\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l.slice();\n    let Z, h, g;\n    this.dataFormat === \"channelsFirst\" ? (Z = 1, h = 2, g = 3) : (Z = 3, h = 1, g = 2);\n    const b = this.kernelSize[0], c = this.kernelSize[1], d = this.strides[0], W = this.strides[1];\n    return G[Z] = this.filters, G[h] = AI(G[h], d, b, this.padding), G[g] = AI(G[g], W, c, this.padding), G;\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return delete l.dilationRate, l;\n  }\n}\n$s.className = \"Conv2DTranspose\";\nj($s);\nclass _s extends hb {\n  constructor(l) {\n    if (super(l), this.inputSpec = [new dG({ ndim: 5 })], this.padding !== \"same\" && this.padding !== \"valid\")\n      throw new y(`Conv3DTranspose currently supports only padding modes 'same' and 'valid', but received padding mode ${this.padding}`);\n  }\n  build(l) {\n    if (l = pl(l), l.length !== 5)\n      throw new y(\"Input should have rank 5; Received input shape: \" + JSON.stringify(l));\n    const G = this.dataFormat === \"channelsFirst\" ? 1 : l.length - 1;\n    if (l[G] == null)\n      throw new y(\"The channel dimension of the inputs should be defined. Found `None`.\");\n    const Z = l[G], h = this.kernelSize.concat([this.filters, Z]);\n    this.kernel = this.addWeight(\"kernel\", h, \"float32\", this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.useBias && (this.bias = this.addWeight(\"bias\", [this.filters], \"float32\", this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint)), this.inputSpec = [new dG({ ndim: 5, axes: { [G]: Z } })], this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      let Z = Tl(l);\n      if (Z.shape.length !== 5)\n        throw new y(`Conv3DTranspose.call() expects input tensor to be rank-4, but received a tensor of rank-${Z.shape.length}`);\n      const h = Z.shape, g = h[0];\n      let b, c, d;\n      this.dataFormat === \"channelsFirst\" ? (d = 2, b = 3, c = 4) : (d = 1, b = 2, c = 3);\n      const W = h[d], Y = h[b], V = h[c], a = this.kernelSize[0], i = this.kernelSize[1], m = this.kernelSize[2], T = this.strides[0], s = this.strides[1], o = this.strides[2], B = AI(W, T, a, this.padding), C = AI(Y, s, i, this.padding), n = AI(V, o, m, this.padding), X = [g, B, C, n, this.filters];\n      this.dataFormat !== \"channelsLast\" && (Z = el(Z, [0, 2, 3, 4, 1]));\n      let t = vX(Z, this.kernel.read(), X, this.strides, this.padding);\n      return this.dataFormat !== \"channelsLast\" && (t = el(t, [0, 4, 1, 2, 3])), this.bias !== null && (t = JI(t, this.bias.read(), this.dataFormat)), this.activation !== null && (t = this.activation.apply(t)), t;\n    });\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l.slice();\n    let Z, h, g, b;\n    this.dataFormat === \"channelsFirst\" ? (Z = 1, h = 2, g = 3, b = 4) : (Z = 4, h = 1, g = 2, b = 3);\n    const c = this.kernelSize[0], d = this.kernelSize[1], W = this.kernelSize[2], Y = this.strides[0], V = this.strides[1], a = this.strides[2];\n    return G[Z] = this.filters, G[h] = AI(G[h], Y, c, this.padding), G[g] = AI(G[g], V, d, this.padding), G[b] = AI(G[b], a, W, this.padding), G;\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return delete l.dilationRate, l;\n  }\n}\n_s.className = \"Conv3DTranspose\";\nj(_s);\nclass lo extends d0 {\n  constructor(l, G) {\n    if (super(l, G), this.DEFAULT_DEPTHWISE_INITIALIZER = \"glorotUniform\", this.DEFAULT_POINTWISE_INITIALIZER = \"glorotUniform\", this.depthwiseKernel = null, this.pointwiseKernel = null, G.filters == null)\n      throw new y(\"The `filters` configuration field is required by SeparableConv, but is unspecified.\");\n    if (G.kernelInitializer != null || G.kernelRegularizer != null || G.kernelConstraint != null)\n      throw new y(\"Fields kernelInitializer, kernelRegularizer and kernelConstraint are invalid for SeparableConv2D. Use depthwiseInitializer, depthwiseRegularizer, depthwiseConstraint, pointwiseInitializer, pointwiseRegularizer and pointwiseConstraint instead.\");\n    if (G.padding != null && G.padding !== \"same\" && G.padding !== \"valid\")\n      throw new y(`SeparableConv${this.rank}D supports only padding modes: 'same' and 'valid', but received ${JSON.stringify(G.padding)}`);\n    this.depthMultiplier = G.depthMultiplier == null ? 1 : G.depthMultiplier, this.depthwiseInitializer = rl(G.depthwiseInitializer || this.DEFAULT_DEPTHWISE_INITIALIZER), this.depthwiseRegularizer = jl(G.depthwiseRegularizer), this.depthwiseConstraint = YG(G.depthwiseConstraint), this.pointwiseInitializer = rl(G.depthwiseInitializer || this.DEFAULT_POINTWISE_INITIALIZER), this.pointwiseRegularizer = jl(G.pointwiseRegularizer), this.pointwiseConstraint = YG(G.pointwiseConstraint);\n  }\n  build(l) {\n    if (l = pl(l), l.length < this.rank + 2)\n      throw new y(`Inputs to SeparableConv${this.rank}D should have rank ${this.rank + 2}, but received input shape: ${JSON.stringify(l)}`);\n    const G = this.dataFormat === \"channelsFirst\" ? 1 : l.length - 1;\n    if (l[G] == null || l[G] < 0)\n      throw new y(`The channel dimension of the inputs should be defined, but found ${JSON.stringify(l[G])}`);\n    const Z = l[G], h = this.kernelSize.concat([Z, this.depthMultiplier]), g = [];\n    for (let c = 0; c < this.rank; ++c)\n      g.push(1);\n    g.push(Z * this.depthMultiplier, this.filters);\n    const b = !0;\n    this.depthwiseKernel = this.addWeight(\"depthwise_kernel\", h, \"float32\", this.depthwiseInitializer, this.depthwiseRegularizer, b, this.depthwiseConstraint), this.pointwiseKernel = this.addWeight(\"pointwise_kernel\", g, \"float32\", this.pointwiseInitializer, this.pointwiseRegularizer, b, this.pointwiseConstraint), this.useBias ? this.bias = this.addWeight(\"bias\", [this.filters], \"float32\", this.biasInitializer, this.biasRegularizer, b, this.biasConstraint) : this.bias = null, this.inputSpec = [new dG({ ndim: this.rank + 2, axes: { [G]: Z } })], this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      l = Tl(l);\n      let Z;\n      if (this.rank === 1)\n        throw new Bl(\"1D separable convolution is not implemented yet.\");\n      return this.rank === 2 && (this.dataFormat === \"channelsFirst\" && (l = el(l, [0, 2, 3, 1])), Z = jm(l, this.depthwiseKernel.read(), this.pointwiseKernel.read(), this.strides, this.padding, this.dilationRate, \"NHWC\")), this.useBias && (Z = JI(Z, this.bias.read(), this.dataFormat)), this.activation != null && (Z = this.activation.apply(Z)), this.dataFormat === \"channelsFirst\" && (Z = el(Z, [0, 3, 1, 2])), Z;\n    });\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return delete l.rank, delete l.kernelInitializer, delete l.kernelRegularizer, delete l.kernelConstraint, l.depthwiseInitializer = fl(this.depthwiseInitializer), l.pointwiseInitializer = fl(this.pointwiseInitializer), l.depthwiseRegularizer = Hl(this.depthwiseRegularizer), l.pointwiseRegularizer = Hl(this.pointwiseRegularizer), l.depthwiseConstraint = WG(this.depthwiseConstraint), l.pointwiseConstraint = WG(this.pointwiseConstraint), l;\n  }\n}\nlo.className = \"SeparableConv\";\nclass Go extends lo {\n  constructor(l) {\n    super(2, l);\n  }\n}\nGo.className = \"SeparableConv2D\";\nj(Go);\nclass ud extends d0 {\n  constructor(l) {\n    super(1, l), ud.verifyArgs(l), this.inputSpec = [{ ndim: 3 }];\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return delete l.rank, delete l.dataFormat, l;\n  }\n  static verifyArgs(l) {\n    if (typeof l.kernelSize != \"number\" && !OV(l.kernelSize, \"number\", 1, 1))\n      throw new y(`Conv1D expects config.kernelSize to be number or number[] with length 1, but received ${JSON.stringify(l.kernelSize)}.`);\n  }\n}\nud.className = \"Conv1D\";\nj(ud);\nclass Io extends ul {\n  constructor(l) {\n    super(l), typeof l.cropping == \"number\" ? this.cropping = [[l.cropping, l.cropping], [l.cropping, l.cropping]] : typeof l.cropping[0] == \"number\" ? this.cropping = [\n      [l.cropping[0], l.cropping[0]],\n      [l.cropping[1], l.cropping[1]]\n    ] : this.cropping = l.cropping, this.dataFormat = l.dataFormat === void 0 ? \"channelsLast\" : l.dataFormat, this.inputSpec = [{ ndim: 4 }];\n  }\n  computeOutputShape(l) {\n    return this.dataFormat === \"channelsFirst\" ? [\n      l[0],\n      l[1],\n      l[2] - this.cropping[0][0] - this.cropping[0][1],\n      l[3] - this.cropping[1][0] - this.cropping[1][1]\n    ] : [\n      l[0],\n      l[1] - this.cropping[0][0] - this.cropping[0][1],\n      l[2] - this.cropping[1][0] - this.cropping[1][1],\n      l[3]\n    ];\n  }\n  call(l, G) {\n    return U(() => {\n      if (l = Tl(l), this.dataFormat === \"channelsLast\") {\n        const Z = Bb(l, this.cropping[0][0], l.shape[1] - this.cropping[0][0] - this.cropping[0][1], 2);\n        return Bb(Z, this.cropping[1][0], l.shape[2] - this.cropping[1][1] - this.cropping[1][0], 3);\n      } else {\n        const Z = Bb(l, this.cropping[0][0], l.shape[2] - this.cropping[0][0] - this.cropping[0][1], 3);\n        return Bb(Z, this.cropping[1][0], l.shape[3] - this.cropping[1][1] - this.cropping[1][0], 4);\n      }\n    });\n  }\n  getConfig() {\n    const l = { cropping: this.cropping, dataFormat: this.dataFormat }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nIo.className = \"Cropping2D\";\nj(Io);\nclass Zo extends ul {\n  constructor(l) {\n    super(l), this.DEFAULT_SIZE = [2, 2], this.inputSpec = [{ ndim: 4 }], this.size = l.size == null ? this.DEFAULT_SIZE : l.size, this.dataFormat = l.dataFormat == null ? \"channelsLast\" : l.dataFormat, IG(this.dataFormat), this.interpolation = l.interpolation == null ? \"nearest\" : l.interpolation, mF(this.interpolation);\n  }\n  computeOutputShape(l) {\n    if (this.dataFormat === \"channelsFirst\") {\n      const G = l[2] == null ? null : this.size[0] * l[2], Z = l[3] == null ? null : this.size[1] * l[3];\n      return [l[0], l[1], G, Z];\n    } else {\n      const G = l[1] == null ? null : this.size[0] * l[1], Z = l[2] == null ? null : this.size[1] * l[2];\n      return [l[0], G, Z, l[3]];\n    }\n  }\n  call(l, G) {\n    return U(() => {\n      let Z = Tl(l);\n      const h = Z.shape;\n      if (this.dataFormat === \"channelsFirst\") {\n        Z = el(Z, [0, 2, 3, 1]);\n        const g = this.size[0] * h[2], b = this.size[1] * h[3], c = this.interpolation === \"nearest\" ? IZ.resizeNearestNeighbor(Z, [g, b]) : IZ.resizeBilinear(Z, [g, b]);\n        return el(c, [0, 3, 1, 2]);\n      } else {\n        const g = this.size[0] * h[1], b = this.size[1] * h[2];\n        return this.interpolation === \"nearest\" ? IZ.resizeNearestNeighbor(Z, [g, b]) : IZ.resizeBilinear(Z, [g, b]);\n      }\n    });\n  }\n  getConfig() {\n    const l = {\n      size: this.size,\n      dataFormat: this.dataFormat,\n      interpolation: this.interpolation\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nZo.className = \"UpSampling2D\";\nj(Zo);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction ky(I, l, G = [1, 1], Z = \"valid\", h, g) {\n  return U(() => {\n    h == null && (h = yI()), IG(h);\n    let b = Y9(I, h);\n    if (I.rank !== 4)\n      throw new y(`Input for depthwiseConv2d is required to be 4-D, but is instead ${I.rank}-D`);\n    if (l.rank !== 4)\n      throw new y(`depthwiseKernel is required to be 4-D, but is instead ${l.rank}-D`);\n    return b = rY(b, l, G, Z === \"same\" ? \"same\" : \"valid\", \"NHWC\", g), h === \"channelsFirst\" && (b = el(b, [0, 3, 1, 2])), b;\n  });\n}\nclass ho extends td {\n  constructor(l) {\n    super(2, l), this.depthwiseKernel = null, this.depthMultiplier = l.depthMultiplier == null ? 1 : l.depthMultiplier, this.depthwiseInitializer = rl(l.depthwiseInitializer || this.DEFAULT_KERNEL_INITIALIZER), this.depthwiseConstraint = YG(l.depthwiseConstraint), this.depthwiseRegularizer = jl(l.depthwiseRegularizer);\n  }\n  build(l) {\n    if (l = pl(l), l.length < 4)\n      throw new y(`Inputs to DepthwiseConv2D should have rank 4. Received input shape: ${JSON.stringify(l)}.`);\n    const G = this.dataFormat === \"channelsFirst\" ? 1 : 3;\n    if (l[G] == null || l[G] < 0)\n      throw new y(`The channel dimension of the inputs to DepthwiseConv2D should be defined, but is not (${l[G]}).`);\n    const Z = l[G], h = [\n      this.kernelSize[0],\n      this.kernelSize[1],\n      Z,\n      this.depthMultiplier\n    ];\n    this.depthwiseKernel = this.addWeight(\"depthwise_kernel\", h, null, this.depthwiseInitializer, this.depthwiseRegularizer, !0, this.depthwiseConstraint), this.useBias ? this.bias = this.addWeight(\"bias\", [Z * this.depthMultiplier], null, this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint) : this.bias = null, this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      l = Tl(l);\n      let Z = ky(l, this.depthwiseKernel.read(), this.strides, this.padding, this.dataFormat, null);\n      return this.useBias && (Z = JI(Z, this.bias.read(), this.dataFormat)), this.activation != null && (Z = this.activation.apply(Z)), Z;\n    });\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = this.dataFormat === \"channelsFirst\" ? l[2] : l[1], Z = this.dataFormat === \"channelsFirst\" ? l[3] : l[2], h = this.dataFormat === \"channelsFirst\" ? l[1] * this.depthMultiplier : l[3] * this.depthMultiplier, g = pI(G, this.kernelSize[0], this.padding, this.strides[0]), b = pI(Z, this.kernelSize[1], this.padding, this.strides[1]);\n    return this.dataFormat === \"channelsFirst\" ? [l[0], h, g, b] : [l[0], g, b, h];\n  }\n  getConfig() {\n    const l = super.getConfig();\n    return l.depthMultiplier = this.depthMultiplier, l.depthwiseInitializer = fl(this.depthwiseInitializer), l.depthwiseRegularizer = Hl(this.depthwiseRegularizer), l.depthwiseConstraint = WG(this.depthwiseRegularizer), l;\n  }\n}\nho.className = \"DepthwiseConv2D\";\nj(ho);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction go(I, l, G, Z) {\n  if (Array.isArray(I)) {\n    if (l != null || G != null)\n      throw new y(\"When inputs is an array, neither initialState or constants should be provided\");\n    Z != null && (G = I.slice(I.length - Z, I.length), I = I.slice(0, I.length - Z)), I.length > 1 && (l = I.slice(1, I.length)), I = I[0];\n  }\n  function h(g) {\n    return g == null || Array.isArray(g) ? g : [g];\n  }\n  return l = h(l), G = h(G), { inputs: I, initialState: l, constants: G };\n}\nfunction bo(I, l, G, Z = !1, h, g, b = !1, c = !1) {\n  return U(() => {\n    const d = l.shape.length;\n    if (d < 3)\n      throw new y(`Input should be at least 3D, but is ${d}D.`);\n    const W = [1, 0].concat(FI(2, d));\n    l = el(l, W), b && console.warn(\"Backend rnn(): the unroll = true option is not applicable to the imperative deeplearn.js backend.\"), h != null && (h = hl(hl(h, \"bool\"), \"float32\"), h.rank === d - 1 && (h = EG(h, -1)), h = el(h, W)), Z && (l = Vh(l, 0), h != null && (h = Vh(h, 0)));\n    const Y = [];\n    let V, a = G;\n    const i = l.shape[0], m = ah(l);\n    let T;\n    h != null && (T = ah(h));\n    for (let o = 0; o < i; ++o) {\n      const B = m[o], C = U(() => I(B, a));\n      if (h == null)\n        V = C[0], a = C[1];\n      else {\n        const n = U(() => {\n          const X = T[o], t = ml(TI(X), X), e = O(N(C[0], X), N(a[0], t)), S = a.map((p, F) => O(N(C[1][F], X), N(p, t)));\n          return { output: e, newStates: S };\n        });\n        V = n.output, a = n.newStates;\n      }\n      c && Y.push(V);\n    }\n    let s;\n    return c && (s = gZ(Y, 1)), [V, s, a];\n  });\n}\nclass AZ extends ul {\n  constructor(l) {\n    super(l);\n    let G;\n    if (l.cell == null)\n      throw new y(\"cell property is missing for the constructor of RNN.\");\n    if (Array.isArray(l.cell) ? G = new i9({ cells: l.cell }) : G = l.cell, G.stateSize == null)\n      throw new y(\"The RNN cell should have an attribute `stateSize` (tuple of integers, one integer per RNN state).\");\n    this.cell = G, this.returnSequences = l.returnSequences == null ? !1 : l.returnSequences, this.returnState = l.returnState == null ? !1 : l.returnState, this.goBackwards = l.goBackwards == null ? !1 : l.goBackwards, this._stateful = l.stateful == null ? !1 : l.stateful, this.unroll = l.unroll == null ? !1 : l.unroll, this.supportsMasking = !0, this.inputSpec = [new dG({ ndim: 3 })], this.stateSpec = null, this.states_ = null, this.numConstants = null, this.keptStates = [];\n  }\n  // Porting Note: This is the equivalent of `RNN.states` property getter in\n  //   PyKeras.\n  getStates() {\n    if (this.states_ == null) {\n      const l = Array.isArray(this.cell.stateSize) ? this.cell.stateSize.length : 1;\n      return FI(0, l).map((G) => null);\n    } else\n      return this.states_;\n  }\n  // Porting Note: This is the equivalent of the `RNN.states` property setter in\n  //   PyKeras.\n  setStates(l) {\n    this.states_ = l;\n  }\n  computeOutputShape(l) {\n    FW(l) && (l = l[0]), l = l;\n    let G = this.cell.stateSize;\n    Array.isArray(G) || (G = [G]);\n    const Z = G[0];\n    let h;\n    if (this.returnSequences ? h = [l[0], l[1], Z] : h = [l[0], Z], this.returnState) {\n      const g = [];\n      for (const b of G)\n        g.push([l[0], b]);\n      return [h].concat(g);\n    } else\n      return h;\n  }\n  computeMask(l, G) {\n    return U(() => {\n      Array.isArray(G) && (G = G[0]);\n      const Z = this.returnSequences ? G : null;\n      if (this.returnState) {\n        const h = this.states.map((g) => null);\n        return [Z].concat(h);\n      } else\n        return Z;\n    });\n  }\n  /**\n   * Get the current state tensors of the RNN.\n   *\n   * If the state hasn't been set, return an array of `null`s of the correct\n   * length.\n   */\n  get states() {\n    if (this.states_ == null) {\n      const l = Array.isArray(this.cell.stateSize) ? this.cell.stateSize.length : 1, G = [];\n      for (let Z = 0; Z < l; ++Z)\n        G.push(null);\n      return G;\n    } else\n      return this.states_;\n  }\n  set states(l) {\n    this.states_ = l;\n  }\n  build(l) {\n    if (this.numConstants != null)\n      throw new Bl(\"Constants support is not implemented in RNN yet.\");\n    FW(l) && (l = l[0]), l = l;\n    const G = this.stateful ? l[0] : null, Z = l.slice(2);\n    this.inputSpec[0] = new dG({ shape: [G, null, ...Z] });\n    const h = [l[0]].concat(l.slice(2));\n    this.cell.build(h);\n    let g;\n    if (Array.isArray(this.cell.stateSize) ? g = this.cell.stateSize : g = [this.cell.stateSize], this.stateSpec != null) {\n      if (!Nl(this.stateSpec.map((b) => b.shape[b.shape.length - 1]), g))\n        throw new y(`An initialState was passed that is not compatible with cell.stateSize. Received stateSpec=${this.stateSpec}; However cell.stateSize is ${this.cell.stateSize}`);\n    } else\n      this.stateSpec = g.map((b) => new dG({ shape: [null, b] }));\n    this.stateful && this.resetStates();\n  }\n  /**\n   * Reset the state tensors of the RNN.\n   *\n   * If the `states` argument is `undefined` or `null`, will set the\n   * state tensor(s) of the RNN to all-zero tensors of the appropriate\n   * shape(s).\n   *\n   * If `states` is provided, will set the state tensors of the RNN to its\n   * value.\n   *\n   * @param states Optional externally-provided initial states.\n   * @param training Whether this call is done during training. For stateful\n   *   RNNs, this affects whether the old states are kept or discarded. In\n   *   particular, if `training` is `true`, the old states will be kept so\n   *   that subsequent backpropgataion through time (BPTT) may work properly.\n   *   Else, the old states will be discarded.\n   */\n  resetStates(l, G = !1) {\n    U(() => {\n      if (!this.stateful)\n        throw new HI(\"Cannot call resetStates() on an RNN Layer that is not stateful.\");\n      const Z = this.inputSpec[0].shape[0];\n      if (Z == null)\n        throw new y(\"If an RNN is stateful, it needs to know its batch size. Specify the batch size of your input tensors: \\n- If using a Sequential model, specify the batch size by passing a `batchInputShape` option to your first layer.\\n- If using the functional API, specify the batch size by passing a `batchShape` option to your Input layer.\");\n      if (this.states_ == null)\n        Array.isArray(this.cell.stateSize) ? this.states_ = this.cell.stateSize.map((h) => mG([Z, h])) : this.states_ = [mG([Z, this.cell.stateSize])];\n      else if (l == null)\n        Cl(this.states_), this.keptStates != null && (Cl(this.keptStates), this.keptStates = []), Array.isArray(this.cell.stateSize) ? this.states_ = this.cell.stateSize.map((h) => mG([Z, h])) : this.states_[0] = mG([Z, this.cell.stateSize]);\n      else {\n        if (Array.isArray(l) || (l = [l]), l.length !== this.states_.length)\n          throw new y(`Layer ${this.name} expects ${this.states_.length} state(s), but it received ${l.length} state value(s). Input received: ${l}`);\n        G === !0 ? this.keptStates.push(this.states_.slice()) : Cl(this.states_);\n        for (let h = 0; h < this.states_.length; ++h) {\n          const g = l[h], b = Array.isArray(this.cell.stateSize) ? this.cell.stateSize[h] : this.cell.stateSize, c = [Z, b];\n          if (!Nl(g.shape, c))\n            throw new y(`State ${h} is incompatible with layer ${this.name}: expected shape=${c}, received shape=${g.shape}`);\n          this.states_[h] = g;\n        }\n      }\n      this.states_ = this.states_.map((h) => LI(h.clone()));\n    });\n  }\n  apply(l, G) {\n    let Z = G == null ? null : G.initialState, h = G == null ? null : G.constants;\n    G == null && (G = {});\n    const g = go(l, Z, h, this.numConstants);\n    l = g.inputs, Z = g.initialState, h = g.constants;\n    let b = [], c = [];\n    if (Z != null) {\n      G.initialState = Z, b = b.concat(Z), this.stateSpec = [];\n      for (const W of Z)\n        this.stateSpec.push(new dG({ shape: W.shape }));\n      c = c.concat(this.stateSpec);\n    }\n    if (h != null && (G.constants = h, b = b.concat(h), this.numConstants = h.length), b[0] instanceof DI) {\n      const W = [l].concat(b), Y = this.inputSpec.concat(c), V = this.inputSpec;\n      this.inputSpec = Y;\n      const a = super.apply(W, G);\n      return this.inputSpec = V, a;\n    } else\n      return super.apply(l, G);\n  }\n  // tslint:disable-next-line:no-any\n  call(l, G) {\n    return U(() => {\n      const Z = G == null ? null : G.mask, h = G == null ? null : G.training;\n      let g = G == null ? null : G.initialState;\n      l = Tl(l), g == null && (this.stateful ? g = this.states_ : g = this.getInitialState(l));\n      const b = Array.isArray(this.cell.stateSize) ? this.cell.stateSize.length : 1;\n      if (g.length !== b)\n        throw new y(`RNN Layer has ${b} state(s) but was passed ${g.length} initial state(s).`);\n      this.unroll && console.warn(\"Ignoring unroll = true for RNN layer, due to imperative backend.\");\n      const c = { training: h }, W = bo((m, T) => {\n        const s = this.cell.call([m].concat(T), c);\n        return [s[0], s.slice(1)];\n      }, l, g, this.goBackwards, Z, null, this.unroll, this.returnSequences), Y = W[0], V = W[1], a = W[2];\n      this.stateful && this.resetStates(a, h);\n      const i = this.returnSequences ? V : Y;\n      return this.returnState ? [i].concat(a) : i;\n    });\n  }\n  getInitialState(l) {\n    return U(() => {\n      let G = mG(l.shape);\n      return G = Yl(G, [1, 2]), G = $g(G), Array.isArray(this.cell.stateSize) ? this.cell.stateSize.map((Z) => Z > 1 ? RW(G, [1, Z]) : G) : this.cell.stateSize > 1 ? [RW(G, [1, this.cell.stateSize])] : [G];\n    });\n  }\n  get trainableWeights() {\n    return this.trainable ? this.cell.trainableWeights : [];\n  }\n  get nonTrainableWeights() {\n    return this.trainable ? this.cell.nonTrainableWeights : this.cell.weights;\n  }\n  setFastWeightInitDuringBuild(l) {\n    super.setFastWeightInitDuringBuild(l), this.cell != null && this.cell.setFastWeightInitDuringBuild(l);\n  }\n  getConfig() {\n    const l = super.getConfig(), G = {\n      returnSequences: this.returnSequences,\n      returnState: this.returnState,\n      goBackwards: this.goBackwards,\n      stateful: this.stateful,\n      unroll: this.unroll\n    };\n    this.numConstants != null && (G.numConstants = this.numConstants);\n    const Z = this.cell.getConfig();\n    return this.getClassName() === AZ.className && (G.cell = {\n      className: this.cell.getClassName(),\n      config: Z\n    }), Object.assign(Object.assign(Object.assign({}, Z), l), G);\n  }\n  /** @nocollapse */\n  static fromConfig(l, G, Z = {}) {\n    const h = G.cell, g = ZZ(h, Z);\n    return new l(Object.assign(G, { cell: g }));\n  }\n}\nAZ.className = \"RNN\";\nj(AZ);\nclass ed extends ul {\n}\nclass V9 extends ed {\n  constructor(l) {\n    super(l), this.DEFAULT_ACTIVATION = \"tanh\", this.DEFAULT_KERNEL_INITIALIZER = \"glorotNormal\", this.DEFAULT_RECURRENT_INITIALIZER = \"orthogonal\", this.DEFAULT_BIAS_INITIALIZER = \"zeros\", this.units = l.units, TG(this.units, \"units\"), this.activation = pZ(l.activation == null ? this.DEFAULT_ACTIVATION : l.activation), this.useBias = l.useBias == null ? !0 : l.useBias, this.kernelInitializer = rl(l.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER), this.recurrentInitializer = rl(l.recurrentInitializer || this.DEFAULT_RECURRENT_INITIALIZER), this.biasInitializer = rl(l.biasInitializer || this.DEFAULT_BIAS_INITIALIZER), this.kernelRegularizer = jl(l.kernelRegularizer), this.recurrentRegularizer = jl(l.recurrentRegularizer), this.biasRegularizer = jl(l.biasRegularizer), this.kernelConstraint = YG(l.kernelConstraint), this.recurrentConstraint = YG(l.recurrentConstraint), this.biasConstraint = YG(l.biasConstraint), this.dropout = Dh([1, SZ([0, l.dropout == null ? 0 : l.dropout])]), this.recurrentDropout = Dh([\n      1,\n      SZ([0, l.recurrentDropout == null ? 0 : l.recurrentDropout])\n    ]), this.dropoutFunc = l.dropoutFunc, this.stateSize = this.units, this.dropoutMask = null, this.recurrentDropoutMask = null;\n  }\n  build(l) {\n    l = pl(l), this.kernel = this.addWeight(\"kernel\", [l[l.length - 1], this.units], null, this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.recurrentKernel = this.addWeight(\"recurrent_kernel\", [this.units, this.units], null, this.recurrentInitializer, this.recurrentRegularizer, !0, this.recurrentConstraint), this.useBias ? this.bias = this.addWeight(\"bias\", [this.units], null, this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint) : this.bias = null, this.built = !0;\n  }\n  // Porting Note: PyKeras' equivalent of this method takes two tensor inputs:\n  //   `inputs` and `states`. Here, the two tensors are combined into an\n  //   `Tensor[]` Array as the first input argument.\n  //   Similarly, PyKeras' equivalent of this method returns two values:\n  //    `output` and `[output]`. Here the two are combined into one length-2\n  //    `Tensor[]`, consisting of `output` repeated.\n  call(l, G) {\n    return U(() => {\n      if (l = l, l.length !== 2)\n        throw new y(`SimpleRNNCell expects 2 input Tensors, got ${l.length}.`);\n      let Z = l[1];\n      l = l[0];\n      const h = G.training == null ? !1 : G.training;\n      0 < this.dropout && this.dropout < 1 && this.dropoutMask == null && (this.dropoutMask = FZ({\n        ones: () => TI(l),\n        rate: this.dropout,\n        training: h,\n        dropoutFunc: this.dropoutFunc\n      })), 0 < this.recurrentDropout && this.recurrentDropout < 1 && this.recurrentDropoutMask == null && (this.recurrentDropoutMask = FZ({\n        ones: () => TI(Z),\n        rate: this.recurrentDropout,\n        training: h,\n        dropoutFunc: this.dropoutFunc\n      }));\n      let g;\n      const b = this.dropoutMask, c = this.recurrentDropoutMask;\n      b != null ? g = QI(N(l, b), this.kernel.read()) : g = QI(l, this.kernel.read()), this.bias != null && (g = JI(g, this.bias.read())), c != null && (Z = N(Z, c));\n      let d = O(g, QI(Z, this.recurrentKernel.read()));\n      return this.activation != null && (d = this.activation.apply(d)), [d, d];\n    });\n  }\n  getConfig() {\n    const l = super.getConfig(), G = {\n      units: this.units,\n      activation: RZ(this.activation),\n      useBias: this.useBias,\n      kernelInitializer: fl(this.kernelInitializer),\n      recurrentInitializer: fl(this.recurrentInitializer),\n      biasInitializer: fl(this.biasInitializer),\n      kernelRegularizer: Hl(this.kernelRegularizer),\n      recurrentRegularizer: Hl(this.recurrentRegularizer),\n      biasRegularizer: Hl(this.biasRegularizer),\n      activityRegularizer: Hl(this.activityRegularizer),\n      kernelConstraint: WG(this.kernelConstraint),\n      recurrentConstraint: WG(this.recurrentConstraint),\n      biasConstraint: WG(this.biasConstraint),\n      dropout: this.dropout,\n      recurrentDropout: this.recurrentDropout\n    };\n    return Object.assign(Object.assign({}, l), G);\n  }\n}\nV9.className = \"SimpleRNNCell\";\nj(V9);\nclass co extends AZ {\n  constructor(l) {\n    l.cell = new V9(l), super(l);\n  }\n  call(l, G) {\n    return U(() => {\n      this.cell.dropoutMask != null && (Cl(this.cell.dropoutMask), this.cell.dropoutMask = null), this.cell.recurrentDropoutMask != null && (Cl(this.cell.recurrentDropoutMask), this.cell.recurrentDropoutMask = null);\n      const Z = G == null ? null : G.mask, h = G == null ? null : G.training, g = G == null ? null : G.initialState;\n      return super.call(l, { mask: Z, training: h, initialState: g });\n    });\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G);\n  }\n}\nco.className = \"SimpleRNN\";\nj(co);\nclass a9 extends ed {\n  constructor(l) {\n    if (super(l), this.DEFAULT_ACTIVATION = \"tanh\", this.DEFAULT_RECURRENT_ACTIVATION = \"hardSigmoid\", this.DEFAULT_KERNEL_INITIALIZER = \"glorotNormal\", this.DEFAULT_RECURRENT_INITIALIZER = \"orthogonal\", this.DEFAULT_BIAS_INITIALIZER = \"zeros\", l.resetAfter)\n      throw new y(\"GRUCell does not support reset_after parameter set to true.\");\n    this.units = l.units, TG(this.units, \"units\"), this.activation = pZ(l.activation === void 0 ? this.DEFAULT_ACTIVATION : l.activation), this.recurrentActivation = pZ(l.recurrentActivation === void 0 ? this.DEFAULT_RECURRENT_ACTIVATION : l.recurrentActivation), this.useBias = l.useBias == null ? !0 : l.useBias, this.kernelInitializer = rl(l.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER), this.recurrentInitializer = rl(l.recurrentInitializer || this.DEFAULT_RECURRENT_INITIALIZER), this.biasInitializer = rl(l.biasInitializer || this.DEFAULT_BIAS_INITIALIZER), this.kernelRegularizer = jl(l.kernelRegularizer), this.recurrentRegularizer = jl(l.recurrentRegularizer), this.biasRegularizer = jl(l.biasRegularizer), this.kernelConstraint = YG(l.kernelConstraint), this.recurrentConstraint = YG(l.recurrentConstraint), this.biasConstraint = YG(l.biasConstraint), this.dropout = Dh([1, SZ([0, l.dropout == null ? 0 : l.dropout])]), this.recurrentDropout = Dh([\n      1,\n      SZ([0, l.recurrentDropout == null ? 0 : l.recurrentDropout])\n    ]), this.dropoutFunc = l.dropoutFunc, this.implementation = l.implementation, this.stateSize = this.units, this.dropoutMask = null, this.recurrentDropoutMask = null;\n  }\n  build(l) {\n    l = pl(l);\n    const G = l[l.length - 1];\n    this.kernel = this.addWeight(\"kernel\", [G, this.units * 3], null, this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.recurrentKernel = this.addWeight(\"recurrent_kernel\", [this.units, this.units * 3], null, this.recurrentInitializer, this.recurrentRegularizer, !0, this.recurrentConstraint), this.useBias ? this.bias = this.addWeight(\"bias\", [this.units * 3], null, this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint) : this.bias = null, this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      if (l = l, l.length !== 2)\n        throw new y(`GRUCell expects 2 input Tensors (inputs, h, c), got ${l.length}.`);\n      const Z = G.training == null ? !1 : G.training;\n      let h = l[1];\n      l = l[0], 0 < this.dropout && this.dropout < 1 && this.dropoutMask == null && (this.dropoutMask = FZ({\n        ones: () => TI(l),\n        rate: this.dropout,\n        training: Z,\n        count: 3,\n        dropoutFunc: this.dropoutFunc\n      })), 0 < this.recurrentDropout && this.recurrentDropout < 1 && this.recurrentDropoutMask == null && (this.recurrentDropoutMask = FZ({\n        ones: () => TI(h),\n        rate: this.recurrentDropout,\n        training: Z,\n        count: 3,\n        dropoutFunc: this.dropoutFunc\n      }));\n      const g = this.dropoutMask, b = this.recurrentDropoutMask;\n      let c, d, W;\n      0 < this.dropout && this.dropout < 1 && (l = N(l, g[0]));\n      let Y = QI(l, this.kernel.read());\n      this.useBias && (Y = JI(Y, this.bias.read())), 0 < this.recurrentDropout && this.recurrentDropout < 1 && (h = N(h, b[0]));\n      const V = this.recurrentKernel.read(), [a, i] = GI(V, [2 * this.units, this.units], V.rank - 1), m = QI(h, a), [T, s, o] = GI(Y, 3, Y.rank - 1), [B, C] = GI(m, 2, m.rank - 1);\n      c = this.recurrentActivation.apply(O(T, B)), d = this.recurrentActivation.apply(O(s, C));\n      const n = QI(N(d, h), i);\n      W = this.activation.apply(O(o, n));\n      const X = O(N(c, h), N(O(1, _l(c)), W));\n      return [X, X];\n    });\n  }\n  getConfig() {\n    const l = super.getConfig(), G = {\n      units: this.units,\n      activation: RZ(this.activation),\n      recurrentActivation: RZ(this.recurrentActivation),\n      useBias: this.useBias,\n      kernelInitializer: fl(this.kernelInitializer),\n      recurrentInitializer: fl(this.recurrentInitializer),\n      biasInitializer: fl(this.biasInitializer),\n      kernelRegularizer: Hl(this.kernelRegularizer),\n      recurrentRegularizer: Hl(this.recurrentRegularizer),\n      biasRegularizer: Hl(this.biasRegularizer),\n      activityRegularizer: Hl(this.activityRegularizer),\n      kernelConstraint: WG(this.kernelConstraint),\n      recurrentConstraint: WG(this.recurrentConstraint),\n      biasConstraint: WG(this.biasConstraint),\n      dropout: this.dropout,\n      recurrentDropout: this.recurrentDropout,\n      implementation: this.implementation,\n      resetAfter: !1\n    };\n    return Object.assign(Object.assign({}, l), G);\n  }\n}\na9.className = \"GRUCell\";\nj(a9);\nclass Wo extends AZ {\n  constructor(l) {\n    l.implementation === 0 && console.warn(\"`implementation=0` has been deprecated, and now defaults to `implementation=1`. Please update your layer call.\"), l.cell = new a9(l), super(l);\n  }\n  call(l, G) {\n    return U(() => {\n      this.cell.dropoutMask != null && (Cl(this.cell.dropoutMask), this.cell.dropoutMask = null), this.cell.recurrentDropoutMask != null && (Cl(this.cell.recurrentDropoutMask), this.cell.recurrentDropoutMask = null);\n      const Z = G == null ? null : G.mask, h = G == null ? null : G.training, g = G == null ? null : G.initialState;\n      return super.call(l, { mask: Z, training: h, initialState: g });\n    });\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return G.implmentation === 0 && (G.implementation = 1), new l(G);\n  }\n}\nWo.className = \"GRU\";\nj(Wo);\nclass Sd extends ed {\n  constructor(l) {\n    super(l), this.DEFAULT_ACTIVATION = \"tanh\", this.DEFAULT_RECURRENT_ACTIVATION = \"hardSigmoid\", this.DEFAULT_KERNEL_INITIALIZER = \"glorotNormal\", this.DEFAULT_RECURRENT_INITIALIZER = \"orthogonal\", this.DEFAULT_BIAS_INITIALIZER = \"zeros\", this.units = l.units, TG(this.units, \"units\"), this.activation = pZ(l.activation === void 0 ? this.DEFAULT_ACTIVATION : l.activation), this.recurrentActivation = pZ(l.recurrentActivation === void 0 ? this.DEFAULT_RECURRENT_ACTIVATION : l.recurrentActivation), this.useBias = l.useBias == null ? !0 : l.useBias, this.kernelInitializer = rl(l.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER), this.recurrentInitializer = rl(l.recurrentInitializer || this.DEFAULT_RECURRENT_INITIALIZER), this.biasInitializer = rl(l.biasInitializer || this.DEFAULT_BIAS_INITIALIZER), this.unitForgetBias = l.unitForgetBias, this.kernelRegularizer = jl(l.kernelRegularizer), this.recurrentRegularizer = jl(l.recurrentRegularizer), this.biasRegularizer = jl(l.biasRegularizer), this.kernelConstraint = YG(l.kernelConstraint), this.recurrentConstraint = YG(l.recurrentConstraint), this.biasConstraint = YG(l.biasConstraint), this.dropout = Dh([1, SZ([0, l.dropout == null ? 0 : l.dropout])]), this.recurrentDropout = Dh([\n      1,\n      SZ([0, l.recurrentDropout == null ? 0 : l.recurrentDropout])\n    ]), this.dropoutFunc = l.dropoutFunc, this.implementation = l.implementation, this.stateSize = [this.units, this.units], this.dropoutMask = null, this.recurrentDropoutMask = null;\n  }\n  build(l) {\n    var G;\n    l = pl(l);\n    const Z = l[l.length - 1];\n    this.kernel = this.addWeight(\"kernel\", [Z, this.units * 4], null, this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.recurrentKernel = this.addWeight(\"recurrent_kernel\", [this.units, this.units * 4], null, this.recurrentInitializer, this.recurrentRegularizer, !0, this.recurrentConstraint);\n    let h;\n    if (this.useBias) {\n      if (this.unitForgetBias) {\n        const g = this.biasInitializer, b = this.units;\n        h = new (G = class extends oI {\n          apply(d, W) {\n            const Y = g.apply([b]), V = new $V().apply([b]), a = g.apply([b * 2]);\n            return sa(sa(Y, V), a);\n          }\n        }, /** @nocollapse */\n        G.className = \"CustomInit\", G)();\n      } else\n        h = this.biasInitializer;\n      this.bias = this.addWeight(\"bias\", [this.units * 4], null, h, this.biasRegularizer, !0, this.biasConstraint);\n    } else\n      this.bias = null;\n    this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = G.training == null ? !1 : G.training;\n      if (l = l, l.length !== 3)\n        throw new y(`LSTMCell expects 3 input Tensors (inputs, h, c), got ${l.length}.`);\n      let h = l[1];\n      const g = l[2];\n      l = l[0], 0 < this.dropout && this.dropout < 1 && this.dropoutMask == null && (this.dropoutMask = FZ({\n        ones: () => TI(l),\n        rate: this.dropout,\n        training: Z,\n        count: 4,\n        dropoutFunc: this.dropoutFunc\n      })), 0 < this.recurrentDropout && this.recurrentDropout < 1 && this.recurrentDropoutMask == null && (this.recurrentDropoutMask = FZ({\n        ones: () => TI(h),\n        rate: this.recurrentDropout,\n        training: Z,\n        count: 4,\n        dropoutFunc: this.dropoutFunc\n      }));\n      const b = this.dropoutMask, c = this.recurrentDropoutMask;\n      let d, W, Y, V;\n      0 < this.dropout && this.dropout < 1 && (l = N(l, b[0]));\n      let a = QI(l, this.kernel.read());\n      0 < this.recurrentDropout && this.recurrentDropout < 1 && (h = N(h, c[0])), a = O(a, QI(h, this.recurrentKernel.read())), this.useBias && (a = JI(a, this.bias.read()));\n      const [i, m, T, s] = GI(a, 4, a.rank - 1);\n      d = this.recurrentActivation.apply(i), W = this.recurrentActivation.apply(m), Y = O(N(W, g), N(d, this.activation.apply(T))), V = this.recurrentActivation.apply(s);\n      const o = N(V, this.activation.apply(Y));\n      return [o, o, Y];\n    });\n  }\n  getConfig() {\n    const l = super.getConfig(), G = {\n      units: this.units,\n      activation: RZ(this.activation),\n      recurrentActivation: RZ(this.recurrentActivation),\n      useBias: this.useBias,\n      kernelInitializer: fl(this.kernelInitializer),\n      recurrentInitializer: fl(this.recurrentInitializer),\n      biasInitializer: fl(this.biasInitializer),\n      unitForgetBias: this.unitForgetBias,\n      kernelRegularizer: Hl(this.kernelRegularizer),\n      recurrentRegularizer: Hl(this.recurrentRegularizer),\n      biasRegularizer: Hl(this.biasRegularizer),\n      activityRegularizer: Hl(this.activityRegularizer),\n      kernelConstraint: WG(this.kernelConstraint),\n      recurrentConstraint: WG(this.recurrentConstraint),\n      biasConstraint: WG(this.biasConstraint),\n      dropout: this.dropout,\n      recurrentDropout: this.recurrentDropout,\n      implementation: this.implementation\n    };\n    return Object.assign(Object.assign({}, l), G);\n  }\n}\nSd.className = \"LSTMCell\";\nj(Sd);\nclass Yo extends AZ {\n  constructor(l) {\n    l.implementation === 0 && console.warn(\"`implementation=0` has been deprecated, and now defaults to `implementation=1`. Please update your layer call.\"), l.cell = new Sd(l), super(l);\n  }\n  call(l, G) {\n    return U(() => {\n      this.cell.dropoutMask != null && (Cl(this.cell.dropoutMask), this.cell.dropoutMask = null), this.cell.recurrentDropoutMask != null && (Cl(this.cell.recurrentDropoutMask), this.cell.recurrentDropoutMask = null);\n      const Z = G == null ? null : G.mask, h = G == null ? null : G.training, g = G == null ? null : G.initialState;\n      return super.call(l, { mask: Z, training: h, initialState: g });\n    });\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return G.implmentation === 0 && (G.implementation = 1), new l(G);\n  }\n}\nYo.className = \"LSTM\";\nj(Yo);\nclass i9 extends ed {\n  constructor(l) {\n    super(l), this.cells = l.cells;\n  }\n  get stateSize() {\n    const l = [];\n    for (const G of this.cells.slice().reverse())\n      Array.isArray(G.stateSize) ? l.push(...G.stateSize) : l.push(G.stateSize);\n    return l;\n  }\n  call(l, G) {\n    return U(() => {\n      l = l;\n      let Z = l.slice(1);\n      const h = [];\n      for (const c of this.cells.slice().reverse())\n        Array.isArray(c.stateSize) ? h.push(Z.splice(0, c.stateSize.length)) : h.push(Z.splice(0, 1));\n      h.reverse();\n      const g = [];\n      let b;\n      for (let c = 0; c < this.cells.length; ++c) {\n        const d = this.cells[c];\n        Z = h[c], c === 0 ? b = [l[0]].concat(Z) : b = [b[0]].concat(Z), b = d.call(b, G), g.push(b.slice(1));\n      }\n      Z = [];\n      for (const c of g.slice().reverse())\n        Z.push(...c);\n      return [b[0]].concat(Z);\n    });\n  }\n  build(l) {\n    FW(l) && (l = l[0]), l = l;\n    let G;\n    this.cells.forEach((Z, h) => {\n      Gh(`RNNCell_${h}`, () => {\n        Z.build(l), Array.isArray(Z.stateSize) ? G = Z.stateSize[0] : G = Z.stateSize, l = [l[0], G];\n      });\n    }), this.built = !0;\n  }\n  getConfig() {\n    const l = super.getConfig(), G = (g) => ({\n      className: g.getClassName(),\n      config: g.getConfig()\n    }), h = { cells: this.cells.map(G) };\n    return Object.assign(Object.assign({}, l), h);\n  }\n  /** @nocollapse */\n  static fromConfig(l, G, Z = {}) {\n    const h = [];\n    for (const g of G.cells)\n      h.push(ZZ(g, Z));\n    return new l({ cells: h });\n  }\n  get trainableWeights() {\n    if (!this.trainable)\n      return [];\n    const l = [];\n    for (const G of this.cells)\n      l.push(...G.trainableWeights);\n    return l;\n  }\n  get nonTrainableWeights() {\n    const l = [];\n    for (const G of this.cells)\n      l.push(...G.nonTrainableWeights);\n    if (!this.trainable) {\n      const G = [];\n      for (const Z of this.cells)\n        G.push(...Z.trainableWeights);\n      return G.concat(l);\n    }\n    return l;\n  }\n  /**\n   * Retrieve the weights of a the model.\n   *\n   * @returns A flat `Array` of `tf.Tensor`s.\n   */\n  getWeights() {\n    const l = [];\n    for (const G of this.cells)\n      l.push(...G.weights);\n    return yW(l);\n  }\n  /**\n   * Set the weights of the model.\n   *\n   * @param weights An `Array` of `tf.Tensor`s with shapes and types matching\n   *     the output of `getWeights()`.\n   */\n  setWeights(l) {\n    const G = [];\n    for (const Z of this.cells) {\n      const h = Z.weights.length, g = l.splice(h);\n      for (let b = 0; b < Z.weights.length; ++b)\n        G.push([Z.weights[b], g[b]]);\n    }\n    g9(G);\n  }\n}\ni9.className = \"StackedRNNCells\";\nj(i9);\nfunction FZ(I) {\n  const { ones: l, rate: G, training: Z = !1, count: h = 1, dropoutFunc: g } = I, b = () => g != null ? g(l(), G) : ls(l(), G), c = () => lb(b, l, Z);\n  return !h || h <= 1 ? LI(c().clone()) : Array(h).fill(void 0).map(c).map((W) => LI(W.clone()));\n}\n/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nvar zy = function(I, l) {\n  var G = {};\n  for (var Z in I) Object.prototype.hasOwnProperty.call(I, Z) && l.indexOf(Z) < 0 && (G[Z] = I[Z]);\n  if (I != null && typeof Object.getOwnPropertySymbols == \"function\")\n    for (var h = 0, Z = Object.getOwnPropertySymbols(I); h < Z.length; h++)\n      l.indexOf(Z[h]) < 0 && Object.prototype.propertyIsEnumerable.call(I, Z[h]) && (G[Z[h]] = I[Z[h]]);\n  return G;\n};\nclass Vo extends AZ {\n  constructor(l) {\n    if (l.unroll)\n      throw new Bl(\"Unrolling is not possible with convolutional RNNs.\");\n    if (Array.isArray(l.cell))\n      throw new Bl(\"It is not possible at the moment to stack convolutional cells.\");\n    super(l), this.inputSpec = [new dG({ ndim: 5 })];\n  }\n  call(l, G) {\n    return U(() => {\n      if (this.cell.dropoutMask != null && (Cl(this.cell.dropoutMask), this.cell.dropoutMask = null), this.cell.recurrentDropoutMask != null && (Cl(this.cell.recurrentDropoutMask), this.cell.recurrentDropoutMask = null), G && G.constants)\n        throw new y(\"ConvRNN2D cell does not support constants\");\n      const Z = G == null ? null : G.mask, h = G == null ? null : G.training, g = G == null ? null : G.initialState;\n      return super.call(l, { mask: Z, training: h, initialState: g });\n    });\n  }\n  computeOutputShape(l) {\n    let G = this.computeSingleOutputShape(l);\n    return this.returnSequences || (G = [G[0], ...G.slice(2)]), this.returnState && (G = [G, ...Array(2).fill([l[0], ...G.slice(-3)])]), G;\n  }\n  getInitialState(l) {\n    return U(() => {\n      const { stateSize: G } = this.cell, Z = l.shape, h = this.computeSingleOutputShape(Z), g = [h[0], ...h.slice(2)], b = mG(g);\n      return Array.isArray(G) ? Array(G.length).fill(b) : [b];\n    });\n  }\n  resetStates(l, G = !1) {\n    U(() => {\n      if (!this.stateful)\n        throw new HI(\"Cannot call resetStates() on an RNN Layer that is not stateful.\");\n      const Z = this.inputSpec[0].shape, h = this.computeSingleOutputShape(Z), g = [h[0], ...h.slice(2)];\n      if (Z[0] == null)\n        throw new y(\"If an RNN is stateful, it needs to know its batch size. Specify the batch size of your input tensors: \\n- If using a Sequential model, specify the batch size by passing a `batchInputShape` option to your first layer.\\n- If using the functional API, specify the batch size by passing a `batchShape` option to your Input layer.\");\n      if (this.getStates() == null)\n        Array.isArray(this.cell.stateSize) ? this.states_ = this.cell.stateSize.map(() => mG(g)) : this.states_ = [mG(g)];\n      else if (l == null)\n        Cl(this.states_), this.keptStates != null && (Cl(this.keptStates), this.keptStates = []), Array.isArray(this.cell.stateSize) ? this.states_ = this.cell.stateSize.map(() => mG(g)) : this.states_[0] = mG(g);\n      else {\n        if (Array.isArray(l) || (l = [l]), l.length !== this.states_.length)\n          throw new y(`Layer ${this.name} expects ${this.states_.length} state(s), but it received ${l.length} state value(s). Input received: ${l}`);\n        G ? this.keptStates.push(this.states_.slice()) : Cl(this.states_);\n        for (let c = 0; c < this.states_.length; ++c) {\n          const d = l[c], W = g;\n          if (!Nl(d.shape, W))\n            throw new y(`State ${c} is incompatible with layer ${this.name}: expected shape=${W}, received shape=${d.shape}`);\n          this.states_[c] = d;\n        }\n      }\n      this.states_ = this.states_.map((c) => LI(c.clone()));\n    });\n  }\n  computeSingleOutputShape(l) {\n    const { dataFormat: G, filters: Z, kernelSize: h, padding: g, strides: b, dilationRate: c } = this.cell, d = G === \"channelsFirst\", W = l[d ? 3 : 2], Y = l[d ? 4 : 3], V = pI(W, h[0], g, b[0], c[0]), a = pI(Y, h[1], g, b[1], c[1]);\n    return [\n      ...l.slice(0, 2),\n      ...d ? [Z, V, a] : [V, a, Z]\n    ];\n  }\n}\nVo.className = \"ConvRNN2D\";\nclass m9 extends Sd {\n  constructor(l) {\n    const { filters: G, kernelSize: Z, strides: h, padding: g, dataFormat: b, dilationRate: c } = l;\n    super(Object.assign(Object.assign({}, l), { units: G })), this.filters = G, TG(this.filters, \"filters\"), this.kernelSize = Lh(Z, 2, \"kernelSize\"), this.kernelSize.forEach((d) => TG(d, \"kernelSize\")), this.strides = Lh(h || 1, 2, \"strides\"), this.strides.forEach((d) => TG(d, \"strides\")), this.padding = g || \"valid\", hI(this.padding), this.dataFormat = b || \"channelsLast\", IG(this.dataFormat), this.dilationRate = Lh(c || 1, 2, \"dilationRate\"), this.dilationRate.forEach((d) => TG(d, \"dilationRate\"));\n  }\n  build(l) {\n    var G;\n    l = pl(l);\n    const Z = this.dataFormat === \"channelsFirst\" ? 1 : l.length - 1;\n    if (l[Z] == null)\n      throw new y(`The channel dimension of the input should be defined. Found ${l[Z]}`);\n    const h = l[Z], g = 4, b = this.kernelSize.concat([h, this.filters * g]);\n    this.kernel = this.addWeight(\"kernel\", b, null, this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint);\n    const c = this.kernelSize.concat([this.filters, this.filters * g]);\n    if (this.recurrentKernel = this.addWeight(\"recurrent_kernel\", c, null, this.recurrentInitializer, this.recurrentRegularizer, !0, this.recurrentConstraint), this.useBias) {\n      let d;\n      if (this.unitForgetBias) {\n        const W = this.biasInitializer, Y = this.filters;\n        d = new (G = class extends oI {\n          apply(a, i) {\n            const m = W.apply([Y]), T = HZ([Y]), s = W.apply([Y * 2]);\n            return qV([m, T, s]);\n          }\n        }, /** @nocollapse */\n        G.className = \"CustomInit\", G)();\n      } else\n        d = this.biasInitializer;\n      this.bias = this.addWeight(\"bias\", [this.filters * g], null, d, this.biasRegularizer, !0, this.biasConstraint);\n    }\n    this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      if (l.length !== 3)\n        throw new y(`ConvLSTM2DCell expects 3 input Tensors (inputs, h, c), got ${l.length}.`);\n      const Z = G.training || !1, h = l[0], g = l[1], b = l[2], c = 4;\n      0 < this.dropout && this.dropout < 1 && this.dropoutMask == null && (this.dropoutMask = FZ({\n        ones: () => TI(h),\n        rate: this.dropout,\n        training: Z,\n        count: c,\n        dropoutFunc: this.dropoutFunc\n      }));\n      const d = this.dropoutMask, W = (D, f, $) => !f || !f[$] ? D : N(f[$], D);\n      let Y = W(h, d, 0), V = W(h, d, 1), a = W(h, d, 2), i = W(h, d, 3);\n      0 < this.recurrentDropout && this.recurrentDropout < 1 && this.recurrentDropoutMask == null && (this.recurrentDropoutMask = FZ({\n        ones: () => TI(g),\n        rate: this.recurrentDropout,\n        training: Z,\n        count: c,\n        dropoutFunc: this.dropoutFunc\n      }));\n      const m = this.recurrentDropoutMask;\n      let T = W(g, m, 0), s = W(g, m, 1), o = W(g, m, 2), B = W(g, m, 3);\n      const C = 3, [n, X, t, e] = GI(this.kernel.read(), c, C), [S, p, F, x] = this.useBias ? GI(this.bias.read(), c) : [null, null, null, null];\n      Y = this.inputConv(Y, n, S, this.padding), V = this.inputConv(V, X, p, this.padding), a = this.inputConv(a, t, F, this.padding), i = this.inputConv(i, e, x, this.padding);\n      const [H, K, z, k] = GI(this.recurrentKernel.read(), c, C);\n      T = this.recurrentConv(T, H), s = this.recurrentConv(s, K), o = this.recurrentConv(o, z), B = this.recurrentConv(B, k);\n      const L = this.recurrentActivation.apply(O(Y, T)), v = this.recurrentActivation.apply(O(V, s)), w = O(N(v, b), N(L, this.activation.apply(O(a, o)))), r = N(this.recurrentActivation.apply(O(i, B)), this.activation.apply(w));\n      return [r, r, w];\n    });\n  }\n  getConfig() {\n    const l = super.getConfig(), G = zy(l, [\"units\"]), Z = {\n      filters: this.filters,\n      kernelSize: this.kernelSize,\n      padding: this.padding,\n      dataFormat: this.dataFormat,\n      dilationRate: this.dilationRate,\n      strides: this.strides\n    };\n    return Object.assign(Object.assign({}, G), Z);\n  }\n  inputConv(l, G, Z, h) {\n    const g = Wh(l, G, this.strides, h || \"valid\", this.dataFormat === \"channelsFirst\" ? \"NCHW\" : \"NHWC\", this.dilationRate);\n    return Z ? JI(g, Z, this.dataFormat) : g;\n  }\n  recurrentConv(l, G) {\n    return Wh(l, G, 1, \"same\", this.dataFormat === \"channelsFirst\" ? \"NCHW\" : \"NHWC\");\n  }\n}\nm9.className = \"ConvLSTM2DCell\";\nj(m9);\nclass ao extends Vo {\n  constructor(l) {\n    const G = new m9(l);\n    super(Object.assign(Object.assign({}, l), { cell: G }));\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    return new l(G);\n  }\n}\nao.className = \"ConvLSTM2D\";\nj(ao);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass T9 extends ul {\n  constructor(l) {\n    super(l), this.rate = Math.max(Math.min(l.rate, 1), 0), this.noiseShape = l.noiseShape, this.seed = l.seed, this.supportsMasking = !0;\n  }\n  getNoiseShape(l) {\n    if (this.noiseShape == null)\n      return this.noiseShape;\n    const G = l.shape, Z = [];\n    for (let h = 0; h < this.noiseShape.length; ++h)\n      Z.push(this.noiseShape[h] == null ? G[h] : this.noiseShape[h]);\n    return Z;\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l);\n      if (0 < this.rate && this.rate < 1) {\n        const h = G.training == null ? !1 : G.training, g = this.getNoiseShape(Z);\n        return lb(() => ls(Z, this.rate, g, this.seed), () => Z, h);\n      }\n      return l;\n    });\n  }\n  getConfig() {\n    const l = {\n      rate: this.rate,\n      noiseShape: this.noiseShape,\n      seed: this.seed\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  dispose() {\n    return super.dispose();\n  }\n}\nT9.className = \"Dropout\";\nj(T9);\nclass io extends T9 {\n  constructor(l) {\n    super(l), this.inputSpec = [{ ndim: 3 }];\n  }\n  getNoiseShape(l) {\n    const G = l.shape;\n    return [G[0], 1, G[2]];\n  }\n}\nio.className = \"SpatialDropout1D\";\nj(io);\nclass mo extends ul {\n  constructor(l) {\n    if (super(l), this.activation = null, this.useBias = !0, this.kernel = null, this.bias = null, this.DEFAULT_KERNEL_INITIALIZER = \"glorotNormal\", this.DEFAULT_BIAS_INITIALIZER = \"zeros\", l.batchInputShape == null && l.inputShape == null && l.inputDim != null) {\n      let G = null;\n      l.batchSize != null && (G = l.batchSize), this.batchInputShape = [G, l.inputDim];\n    }\n    this.units = l.units, TG(this.units, \"units\"), this.activation = pZ(l.activation), l.useBias != null && (this.useBias = l.useBias), this.kernelInitializer = rl(l.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER), this.biasInitializer = rl(l.biasInitializer || this.DEFAULT_BIAS_INITIALIZER), this.kernelConstraint = YG(l.kernelConstraint), this.biasConstraint = YG(l.biasConstraint), this.kernelRegularizer = jl(l.kernelRegularizer), this.biasRegularizer = jl(l.biasRegularizer), this.activityRegularizer = jl(l.activityRegularizer), this.supportsMasking = !0, this.inputSpec = [{ minNDim: 2 }];\n  }\n  build(l) {\n    l = pl(l);\n    const G = l[l.length - 1];\n    this.kernel == null && (this.kernel = this.addWeight(\"kernel\", [G, this.units], null, this.kernelInitializer, this.kernelRegularizer, !0, this.kernelConstraint), this.useBias && (this.bias = this.addWeight(\"bias\", [this.units], null, this.biasInitializer, this.biasRegularizer, !0, this.biasConstraint))), this.inputSpec = [{ minNDim: 2, axes: { [-1]: G } }], this.built = !0;\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l.slice();\n    return G[G.length - 1] = this.units, G;\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l), h = jT(this.activation.getClassName());\n      let g;\n      return h != null ? g = QI(Z, this.kernel.read(), h, this.bias ? this.bias.read() : null) : (g = QI(Z, this.kernel.read()), this.bias != null && (g = JI(g, this.bias.read())), this.activation != null && (g = this.activation.apply(g))), g;\n    });\n  }\n  getConfig() {\n    const l = {\n      units: this.units,\n      activation: RZ(this.activation),\n      useBias: this.useBias,\n      kernelInitializer: fl(this.kernelInitializer),\n      biasInitializer: fl(this.biasInitializer),\n      kernelRegularizer: Hl(this.kernelRegularizer),\n      biasRegularizer: Hl(this.biasRegularizer),\n      activityRegularizer: Hl(this.activityRegularizer),\n      kernelConstraint: WG(this.kernelConstraint),\n      biasConstraint: WG(this.biasConstraint)\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nmo.className = \"Dense\";\nj(mo);\nclass To extends ul {\n  constructor(l) {\n    l = l || {}, super(l), this.inputSpec = [{ minNDim: 3 }], this.dataFormat = l.dataFormat;\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    for (const G of l.slice(1))\n      if (G == null)\n        throw new y(`The shape of the input to \"Flatten\" is not fully defined (got ${l.slice(1)}). Make sure to pass a complete \"input_shape\" or \"batch_input_shape\" argument to the first layer in your model.`);\n    return [l[0], uZ(l, 1)];\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      let Z = Tl(l);\n      if (this.dataFormat === \"channelsFirst\" && Z.rank > 1) {\n        const h = [0];\n        for (let g = 2; g < Z.rank; ++g)\n          h.push(g);\n        h.push(1), Z = el(Z, h);\n      }\n      return CF(Z);\n    });\n  }\n  getConfig() {\n    const l = {};\n    this.dataFormat != null && (l.dataFormat = this.dataFormat);\n    const G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nTo.className = \"Flatten\";\nj(To);\nclass so extends ul {\n  constructor(l) {\n    super(l), this.supportsMasking = !0, this.activation = pZ(l.activation);\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l);\n      return this.activation.apply(Z);\n    });\n  }\n  getConfig() {\n    const l = { activation: RZ(this.activation) }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nso.className = \"Activation\";\nj(so);\nclass oo extends ul {\n  constructor(l) {\n    super(l), this.n = l.n, this.inputSpec = [{ ndim: 2 }];\n  }\n  computeOutputShape(l) {\n    return [l[0], this.n, l[1]];\n  }\n  call(l, G) {\n    return U(() => (l = Tl(l), BF(l, this.n)));\n  }\n  getConfig() {\n    const l = {\n      n: this.n\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\noo.className = \"RepeatVector\";\nj(oo);\nclass Bo extends ul {\n  constructor(l) {\n    super(l), this.targetShape = l.targetShape;\n    for (let G = 0; G < this.targetShape.length; ++G)\n      this.isUnknown(this.targetShape[G]) && (this.targetShape[G] = null);\n  }\n  isUnknown(l) {\n    return l < 0 || l == null;\n  }\n  /**\n   * Finds and replaces a missing dimension in output shape.\n   *\n   * This is a near direct port of the internal Numpy function\n   * `_fix_unknown_dimension` in `numpy/core/src/multiarray/shape.c`.\n   *\n   * @param inputShape: Original shape of array begin reshape.\n   * @param outputShape: Target shape of the array, with at most a single\n   * `null` or negative number, which indicates an underdetermined dimension\n   * that should be derived from `inputShape` and the known dimensions of\n   *   `outputShape`.\n   * @returns: The output shape with `null` replaced with its computed value.\n   * @throws: ValueError: If `inputShape` and `outputShape` do not match.\n   */\n  fixUnknownDimension(l, G) {\n    const Z = \"Total size of new array must be unchanged.\", h = G.slice();\n    let g = 1, b = null;\n    for (let d = 0; d < h.length; ++d) {\n      const W = h[d];\n      if (this.isUnknown(W))\n        if (b === null)\n          b = d;\n        else\n          throw new y(\"Can only specifiy one unknown dimension.\");\n      else\n        g *= W;\n    }\n    const c = uZ(l);\n    if (b !== null) {\n      if (g === 0 || c % g !== 0)\n        throw new y(Z);\n      h[b] = c / g;\n    } else if (c !== g)\n      throw new y(Z);\n    return h;\n  }\n  computeOutputShape(l) {\n    let G = !1;\n    for (let Z = 0; Z < l.length; ++Z)\n      if (this.isUnknown(l[Z])) {\n        G = !0;\n        break;\n      }\n    return G ? l.slice(0, 1).concat(this.targetShape) : l.slice(0, 1).concat(this.fixUnknownDimension(l.slice(1), this.targetShape));\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l), h = Z.shape, g = h.slice(0, 1).concat(this.fixUnknownDimension(h.slice(1), this.targetShape));\n      return J(Z, g);\n    });\n  }\n  getConfig() {\n    const l = {\n      targetShape: this.targetShape\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nBo.className = \"Reshape\";\nj(Bo);\nclass no extends ul {\n  constructor(l) {\n    if (super(l), l.dims == null)\n      throw new Error(\"Required configuration field `dims` is missing during Permute constructor call.\");\n    if (!Array.isArray(l.dims))\n      throw new Error(`Permute constructor requires \\`dims\\` to be an Array, but received ${l.dims} instead.`);\n    const G = FI(1, l.dims.length + 1);\n    if (!Nl(l.dims.slice().sort(), G))\n      throw new Error(\"Invalid permutation `dims`: \" + JSON.stringify(l.dims) + \" `dims` must contain consecutive integers starting from 1.\");\n    this.dims = l.dims, this.dimsIncludingBatch = [0].concat(this.dims), this.inputSpec = [new dG({ ndim: this.dims.length + 1 })];\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l.slice();\n    return this.dims.forEach((Z, h) => {\n      G[h + 1] = l[Z];\n    }), G;\n  }\n  call(l, G) {\n    return el(Tl(l), this.dimsIncludingBatch);\n  }\n  getConfig() {\n    const l = {\n      dims: this.dims\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nno.className = \"Permute\";\nj(no);\nclass Co extends ul {\n  constructor(l) {\n    super(l ?? {}), this.supportsMasking = !0, l != null ? this.maskValue = l.maskValue == null ? 0 : l.maskValue : this.maskValue = 0;\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = super.getConfig(), G = { maskValue: this.maskValue };\n    return Object.assign(G, l), G;\n  }\n  computeMask(l, G) {\n    const Z = Tl(l);\n    return nW(Ab(Z, this.maskValue), -1);\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l), b = nW(Ab(Z, this.maskValue), -1, !0);\n      return N(Z, hl(b, Z.dtype));\n    });\n  }\n}\nCo.className = \"Masking\";\nj(Co);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass Xo extends ul {\n  constructor(l) {\n    if (super(l), this.embeddings = null, this.DEFAULT_EMBEDDINGS_INITIALIZER = \"randomUniform\", l.batchInputShape == null && l.inputShape == null) {\n      let G = null;\n      l.batchSize != null && (G = l.batchSize), l.inputLength == null ? this.batchInputShape = [G, null] : this.batchInputShape = [G].concat(Jl(l.inputLength));\n    }\n    this.inputDim = l.inputDim, TG(this.inputDim, \"inputDim\"), this.outputDim = l.outputDim, TG(this.outputDim, \"outputDim\"), this.embeddingsInitializer = rl(l.embeddingsInitializer || this.DEFAULT_EMBEDDINGS_INITIALIZER), this.embeddingsRegularizer = jl(l.embeddingsRegularizer), this.activityRegularizer = jl(l.activityRegularizer), this.embeddingsConstraint = YG(l.embeddingsConstraint), this.maskZero = l.maskZero, this.supportsMasking = l.maskZero, this.inputLength = l.inputLength;\n  }\n  build(l) {\n    this.embeddings = this.addWeight(\"embeddings\", [this.inputDim, this.outputDim], this.dtype, this.embeddingsInitializer, this.embeddingsRegularizer, !0, this.embeddingsConstraint), this.built = !0;\n  }\n  // Override warnOnIncompatibleInputShape because an embedding layer allows\n  // the input to have varying ranks.\n  warnOnIncompatibleInputShape(l) {\n  }\n  computeMask(l, G) {\n    return U(() => this.maskZero ? (l = Tl(l), Ab(l, Sl(l))) : null);\n  }\n  computeOutputShape(l) {\n    if (l = pl(l), this.inputLength == null)\n      return [...l, this.outputDim];\n    const G = Jl(this.inputLength);\n    if (G.length !== l.length - 1)\n      throw new y(`\"inputLength\" is ${this.inputLength}, but received input shape has shape ${l}`);\n    {\n      let Z = 0;\n      for (let h = 0; h < G.length; ++h) {\n        const g = G[h], b = l[h + 1];\n        if (g != null && b != null && g !== b)\n          throw new y(`\"inputLength\" is ${this.inputLength}, but received input shape has shape ${l}`);\n        g == null && (G[Z] = b), Z++;\n      }\n    }\n    return [l[0], ...G, this.outputDim];\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      let Z = Tl(l);\n      Z.dtype !== \"int32\" && (Z = wI(Z, \"int32\"));\n      const h = _T(this.embeddings.read(), J(Z, [Z.size]));\n      return J(h, pl(this.computeOutputShape(Z.shape)));\n    });\n  }\n  getConfig() {\n    const l = {\n      inputDim: this.inputDim,\n      outputDim: this.outputDim,\n      embeddingsInitializer: fl(this.embeddingsInitializer),\n      embeddingsRegularizer: Hl(this.embeddingsRegularizer),\n      activityRegularizer: Hl(this.activityRegularizer),\n      embeddingsConstraint: WG(this.embeddingsConstraint),\n      maskZero: this.maskZero,\n      inputLength: this.inputLength\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nXo.className = \"Embedding\";\nj(Xo);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass Sh extends ul {\n  constructor(l) {\n    super(l || {}), this.supportsMasking = !0;\n  }\n  /**\n   * Logic for merging multiple tensors, to be overridden by subclasses.\n   * @param inputs\n   */\n  mergeFunction(l) {\n    throw new Bl();\n  }\n  /**\n   * Computes the shape of the result of an elementwise operation.\n   *\n   * @param shape1: Shape of the first tensor.\n   * @param shape2: Shape of the second tensor.\n   * @returns Expected output shape when an elementwise operation is carried\n   *   out on 2 tensors with shapes `shape1` and `shape2`.\n   * @throws ValueError: If `shape1` and `shape2` are not compatible for\n   *   element-wise operations.\n   */\n  computeElementwiseOpOutputShape(l, G) {\n    if (l == null || G == null)\n      return null;\n    if (l.length < G.length)\n      return this.computeElementwiseOpOutputShape(G, l);\n    if (G.length === 0)\n      return l;\n    const Z = l.slice(0, l.length - G.length);\n    for (let h = 0; h < G.length; ++h) {\n      const g = l[l.length - G.length + h], b = G[h];\n      if (g == null || b == null || g < 0 || b < 0)\n        Z.push(null);\n      else if (g === 1)\n        Z.push(b);\n      else if (b === 1)\n        Z.push(g);\n      else {\n        if (g !== b)\n          throw new y(\"Operands could not be broadcast together with shapes \" + JSON.stringify(l) + \" \" + JSON.stringify(G));\n        Z.push(g);\n      }\n    }\n    return Z;\n  }\n  build(l) {\n    if (Array.isArray(l) && !Array.isArray(l[0]) && (l = [pl(l)]), l = l, l.length < 2)\n      throw new y(`A merge layer should be called on an Array of at least 2 inputs. Got ${l.length} input(s).`);\n    let G = [];\n    for (const g of l)\n      g != null && g[0] !== null && G.push(g[0]);\n    if (G = tZ(G), G.length > 1)\n      throw new y(`Can not merge tensors with different batch sizes. Got tensors with shapes: ${JSON.stringify(l)}.`);\n    let Z = l[0] == null ? null : l[0].slice(1);\n    for (let g = 1; g < l.length; ++g) {\n      const b = l[g] == null ? null : l[g].slice(1);\n      Z = this.computeElementwiseOpOutputShape(Z, b);\n    }\n    const h = l.map((g) => g.length);\n    l.indexOf(null) === -1 && tZ(h).length === 1 ? this.reshapeRequired = !1 : this.reshapeRequired = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      if (l = l, this.reshapeRequired) {\n        const Z = [], h = l.map((g) => g.rank);\n        if (h.indexOf(null) === -1) {\n          const g = SZ(h);\n          for (let b of l) {\n            const c = b.rank;\n            for (let d = 0; d < g - c; ++d)\n              b = $g(b, 1);\n            Z.push(b);\n          }\n          return this.mergeFunction(Z);\n        } else {\n          let g = !1;\n          for (const d of l) {\n            const W = d.rank;\n            if (W == null) {\n              const Y = d.shape, V = Y[0], a = Y.slice(1).concat([V]);\n              let i = J(d, [V].concat(uZ(Y.slice(1))));\n              i = el(i, [1, 0]), i = J(i, a), Z.push(i), g = !0;\n            } else if (W > 1) {\n              const Y = FI(1, W).concat([0]);\n              Z.push(el(d, Y)), g = !0;\n            } else\n              Z.push(d);\n          }\n          let b = this.mergeFunction(Z);\n          const c = b.rank;\n          if (g) {\n            if (c == null) {\n              const d = b.shape, W = d.length, Y = d[W - 1], V = [Y].concat(d.slice(0, d.length - 1));\n              b = J(el(J(b, [-1, Y]), [1, 0]), V);\n            } else if (c > 1) {\n              const d = [c - 1].concat(FI(0, c - 1));\n              b = el(b, d);\n            }\n          }\n          return b;\n        }\n      } else\n        return this.mergeFunction(l);\n    });\n  }\n  computeOutputShape(l) {\n    l = l;\n    let G;\n    l[0] == null ? G = null : G = l[0].slice(1);\n    for (let h = 1; h < l.length; ++h) {\n      const g = l[h] == null ? null : l[h].slice(1);\n      G = this.computeElementwiseOpOutputShape(G, g);\n    }\n    let Z = [];\n    for (const h of l)\n      h != null && h[0] !== null && Z.push(h[0]);\n    return Z = tZ(Z), Z.length === 1 ? G = Z.concat(G) : G = [null].concat(G), G;\n  }\n  computeMask(l, G) {\n    return U(() => {\n      if (G == null)\n        return null;\n      if (!Array.isArray(G))\n        throw new y(\"`mask` should be an Array\");\n      if (!Array.isArray(l))\n        throw new y(\"`inputs` should be an Array\");\n      if (G.length !== l.length)\n        throw new y(`The Array 'inputs' and 'mask' are expected to have the same length, but have different lengths (${l.length} vs ${G.length})`);\n      if (G.every((h) => h == null))\n        return null;\n      G = G.map((h) => h == null ? h : EG(h, 0));\n      let Z = G[0];\n      for (let h = 1; h < G.length - 1; ++h)\n        Z = hZ(Z, G[h]);\n      return Z;\n    });\n  }\n}\nclass to extends Sh {\n  constructor(l) {\n    super(l);\n  }\n  mergeFunction(l) {\n    return U(() => {\n      let G = l[0].clone();\n      for (let Z = 1; Z < l.length; ++Z)\n        G = O(G, l[Z]);\n      return G;\n    });\n  }\n}\nto.className = \"Add\";\nj(to);\nclass uo extends Sh {\n  constructor(l) {\n    super(l);\n  }\n  mergeFunction(l) {\n    return U(() => {\n      let G = l[0].clone();\n      for (let Z = 1; Z < l.length; ++Z)\n        G = N(G, l[Z]);\n      return G;\n    });\n  }\n}\nuo.className = \"Multiply\";\nj(uo);\nclass eo extends Sh {\n  constructor(l) {\n    super(l);\n  }\n  mergeFunction(l) {\n    return U(() => {\n      let G = l[0].clone();\n      for (let Z = 1; Z < l.length; ++Z)\n        G = O(G, l[Z]);\n      return N(1 / l.length, G);\n    });\n  }\n}\neo.className = \"Average\";\nj(eo);\nclass So extends Sh {\n  constructor(l) {\n    super(l);\n  }\n  mergeFunction(l) {\n    return U(() => {\n      let G = l[0];\n      for (let Z = 1; Z < l.length; ++Z)\n        G = UZ(G, l[Z]);\n      return G;\n    });\n  }\n}\nSo.className = \"Maximum\";\nj(So);\nclass Ro extends Sh {\n  constructor(l) {\n    super(l);\n  }\n  mergeFunction(l) {\n    return U(() => {\n      let G = l[0];\n      for (let Z = 1; Z < l.length; ++Z)\n        G = x0(G, l[Z]);\n      return G;\n    });\n  }\n}\nRo.className = \"Minimum\";\nj(Ro);\nclass po extends Sh {\n  constructor(l) {\n    super(l), this.DEFAULT_AXIS = -1, l == null && (l = {}), this.axis = l.axis == null ? this.DEFAULT_AXIS : l.axis, this.supportsMasking = !0, this.reshapeRequired = !1;\n  }\n  build(l) {\n    if (!(Array.isArray(l) && Array.isArray(l[0])) || l.length === 1)\n      throw new y(\"A `Concatenate` layer should be called on a list of at least 2 inputs\");\n    l = l;\n    let G = !0;\n    for (const h of l)\n      if (h != null) {\n        G = !1;\n        break;\n      }\n    if (G)\n      return;\n    const Z = [];\n    for (let h = 0; h < l.length; ++h) {\n      const g = l[h].slice();\n      g.splice(this.axis, 1);\n      let b = !1;\n      for (const c of Z)\n        if (Nl(c, g)) {\n          b = !0;\n          break;\n        }\n      b || Z.push(g);\n    }\n    if (Z.length > 1)\n      throw new y(\"A `Concatenate` layer requires inputs with matching shapes except for the concat axis. Got input shapes: \" + JSON.stringify(l));\n  }\n  mergeFunction(l) {\n    return U(() => qV(l, this.axis));\n  }\n  computeOutputShape(l) {\n    if (!(Array.isArray(l) && Array.isArray(l[0])))\n      throw new y(\"A `Concatenate` layer should be called on a list of inputs.\");\n    const G = l, Z = G[0].slice(), h = this.axis < 0 ? Z.length + this.axis : this.axis;\n    for (const g of G.slice(1)) {\n      if (Z[h] == null || g[h] == null) {\n        Z[h] = null;\n        break;\n      }\n      Z[h] += g[h];\n    }\n    return Z;\n  }\n  computeMask(l, G) {\n    if (G == null)\n      return null;\n    if (!Array.isArray(G))\n      throw new y(\"`mask` should be an array for Concatenate\");\n    if (!Array.isArray(l))\n      throw new y(\"`inputs` should be an array for Concatenate\");\n    if (G.length !== l.length)\n      throw new y(`Mismatch in the length of mask (${G.length}) and the legnth of inputs (${l.length})`);\n    return U(() => {\n      let Z = !0;\n      if (G.forEach((b) => {\n        if (b != null) {\n          Z = !1;\n          return;\n        }\n      }), Z)\n        return null;\n      const h = [];\n      for (let b = 0; b < l.length; ++b)\n        G[b] == null ? h.push(hl(TI(l[b]), \"bool\")) : G[b].rank < l[b].rank ? h.push(EG(G[b], -1)) : h.push(G[b]);\n      const g = zG(h, this.axis);\n      return Rm(g, -1, !1);\n    });\n  }\n  getConfig() {\n    const l = {\n      axis: this.axis\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\npo.className = \"Concatenate\";\nj(po);\nfunction t0(I, l) {\n  for (; I < 0; )\n    I += l;\n  return I;\n}\nfunction Ly(I, l, G) {\n  if (I.shape.length > 3 || l.shape.length > 3)\n    throw new Bl(\"batchDot is not implemented for tensors of 4D or higher rank yet\");\n  if (u(I.shape.length >= 2, () => `batchDot requires the rank of x to be >= 2, but got ${I.shape.length}`), u(I.shape.length >= 2, () => `batchDot requires the rank of y to be >= 2, but got ${l.shape.length}`), typeof G == \"number\" && (G = [G, G]), I.dtype === \"complex64\" || l.dtype === \"complex64\")\n    throw new Bl(\"batchDot is not implemented for complex64-type Tensors yet.\");\n  const Z = I.shape.length, h = l.shape.length;\n  G == null && (G = [Z - 1, h - 2]);\n  const g = G;\n  return U(() => {\n    let b;\n    if (Z > h) {\n      b = Z - h;\n      const d = [];\n      for (let W = 0; W < b; ++W)\n        d.push(1);\n      l = J(l, l.shape.concat(d));\n    } else if (h > Z) {\n      b = h - Z;\n      const d = [];\n      for (let W = 0; W < b; ++W)\n        d.push(1);\n      I = J(I, I.shape.concat(d));\n    } else\n      b = 0;\n    let c;\n    if (I.shape.length === 2 && l.shape.length === 2)\n      g[0] === g[1] ? c = Yl(N(I, l), g[0]) : c = Yl(N(el(I, [1, 0]), l), g[1]);\n    else {\n      const d = g[0] !== I.shape.length - 1, W = g[1] === l.shape.length - 1;\n      c = Fl(I, l, d, W);\n    }\n    if (b > 0) {\n      let d;\n      Z > h ? d = Z + h - 3 : d = Z - 1;\n      const W = [];\n      for (let Y = d; Y < d + b; ++Y)\n        W.push(Y);\n      c = rg(c, W);\n    }\n    return c.shape.length === 1 && (c = EG(c, 1)), c;\n  });\n}\nclass Fo extends Sh {\n  constructor(l) {\n    super(l), this.axes = l.axes, this.normalize = l.normalize == null ? !1 : l.normalize, this.supportsMasking = !0, this.reshapeRequired = !1;\n  }\n  build(l) {\n    u(Array.isArray(l) && l.length === 2 && Array.isArray(l[0]) && Array.isArray(l[1]), () => \"A `Dot` layer should be called on a list of exactly 2 inputs.\");\n    const G = l[0], Z = l[1];\n    if (G.length > 3 || Z.length > 3)\n      throw new Bl(\"Dot layer does not support tensors of 4D or higher rank yet.\");\n    const h = this.interpretAxes(G, Z);\n    if (G[h[0]] !== Z[h[1]])\n      throw new y(`Dimension incompatibility: ${G[h[0]]} !== ${Z[h[1]]}`);\n  }\n  mergeFunction(l) {\n    if (l.length !== 2)\n      throw new y(`A \\`Dot\\` layer must be called on exactly 2 inputs, but received ${l.length} input(s).`);\n    let G = l[0], Z = l[1], h;\n    return Array.isArray(this.axes) ? h = this.axes.map((g, b) => t0(g, l[b].shape.length)) : h = [\n      t0(this.axes, G.shape.length),\n      t0(this.axes, Z.shape.length)\n    ], this.normalize && (G = vb(G, h[0]), Z = vb(Z, h[1])), Ly(G, Z, h);\n  }\n  interpretAxes(l, G) {\n    let Z;\n    return Array.isArray(this.axes) ? Z = this.axes : Z = [\n      t0(this.axes, l.length),\n      t0(this.axes, G.length)\n    ], Z;\n  }\n  computeOutputShape(l) {\n    u(Array.isArray(l) && l.length === 2 && Array.isArray(l[0]) && Array.isArray(l[1]), () => \"A `Dot` layer should be called on a list of exactly 2 inputs.\");\n    const G = l[0].slice(), Z = l[1].slice();\n    if (G.length > 3 || Z.length > 3)\n      throw new Bl(\"Dot layer does not support tensors of 4D or higher rank yet.\");\n    const h = this.interpretAxes(G, Z);\n    G.splice(h[0], 1), Z.splice(h[1], 1), Z.splice(0, 1);\n    const g = G.concat(Z);\n    return g.length === 1 && g.push(1), g;\n  }\n  computeMask(l, G) {\n    return null;\n  }\n  getConfig() {\n    const l = {\n      axes: this.axes,\n      normalize: this.normalize\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nFo.className = \"Dot\";\nj(Fo);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass yo extends ul {\n  constructor(l) {\n    super(l), this.supportsMasking = !0, this.stddev = l.stddev;\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = super.getConfig(), G = { stddev: this.stddev };\n    return Object.assign(G, l), G;\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l);\n      return lb(() => O(Bd(Z.shape, 0, this.stddev), Z), () => Z, G.training || !1);\n    });\n  }\n}\nyo.className = \"GaussianNoise\";\nj(yo);\nclass No extends ul {\n  constructor(l) {\n    super(l), this.supportsMasking = !0, this.rate = l.rate;\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = super.getConfig(), G = { rate: this.rate };\n    return Object.assign(G, l), G;\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G);\n      const Z = Tl(l);\n      return this.rate > 0 && this.rate < 1 ? lb(() => {\n        const g = Math.sqrt(this.rate / (1 - this.rate));\n        return N(Z, Bd(Z.shape, 1, g));\n      }, () => Z, G.training || !1) : Z;\n    });\n  }\n}\nNo.className = \"GaussianDropout\";\nj(No);\nclass Po extends ul {\n  constructor(l) {\n    super(l), this.supportsMasking = !0, this.rate = l.rate, this.noiseShape = l.noiseShape;\n  }\n  _getNoiseShape(l) {\n    return this.noiseShape || Tl(l).shape;\n  }\n  computeOutputShape(l) {\n    return l;\n  }\n  getConfig() {\n    const l = super.getConfig(), G = { rate: this.rate };\n    return Object.assign(G, l), G;\n  }\n  call(l, G) {\n    return U(() => {\n      if (this.rate < 1 && this.rate > 0) {\n        const Z = this._getNoiseShape(l);\n        return lb(() => {\n          const g = Tl(l), d = -1.6732632423543772 * 1.0507009873554805;\n          let W = Ch(vg(Z), this.rate);\n          W = wI(W, \"float32\");\n          const Y = ((1 - this.rate) * (1 + this.rate * d ** 2)) ** -0.5, V = -Y * d * this.rate, a = O(N(g, W), N(O(W, -1), d));\n          return O(N(a, Y), V);\n        }, () => Tl(l), G.training || !1);\n      }\n      return l;\n    });\n  }\n}\nPo.className = \"AlphaDropout\";\nj(Po);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction k0(I, l, G, Z, h, g = 1e-3) {\n  let b;\n  if (I.rank === 2)\n    b = BX(I, l, G, Z, h, g);\n  else if (I.rank === 3)\n    b = CX(I, l, G, Z, h, g);\n  else if (I.rank === 4)\n    b = tX(I, l, G, Z, h, g);\n  else\n    throw new Bl(`batchNormalization is not implemented for array of rank ${I.rank} yet`);\n  return b;\n}\nfunction My(I, l, G, Z, h = 1e-3) {\n  return U(() => {\n    const g = _Y(I, Z), b = g.mean, c = g.variance;\n    return [k0(I, b, c, G, l, h), b, c];\n  });\n}\nfunction wy(I, l, G, Z, h = 1e-3) {\n  return U(() => {\n    const g = _Y(I, Z), b = g.mean, c = g.variance, d = [];\n    for (const m of FI(0, I.rank))\n      Z.indexOf(m) !== -1 ? d.push(1) : d.push(I.shape[m]);\n    const W = J(b, d), Y = J(c, d), V = l == null ? null : J(l, d), a = G == null ? null : J(G, d);\n    return [k0(I, W, Y, a, V, h), b, c];\n  });\n}\nfunction Qy(I, l, G, Z, h = 1e-3) {\n  return Nl(Z.slice().sort(), FI(0, I.rank - 1)) ? My(I, l, G, Z, h) : wy(I, l, G, Z, h);\n}\nclass Jo extends ul {\n  constructor(l) {\n    l == null && (l = {}), super(l), this.supportsMasking = !0, this.axis = l.axis == null ? -1 : l.axis, this.momentum = l.momentum == null ? 0.99 : l.momentum, this.epsilon = l.epsilon == null ? 1e-3 : l.epsilon, this.center = l.center == null ? !0 : l.center, this.scale = l.scale == null ? !0 : l.scale, this.betaInitializer = rl(l.betaInitializer || \"zeros\"), this.gammaInitializer = rl(l.gammaInitializer || \"ones\"), this.movingMeanInitializer = rl(l.movingMeanInitializer || \"zeros\"), this.movingVarianceInitializer = rl(l.movingVarianceInitializer || \"ones\"), this.betaConstraint = YG(l.betaConstraint), this.gammaConstraint = YG(l.gammaConstraint), this.betaRegularizer = jl(l.betaRegularizer), this.gammaRegularizer = jl(l.gammaRegularizer);\n  }\n  build(l) {\n    l = pl(l);\n    const G = this.axis >= 0 ? this.axis : this.axis + l.length, Z = l[G];\n    if (Z == null)\n      throw new y(`Axis ${G} of input tensor should have a defined dimension but the layer received an input with shape ${JSON.stringify(l)}.`);\n    this.inputSpec = [new dG({ ndim: l.length, axes: { [G]: Z } })];\n    const h = [Z];\n    this.scale && (this.gamma = this.addWeight(\"gamma\", h, null, this.gammaInitializer, this.gammaRegularizer, !0, this.gammaConstraint)), this.center && (this.beta = this.addWeight(\"beta\", h, null, this.betaInitializer, this.betaRegularizer, !0, this.betaConstraint)), this.movingMean = this.addWeight(\"moving_mean\", h, null, this.movingMeanInitializer, null, !1), this.movingVariance = this.addWeight(\"moving_variance\", h, null, this.movingVarianceInitializer, null, !1), this.built = !0;\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = G.training == null ? !1 : G.training, h = Tl(l), g = h.shape, b = g.length, c = FI(0, b), d = this.axis >= 0 ? this.axis : this.axis + b;\n      c.splice(d, 1);\n      const W = ih(1, b);\n      W[d] = g[d];\n      const Y = c.slice();\n      Y.sort();\n      const V = !Nl(Y, FI(0, b).slice(0, b - 1)), a = () => {\n        if (V) {\n          const B = J(this.movingMean.read(), W), C = J(this.movingVariance.read(), W), n = this.center ? J(this.beta.read(), W) : null, X = this.scale ? J(this.gamma.read(), W) : null;\n          return k0(h, B, C, n, X, this.epsilon);\n        } else\n          return k0(h, this.movingMean.read(), this.movingVariance.read(), this.beta == null ? null : this.beta.read(), this.gamma == null ? null : this.gamma.read(), this.epsilon);\n      };\n      if (!Z)\n        return a();\n      const [i, m, T] = Qy(h, this.gamma.read(), this.beta.read(), c, this.epsilon), s = (B, C, n) => {\n        U(() => {\n          const X = 1 - n, t = B.read(), e = N(ml(t, C), X);\n          B.write(ml(t, e));\n        });\n      };\n      return (() => {\n        s(this.movingMean, m, this.momentum), s(this.movingVariance, T, this.momentum);\n      })(), i;\n    });\n  }\n  getConfig() {\n    const l = {\n      axis: this.axis,\n      momentum: this.momentum,\n      epsilon: this.epsilon,\n      center: this.center,\n      scale: this.scale,\n      betaInitializer: fl(this.betaInitializer),\n      gammaInitializer: fl(this.gammaInitializer),\n      movingMeanInitializer: fl(this.movingMeanInitializer),\n      movingVarianceInitializer: fl(this.movingVarianceInitializer),\n      betaRegularizer: Hl(this.betaRegularizer),\n      gammaRegularizer: Hl(this.gammaRegularizer),\n      betaConstraint: WG(this.betaConstraint),\n      gammaConstraint: WG(this.gammaConstraint)\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nJo.className = \"BatchNormalization\";\nj(Jo);\nclass Eo extends ul {\n  constructor(l) {\n    if (l == null && (l = {}), super(l), this.axis = l.axis == null ? -1 : l.axis, typeof this.axis == \"number\") {\n      if (!Number.isInteger(this.axis))\n        throw new Error(`Expected axis to be an integer, but received ${this.axis}`);\n    } else if (Array.isArray(this.axis)) {\n      for (const G of this.axis)\n        if (!Number.isInteger(G))\n          throw new Error(`Expected axis to be an array of integers, but received ${JSON.stringify(this.axis)}`);\n    } else\n      throw new Error(`Expected axis to be an integer or an array of integers, but received ${JSON.stringify(this.axis)}`);\n    this.epsilon = l.epsilon == null ? 1e-3 : l.epsilon, this.center = l.center == null ? !0 : l.center, this.scale = l.scale == null ? !0 : l.scale, this.betaInitializer = rl(l.betaInitializer || \"zeros\"), this.gammaInitializer = rl(l.gammaInitializer || \"ones\"), this.betaRegularizer = jl(l.betaRegularizer), this.gammaRegularizer = jl(l.gammaRegularizer), this.supportsMasking = !0;\n  }\n  build(l) {\n    l = pl(l);\n    const G = l.length;\n    typeof this.axis == \"number\" && (this.axis = [this.axis]);\n    for (let g = 0; g < this.axis.length; ++g)\n      this.axis[g] < 0 && (this.axis[g] += G);\n    for (const g of this.axis)\n      if (g < 0 || g >= G)\n        throw new Error(`Invalid axis: ${g}`);\n    if (this.axis.length !== tZ(this.axis).length)\n      throw new Error(`Found duplicate axes in: ${this.axis}`);\n    const Z = this.axis.map((g) => l[g]), h = !0;\n    this.scale ? this.gamma = this.addWeight(\"gamma\", Z, \"float32\", this.gammaInitializer, this.gammaRegularizer, h) : this.gamma = null, this.center ? this.beta = this.addWeight(\"beta\", Z, \"float32\", this.betaInitializer, this.betaRegularizer, h) : this.beta = null, this.built = !0;\n  }\n  call(l, G) {\n    const Z = Tl(l), h = Z.shape, g = h.length;\n    return U(() => {\n      let { mean: c, variance: d } = _Y(Z, this.axis, !0);\n      const W = ih(1, g);\n      for (const T of this.axis)\n        W[T] = h[T];\n      const Y = (T) => T != null && T.shape.length !== g ? J(T, W) : T;\n      let V = this.scale ? Y(this.gamma.read()) : null, a = this.center ? Y(this.beta.read()) : null;\n      const i = [], m = [];\n      for (let T = 0; T < g; ++T)\n        this.axis.indexOf(T) !== -1 ? (i.push(h[T]), m.push(1)) : (i.push(1), m.push(h[T]));\n      return c = eI(c, i), d = eI(d, i), V != null && (V = eI(V, m)), a != null && (a = eI(a, m)), k0(Z, c, d, a, V, this.epsilon);\n    });\n  }\n  getConfig() {\n    const l = {\n      axis: this.axis,\n      epsilon: this.epsilon,\n      center: this.center,\n      scale: this.scale,\n      betaInitializer: fl(this.betaInitializer),\n      gammaInitializer: fl(this.gammaInitializer),\n      betaRegularizer: Hl(this.betaRegularizer),\n      gammaRegularizer: Hl(this.gammaRegularizer)\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nEo.className = \"LayerNormalization\";\nj(Eo);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction vy(I, l, G) {\n  return U(() => {\n    if (I.rank !== 4)\n      throw new y(`temporalPadding expects input tensor to be 4-D, but received a ${I.rank}-D tensor.`);\n    if (l == null && (l = [[1, 1], [1, 1]]), l.length !== 2 || l[0].length !== 2 || l[1].length !== 2)\n      throw new y(\"spatial2dPadding expects `padding` to be an Array of two Arrays, each of which is an Array of two integers.\");\n    if (G == null && (G = yI()), G !== \"channelsLast\" && G !== \"channelsFirst\")\n      throw new y(`Unknown data format: ${G}. Supported data formats are 'channelsLast' and 'channelsFirst.`);\n    let Z;\n    return G === \"channelsFirst\" ? Z = [[0, 0], [0, 0], l[0], l[1]] : Z = [[0, 0], l[0], l[1], [0, 0]], lV(I, Z);\n  });\n}\nclass xo extends ul {\n  constructor(l) {\n    if (l == null && (l = {}), super(l), this.dataFormat = l.dataFormat == null ? yI() : l.dataFormat, l.padding == null)\n      this.padding = [[1, 1], [1, 1]];\n    else if (typeof l.padding == \"number\")\n      this.padding = [[l.padding, l.padding], [l.padding, l.padding]];\n    else {\n      if (l.padding = l.padding, l.padding.length !== 2)\n        throw new y(`ZeroPadding2D expects padding to be a length-2 array, but received a length-${l.padding.length} array.`);\n      let G, Z;\n      if (typeof l.padding[0] == \"number\")\n        G = [l.padding[0], l.padding[0]], Z = [l.padding[1], l.padding[1]];\n      else {\n        if (l.padding = l.padding, l.padding[0].length !== 2)\n          throw new y(`ZeroPadding2D expects height padding to be a length-2 array, but received a length-${l.padding[0].length} array.`);\n        if (G = l.padding[0], l.padding[1].length !== 2)\n          throw new y(`ZeroPadding2D expects width padding to be a length-2 array, but received a length-${l.padding[1].length} array.`);\n        Z = l.padding[1];\n      }\n      this.padding = [G, Z];\n    }\n    this.inputSpec = [new dG({ ndim: 4 })];\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    let G, Z;\n    return this.dataFormat === \"channelsFirst\" ? (l[2] != null && l[2] >= 0 ? G = l[2] + this.padding[0][0] + this.padding[0][1] : G = null, l[3] != null && l[3] >= 0 ? Z = l[3] + this.padding[1][0] + this.padding[1][1] : Z = null, [l[0], l[1], G, Z]) : (l[1] != null && l[1] >= 0 ? G = l[1] + this.padding[0][0] + this.padding[0][1] : G = null, l[2] != null && l[2] >= 0 ? Z = l[2] + this.padding[1][0] + this.padding[1][1] : Z = null, [l[0], G, Z, l[3]]);\n  }\n  call(l, G) {\n    return U(() => vy(Tl(l), this.padding, this.dataFormat));\n  }\n  getConfig() {\n    const l = {\n      padding: this.padding,\n      dataFormat: this.dataFormat\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nxo.className = \"ZeroPadding2D\";\nj(xo);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Rd(I, l, G, Z, h, g) {\n  return U(() => {\n    IG(h), fT(g), hI(Z), G == null && (G = [1, 1]), Z == null && (Z = \"valid\"), h == null && (h = yI()), g == null && (g = \"max\"), I = Y9(I, h);\n    let b;\n    const c = Z === \"same\" ? \"same\" : \"valid\";\n    return g === \"max\" ? b = $Y(I, l, G, c) : b = MY(\n      // TODO(cais): Rank check?\n      I,\n      l,\n      G,\n      c\n    ), h === \"channelsFirst\" && (b = el(b, [0, 3, 1, 2])), b;\n  });\n}\nfunction Uo(I, l, G, Z, h, g) {\n  return U(() => {\n    IG(h), fT(g), hI(Z), G == null && (G = [1, 1, 1]), Z == null && (Z = \"valid\"), h == null && (h = yI()), g == null && (g = \"max\"), I = qs(I, h);\n    let b;\n    const c = Z === \"same\" ? \"same\" : \"valid\";\n    return g === \"max\" ? b = bu(I, l, G, c) : b = dX(I, l, G, c), h === \"channelsFirst\" && (b = el(b, [0, 4, 1, 2, 3])), b;\n  });\n}\nclass Ho extends ul {\n  /**\n   *\n   * @param args Parameters for the Pooling layer.\n   *\n   * config.poolSize defaults to 2.\n   */\n  constructor(l) {\n    if (l.poolSize == null && (l.poolSize = 2), super(l), typeof l.poolSize == \"number\")\n      this.poolSize = [l.poolSize];\n    else if (Array.isArray(l.poolSize) && l.poolSize.length === 1 && typeof l.poolSize[0] == \"number\")\n      this.poolSize = l.poolSize;\n    else\n      throw new y(`poolSize for 1D convolutional layer must be a number or an Array of a single number, but received ${JSON.stringify(l.poolSize)}`);\n    if (TG(this.poolSize, \"poolSize\"), l.strides == null)\n      this.strides = this.poolSize;\n    else if (typeof l.strides == \"number\")\n      this.strides = [l.strides];\n    else if (Array.isArray(l.strides) && l.strides.length === 1 && typeof l.strides[0] == \"number\")\n      this.strides = l.strides;\n    else\n      throw new y(`strides for 1D convolutional layer must be a number or an Array of a single number, but received ${JSON.stringify(l.strides)}`);\n    TG(this.strides, \"strides\"), this.padding = l.padding == null ? \"valid\" : l.padding, hI(this.padding), this.inputSpec = [new dG({ ndim: 3 })];\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = pI(l[1], this.poolSize[0], this.padding, this.strides[0]);\n    return [l[0], G, l[2]];\n  }\n  call(l, G) {\n    return U(() => {\n      this.invokeCallHook(l, G), l = $g(Tl(l), 2);\n      const Z = this.poolingFunction(Tl(l), [this.poolSize[0], 1], [this.strides[0], 1], this.padding, \"channelsLast\");\n      return rg(Z, [2]);\n    });\n  }\n  getConfig() {\n    const l = {\n      poolSize: this.poolSize,\n      padding: this.padding,\n      strides: this.strides\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nclass Ko extends Ho {\n  constructor(l) {\n    super(l);\n  }\n  poolingFunction(l, G, Z, h, g) {\n    return IG(g), hI(h), Rd(l, G, Z, h, g, \"max\");\n  }\n}\nKo.className = \"MaxPooling1D\";\nj(Ko);\nclass Ao extends Ho {\n  constructor(l) {\n    super(l);\n  }\n  poolingFunction(l, G, Z, h, g) {\n    return IG(g), hI(h), Rd(l, G, Z, h, g, \"avg\");\n  }\n}\nAo.className = \"AveragePooling1D\";\nj(Ao);\nclass ko extends ul {\n  constructor(l) {\n    if (l.poolSize == null && (l.poolSize = [2, 2]), super(l), this.poolSize = Array.isArray(l.poolSize) ? l.poolSize : [l.poolSize, l.poolSize], l.strides == null)\n      this.strides = this.poolSize;\n    else if (Array.isArray(l.strides)) {\n      if (l.strides.length !== 2)\n        throw new y(`If the strides property of a 2D pooling layer is an Array, it is expected to have a length of 2, but received length ${l.strides.length}.`);\n      this.strides = l.strides;\n    } else\n      this.strides = [l.strides, l.strides];\n    TG(this.poolSize, \"poolSize\"), TG(this.strides, \"strides\"), this.padding = l.padding == null ? \"valid\" : l.padding, this.dataFormat = l.dataFormat == null ? \"channelsLast\" : l.dataFormat, IG(this.dataFormat), hI(this.padding), this.inputSpec = [new dG({ ndim: 4 })];\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    let G = this.dataFormat === \"channelsFirst\" ? l[2] : l[1], Z = this.dataFormat === \"channelsFirst\" ? l[3] : l[2];\n    return G = pI(G, this.poolSize[0], this.padding, this.strides[0]), Z = pI(Z, this.poolSize[1], this.padding, this.strides[1]), this.dataFormat === \"channelsFirst\" ? [l[0], l[1], G, Z] : [l[0], G, Z, l[3]];\n  }\n  call(l, G) {\n    return U(() => (this.invokeCallHook(l, G), this.poolingFunction(Tl(l), this.poolSize, this.strides, this.padding, this.dataFormat)));\n  }\n  getConfig() {\n    const l = {\n      poolSize: this.poolSize,\n      padding: this.padding,\n      strides: this.strides,\n      dataFormat: this.dataFormat\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nclass zo extends ko {\n  constructor(l) {\n    super(l);\n  }\n  poolingFunction(l, G, Z, h, g) {\n    return IG(g), hI(h), Rd(l, G, Z, h, g, \"max\");\n  }\n}\nzo.className = \"MaxPooling2D\";\nj(zo);\nclass Lo extends ko {\n  constructor(l) {\n    super(l);\n  }\n  poolingFunction(l, G, Z, h, g) {\n    return IG(g), hI(h), Rd(l, G, Z, h, g, \"avg\");\n  }\n}\nLo.className = \"AveragePooling2D\";\nj(Lo);\nclass Mo extends ul {\n  constructor(l) {\n    if (l.poolSize == null && (l.poolSize = [2, 2, 2]), super(l), this.poolSize = Array.isArray(l.poolSize) ? l.poolSize : [l.poolSize, l.poolSize, l.poolSize], l.strides == null)\n      this.strides = this.poolSize;\n    else if (Array.isArray(l.strides)) {\n      if (l.strides.length !== 3)\n        throw new y(`If the strides property of a 3D pooling layer is an Array, it is expected to have a length of 3, but received length ${l.strides.length}.`);\n      this.strides = l.strides;\n    } else\n      this.strides = [l.strides, l.strides, l.strides];\n    TG(this.poolSize, \"poolSize\"), TG(this.strides, \"strides\"), this.padding = l.padding == null ? \"valid\" : l.padding, this.dataFormat = l.dataFormat == null ? \"channelsLast\" : l.dataFormat, IG(this.dataFormat), hI(this.padding), this.inputSpec = [new dG({ ndim: 5 })];\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    let G = this.dataFormat === \"channelsFirst\" ? l[2] : l[1], Z = this.dataFormat === \"channelsFirst\" ? l[3] : l[2], h = this.dataFormat === \"channelsFirst\" ? l[4] : l[3];\n    return G = pI(G, this.poolSize[0], this.padding, this.strides[0]), Z = pI(Z, this.poolSize[1], this.padding, this.strides[1]), h = pI(h, this.poolSize[2], this.padding, this.strides[2]), this.dataFormat === \"channelsFirst\" ? [l[0], l[1], G, Z, h] : [l[0], G, Z, h, l[4]];\n  }\n  call(l, G) {\n    return U(() => (this.invokeCallHook(l, G), this.poolingFunction(Tl(l), this.poolSize, this.strides, this.padding, this.dataFormat)));\n  }\n  getConfig() {\n    const l = {\n      poolSize: this.poolSize,\n      padding: this.padding,\n      strides: this.strides,\n      dataFormat: this.dataFormat\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nclass wo extends Mo {\n  constructor(l) {\n    super(l);\n  }\n  poolingFunction(l, G, Z, h, g) {\n    return IG(g), hI(h), Uo(l, G, Z, h, g, \"max\");\n  }\n}\nwo.className = \"MaxPooling3D\";\nj(wo);\nclass Qo extends Mo {\n  constructor(l) {\n    super(l);\n  }\n  poolingFunction(l, G, Z, h, g) {\n    return IG(g), hI(h), Uo(l, G, Z, h, g, \"avg\");\n  }\n}\nQo.className = \"AveragePooling3D\";\nj(Qo);\nclass vo extends ul {\n  constructor(l) {\n    super(l), this.inputSpec = [new dG({ ndim: 3 })];\n  }\n  computeOutputShape(l) {\n    return [l[0], l[2]];\n  }\n  call(l, G) {\n    throw new Bl();\n  }\n}\nclass ro extends vo {\n  constructor(l) {\n    super(l || {});\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = Tl(l);\n      return gG(Z, 1);\n    });\n  }\n}\nro.className = \"GlobalAveragePooling1D\";\nj(ro);\nclass jo extends vo {\n  constructor(l) {\n    super(l || {});\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = Tl(l);\n      return RI(Z, 1);\n    });\n  }\n}\njo.className = \"GlobalMaxPooling1D\";\nj(jo);\nclass Do extends ul {\n  constructor(l) {\n    super(l), this.dataFormat = l.dataFormat == null ? \"channelsLast\" : l.dataFormat, IG(this.dataFormat), this.inputSpec = [new dG({ ndim: 4 })];\n  }\n  computeOutputShape(l) {\n    return l = l, this.dataFormat === \"channelsLast\" ? [l[0], l[3]] : [l[0], l[1]];\n  }\n  call(l, G) {\n    throw new Bl();\n  }\n  getConfig() {\n    const l = { dataFormat: this.dataFormat }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\nclass fo extends Do {\n  call(l, G) {\n    return U(() => {\n      const Z = Tl(l);\n      return this.dataFormat === \"channelsLast\" ? gG(Z, [1, 2]) : gG(Z, [2, 3]);\n    });\n  }\n}\nfo.className = \"GlobalAveragePooling2D\";\nj(fo);\nclass Oo extends Do {\n  call(l, G) {\n    return U(() => {\n      const Z = Tl(l);\n      return this.dataFormat === \"channelsLast\" ? RI(Z, [1, 2]) : RI(Z, [2, 3]);\n    });\n  }\n}\nOo.className = \"GlobalMaxPooling2D\";\nj(Oo);\n/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass qo extends ul {\n  constructor(l) {\n    super(l), this.layer = l.layer;\n  }\n  build(l) {\n    this.built = !0;\n  }\n  // TODO(cais): Implement activityRegularizer getter.\n  get trainable() {\n    return this.layer != null ? this.layer.trainable : !1;\n  }\n  set trainable(l) {\n    this.layer != null && (this.layer.trainable = l);\n  }\n  get trainableWeights() {\n    return this.layer.trainableWeights;\n  }\n  // TODO(cais): Implement setter for trainableWeights.\n  get nonTrainableWeights() {\n    return this.layer.nonTrainableWeights;\n  }\n  // TODO(cais): Implement setter for nonTrainableWeights.\n  get updates() {\n    return this.layer._updates;\n  }\n  // TODO(cais): Implement getUpdatesFor().\n  get losses() {\n    return this.layer.losses;\n  }\n  // TODO(cais): Implement getLossesFor().\n  getWeights() {\n    return this.layer.getWeights();\n  }\n  setWeights(l) {\n    this.layer.setWeights(l);\n  }\n  getConfig() {\n    const l = {\n      layer: {\n        className: this.layer.getClassName(),\n        config: this.layer.getConfig()\n      }\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  setFastWeightInitDuringBuild(l) {\n    super.setFastWeightInitDuringBuild(l), this.layer != null && this.layer.setFastWeightInitDuringBuild(l);\n  }\n  /** @nocollapse */\n  static fromConfig(l, G, Z = {}) {\n    const h = G.layer, g = ZZ(h, Z);\n    delete G.layer;\n    const b = { layer: g };\n    return Object.assign(b, G), new l(b);\n  }\n}\nclass $o extends qo {\n  constructor(l) {\n    super(l), this.supportsMasking = !0;\n  }\n  build(l) {\n    if (l = pl(l), l.length < 3)\n      throw new y(`TimeDistributed layer expects an input shape >= 3D, but received input shape ${JSON.stringify(l)}`);\n    this.inputSpec = [{ shape: l }];\n    const G = [l[0]].concat(l.slice(2));\n    this.layer.built || (this.layer.build(G), this.layer.built = !0), super.build(l);\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = [l[0]].concat(l.slice(2)), Z = this.layer.computeOutputShape(G), h = l[1];\n    return [Z[0], h].concat(Z.slice(1));\n  }\n  call(l, G) {\n    return U(() => (l = Tl(l), bo(\n      (b, c) => [Tl(this.layer.call(b, G)), []],\n      l,\n      [],\n      !1,\n      null,\n      null,\n      !1,\n      !0\n      /* needPerStepOutputs */\n    )[1]));\n  }\n}\n$o.className = \"TimeDistributed\";\nj($o);\nfunction ry(I) {\n  eh(iF, \"BidirectionalMergeMode\", I);\n}\nconst jy = \"concat\";\nclass _o extends qo {\n  constructor(l) {\n    super(l);\n    const G = l.layer.getConfig(), Z = {};\n    Z.className = l.layer.getClassName(), Z.config = G, this.forwardLayer = ZZ(Z), G.goBackwards = G.goBackwards !== !0;\n    const h = {};\n    if (h.className = l.layer.getClassName(), h.config = G, this.backwardLayer = ZZ(h), this.forwardLayer.name = \"forward_\" + this.forwardLayer.name, this.backwardLayer.name = \"backward_\" + this.backwardLayer.name, this.mergeMode = l.mergeMode === void 0 ? jy : l.mergeMode, ry(this.mergeMode), l.weights)\n      throw new Bl(\"weights support is not implemented for Bidirectional layer yet.\");\n    this._stateful = l.layer.stateful, this.returnSequences = l.layer.returnSequences, this.returnState = l.layer.returnState, this.supportsMasking = !0, this._trainable = !0, this.inputSpec = l.layer.inputSpec, this.numConstants = null;\n  }\n  get trainable() {\n    return this._trainable;\n  }\n  set trainable(l) {\n    this._trainable = l, this.forwardLayer != null && (this.forwardLayer.trainable = l), this.backwardLayer != null && (this.backwardLayer.trainable = l);\n  }\n  getWeights() {\n    return this.forwardLayer.getWeights().concat(this.backwardLayer.getWeights());\n  }\n  setWeights(l) {\n    const G = l.length, Z = Math.floor(G / 2);\n    this.forwardLayer.setWeights(l.slice(0, Z)), this.backwardLayer.setWeights(l.slice(Z));\n  }\n  computeOutputShape(l) {\n    let G = this.forwardLayer.computeOutputShape(l);\n    Array.isArray(G) && Array.isArray(G[0]) || (G = [G]), G = G;\n    let Z, h, g;\n    return this.returnState && (g = G.slice(1)), Z = G[0], Z = Z, this.mergeMode === \"concat\" ? (Z[Z.length - 1] *= 2, h = [Z]) : this.mergeMode == null ? h = [Z, Z.slice()] : h = [Z], this.returnState ? this.mergeMode == null ? h.concat(g).concat(g.slice()) : [Z].concat(g).concat(g.slice()) : kG(h);\n  }\n  apply(l, G) {\n    let Z = G == null ? null : G.initialState, h = G == null ? null : G.constants;\n    G == null && (G = {});\n    const g = go(l, Z, h, this.numConstants);\n    if (l = g.inputs, Z = g.initialState, h = g.constants, Array.isArray(l) && (Z = l.slice(1), l = l[0]), (Z == null || Z.length === 0) && h == null)\n      return super.apply(l, G);\n    const b = [], c = [];\n    if (Z != null) {\n      const W = Z.length;\n      if (W % 2 > 0)\n        throw new y(\"When passing `initialState` to a Bidrectional RNN, the state should be an Array containing the states of the underlying RNNs.\");\n      G.initialState = Z, b.push(...Z);\n      const Y = Z.map((V) => new dG({ shape: V.shape }));\n      this.forwardLayer.stateSpec = Y.slice(0, W / 2), this.backwardLayer.stateSpec = Y.slice(W / 2), c.push(...Y);\n    }\n    if (h != null)\n      throw new Bl(\"Support for constants in Bidirectional layers is not implemented yet.\");\n    const d = b[0] instanceof DI;\n    for (const W of b)\n      if (W instanceof DI !== d)\n        throw new y(\"The initial state of a Bidirectional layer cannot be specified as a mix of symbolic and non-symbolic tensors\");\n    if (d) {\n      const W = [l].concat(b), Y = this.inputSpec.concat(c), V = this.inputSpec;\n      this.inputSpec = Y;\n      const a = super.apply(W, G);\n      return this.inputSpec = V, a;\n    } else\n      return super.apply(l, G);\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = G.initialState;\n      let h, g;\n      if (Z == null)\n        h = this.forwardLayer.call(l, G), g = this.backwardLayer.call(l, G);\n      else {\n        const d = Z.slice(0, Z.length / 2), W = Z.slice(Z.length / 2);\n        h = this.forwardLayer.call(l, Object.assign(G, { initialState: d })), g = this.backwardLayer.call(l, Object.assign(G, { initialState: W }));\n      }\n      let b;\n      this.returnState && (Array.isArray(h) && (b = h.slice(1).concat(g.slice(1))), h = h[0], g = g[0]), this.returnSequences && (g = Vh(g, 1));\n      let c;\n      return this.mergeMode === \"concat\" ? c = qV([h, g]) : this.mergeMode === \"sum\" ? c = O(h, g) : this.mergeMode === \"ave\" ? c = N(0.5, O(h, g)) : this.mergeMode === \"mul\" ? c = N(h, g) : this.mergeMode == null && (c = [h, g]), this.returnState ? this.mergeMode == null ? c.concat(b) : [c].concat(b) : c;\n    });\n  }\n  resetStates(l) {\n    this.forwardLayer.resetStates(), this.backwardLayer.resetStates();\n  }\n  build(l) {\n    Gh(this.forwardLayer.name, () => {\n      this.forwardLayer.build(l);\n    }), Gh(this.backwardLayer.name, () => {\n      this.backwardLayer.build(l);\n    }), this.built = !0;\n  }\n  computeMask(l, G) {\n    Array.isArray(G) && (G = G[0]);\n    let Z;\n    if (this.returnSequences ? this.mergeMode == null ? Z = [G, G] : Z = G : this.mergeMode == null ? Z = [null, null] : Z = null, this.returnState) {\n      const g = this.forwardLayer.states.map((b) => null);\n      return Array.isArray(Z) ? Z.concat(g).concat(g) : [Z].concat(g).concat(g);\n    } else\n      return Z;\n  }\n  get trainableWeights() {\n    return this.forwardLayer.trainableWeights.concat(this.backwardLayer.trainableWeights);\n  }\n  get nonTrainableWeights() {\n    return this.forwardLayer.nonTrainableWeights.concat(this.backwardLayer.nonTrainableWeights);\n  }\n  // TODO(cais): Implement constraints().\n  setFastWeightInitDuringBuild(l) {\n    super.setFastWeightInitDuringBuild(l), this.forwardLayer != null && this.forwardLayer.setFastWeightInitDuringBuild(l), this.backwardLayer != null && this.backwardLayer.setFastWeightInitDuringBuild(l);\n  }\n  getConfig() {\n    const l = {\n      mergeMode: this.mergeMode\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  /** @nocollapse */\n  static fromConfig(l, G) {\n    const Z = ZZ(G.layer);\n    if (delete G.layer, G.numConstants != null)\n      throw new Bl(\"Deserialization of a Bidirectional layer with numConstants present is not supported yet.\");\n    const h = G;\n    return h.layer = Z, new l(h);\n  }\n}\n_o.className = \"Bidirectional\";\nj(_o);\n/**\n * @license\n * Copyright 2022 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass l2 extends ul {\n  constructor(l) {\n    super(l), this.scale = l.scale, l.offset ? this.offset = l.offset : this.offset = 0;\n  }\n  getConfig() {\n    const l = {\n      scale: this.scale,\n      offset: this.offset\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  call(l, G) {\n    return U(() => (l = Tl(l), l.dtype !== \"float32\" && (l = wI(l, \"float32\")), O(N(l, this.scale), this.offset)));\n  }\n}\nl2.className = \"Rescaling\";\nj(l2);\n/**\n * @license\n * Copyright 2022 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst { resizeBilinear: Dy, cropAndResize: fy } = IZ;\nclass G2 extends ul {\n  constructor(l) {\n    super(l), this.height = l.height, this.width = l.width;\n  }\n  centerCrop(l, G, Z, h, g, b, c, d) {\n    return U(() => {\n      let W, Y = !1;\n      const V = G / b, a = Z / c, i = (h + G) / b, m = (g + Z) / c, T = [V, a, i, m], s = [];\n      l.rank === 3 ? (Y = !0, W = gZ([l])) : W = l;\n      for (let X = 0; X < W.shape[0]; X++)\n        s.push(T);\n      const o = kY(s, [s.length, 4]), B = U0(0, s.length, 1, \"int32\"), n = fy(W, o, B, [h, g], \"nearest\");\n      return wI(Y ? Tl(ah(n)) : n, d);\n    });\n  }\n  upsize(l, G, Z, h) {\n    return U(() => {\n      const g = Dy(l, [G, Z]);\n      return wI(g, h);\n    });\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = Tl(l), h = Z.dtype, g = Z.shape, b = g[g.length - 3], c = g[g.length - 2];\n      let d = 0;\n      b !== this.height && (d = Math.floor((b - this.height) / 2));\n      let W = 0;\n      return c !== this.width && (W = Math.floor((c - this.width) / 2), W === 0 && (W = 1)), d >= 0 && W >= 0 ? this.centerCrop(Z, d, W, this.height, this.width, b, c, h) : this.upsize(l, this.height, this.width, h);\n    });\n  }\n  getConfig() {\n    const l = {\n      height: this.height,\n      width: this.width\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l.length - 3, Z = l.length - 2;\n    return l[G] = this.height, l[Z] = this.width, l;\n  }\n}\nG2.className = \"CenterCrop\";\nj(G2);\n/**\n * @license\n * Copyright 2022 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nfunction Oy(I, l, G, Z) {\n  let h = Tl(I);\n  if (h.dtype !== \"int32\" && (h = wI(h, \"int32\")), l === \"int\")\n    return h;\n  const g = h.shape;\n  if (h.rank === 0 && (h = EG(h, -1)), l === \"oneHot\" && h.shape[h.shape.length - 1] !== 1 && (h = EG(h, -1)), h.rank > 2)\n    throw new y(`When outputMode is not int, maximum output rank is 2 Received outputMode ${l} and input shape ${g} which would result in output rank ${h.rank}.`);\n  const b = [\"multiHot\", \"oneHot\"].includes(l), c = h;\n  let d;\n  if (typeof Z < \"u\" && l === \"count\" ? d = Ga(c, Z, G, b) : d = Ga(c, [], G, b), l !== \"tfIdf\")\n    return d;\n  if (Z)\n    return N(d, Z);\n  throw new y(\"When outputMode is 'tfIdf', weights must be provided.\");\n}\n/**\n * @license\n * Copyright 2022 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass I2 extends ul {\n  constructor(l) {\n    super(l), this.numTokens = l.numTokens, l.outputMode ? this.outputMode = l.outputMode : this.outputMode = \"multiHot\";\n  }\n  getConfig() {\n    const l = {\n      numTokens: this.numTokens,\n      outputMode: this.outputMode\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  computeOutputShape(l) {\n    return l = pl(l), l == null ? [this.numTokens] : this.outputMode === \"oneHot\" && l[l.length - 1] !== 1 ? (l.push(this.numTokens), l) : (l[l.length - 1] = this.numTokens, l);\n  }\n  call(l, G) {\n    return U(() => {\n      l = Tl(l), l.dtype !== \"int32\" && (l = wI(l, \"int32\"));\n      let Z;\n      if (typeof G.countWeights < \"u\") {\n        if (this.outputMode !== \"count\")\n          throw new y(`countWeights is not used when outputMode !== count.\n              Received countWeights=${G.countWeights}`);\n        Z = Tl(G.countWeights);\n      }\n      const h = RI(l), g = Hb(l), b = ZI(this.numTokens, h).bufferSync().get(0), c = Ch(g, 0).bufferSync().get(0);\n      if (!(b && c))\n        throw new y(`Input values must be between 0 < values <= numTokens with numTokens=${this.numTokens}`);\n      return Oy(l, this.outputMode, this.numTokens, Z);\n    });\n  }\n}\nI2.className = \"CategoryEncoding\";\nj(I2);\n/**\n * @license\n * Copyright 2022 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst qy = [\"bilinear\", \"nearest\"], xa = new Set(qy);\nclass Z2 extends ul {\n  constructor(l) {\n    if (super(l), this.height = l.height, this.width = l.width, l.interpolation)\n      if (xa.has(l.interpolation))\n        this.interpolation = l.interpolation;\n      else\n        throw new y(`Invalid interpolation parameter: ${l.interpolation} is not implemented`);\n    else\n      this.interpolation = \"bilinear\";\n    this.cropToAspectRatio = !!l.cropToAspectRatio;\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l[2];\n    return [this.height, this.width, G];\n  }\n  getConfig() {\n    const l = {\n      height: this.height,\n      width: this.width,\n      interpolation: this.interpolation,\n      cropToAspectRatio: this.cropToAspectRatio\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = [this.height, this.width];\n      if (this.interpolation === \"bilinear\")\n        return IZ.resizeBilinear(l, Z, !this.cropToAspectRatio);\n      if (this.interpolation === \"nearest\")\n        return IZ.resizeNearestNeighbor(l, Z, !this.cropToAspectRatio);\n      throw new Error(`Interpolation is ${this.interpolation} but only ${[...xa]} are supported`);\n    });\n  }\n}\nZ2.className = \"Resizing\";\nj(Z2);\n/**\n * @license\n * Copyright 2023 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass h2 {\n  constructor(l) {\n    this.seed = l;\n  }\n  next() {\n    if (this.seed !== void 0)\n      return this.seed++;\n  }\n}\nh2.className = \"RandomSeed\";\n/**\n * @license\n * Copyright 2023 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nclass g2 extends ul {\n  constructor(l) {\n    super(l), this.randomGenerator = new h2(l.seed);\n  }\n  getConfig() {\n    const l = {\n      seed: this.randomGenerator.seed\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n}\ng2.className = \"BaseRandomLayer\";\n/**\n * @license\n * Copyright 2023 CodeSmith LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\nconst $y = [\"bilinear\", \"nearest\"], Ua = new Set($y);\nclass b2 extends g2 {\n  constructor(l) {\n    super(l);\n    const { factor: G, interpolation: Z = \"bilinear\" } = l;\n    if (this.factor = G, Array.isArray(this.factor) && this.factor.length === 2)\n      this.widthLower = this.factor[0], this.widthUpper = this.factor[1];\n    else if (!Array.isArray(this.factor) && this.factor > 0)\n      this.widthLower = -this.factor, this.widthUpper = this.factor;\n    else\n      throw new y(`Invalid factor: ${this.factor}. Must be positive number or tuple of 2 numbers`);\n    if (this.widthLower < -1 || this.widthUpper < -1)\n      throw new y(`factor must have values larger than -1. Got: ${this.factor}`);\n    if (this.widthUpper < this.widthLower)\n      throw new y(`factor cannot have upper bound less than lower bound.\n        Got upper bound: ${this.widthUpper}.\n        Got lower bound: ${this.widthLower}\n      `);\n    if (Z)\n      if (Ua.has(Z))\n        this.interpolation = Z;\n      else\n        throw new y(`Invalid interpolation parameter: ${Z} is not implemented`);\n  }\n  getConfig() {\n    const l = {\n      factor: this.factor,\n      interpolation: this.interpolation\n    }, G = super.getConfig();\n    return Object.assign(l, G), l;\n  }\n  computeOutputShape(l) {\n    l = pl(l);\n    const G = l[2];\n    return [this.imgHeight, -1, G];\n  }\n  call(l, G) {\n    return U(() => {\n      const Z = Tl(l);\n      this.imgHeight = Z.shape[Z.shape.length - 3];\n      const h = Z.shape[Z.shape.length - 2];\n      this.widthFactor = vg([1], 1 + this.widthLower, 1 + this.widthUpper, \"float32\", this.randomGenerator.next());\n      let g = this.widthFactor.dataSync()[0] * h;\n      g = Math.round(g);\n      const b = [this.imgHeight, g];\n      switch (this.interpolation) {\n        case \"bilinear\":\n          return IZ.resizeBilinear(l, b);\n        case \"nearest\":\n          return IZ.resizeNearestNeighbor(l, b);\n        default:\n          throw new Error(`Interpolation is ${this.interpolation}\n          but only ${[...Ua]} are supported`);\n      }\n    });\n  }\n}\nb2.className = \"RandomWidth\";\nj(b2);\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst _y = A();\n_y.registerFlag(\"KEEP_INTERMEDIATE_TENSORS\", () => !1, (I) => {\n  I && console.warn(\"Keep intermediate tensors is ON. This will print the values of all intermediate tensors during model inference. Not all models support this mode. For details, check e2e/benchmarks/ model_config.js. This significantly impacts performance.\");\n});\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\nvar Ha;\n(function(I) {\n  I[I.DT_INVALID = 0] = \"DT_INVALID\", I[I.DT_FLOAT = 1] = \"DT_FLOAT\", I[I.DT_DOUBLE = 2] = \"DT_DOUBLE\", I[I.DT_INT32 = 3] = \"DT_INT32\", I[I.DT_UINT8 = 4] = \"DT_UINT8\", I[I.DT_INT16 = 5] = \"DT_INT16\", I[I.DT_INT8 = 6] = \"DT_INT8\", I[I.DT_STRING = 7] = \"DT_STRING\", I[I.DT_COMPLEX64 = 8] = \"DT_COMPLEX64\", I[I.DT_INT64 = 9] = \"DT_INT64\", I[I.DT_BOOL = 10] = \"DT_BOOL\", I[I.DT_QINT8 = 11] = \"DT_QINT8\", I[I.DT_QUINT8 = 12] = \"DT_QUINT8\", I[I.DT_QINT32 = 13] = \"DT_QINT32\", I[I.DT_BFLOAT16 = 14] = \"DT_BFLOAT16\", I[I.DT_QINT16 = 15] = \"DT_QINT16\", I[I.DT_QUINT16 = 16] = \"DT_QUINT16\", I[I.DT_UINT16 = 17] = \"DT_UINT16\", I[I.DT_COMPLEX128 = 18] = \"DT_COMPLEX128\", I[I.DT_HALF = 19] = \"DT_HALF\", I[I.DT_RESOURCE = 20] = \"DT_RESOURCE\", I[I.DT_VARIANT = 21] = \"DT_VARIANT\", I[I.DT_UINT32 = 22] = \"DT_UINT32\", I[I.DT_UINT64 = 23] = \"DT_UINT64\", I[I.DT_FLOAT_REF = 101] = \"DT_FLOAT_REF\", I[I.DT_DOUBLE_REF = 102] = \"DT_DOUBLE_REF\", I[I.DT_INT32_REF = 103] = \"DT_INT32_REF\", I[I.DT_UINT8_REF = 104] = \"DT_UINT8_REF\", I[I.DT_INT16_REF = 105] = \"DT_INT16_REF\", I[I.DT_INT8_REF = 106] = \"DT_INT8_REF\", I[I.DT_STRING_REF = 107] = \"DT_STRING_REF\", I[I.DT_COMPLEX64_REF = 108] = \"DT_COMPLEX64_REF\", I[I.DT_INT64_REF = 109] = \"DT_INT64_REF\", I[I.DT_BOOL_REF = 110] = \"DT_BOOL_REF\", I[I.DT_QINT8_REF = 111] = \"DT_QINT8_REF\", I[I.DT_QUINT8_REF = 112] = \"DT_QUINT8_REF\", I[I.DT_QINT32_REF = 113] = \"DT_QINT32_REF\", I[I.DT_BFLOAT16_REF = 114] = \"DT_BFLOAT16_REF\", I[I.DT_QINT16_REF = 115] = \"DT_QINT16_REF\", I[I.DT_QUINT16_REF = 116] = \"DT_QUINT16_REF\", I[I.DT_UINT16_REF = 117] = \"DT_UINT16_REF\", I[I.DT_COMPLEX128_REF = 118] = \"DT_COMPLEX128_REF\", I[I.DT_HALF_REF = 119] = \"DT_HALF_REF\", I[I.DT_RESOURCE_REF = 120] = \"DT_RESOURCE_REF\", I[I.DT_VARIANT_REF = 121] = \"DT_VARIANT_REF\", I[I.DT_UINT32_REF = 122] = \"DT_UINT32_REF\", I[I.DT_UINT64_REF = 123] = \"DT_UINT64_REF\";\n})(Ha || (Ha = {}));\nvar Ka;\n(function(I) {\n  (function(l) {\n    l[l.LEGACY = 0] = \"LEGACY\", l[l.V1 = 1] = \"V1\", l[l.V2 = 2] = \"V2\";\n  })(I.CheckpointFormatVersion || (I.CheckpointFormatVersion = {}));\n})(Ka || (Ka = {}));\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * =============================================================================\n */\nvar Aa;\n(function(I) {\n  I[I.FAIL = 0] = \"FAIL\", I[I.SHORTEST = 1] = \"SHORTEST\", I[I.LONGEST = 2] = \"LONGEST\";\n})(Aa || (Aa = {}));\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction bl(I, l) {\n  Array.isArray(I) || (I = [I]), I.forEach((G) => {\n    G != null && u(G.dtype !== \"complex64\", () => `${l} does not support complex64 tensors in the CPU backend.`);\n  });\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst lN = GT;\nclass pd extends wW {\n  nextDataId() {\n    return pd.nextDataId++;\n  }\n  constructor() {\n    super(), this.blockSize = 48, this.firstUse = !0, this.data = new ti(this, EI());\n  }\n  write(l, G, Z) {\n    this.firstUse && (this.firstUse = !1, A().get(\"IS_NODE\") && _G(`\n============================\nHi, looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, visit https://github.com/tensorflow/tfjs-node for more details. \n============================`));\n    const h = { id: this.nextDataId() };\n    return this.data.set(h, { values: l, dtype: Z, refCount: 1 }), h;\n  }\n  /**\n   * Create a data bucket in cpu backend.\n   * @param shape Shape of the `TensorInfo`.\n   * @param dtype DType of the `TensorInfo`.\n   * @param values The value of the `TensorInfo` stored as a flattened array.\n   */\n  makeTensorInfo(l, G, Z) {\n    let h;\n    if (G === \"string\" && Z != null && Z.length > 0 && v0(Z[0])) {\n      const g = Z.map((b) => XZ(b));\n      h = this.write(g, l, G);\n    } else\n      h = this.write(Z, l, G);\n    return { dataId: h, shape: l, dtype: G };\n  }\n  /** Return refCount of a `TensorData`. */\n  refCount(l) {\n    return this.data.has(l) ? this.data.get(l).refCount : 0;\n  }\n  /** Increase refCount of a `TensorData`. */\n  incRef(l) {\n    const G = this.data.get(l);\n    G.refCount++;\n  }\n  /** Decrease refCount of a `TensorData`. */\n  decRef(l) {\n    if (this.data.has(l)) {\n      const G = this.data.get(l);\n      G.refCount--;\n    }\n  }\n  move(l, G, Z, h, g) {\n    this.data.set(l, { values: G, dtype: h, refCount: g });\n  }\n  numDataIds() {\n    return this.data.numDataIds();\n  }\n  async read(l) {\n    return this.readSync(l);\n  }\n  readSync(l) {\n    const { dtype: G, complexTensorInfos: Z } = this.data.get(l);\n    if (G === \"complex64\") {\n      const h = this.readSync(Z.real.dataId), g = this.readSync(Z.imag.dataId);\n      return bZ(h, g);\n    }\n    return tn(this.data.get(l).values, G);\n  }\n  bufferSync(l) {\n    const G = this.readSync(l.dataId);\n    if (l.dtype === \"string\")\n      try {\n        const Z = G.map((h) => eZ(h));\n        return Xl(l.shape, l.dtype, Z);\n      } catch {\n        throw new Error(\"Failed to decode encoded string bytes into utf-8\");\n      }\n    return Xl(l.shape, l.dtype, G);\n  }\n  makeOutput(l, G, Z) {\n    return EI().makeTensorFromTensorInfo(this.makeTensorInfo(G, Z, l), this);\n  }\n  /**\n   * Dispose the memory if the dataId has 0 refCount. Return true if the memory\n   * is released or memory is not managed in this backend, false if memory is\n   * not cleared.\n   * @param dataId\n   * @oaram force Optional, remove the data regardless of refCount\n   */\n  disposeData(l, G = !1) {\n    if (this.data.has(l)) {\n      if (this.data.get(l).refCount--, !G && this.data.get(l).refCount > 0)\n        return !1;\n      const { complexTensorInfos: Z } = this.data.get(l);\n      Z != null && (this.disposeData(Z.real.dataId, !0), this.disposeData(Z.imag.dataId, !0)), this.data.delete(l);\n    }\n    return !0;\n  }\n  disposeIntermediateTensorInfo(l) {\n    this.disposeData(l.dataId);\n  }\n  async time(l) {\n    const G = AG();\n    return l(), { kernelMs: AG() - G };\n  }\n  memory() {\n    return {\n      // Unreliable due to automatic gc. The numbers above are cumulative.\n      unreliable: !0,\n      reasons: [\"The reported memory is an upper bound. Due to automatic garbage collection, the true allocated memory may be less.\"]\n    };\n  }\n  where(l) {\n    bl([l], \"where\");\n    const G = this.readSync(l.dataId);\n    return lN(l.shape, G);\n  }\n  dispose() {\n  }\n  floatPrecision() {\n    return 32;\n  }\n  /** Returns the smallest representable number.  */\n  epsilon() {\n    return super.epsilon();\n  }\n}\npd.nextDataId = 0;\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction c2(I) {\n  const l = new Float32Array(I.length);\n  for (let G = 0; G < I.length; ++G)\n    l[G] = Math.abs(I[G]);\n  return l;\n}\nconst GN = (I) => {\n  const { x: l } = I.inputs, G = I.backend;\n  bl(l, \"abs\");\n  let Z = new Float32Array(Q(l.shape));\n  const h = G.data.get(l.dataId).values;\n  return Z = c2(h), G.makeOutput(Z, l.shape, l.dtype);\n}, IN = {\n  kernelName: bc,\n  backendName: \"cpu\",\n  kernelFunc: GN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ZG(I) {\n  return (l, G, Z, h, g) => {\n    const b = sl(l, G), c = b.length, d = Wl(b), W = Q(b), Y = eG(g, W), V = l.length, a = G.length, i = Wl(l), m = Wl(G), T = rh(l, b), s = rh(G, b);\n    if (T.length + s.length === 0)\n      for (let o = 0; o < Y.length; ++o)\n        Y[o] = I(Z[o % Z.length], h[o % h.length]);\n    else\n      for (let o = 0; o < Y.length; ++o) {\n        const B = G0(o, c, d), C = B.slice(-V);\n        T.forEach((e) => C[e] = 0);\n        const n = zI(C, V, i), X = B.slice(-a);\n        s.forEach((e) => X[e] = 0);\n        const t = zI(X, a, m);\n        Y[o] = I(Z[n], h[t]);\n      }\n    return [Y, b];\n  };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vG(I) {\n  const { inputs: l, backend: G } = I, { real: Z, imag: h } = l, g = G.data.get(Z.dataId).values, b = G.data.get(h.dataId).values, c = G.makeTensorInfo(Z.shape, \"complex64\"), d = G.data.get(c.dataId);\n  return d.complexTensorInfos = {\n    real: G.makeTensorInfo(Z.shape, \"float32\", g),\n    imag: G.makeTensorInfo(h.shape, \"float32\", b)\n  }, c;\n}\nconst ZN = {\n  kernelName: ZY,\n  backendName: \"cpu\",\n  kernelFunc: vG\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ob(I, l, G = \"float32\") {\n  if (G === \"complex64\") {\n    const h = Ob(I, l, \"float32\"), g = Ob(I, l, \"float32\");\n    return vG({ inputs: { real: h, imag: g }, backend: I });\n  }\n  const Z = SG(Q(l), G);\n  return I.makeTensorInfo(l, G, Z);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction fI(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  return G.incRef(Z.dataId), { dataId: Z.dataId, shape: Z.shape, dtype: Z.dtype };\n}\nconst hN = {\n  kernelName: ag,\n  backendName: \"cpu\",\n  kernelFunc: fI\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mh(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l, h = G.data.get(Z.dataId).complexTensorInfos.real, g = G.data.get(h.dataId).values;\n  return G.makeTensorInfo(h.shape, h.dtype, g);\n}\nconst gN = {\n  kernelName: pY,\n  backendName: \"cpu\",\n  kernelFunc: mh\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction d2(I, l, G, Z) {\n  if (Z === \"int32\") {\n    const h = Int32Array.from(I);\n    return [l, \"int32\", h];\n  }\n  if (Z === \"bool\") {\n    const h = nh([0], G), [g, b] = ZG((c, d) => c !== d ? 1 : 0)(l, [], I, h, \"bool\");\n    return [b, \"bool\", g];\n  }\n  throw new Error(`Error in Cast: failed to cast ${G} to ${Z}`);\n}\nfunction yZ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { dtype: g } = Z;\n  if (g === \"complex64\") {\n    if (h.dtype === \"complex64\")\n      return fI({ inputs: { x: h }, backend: G });\n    const Y = Ob(G, h.shape, h.dtype), V = yZ({ inputs: { x: h }, backend: G, attrs: { dtype: \"float32\" } }), a = vG({ inputs: { real: V, imag: Y }, backend: G });\n    return G.disposeIntermediateTensorInfo(Y), G.disposeIntermediateTensorInfo(V), a;\n  }\n  if (h.dtype === \"complex64\") {\n    const Y = mh({ inputs: { input: h }, backend: G }), V = yZ({ inputs: { x: Y }, backend: G, attrs: { dtype: g } });\n    return G.disposeIntermediateTensorInfo(Y), V;\n  }\n  if (!ei(h.dtype, g)) {\n    const Y = fI({ inputs: { x: h }, backend: G });\n    return { dataId: Y.dataId, shape: Y.shape, dtype: g };\n  }\n  const b = G.data.get(h.dataId).values, [c, d, W] = d2(b, h.shape, h.dtype, g);\n  return G.makeTensorInfo(c, d, W);\n}\nconst bN = {\n  kernelName: _0,\n  backendName: \"cpu\",\n  kernelFunc: yZ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction aG(I, l, G, Z) {\n  return G == null ? ({ inputs: h, backend: g }) => {\n    const { a: b, b: c } = h, d = g;\n    bl([b, c], I);\n    const W = d.data.get(b.dataId).values, Y = d.data.get(c.dataId).values, V = b.dtype === \"string\" ? (\n      // tslint:disable-next-line: no-any\n      cZ(W)\n    ) : W, a = b.dtype === \"string\" ? (\n      // tslint:disable-next-line: no-any\n      cZ(Y)\n    ) : Y, i = Z || b.dtype, [m, T] = l(b.shape, c.shape, V, a, i);\n    return d.makeTensorInfo(T, i, m);\n  } : ({ inputs: h, backend: g }) => {\n    const { a: b, b: c } = h, d = g;\n    if (b.dtype === \"complex64\" || c.dtype === \"complex64\") {\n      const W = yZ({ inputs: { x: b }, backend: d, attrs: { dtype: \"complex64\" } }), Y = d.data.get(W.dataId), V = Y.complexTensorInfos.real, a = Y.complexTensorInfos.imag, i = d.data.get(V.dataId).values, m = d.data.get(a.dataId).values, T = yZ({ inputs: { x: c }, backend: d, attrs: { dtype: \"complex64\" } }), s = d.data.get(T.dataId), o = s.complexTensorInfos.real, B = s.complexTensorInfos.imag, C = d.data.get(o.dataId).values, n = d.data.get(B.dataId).values, [X, t, e] = G(b.shape, c.shape, i, m, C, n), S = d.makeTensorInfo(e, \"float32\", X), p = d.makeTensorInfo(e, \"float32\", t), F = vG({ inputs: { real: S, imag: p }, backend: d });\n      return d.disposeIntermediateTensorInfo(W), d.disposeIntermediateTensorInfo(T), d.disposeIntermediateTensorInfo(S), d.disposeIntermediateTensorInfo(p), F;\n    } else {\n      const W = d.data.get(b.dataId).values, Y = d.data.get(c.dataId).values, V = Z || b.dtype, [a, i] = l(b.shape, c.shape, W, Y, V);\n      return d.makeTensorInfo(i, V, a);\n    }\n  };\n}\nfunction s9(I) {\n  return (l, G, Z, h, g, b) => {\n    const c = sl(l, G), d = Q(c), W = c.length, Y = Wl(c), V = eG(\"float32\", d), a = eG(\"float32\", d), i = rh(l, c), m = rh(G, c), T = bZ(Z, h), s = bZ(g, b), o = l.length, B = Wl(l), C = G.length, n = Wl(G);\n    if (i.length + m.length === 0)\n      for (let X = 0; X < V.length; X++) {\n        const t = X % T.length, e = X % s.length, S = I(T[t * 2], T[t * 2 + 1], s[e * 2], s[e * 2 + 1]);\n        V[X] = S.real, a[X] = S.imag;\n      }\n    else\n      for (let X = 0; X < V.length; X++) {\n        const t = G0(X, W, Y), e = t.slice(-o);\n        i.forEach((H) => e[H] = 0);\n        const S = zI(e, o, B), p = t.slice(-C);\n        m.forEach((H) => p[H] = 0);\n        const F = zI(p, C, n), x = I(T[S * 2], T[S * 2 + 1], s[F * 2], s[F * 2 + 1]);\n        V[X] = x.real, a[X] = x.imag;\n      }\n    return [V, a, c];\n  };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst W2 = ZG((I, l) => I + l), cN = s9((I, l, G, Z) => ({ real: I + G, imag: l + Z })), fh = aG(I0, W2, cN), dN = {\n  kernelName: I0,\n  backendName: \"cpu\",\n  kernelFunc: fh\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction o9(I, l, G, Z, h) {\n  const g = Q(Z), b = SG(h, G);\n  for (let c = 0; c < I.length; c++) {\n    const d = I[c];\n    if (d < 0)\n      throw new Error(\"Input x must be non-negative!\");\n    d >= h || (g > 0 ? b[d] += l[c] : b[d] += 1);\n  }\n  return b;\n}\nfunction Y2(I, l, G, Z = !1) {\n  const h = I.shape[0], g = I.shape[1], b = Xl([h, G], l.dtype);\n  for (let c = 0; c < h; c++)\n    for (let d = 0; d < g; d++) {\n      const W = I.get(c, d);\n      if (W < 0)\n        throw new Error(\"Input x must be non-negative!\");\n      W >= G || (Z ? b.set(1, c, W) : l.size > 0 ? b.set(b.get(c, W) + l.get(c, d), c, W) : b.set(b.get(c, W) + 1, c, W));\n    }\n  return b;\n}\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst V2 = ZG((I, l) => I & l), WN = aG(IY, V2), YN = {\n  kernelName: IY,\n  backendName: \"cpu\",\n  kernelFunc: WN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction OI(I) {\n  return (l, G, Z) => {\n    const h = $l(G, l.length);\n    for (let g = 0; g < l.length; ++g)\n      h[g] = I(l[g], Z);\n    return h;\n  };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction El(I, l, G) {\n  const Z = OI(l);\n  return kZ(I, Z, G);\n}\nfunction kZ(I, l, G) {\n  return ({ inputs: Z, attrs: h, backend: g }) => {\n    const { x: b } = Z;\n    bl(b, I);\n    const c = g, d = c.data.get(b.dataId).values;\n    let W;\n    if (b.dtype === \"string\") {\n      if (!Array.isArray(d))\n        throw new Error(\"String tensor's value was not an instance of Array\");\n      W = cZ(d);\n    } else\n      W = d;\n    const Y = G || b.dtype, V = l(W, Y, h);\n    return c.makeTensorInfo(b.shape, Y, V);\n  };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst a2 = OI((I) => Math.ceil(I)), VN = kZ(lg, a2), aN = {\n  kernelName: lg,\n  backendName: \"cpu\",\n  kernelFunc: VN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction i2(I, l, G, Z) {\n  const h = $l(G, Q(l));\n  if (Z && G !== \"string\") {\n    let g = 0;\n    I.forEach((b) => {\n      const c = Q(b.shape);\n      h.set(b.vals, g), g += c;\n    });\n  } else {\n    let g = 0;\n    I.forEach((b) => {\n      const c = G === \"string\" ? cZ(b.vals) : b.vals;\n      let d = 0;\n      for (let W = 0; W < b.shape[0]; ++W) {\n        const Y = W * l[1] + g;\n        for (let V = 0; V < b.shape[1]; ++V)\n          h[Y + V] = c[d++];\n      }\n      g += b.shape[1];\n    });\n  }\n  return h;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst m2 = ZG((I, l) => I === l ? 1 : 0), T2 = aG(Xc, m2, null, \"bool\"), iN = {\n  kernelName: Xc,\n  backendName: \"cpu\",\n  kernelFunc: T2\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst s2 = OI((I) => Math.exp(I)), o2 = kZ(cg, s2, \"float32\"), mN = {\n  kernelName: cg,\n  backendName: \"cpu\",\n  kernelFunc: o2\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst B2 = OI((I) => Math.expm1(I)), TN = kZ(dg, B2), sN = {\n  kernelName: dg,\n  backendName: \"cpu\",\n  kernelFunc: TN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst n2 = OI((I) => Math.floor(I)), oN = kZ(Wg, n2), BN = {\n  kernelName: Wg,\n  backendName: \"cpu\",\n  kernelFunc: oN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst C2 = ZG((I, l) => Math.floor(I / l)), nN = aG(Yg, C2, null, \"int32\"), CN = {\n  kernelName: Yg,\n  backendName: \"cpu\",\n  kernelFunc: nN\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction X2(I, l, G, Z, h, g, b, c, d) {\n  const W = Xl([Z, g], G);\n  for (let Y = 0; Y < Z; Y++) {\n    const V = [];\n    let a = 0;\n    for (let i = 0; i < h; i++) {\n      const m = I[Y * h + i];\n      a += m * b[i], V.push(m);\n    }\n    if (a < 0 || a >= d / g)\n      throw new Error(`Invalid indices: ${V} does not index into ${c}`);\n    for (let i = 0; i < g; i++)\n      W.values[Y * g + i] = l.get(...l.indexToLoc(a * g + i));\n  }\n  return W;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction t2(I, l, G) {\n  const Z = Xl(G, I.dtype);\n  for (let h = 0; h < Z.size; ++h) {\n    const b = Z.indexToLoc(h).slice(), c = b[0], d = b[2], W = l.locToIndex([c, d]);\n    b[2] = l.values[W];\n    const Y = I.locToIndex(b);\n    0 <= Y && Y < I.values.length && (Z.values[h] = I.values[Y]);\n  }\n  return Z;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst u2 = ZG((I, l) => I > l ? 1 : 0), XN = aG(Sc, u2, null, \"bool\"), tN = {\n  kernelName: Sc,\n  backendName: \"cpu\",\n  kernelFunc: XN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst e2 = ZG((I, l) => I >= l ? 1 : 0), uN = aG(Vg, e2, null, \"bool\"), eN = {\n  kernelName: Vg,\n  backendName: \"cpu\",\n  kernelFunc: uN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst S2 = ZG((I, l) => I < l ? 1 : 0), SN = aG(pc, S2, null, \"bool\"), RN = {\n  kernelName: pc,\n  backendName: \"cpu\",\n  kernelFunc: SN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst R2 = ZG((I, l) => I <= l ? 1 : 0), pN = aG(Fc, R2, null, \"bool\"), FN = {\n  kernelName: Fc,\n  backendName: \"cpu\",\n  kernelFunc: pN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction p2(I, l, G) {\n  const Z = (l - I) / (G - 1), h = SG(G, \"float32\");\n  h[0] = I;\n  for (let g = 1; g < h.length; g++)\n    h[g] = h[g - 1] + Z;\n  return h;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst F2 = OI((I) => Math.log(I)), yN = kZ(sg, F2), NN = {\n  kernelName: sg,\n  backendName: \"cpu\",\n  kernelFunc: yN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction y2(I, l, G, Z) {\n  const h = eG(Z, Q(G));\n  for (let g = 0; g < h.length; ++g) {\n    const b = g * l;\n    let c = I[b];\n    for (let d = 0; d < l; ++d) {\n      const W = I[b + d];\n      (Number.isNaN(W) || W > c) && (c = W);\n    }\n    h[g] = c;\n  }\n  return h;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst N2 = ZG((I, l) => Math.max(I, l)), PN = aG(Bg, N2), JN = {\n  kernelName: Bg,\n  backendName: \"cpu\",\n  kernelFunc: PN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst P2 = ZG((I, l) => Math.min(I, l)), EN = aG(ng, P2), xN = {\n  kernelName: ng,\n  backendName: \"cpu\",\n  kernelFunc: EN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst B9 = ZG((I, l) => I * l), UN = s9((I, l, G, Z) => ({\n  real: I * G - l * Z,\n  imag: I * Z + l * G\n})), Fd = aG(Xg, B9, UN), HN = {\n  kernelName: Xg,\n  backendName: \"cpu\",\n  kernelFunc: Fd\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction J2(I, l, G) {\n  const Z = JZ(-1, G);\n  return B9([], l, Z, I, G);\n}\nfunction KN(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  bl(Z, \"neg\");\n  const h = G.data.get(Z.dataId).values, [g, b] = J2(h, Z.shape, Z.dtype);\n  return G.makeTensorInfo(b, Z.dtype, g);\n}\nconst AN = {\n  kernelName: kc,\n  backendName: \"cpu\",\n  kernelFunc: KN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst E2 = ZG((I, l) => I !== l ? 1 : 0), kN = aG(zc, E2, null, \"bool\"), zN = {\n  kernelName: zc,\n  backendName: \"cpu\",\n  kernelFunc: kN\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction n9(I, l, G, Z, h) {\n  const g = l.length, b = Q(l), c = Wl(l), d = Wl(h), W = eG(G, Q(h));\n  for (let Y = 0; Y < b; ++Y) {\n    const V = G0(Y, g, c), a = new Array(V.length);\n    for (let m = 0; m < a.length; m++)\n      a[m] = V[Z[m]];\n    const i = zI(a, g, d);\n    W[i] = I[Y];\n  }\n  return W;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction MG(I) {\n  const { inputs: l, attrs: G, backend: Z } = I, { x: h } = l, { perm: g } = G;\n  bl(h, \"transpose\");\n  const b = h.shape.length, c = new Array(b);\n  for (let V = 0; V < c.length; V++)\n    c[V] = h.shape[g[V]];\n  const d = Z.data.get(h.dataId).values, W = n9(d, h.shape, h.dtype, g, c);\n  return { dataId: Z.write(W, c, h.dtype), shape: c, dtype: h.dtype };\n}\nconst LN = {\n  kernelName: Ah,\n  backendName: \"cpu\",\n  kernelFunc: MG\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction x2(I, l, G, Z) {\n  const [h, g] = sG(I, Z), b = DG(l, \"int32\"), c = SG(Q(h), b), d = Q(g);\n  for (let W = 0; W < c.length; ++W) {\n    const Y = W * d;\n    let V = 1;\n    for (let a = 0; a < d; ++a)\n      V *= G[Y + a];\n    c[W] = V;\n  }\n  return { outVals: c, outShape: h, outDtype: b };\n}\nfunction MN(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z;\n  bl(h, \"prod\");\n  const c = h.shape.length, d = tl(g, h.shape), W = Ol(d, c);\n  let Y = d, V = h;\n  const a = [];\n  W != null && (V = MG({ inputs: { x: h }, backend: G, attrs: { perm: W } }), a.push(V), Y = GG(Y.length, c));\n  const i = G.data.get(V.dataId).values, { outVals: m, outShape: T, outDtype: s } = x2(V.shape, V.dtype, i, Y);\n  let o = T;\n  return b && (o = bG(T, d)), a.forEach((B) => G.disposeIntermediateTensorInfo(B)), G.makeTensorInfo(o, s, m);\n}\nconst wN = {\n  kernelName: rc,\n  backendName: \"cpu\",\n  kernelFunc: MN\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction QN(I, l, G) {\n  I.forEach((Z, h) => {\n    if (Z < 0 || Z >= G) {\n      const g = G0(h, l.length, Wl(l)).join(\",\");\n      throw new Error(`indices[${g}] = ${Z} is not in [0, ${G})`);\n    }\n  });\n}\nfunction vN(I, l) {\n  for (let G = 0; G < I.length; ++G) {\n    const Z = I[G], h = G === I.length - 1 ? l : I[G + 1].length;\n    if (Z.length === 0)\n      throw new Error(\"Ragged splits may not be empty\");\n    if (Z[0] < 0)\n      throw new Error(\"Ragged splits must be non-negative\");\n    if (Z[Z.length - 1] > h)\n      throw new Error(\"Ragged splits must not point past values\");\n    for (let g = 1; g < Z.length; ++g)\n      if (Z[g - 1] > Z[g])\n        throw new Error(\"Ragged splits must be sorted in ascending order\");\n  }\n}\nfunction rN(I, l, G, Z) {\n  const h = [];\n  let g = 0;\n  const b = l.length - 1 + G.length, c = new Array(b).fill(null).map(() => [0]);\n  vN(G, Z);\n  let d = 1;\n  for (let W = 0; W < l.length - 1; ++W) {\n    d *= l[W];\n    const Y = l[W + 1];\n    for (let V = 1; V < d + 1; ++V)\n      c[W].push(V * Y);\n  }\n  for (let W = 0; W < I.length; ++W) {\n    let Y = I[W], V = I[W] + 1;\n    for (let a = 0; a < G.length; ++a) {\n      const i = G[a], m = a + l.length - 1;\n      if (m >= 0) {\n        const T = c[m], s = T[T.length - 1] - i[Y];\n        for (let o = Y; o < V; ++o)\n          c[m].push(i[o + 1] + s);\n      }\n      Y = i[Y], V = i[V];\n    }\n    V !== Y && (h.push([Y, V]), g += V - Y);\n  }\n  return { outSplits: c, valueSlices: h, numValues: g };\n}\nfunction jN(I) {\n  const l = [];\n  for (let G = 0; G < I.length; ++G) {\n    const Z = I[G].length, h = $l(\"int32\", Z);\n    l.push(h), I[G].forEach((g, b) => h[b] = g);\n  }\n  return l;\n}\nfunction ka(I, l) {\n  const G = I.slice(0, l);\n  for (; G.length < l; )\n    G.push(1);\n  for (let Z = l; Z < I.length; Z++)\n    G[l - 1] *= I[Z];\n  return G;\n}\nfunction DN(I, l, G, Z, h, g) {\n  const b = ka(l, 2)[1], c = ka(g, 2)[1];\n  let d = 0;\n  for (const W of G)\n    for (let Y = W[0]; Y < W[1]; ++Y) {\n      for (let V = 0; V < Z; ++V)\n        h[d * c + V] = I[Y * b + V];\n      ++d;\n    }\n}\nfunction fN(I, l, G, Z, h) {\n  const g = l.slice();\n  g[0] = h;\n  const b = $l(G, Q(g)), c = I.length, d = c === 0 ? 0 : c / l[0];\n  return DN(I, l, Z, d, b, g), [b, g];\n}\nfunction U2(I, l, G, Z, h, g, b, c) {\n  if (I.length === 0)\n    throw new Error(\"paramsNestedSplits must be non empty\");\n  if (l[0].length === 0)\n    throw new Error(\"Split tensors must not be scalars\");\n  const d = l[0][0] - 1;\n  if (QN(g, b, d), Z.length === 0)\n    throw new Error(\"params.rank must be nonzero\");\n  const W = Z[0], { outSplits: Y, valueSlices: V, numValues: a } = rN(g, b, I, W), i = jN(Y), m = fN(G, Z, h, V, a);\n  return [i, m[0], m[1]];\n}\n/**\n * @license\n * Copyright 2022 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst za = 2147483647;\nfunction H2(I, l, G, Z, h, g, b) {\n  if (l.length > 1)\n    throw new Error(\"starts must be a scalar or vector\");\n  if (h.length > 1)\n    throw new Error(\"limits must be a scalar or vector\");\n  if (b.length > 1)\n    throw new Error(\"deltas must be a scalar or vector\");\n  const c = l.length === 0, d = h.length === 0, W = b.length === 0, Y = [];\n  c || Y.push(l[0]), d || Y.push(h[0]), W || Y.push(b[0]);\n  for (let s = 1; s < Y.length; ++s)\n    if (Y[s] !== Y[s - 1])\n      throw new Error(\"starts, limits, and deltas must have the same shape\");\n  const V = Y.length === 0 ? 1 : Y[0], a = $l(\"int32\", V + 1);\n  a[0] = 0;\n  for (let s = 0; s < V; ++s) {\n    const o = c ? I[0] : I[s], B = d ? Z[0] : Z[s], C = W ? g[0] : g[s];\n    if (C === 0)\n      throw new Error(\"Requires delta != 0\");\n    let n;\n    if (C > 0 && B < o || C < 0 && B > o)\n      n = 0;\n    else if (n = Math.ceil(Math.abs((B - o) / C)), n > za)\n      throw new Error(`Requires ((limit - start) / delta) <= ${za}`);\n    a[s + 1] = a[s] + n;\n  }\n  const i = a[V], m = $l(G, i);\n  let T = 0;\n  for (let s = 0; s < V; ++s) {\n    const o = a[s + 1] - a[s];\n    let B = c ? I[0] : I[s];\n    const C = W ? g[0] : g[s];\n    for (let n = 0; n < o; ++n)\n      m[T++] = B, B += C;\n  }\n  return [a, m];\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nvar bI = uI;\nclass qb {\n  constructor(l, G, Z, h, g, b, c, d, W, Y) {\n    this.shape = l, this.shapeShape = G, this.values = Z, this.valuesShape = h, this.valuesDType = g, this.defaultValue = b, this.defaultValueShape = c, this.rowPartitionValues = d, this.rowPartitionValuesShapes = W, this.rowPartitionTypes = CT(Y), this.raggedRank = XT(this.rowPartitionTypes);\n  }\n  getRowPartitionTypeByDimension(l) {\n    return this.rowPartitionTypes[0] === bI.FIRST_DIM_SIZE ? this.rowPartitionTypes[l + 1] : this.rowPartitionTypes[l];\n  }\n  // Returns the relationship between dimension and dimension + 1.\n  getRowPartitionTensor(l) {\n    return this.rowPartitionTypes[0] === bI.FIRST_DIM_SIZE ? this.rowPartitionValues[l + 1] : this.rowPartitionValues[l];\n  }\n  getMaxWidth(l) {\n    const G = this.getRowPartitionTensor(l - 1);\n    switch (this.getRowPartitionTypeByDimension(l - 1)) {\n      case bI.VALUE_ROWIDS:\n        return qb.getMaxWidthValueRowID(G);\n      case bI.ROW_SPLITS:\n        return qb.getMaxWidthRowSplit(G);\n      default:\n        throw new Error(`Cannot handle partition type ${bI[this.getRowPartitionTypeByDimension(l - 1)]}`);\n    }\n  }\n  static getMaxWidthRowSplit(l) {\n    const G = l.length;\n    if (G === 0 || G === 1)\n      return 0;\n    let Z = 0;\n    for (let h = 0; h < G - 1; ++h) {\n      const g = l[h + 1] - l[h];\n      g > Z && (Z = g);\n    }\n    return Z;\n  }\n  static getMaxWidthValueRowID(l) {\n    const G = l.length;\n    if (G === 0)\n      return 0;\n    let Z = 0, h = l[0], g = 0;\n    for (let b = 1; b < G; ++b) {\n      const c = l[b];\n      c !== h && (h = c, g = Math.max(b - Z, g), Z = b);\n    }\n    return Math.max(G - Z, g);\n  }\n  tensorShapeFromTensor(l, G, Z = !0) {\n    if (G.length === 0) {\n      if (l[0] === -1)\n        return [];\n      throw new Error(\"The only valid scalar shape tensor is the fully unknown shape specified as -1.\");\n    }\n    return Ma(l, Z);\n  }\n  calculateOutputSize(l) {\n    const G = this.valuesShape, Z = this.defaultValueShape;\n    tT(Z, G);\n    const h = this.tensorShapeFromTensor(this.shape, this.shapeShape), b = nT(this.raggedRank, h, G);\n    b[0] < 0 && (b[0] = l);\n    for (let c = 1; c <= this.raggedRank; ++c)\n      b[c] < 0 && (b[c] = this.getMaxWidth(c));\n    return b;\n  }\n  /**\n   * The outputIndex represents the index in the output tensor\n   * where the first element of a particular dimension would be written.\n   * If it is -1, it indicates that the index is out of scope.\n   * Example, given firstDimension = 10, firstDimensionOutput = 6,\n   * and outputIndexMultiplier = 100:\n   * result = [0 100 200 300 400 500 -1 -1 -1 -1]\n   * If firstDimensionOutput = 11 instead, then:\n   * result = [0 100 200 300 400 500 600 700 800 900]\n   */\n  calculateFirstParentOutputIndex(l, G, Z) {\n    const h = Math.min(l, Z), g = [];\n    let b = 0;\n    for (let c = 0; c < h; ++c, b += G)\n      g.push(b);\n    for (let c = h; c < l; ++c)\n      g.push(-1);\n    return u(g.length === l, () => \"Final length of result must be equal to firstDimension.\"), g;\n  }\n  calculateOutputIndexRowSplit(l, G, Z, h) {\n    const g = l.length, b = [];\n    for (let c = 0; c < g - 1; ++c) {\n      const d = l[c + 1] - l[c];\n      let W = Math.min(h, d), Y = G[c];\n      Y === -1 && (W = 0);\n      for (let V = 0; V < W; ++V)\n        b.push(Y), Y += Z;\n      for (let V = 0; V < d - W; ++V)\n        b.push(-1);\n    }\n    if (g > 0 && b.length !== l[g - 1])\n      throw new Error(\"Invalid row split size.\");\n    return b;\n  }\n  // Calculate the output index of the first element of a list.\n  // The parentOutputIndex is the same computation for the previous list.\n  // -1 indicates an element or list that is out of range.\n  // The outputIndexMultiplier is the number of output indices one moves\n  // forward for each column.\n  // E.g., given:\n  // valueRowIds:[0 1 2 2 2 3 5 5 6]\n  // parentOutputIndex:[1000 1100 2000 2100 -1 3000 4000]\n  // outputIndexMultiplier: 10\n  // outputSize: 2\n  // You get:\n  // result = [1000 1100 2000 2010 -1 2100 -1 -1 3000]\n  // result[0] = parentOutputIndex[valueRowIds[0]]\n  // result[1] = parentOutputIndex[valueRowIds[1]]\n  // result[2] = parentOutputIndex[valueRowIds[2]]\n  // result[3] = parentOutputIndex[valueRowIds[2] + 10]\n  // result[4] = -1 because it is the third element the size is 2.\n  // result[5] = parentOutputIndex[valueRowIds[3]]\n  // result[6] = -1 because parentOutputIndex[valueRowIds[6]] == -1\n  // result[7] = -1 because parentOutputIndex[valueRowIds[6]] == -1\n  // result[8] = parentOutputIndex[valueRowIds[7]]\n  calculateOutputIndexValueRowID(l, G, Z, h) {\n    const g = l.length, b = [];\n    if (g === 0)\n      return [];\n    let c = 0, d = l[0];\n    if (d >= G.length)\n      throw new Error(`Got currentValueRowId=${d}, which is not less than ${G.length}`);\n    let W = G[d];\n    b.push(W);\n    for (let Y = 1; Y < g; ++Y) {\n      const V = l[Y];\n      if (V === d)\n        W >= 0 && (++c, c < h ? W += Z : W = -1);\n      else {\n        if (c = 0, d = V, V >= G.length)\n          throw new Error(`Got nextValueRowId=${V} which is not less than ${G.length}`);\n        W = G[V];\n      }\n      b.push(W);\n    }\n    if (b.length !== l.length)\n      throw new Error(\"Invalid row ids.\");\n    return b;\n  }\n  calculateOutputIndex(l, G, Z, h) {\n    const g = this.getRowPartitionTensor(l), b = this.getRowPartitionTypeByDimension(l);\n    switch (b) {\n      case bI.VALUE_ROWIDS:\n        return this.calculateOutputIndexValueRowID(g, G, Z, h);\n      case bI.ROW_SPLITS:\n        if (g.length - 1 > G.length)\n          throw new Error(`Row partition size is greater than output size: ${g.length - 1} > ${G.length}`);\n        return this.calculateOutputIndexRowSplit(g, G, Z, h);\n      default:\n        throw new Error(`Unsupported partition type: ${bI[b]}`);\n    }\n  }\n  getFirstDimensionSize() {\n    const l = this.rowPartitionValues[0];\n    if (this.rowPartitionTypes.length === 0)\n      throw new Error(\"No row_partition_types given.\");\n    const G = this.rowPartitionTypes[0];\n    switch (G) {\n      case bI.FIRST_DIM_SIZE:\n        return l[0];\n      case bI.VALUE_ROWIDS:\n        throw new Error(\"Cannot handle VALUE_ROWIDS in first dimension.\");\n      case bI.ROW_SPLITS:\n        return this.rowPartitionValuesShapes[0][0] - 1;\n      default:\n        throw new Error(`Cannot handle type ${bI[G]}`);\n    }\n  }\n  compute() {\n    if (this.rowPartitionValues[0].length <= 0)\n      throw new Error(\"Invalid first partition input. Tensor requires at least one element.\");\n    const G = this.getFirstDimensionSize(), Z = this.calculateOutputSize(G), h = new Array(this.raggedRank + 1);\n    h[h.length - 1] = 1;\n    for (let d = h.length - 2; d >= 0; --d)\n      h[d] = h[d + 1] * Z[d + 1];\n    const g = Ma(Z, !1), b = $l(this.valuesDType, Q(g));\n    if (h[0] * Z[0] > 0) {\n      let d = this.calculateFirstParentOutputIndex(G, h[0], Z[0]);\n      for (let W = 1; W <= this.raggedRank; ++W)\n        d = this.calculateOutputIndex(W - 1, d, h[W], Z[W]);\n      this.setOutput(this.raggedRank, d, b, g);\n    }\n    return [g, b];\n  }\n  setOutput(l, G, Z, h) {\n    if (Z.length === 0)\n      return;\n    const g = this.values, b = Z;\n    let c = h.slice();\n    c = c.slice(l + 1);\n    const d = Q(c), W = G.length;\n    let Y = this.defaultValue;\n    if (Y.length !== d && Y.length !== 1) {\n      const m = this.defaultValueShape;\n      U(() => {\n        const T = J(Y, m);\n        Y = y0(T, c).dataSync();\n      });\n    }\n    let V = 0, a = 0, i = 0;\n    for (let m = 0; m <= W; ++m) {\n      let T = m < W ? G[m] : -1;\n      if (T === i) {\n        ++i;\n        continue;\n      }\n      if (a < i) {\n        const s = g.subarray(V * d), o = b.subarray(a * d), B = (i - a) * d;\n        La(o, s, B);\n      }\n      if (m >= W) {\n        const s = Z.length;\n        T = Math.floor(s / d);\n      }\n      if (T > i)\n        if (this.defaultValue.length === 1)\n          b.subarray(i * d, T * d).fill(this.defaultValue[0]), i = T;\n        else\n          for (; T > i; ) {\n            const s = b.slice(i * d);\n            La(s, Y, d), ++i;\n          }\n      T < 0 ? (V = m + 1, a = i) : (V = m, a = i, i = a + 1);\n    }\n  }\n}\nfunction La(I, l, G) {\n  for (let Z = 0; Z < G; Z++)\n    I[Z] = l[Z];\n}\nfunction Ma(I, l) {\n  const G = [];\n  for (let Z of I) {\n    if (Z < 0) {\n      if (!l)\n        throw new Error(`Dimension ${Z} must be >= 0`);\n      if (Z < -1)\n        throw new Error(`Dimension ${Z} must be >= -1`);\n      Z = -1;\n    }\n    G.push(Z);\n  }\n  return G;\n}\nfunction K2(I, l, G, Z, h, g, b, c, d, W) {\n  return new qb(I, l, G, Z, h, g, b, c, d, W).compute();\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction A2(I, l, G, Z) {\n  const h = I === l, g = I < l && G < 0, b = l < I && G > 1;\n  if (h || g || b)\n    return SG(0, Z);\n  const c = Math.abs(Math.ceil((l - I) / G)), d = SG(c, Z);\n  l < I && G === 1 && (G = -1), d[0] = I;\n  for (let W = 1; W < d.length; W++)\n    d[W] = d[W - 1] + G;\n  return d;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst k2 = OI((I) => 1 / Math.sqrt(I)), ON = kZ(pg, k2), qN = {\n  kernelName: pg,\n  backendName: \"cpu\",\n  kernelFunc: ON\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $Z(I, l, G, Z, h, g, b, c, d, W) {\n  const Y = [Z / h, h], V = I.values, a = l.values;\n  if (Z === 0)\n    return Xl(G, l.dtype);\n  const i = d instanceof nG ? d : Xl(Y, l.dtype);\n  typeof d == \"string\" || typeof d == \"number\" ? i.values.fill(d) : typeof d == \"boolean\" && i.values.fill(+d);\n  for (let m = 0; m < g; m++) {\n    const T = [];\n    let s = 0;\n    for (let o = 0; o < b; o++) {\n      const B = V[m * b + o];\n      T.push(B), s += B * c[o];\n    }\n    if (s < 0 || s >= Z / h)\n      throw new Error(`Invalid indices: ${T} does not index into ${G}`);\n    for (let o = 0; o < h; o++)\n      W ? i.values[s * h + o] += a[m * h + o] : i.values[s * h + o] = l.rank === 0 ? a[0] : a[m * h + o];\n  }\n  return i;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst $N = OI((I) => 1 / (1 + Math.exp(-I))), z2 = El(Jg, (I) => 1 / (1 + Math.exp(-I))), _N = {\n  kernelName: Jg,\n  backendName: \"cpu\",\n  kernelFunc: z2\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction L2(I, l, G, Z, h) {\n  const g = RV(Z, l, G), b = Q(G), c = Wl(Z);\n  if (g) {\n    const V = pV(l, c);\n    return h === \"string\" ? I.slice(V, V + b) : I.subarray(V, V + b);\n  }\n  const d = h === \"string\" ? cZ(I) : I, W = Xl(Z, h, d), Y = Xl(G, h);\n  for (let V = 0; V < Y.size; ++V) {\n    const a = Y.indexToLoc(V), i = a.map((m, T) => m + l[T]);\n    Y.set(W.get(...i), ...a);\n  }\n  return h === \"string\" ? MT(Y.values) : Y.values;\n}\nfunction Th(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { begin: g, size: b } = Z;\n  bl(h, \"slice\");\n  const [c, d] = id(h, g, b);\n  eV(h, c, d);\n  const W = G.data.get(h.dataId).values, Y = L2(W, c, d, h.shape, h.dtype);\n  return G.makeTensorInfo(d, h.dtype, Y);\n}\nconst lP = {\n  kernelName: $c,\n  backendName: \"cpu\",\n  kernelFunc: Th\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction M2(I, l, G, Z, h, g, b) {\n  const c = l[0], d = g[0], W = new Array(d), Y = new Array(c), V = l[1];\n  if (d === 0) {\n    if (c !== 0)\n      throw new Error(yT(c));\n    const s = $l(G, 0), o = $l(h, 0);\n    return [\n      s,\n      [0, V],\n      o,\n      W,\n      Y\n    ];\n  }\n  let a = !0, i = 0;\n  const m = new Array(d).fill(0);\n  for (let s = 0; s < c; ++s) {\n    const o = I[s * V];\n    if (o < 0)\n      throw new Error(NT(s, o));\n    if (o >= d)\n      throw new Error(PT(s, o, d));\n    ++m[o], a = a && o >= i, i = o;\n  }\n  let T = !0;\n  for (let s = 0; s < d; ++s) {\n    const o = m[s] === 0;\n    W[s] = o, T = T && !o, m[s] = Math.max(m[s], 1), s > 0 && (m[s] += m[s - 1]);\n  }\n  if (T && a) {\n    const s = I, o = Z;\n    for (let B = 0; B < c; ++B)\n      Y[B] = B;\n    return [\n      s,\n      [c, V],\n      o,\n      W,\n      Y\n    ];\n  } else {\n    const s = m[d - 1], o = $l(G, s * V), B = $l(h, s), C = new Array(d).fill(0);\n    for (let n = 0; n < c; ++n) {\n      const X = I[n * V], t = C[X], e = (X === 0 ? 0 : m[X - 1]) + t;\n      C[X]++;\n      for (let S = 0; S < V; ++S)\n        o[e * V + S] = I[n * V + S];\n      B[e] = Z[n], Y[n] = e;\n    }\n    for (let n = 0; n < d; ++n)\n      if (C[n] === 0) {\n        const t = n === 0 ? 0 : m[n - 1];\n        o[t * V + 0] = n;\n        for (let e = 1; e < V; ++e)\n          o[t * V + e] = 0;\n        B[t] = b;\n      }\n    return [\n      o,\n      [s, V],\n      B,\n      W,\n      Y\n    ];\n  }\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction w2(I, l, G, Z, h) {\n  const g = Q(Z), b = l[0], c = h.length, d = [];\n  let W = 1, Y = -1;\n  for (let s = 0; s < c; ++s) {\n    const o = h[s];\n    if (o === -1) {\n      if (Y !== -1)\n        throw new Error(JT(Y, s));\n      Y = s, d.push(1);\n    } else {\n      if (o < 0)\n        throw new Error(ET(s, o));\n      W *= o, d.push(o);\n    }\n  }\n  if (Y !== -1) {\n    if (W <= 0)\n      throw new Error(xT());\n    const s = Math.trunc(g / W);\n    if (W * s !== g)\n      throw new Error(UT(Z, d));\n    d[Y] = s;\n  }\n  if (Q(d) !== g)\n    throw new Error(HT(Z, d));\n  const a = Z.length, i = [];\n  if (a > 0) {\n    i[a - 1] = 1;\n    for (let s = a - 2; s >= 0; --s)\n      i[s] = i[s + 1] * Z[s + 1];\n  }\n  const m = [];\n  if (c > 0) {\n    m[c - 1] = 1;\n    for (let s = c - 2; s >= 0; --s)\n      m[s] = m[s + 1] * d[s + 1];\n  }\n  const T = $l(G, b * c);\n  for (let s = 0; s < b; ++s) {\n    let o = 0;\n    for (let B = 0; B < a; ++B)\n      o += I[s * a + B] * i[B];\n    for (let B = 0; B < c; ++B)\n      T[s * c + B] = Math.trunc(o / m[B]), o %= m[B];\n  }\n  return [T, [b, c], d];\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction C9(I, l, G, Z, h, g = !1, b = 0) {\n  const c = Z.length, d = [l[0], I.length / l[0]], W = d[1], V = c > 0 ? h[c - 1] + 1 : 0;\n  if (V < 0)\n    throw new Error(eW());\n  const a = l.slice();\n  a[0] = V;\n  const i = a.reduce((C, n) => C * n, 1), m = $l(G, i);\n  if (c === 0)\n    return V > 0 && m.fill(b), [m, a];\n  if (V <= 0)\n    throw new Error(eW());\n  let T = 0, s = 1, o = 0, B = h[T];\n  for (; ; ) {\n    let C = 0;\n    if (s < c) {\n      if (C = h[s], B === C) {\n        ++s;\n        continue;\n      }\n      if (B >= C)\n        throw new Error(KT());\n    }\n    if (B < 0 || B >= V)\n      throw new Error(AT(B, V));\n    B > o && m.fill(b, o * W, B * W);\n    for (let n = T; n < s; ++n) {\n      const X = Z[n];\n      if (X < 0 || X >= d[0])\n        throw new Error(kT(n, Z[n], d[0]));\n      for (let t = 0; t < W; t++)\n        m[B * W + t] += I[X * W + t];\n    }\n    if (g)\n      for (let n = 0; n < W; n++)\n        m[B * W + n] /= s - T;\n    if (T = s, ++s, o = B + 1, B = C, s > c)\n      break;\n  }\n  return o < V && m.fill(b, o * W, V * W), [m, a];\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst GP = OI((I) => Math.sqrt(I)), IP = El(xg, (I) => Math.sqrt(I)), ZP = {\n  kernelName: xg,\n  backendName: \"cpu\",\n  kernelFunc: IP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Q2 = ZG((I, l) => {\n  const G = I - l;\n  return G * G;\n}), hP = aG(Ug, Q2), gP = {\n  kernelName: Ug,\n  backendName: \"cpu\",\n  kernelFunc: hP\n};\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst v2 = OI((I, l) => {\n  const { pattern: G, replaceGlobal: Z, rewrite: h } = l;\n  return I.replace(new RegExp(G, Z ? \"g\" : \"\"), h);\n}), bP = kZ(PY, v2), cP = {\n  kernelName: PY,\n  backendName: \"cpu\",\n  kernelFunc: bP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction r2(I, l, G, Z) {\n  const h = Xl(I, l.dtype);\n  for (let g = 0; g < h.size; g++) {\n    const b = h.indexToLoc(g), c = new Array(b.length);\n    for (let d = 0; d < c.length; d++)\n      c[d] = b[d] * G[d] + Z[d];\n    h.set(l.get(...c), ...b);\n  }\n  return h;\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass dP {\n  constructor(l, G, Z, h, g, b) {\n    this.separator = XZ(l), this.nGramWidths = G, this.leftPad = XZ(Z), this.rightPad = XZ(h), this.padWidth = g, this.preserveShort = b;\n  }\n  getPadWidth(l) {\n    return Math.min(this.padWidth < 0 ? l - 1 : this.padWidth, l - 1);\n  }\n  getNumNGrams(l, G) {\n    const Z = this.getPadWidth(G);\n    return Math.max(0, l + 2 * Z - G + 1);\n  }\n  createNGrams(l, G, Z, h, g, b) {\n    for (let c = 0; c < g; ++c) {\n      const d = this.getPadWidth(b), W = Math.max(0, d - c), Y = Math.max(0, d - (g - (c + 1))), V = b - (W + Y), a = G + (W > 0 ? 0 : c - d);\n      let i = 0;\n      i += W * this.leftPad.length;\n      for (let B = 0; B < V; ++B)\n        i += l[a + B].length;\n      i += Y * this.rightPad.length;\n      const m = W + Y + V - 1;\n      i += m * this.separator.length, Z[h + c] = new Uint8Array(i);\n      const T = Z[h + c];\n      let s = 0;\n      const o = (B) => B.forEach((C) => T[s++] = C);\n      for (let B = 0; B < W; ++B)\n        o(this.leftPad), o(this.separator);\n      for (let B = 0; B < V - 1; ++B)\n        o(l[a + B]), o(this.separator);\n      if (V > 0) {\n        o(l[a + V - 1]);\n        for (let B = 0; B < Y; ++B)\n          o(this.separator), o(this.rightPad);\n      } else {\n        for (let B = 0; B < Y - 1; ++B)\n          o(this.rightPad), o(this.separator);\n        o(this.rightPad);\n      }\n    }\n  }\n  // Data and splits together form the definition of the ragged tensor,\n  // where data is 1 dimensional and contains the values of the tensor\n  // and splits denotes the indices at which each row starts.\n  compute(l, G) {\n    const Z = l.length, h = G.length;\n    if (h > 0) {\n      let d = G[0];\n      if (d !== 0)\n        throw new Error(`First split value must be 0, got ${d}`);\n      for (let W = 1; W < h; ++W) {\n        let Y = G[W] >= d;\n        if (Y = Y && G[W] <= Z, !Y)\n          throw new Error(`Invalid split value ${G[W]}, must be in [${d}, ${Z}]`);\n        d = G[W];\n      }\n      if (d !== Z)\n        throw new Error(`Last split value must be data size. Expected ${Z}, got ${d}`);\n    }\n    const g = h - 1, b = $l(\"int32\", h);\n    if (Z === 0 || h === 0) {\n      const d = new Array(Z);\n      for (let W = 0; W <= g; ++W)\n        b[W] = 0;\n      return [d, b];\n    }\n    b[0] = 0;\n    for (let d = 1; d <= g; ++d) {\n      const W = G[d] - G[d - 1];\n      let Y = 0;\n      this.nGramWidths.forEach((V) => {\n        Y += this.getNumNGrams(W, V);\n      }), this.preserveShort && W > 0 && Y === 0 && (Y = 1), b[d] = b[d - 1] + Y;\n    }\n    const c = new Array(b[g]);\n    for (let d = 0; d < g; ++d) {\n      const W = G[d];\n      let Y = b[d];\n      if (this.nGramWidths.forEach((V) => {\n        const a = G[d + 1] - G[d], i = this.getNumNGrams(a, V);\n        this.createNGrams(l, W, c, Y, i, V), Y += i;\n      }), this.preserveShort && Y === b[d]) {\n        const V = G[d + 1] - G[d];\n        if (V === 0)\n          continue;\n        const a = V + 2 * this.padWidth;\n        this.createNGrams(l, W, c, Y, 1, a);\n      }\n    }\n    return [c, b];\n  }\n}\nfunction j2(I, l, G, Z, h, g, b, c) {\n  return new dP(G, Z, h, g, b, c).compute(I, l);\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction WP(I, l, G, Z) {\n  if (!I.length)\n    return;\n  if (l.length === 0) {\n    for (let g = 0; g < I.length; ++g)\n      Z.push(I.subarray(g, g + 1));\n    return;\n  }\n  if (l.length === 1) {\n    const g = l[0];\n    let b = I.indexOf(g);\n    for (; b !== -1; ) {\n      const c = I.subarray(0, b);\n      (!G || c.length !== 0) && Z.push(c), I = I.subarray(b + 1), b = I.indexOf(g);\n    }\n    (!G || I.length !== 0) && Z.push(I);\n    return;\n  }\n  let h = 0;\n  for (let g = 0; g < I.length + 1; g++)\n    if (g === I.length || l.indexOf(I[g]) !== -1) {\n      const b = I.subarray(h, g);\n      (!G || b.length !== 0) && Z.push(b), h = g + 1;\n    }\n}\nfunction D2(I, l, G) {\n  const Z = I.length, h = [];\n  let g = 0, b = 0;\n  const c = new Array(Z);\n  for (let a = 0; a < Z; ++a) {\n    const i = h.length;\n    WP(I[a], l, G, h);\n    const m = h.length - i;\n    c[a] = m, g += m, b = Math.max(b, m);\n  }\n  const d = $l(\"int32\", g * 2), W = new Array(g), Y = [Z, b];\n  let V = 0;\n  for (let a = 0; a < Z; ++a)\n    for (let i = 0; i < c[a]; ++i)\n      d[V * 2] = a, d[V * 2 + 1] = i, W[V] = h[V], ++V;\n  return [d, W, Y];\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction f2(I, l) {\n  const G = $l(\"int32\", I.length);\n  for (let Z = 0; Z < I.length; ++Z)\n    G[Z] = Mn(I[Z]).modulo(l).getLowBitsUnsigned();\n  return G;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst O2 = ZG((I, l) => I - l), YP = s9((I, l, G, Z) => ({ real: I - G, imag: l - Z })), X9 = aG(Hg, O2, YP), VP = {\n  kernelName: Hg,\n  backendName: \"cpu\",\n  kernelFunc: X9\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction q2(I, l) {\n  const G = new Array(I.rank);\n  for (let h = 0; h < G.length; h++)\n    G[h] = I.shape[h] * l[h];\n  const Z = Xl(G, I.dtype);\n  for (let h = 0; h < Z.values.length; ++h) {\n    const g = Z.indexToLoc(h), b = new Array(I.rank);\n    for (let d = 0; d < b.length; d++)\n      b[d] = g[d] % I.shape[d];\n    const c = I.locToIndex(b);\n    Z.values[h] = I.values[c];\n  }\n  return Z;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst R0 = (I, l) => {\n  const G = l.value - I.value;\n  return G === 0 ? I.index - l.index : G;\n};\nfunction $2(I, l, G = 0, Z = I.length - 1) {\n  for (; Z > G; ) {\n    if (Z - G > 600) {\n      const c = Z - G + 1, d = l - G + 1, W = Math.log(c), Y = 0.5 * Math.exp(2 * W / 3), V = 0.5 * Math.sqrt(W * Y * (c - Y) / c) * Math.sign(d - c / 2), a = Math.max(G, Math.floor(l - d * Y / c + V)), i = Math.min(Z, Math.floor(l + (c - d) * Y / c + V));\n      $2(I, l, a, i);\n    }\n    const h = I[l];\n    let g = G, b = Z;\n    for (Eh(I, G, l), R0(I[Z], h) > 0 && Eh(I, G, Z); g < b; ) {\n      for (Eh(I, g, b), g++, b--; R0(I[g], h) < 0; )\n        g = g + 1;\n      for (; R0(I[b], h) > 0; )\n        b = b - 1;\n    }\n    R0(I[G], h) === 0 ? Eh(I, G, b) : (b = b + 1, Eh(I, b, Z)), b <= l && (G = b + 1), l <= b && (Z = b - 1);\n  }\n}\nfunction _2(I, l, G, Z, h) {\n  const g = l[l.length - 1], [b, c] = [I.length / g, g], d = eG(G, b * Z), W = eG(\"int32\", b * Z);\n  for (let V = 0; V < b; V++) {\n    const a = V * c, i = I.subarray(a, a + c);\n    let m = new Array(i.length);\n    i.forEach((B, C) => m[C] = { value: B, index: C }), Z < m.length && ($2(m, Z), m = m.slice(0, Z)), h && m.sort(R0);\n    const T = V * Z, s = d.subarray(T, T + Z), o = W.subarray(T, T + Z);\n    for (let B = 0; B < Z; B++)\n      s[B] = m[B].value, o[B] = m[B].index;\n  }\n  const Y = l.slice();\n  return Y[Y.length - 1] = Z, [\n    Xl(Y, G, d),\n    Xl(Y, \"int32\", W)\n  ];\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lB(I, l, G, Z) {\n  const h = tl(l, G)[0], g = [1, G[0], 1];\n  for (let m = 0; m < h; m++)\n    g[0] *= G[m];\n  g[1] = G[h];\n  for (let m = h + 1; m < G.length; m++)\n    g[2] *= G[m];\n  const b = /* @__PURE__ */ new Map(), c = new Int32Array(G[h]), d = new nG(g, Z, I), W = [], Y = g[0] === 1 && g[2] === 1;\n  for (let m = 0; m < G[h]; m++) {\n    let T;\n    if (Y)\n      T = I[m].toString();\n    else {\n      const o = [];\n      for (let B = 0; B < g[0]; B++)\n        for (let C = 0; C < g[2]; C++)\n          o.push(d.get(B, m, C));\n      T = o.join(\",\");\n    }\n    const s = b.get(T);\n    if (s != null)\n      c[m] = s;\n    else {\n      const o = b.size;\n      b.set(T, o), c[m] = o, W.push(m);\n    }\n  }\n  const V = g.slice();\n  V[1] = b.size;\n  const a = new nG(V, Z);\n  W.forEach((m, T) => {\n    for (let s = 0; s < g[0]; s++)\n      for (let o = 0; o < g[2]; o++)\n        a.set(d.get(s, m, o), s, T, o);\n  });\n  const i = G.slice();\n  return i[h] = V[1], {\n    outputValues: a.values,\n    outputShape: i,\n    indices: c\n  };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst aP = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  addImpl: W2,\n  bincountImpl: o9,\n  bincountReduceImpl: Y2,\n  bitwiseAndImpl: V2,\n  castImpl: d2,\n  ceilImpl: a2,\n  concatImpl: i2,\n  equalImpl: m2,\n  expImpl: s2,\n  expm1Impl: B2,\n  floorDivImpl: C2,\n  floorImpl: n2,\n  gatherNdImpl: X2,\n  gatherV2Impl: t2,\n  greaterEqualImpl: e2,\n  greaterImpl: u2,\n  lessEqualImpl: R2,\n  lessImpl: S2,\n  linSpaceImpl: p2,\n  logImpl: F2,\n  maxImpl: y2,\n  maximumImpl: N2,\n  minimumImpl: P2,\n  multiplyImpl: B9,\n  negImpl: J2,\n  notEqualImpl: E2,\n  prodImpl: x2,\n  raggedGatherImpl: U2,\n  raggedRangeImpl: H2,\n  raggedTensorToTensorImpl: K2,\n  rangeImpl: A2,\n  rsqrtImpl: k2,\n  scatterImpl: $Z,\n  sigmoidImpl: $N,\n  simpleAbsImpl: c2,\n  sliceImpl: L2,\n  sparseFillEmptyRowsImpl: M2,\n  sparseReshapeImpl: w2,\n  sparseSegmentReductionImpl: C9,\n  sqrtImpl: GP,\n  squaredDifferenceImpl: Q2,\n  staticRegexReplaceImpl: v2,\n  stridedSliceImpl: r2,\n  stringNGramsImpl: j2,\n  stringSplitImpl: D2,\n  stringToHashBucketFastImpl: f2,\n  subImpl: O2,\n  tileImpl: q2,\n  topKImpl: _2,\n  transposeImpl: n9,\n  uniqueImpl: lB\n}, Symbol.toStringTag, { value: \"Module\" }));\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nom(\n  \"cpu\",\n  () => new pd(),\n  1\n  /* priority */\n);\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst GB = El(gg, (I) => I >= 0 ? I : Math.exp(I) - 1), iP = {\n  kernelName: gg,\n  backendName: \"cpu\",\n  kernelFunc: GB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction IB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { alpha: g } = Z;\n  bl([h], \"leakyRelu\");\n  const b = Q(h.shape), c = G.data.get(h.dataId).values, d = eG(\"float32\", b);\n  for (let W = 0; W < c.length; W++)\n    d[W] = c[W] < 0 ? g * c[W] : c[W];\n  return G.makeTensorInfo(h.shape, \"float32\", d);\n}\nconst mP = {\n  kernelName: Rc,\n  backendName: \"cpu\",\n  kernelFunc: IB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst TP = ZG((I, l) => I < 0 ? l * I : I);\nfunction ZB(I) {\n  const { inputs: l, backend: G } = I, { x: Z, alpha: h } = l;\n  bl([Z, h], \"prelu\");\n  const g = G.data.get(Z.dataId).values, b = G.data.get(h.dataId).values, [c, d] = TP(Z.shape, h.shape, g, b, \"float32\");\n  return G.makeTensorInfo(d, \"float32\", c);\n}\nconst sP = {\n  kernelName: vc,\n  backendName: \"cpu\",\n  kernelFunc: ZB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hB = El(eg, (I) => Math.max(0, I)), oP = {\n  kernelName: eg,\n  backendName: \"cpu\",\n  kernelFunc: hB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst gB = El(Sg, (I) => Math.min(Math.max(0, I), 6)), BP = {\n  kernelName: Sg,\n  backendName: \"cpu\",\n  kernelFunc: gB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $b(I, l, G, Z, h) {\n  if (G === \"linear\")\n    return fI({ inputs: { x: l }, backend: I });\n  if (G === \"relu\")\n    return hB({ inputs: { x: l }, backend: I });\n  if (G === \"elu\")\n    return GB({ inputs: { x: l }, backend: I });\n  if (G === \"relu6\")\n    return gB({ inputs: { x: l }, backend: I });\n  if (G === \"prelu\")\n    return ZB({ inputs: { x: l, alpha: Z }, backend: I });\n  if (G === \"leakyrelu\")\n    return IB({ inputs: { x: l }, backend: I, attrs: { alpha: h } });\n  if (G === \"sigmoid\")\n    return z2({ inputs: { x: l }, backend: I });\n  throw new Error(`Activation ${G} has not been implemented for the CPU backend.`);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ll(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { shape: g } = Z, b = Q(h.shape), c = ui(g, b), d = Q(c);\n  u(b === d, () => `The new shape (${c}) has ${d} elements and the old shape (${h.shape}) has ${b} elements. The new shape and old shape must have the same number of elements.`), G.incRef(h.dataId);\n  const W = G.data.get(h.dataId);\n  if (W.complexTensorInfos != null) {\n    const Y = W.complexTensorInfos.real, V = W.complexTensorInfos.imag;\n    Y.shape = c, V.shape = c;\n  }\n  return { dataId: h.dataId, shape: c, dtype: h.dtype };\n}\nconst nP = {\n  kernelName: jc,\n  backendName: \"cpu\",\n  kernelFunc: Ll\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction bB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { a: h, b: g } = l, { transposeA: b, transposeB: c } = Z;\n  bl([h, g], \"matMul\");\n  const d = h.shape.length, W = g.shape.length, Y = b ? h.shape[d - 2] : h.shape[d - 1], V = c ? g.shape[W - 1] : g.shape[W - 2], a = b ? h.shape[d - 1] : h.shape[d - 2], i = c ? g.shape[W - 2] : g.shape[W - 1], m = h.shape.slice(0, -2), T = g.shape.slice(0, -2), s = Q(m), o = Q(T), C = sl(h.shape.slice(0, -2), g.shape.slice(0, -2)).concat([a, i]);\n  u(Y === V, () => `Error in matMul: inner shapes (${Y}) and (${V}) of Tensors with shapes ${h.shape} and ${g.shape} and transposeA=${b} and transposeB=${c} must match.`);\n  const n = b ? [s, Y, a] : [s, a, Y], X = c ? [o, i, V] : [o, V, i], t = Ll({ inputs: { x: h }, backend: G, attrs: { shape: n } }), e = Ll({ inputs: { x: g }, backend: G, attrs: { shape: X } }), S = b ? t.shape[1] : t.shape[2], p = b ? t.shape[2] : t.shape[1], F = c ? e.shape[1] : e.shape[2], x = Math.max(s, o), H = G.data.get(t.dataId).values, K = G.data.get(e.dataId).values, z = Wl(t.shape), k = Wl(e.shape), [L, v, w] = b ? [z[0], 1, z[1]] : [z[0], z[1], 1], [r, D, f] = c ? [1, k[1], k[0]] : [k[1], 1, k[0]], $ = p * F, q = Xl([x, p, F], t.dtype), Il = q.values, _ = G.blockSize;\n  for (let gl = 0; gl < x; gl++) {\n    const dl = gl % s, il = gl % o;\n    for (let al = 0; al < p; al += _) {\n      const ol = Math.min(al + _, p);\n      for (let nl = 0; nl < F; nl += _) {\n        const Pl = Math.min(nl + _, F);\n        for (let Kl = 0; Kl < S; Kl += _) {\n          const ql = Math.min(Kl + _, S);\n          for (let Al = al; Al < ol; Al++)\n            for (let xl = nl; xl < Pl; xl++) {\n              let Dl = 0;\n              for (let vl = Kl; vl < ql; vl++) {\n                const qI = (\n                  // tslint:disable-next-line: max-line-length\n                  H[dl * L + Al * v + vl * w]\n                ), oG = (\n                  // tslint:disable-next-line: max-line-length\n                  K[vl * r + xl * D + il * f]\n                );\n                Dl += qI * oG;\n              }\n              Il[gl * $ + (Al * F + xl)] += Dl;\n            }\n        }\n      }\n    }\n  }\n  return G.disposeIntermediateTensorInfo(t), G.disposeIntermediateTensorInfo(e), G.makeTensorInfo(C, q.dtype, q.values);\n}\nconst CP = {\n  kernelName: Vc,\n  backendName: \"cpu\",\n  kernelFunc: bB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction XP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { a: h, b: g, bias: b, preluActivationWeights: c } = l, { transposeA: d, transposeB: W, activation: Y, leakyreluAlpha: V } = Z;\n  let a, i, m;\n  const T = [];\n  a = bB({ inputs: { a: h, b: g }, attrs: { transposeA: d, transposeB: W }, backend: G }), b && (i = fh({ inputs: { a, b }, backend: G }), T.push(a), a = i), Y && (m = $b(G, a, Y, c, V), T.push(a), a = m);\n  for (const o of T)\n    G.disposeIntermediateTensorInfo(o);\n  return a;\n}\nconst tP = {\n  kernelName: Pb,\n  backendName: \"cpu\",\n  kernelFunc: XP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst uP = El(r0, (I) => Math.acos(I)), eP = {\n  kernelName: r0,\n  backendName: \"cpu\",\n  kernelFunc: uP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst SP = El(j0, (I) => Math.acosh(I)), RP = {\n  kernelName: j0,\n  backendName: \"cpu\",\n  kernelFunc: SP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pP(I) {\n  const { inputs: l, backend: G } = I, Z = l;\n  bl(l, \"addN\");\n  const h = Z.map((c) => G.data.get(c.dataId).values), g = Xl(Z[0].shape, Z[0].dtype), b = g.values;\n  for (let c = 0; c < Z.length; c++) {\n    const d = h[c];\n    for (let W = 0; W < b.length; W++)\n      b[W] += d[W];\n  }\n  return G.makeTensorInfo(g.shape, g.dtype, g.values);\n}\nconst FP = {\n  kernelName: OW,\n  backendName: \"cpu\",\n  kernelFunc: pP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z;\n  bl(h, \"all\");\n  const c = tl(g, h.shape);\n  let d = c;\n  const W = Ol(d, h.shape.length);\n  let Y = h;\n  W != null && (Y = MG({ inputs: { x: h }, backend: G, attrs: { perm: W } }), d = GG(d.length, h.shape.length)), XG(\"all\", d, Y.shape.length);\n  const [V, a] = sG(Y.shape, d), i = Q(a), m = SG(Q(V), Y.dtype), T = G.data.get(Y.dataId).values;\n  for (let o = 0; o < m.length; ++o) {\n    const B = o * i;\n    let C = T[B];\n    for (let n = 0; n < i; ++n) {\n      const X = T[B + n];\n      C = C && X;\n    }\n    m[o] = C;\n  }\n  W != null && G.disposeIntermediateTensorInfo(Y);\n  const s = G.makeTensorInfo(V, Y.dtype, m);\n  if (b) {\n    const o = bG(V, c), B = Ll({ inputs: { x: s }, backend: G, attrs: { shape: o } });\n    return G.disposeIntermediateTensorInfo(s), B;\n  }\n  return s;\n}\nconst NP = {\n  kernelName: qW,\n  backendName: \"cpu\",\n  kernelFunc: yP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction PP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z;\n  bl(h, \"any\");\n  const c = tl(g, h.shape);\n  let d = c;\n  const W = Ol(d, h.shape.length);\n  let Y = h;\n  W != null && (Y = MG({ inputs: { x: h }, backend: G, attrs: { perm: W } }), d = GG(d.length, h.shape.length)), XG(\"any\", d, Y.shape.length);\n  const [V, a] = sG(Y.shape, d), i = Q(a), m = SG(Q(V), Y.dtype), T = G.data.get(Y.dataId).values;\n  for (let o = 0; o < m.length; ++o) {\n    const B = o * i;\n    let C = T[B];\n    for (let n = 0; n < i; ++n) {\n      const X = T[B + n];\n      C = C || X;\n    }\n    m[o] = C;\n  }\n  W != null && G.disposeIntermediateTensorInfo(Y);\n  const s = G.makeTensorInfo(V, Y.dtype, m);\n  if (b) {\n    const o = bG(V, c), B = Ll({ inputs: { x: s }, backend: G, attrs: { shape: o } });\n    return G.disposeIntermediateTensorInfo(s), B;\n  }\n  return s;\n}\nconst JP = {\n  kernelName: $W,\n  backendName: \"cpu\",\n  kernelFunc: PP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction EP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g } = Z;\n  bl(h, \"argMax\");\n  let b = tl(g, h.shape);\n  const c = Ol(b, h.shape.length);\n  let d = h;\n  const W = [];\n  c != null && (d = MG({ inputs: { x: h }, backend: G, attrs: { perm: c } }), W.push(d), b = GG(b.length, d.shape.length)), b = [b[0]], XG(\"argMax\", b, d.shape.length);\n  const [Y, V] = sG(d.shape, b), a = Q(Y), i = SG(a, \"int32\"), m = Q(V), T = G.data.get(d.dataId).values;\n  for (let s = 0; s < i.length; ++s) {\n    const o = s * m;\n    let B = T[o], C = 0;\n    for (let n = 0; n < m; ++n) {\n      const X = T[o + n];\n      X > B && (B = X, C = n);\n    }\n    i[s] = C;\n  }\n  return W.forEach((s) => G.disposeIntermediateTensorInfo(s)), G.makeTensorInfo(Y, \"int32\", i);\n}\nconst xP = {\n  kernelName: cc,\n  backendName: \"cpu\",\n  kernelFunc: EP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction UP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g } = Z;\n  bl(h, \"argMin\");\n  let b = tl(g, h.shape);\n  const c = Ol(b, h.shape.length);\n  let d = h;\n  const W = [];\n  c != null && (d = MG({ inputs: { x: h }, backend: G, attrs: { perm: c } }), W.push(d), b = GG(b.length, d.shape.length)), b = [b[0]], XG(\"argMin\", b, d.shape.length);\n  const [Y, V] = sG(d.shape, b), a = Q(Y), i = SG(a, \"int32\"), m = Q(V), T = G.data.get(d.dataId).values;\n  for (let s = 0; s < i.length; ++s) {\n    const o = s * m;\n    let B = T[o], C = 0;\n    for (let n = 0; n < m; ++n) {\n      const X = T[o + n];\n      X < B && (B = X, C = n);\n    }\n    i[s] = C;\n  }\n  return W.forEach((s) => G.disposeIntermediateTensorInfo(s)), G.makeTensorInfo(Y, \"int32\", i);\n}\nconst HP = {\n  kernelName: dc,\n  backendName: \"cpu\",\n  kernelFunc: UP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst KP = El(D0, (I) => Math.asin(I)), AP = {\n  kernelName: D0,\n  backendName: \"cpu\",\n  kernelFunc: KP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst kP = El(f0, (I) => Math.asinh(I)), zP = {\n  kernelName: f0,\n  backendName: \"cpu\",\n  kernelFunc: kP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst LP = El(O0, (I) => Math.atan(I)), MP = {\n  kernelName: O0,\n  backendName: \"cpu\",\n  kernelFunc: LP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst wP = ZG((I, l) => Math.atan2(I, l)), QP = aG($0, wP), vP = {\n  kernelName: $0,\n  backendName: \"cpu\",\n  kernelFunc: QP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst rP = El(q0, (I) => Math.atanh(I)), jP = {\n  kernelName: q0,\n  backendName: \"cpu\",\n  kernelFunc: rP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction t9(I, l, G, Z, h, g) {\n  const b = h.strideHeight, c = h.strideWidth, d = h.dilationHeight, W = h.dilationWidth, Y = h.effectiveFilterHeight, V = h.effectiveFilterWidth, a = h.padInfo.top, i = h.padInfo.left, m = g === \"max\" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, T = Xl(h.outShape, G), s = T.values, o = h.outShape[1] * h.outShape[2] * h.outShape[3], B = h.outShape[2] * h.outShape[3], C = h.outShape[3];\n  for (let n = 0; n < h.batchSize; ++n) {\n    const X = n * o, t = n * Z[0];\n    for (let e = 0; e < h.inChannels; ++e)\n      for (let S = 0; S < h.outHeight; ++S) {\n        const p = S * b - a, F = Math.max(0, p), x = Math.min(h.inHeight, Y + p), H = X + S * B;\n        for (let K = 0; K < h.outWidth; ++K) {\n          const z = K * c - i, k = Math.max(0, z), L = Math.min(h.inWidth, V + z);\n          let v = m, w = 0, r = 0;\n          for (let f = F; f < x; f += d) {\n            const $ = t + f * Z[1];\n            for (let q = k; q < L; q += W) {\n              const Il = $ + q * Z[2], _ = I[Il + e];\n              g === \"max\" && _ > v ? v = _ : g === \"avg\" && (w += _, r++);\n            }\n            if (isNaN(v))\n              break;\n          }\n          const D = H + K * C + e;\n          s[D] = g === \"avg\" ? w / r : v;\n        }\n      }\n  }\n  return T;\n}\nfunction cB(I, l, G, Z, h = !1, g = !1) {\n  const b = Xl(Z.outShape, \"int32\"), c = Z.strideHeight, d = Z.strideWidth, W = Z.dilationHeight, Y = Z.dilationWidth, V = Z.effectiveFilterHeight, a = Z.effectiveFilterWidth, i = Z.padInfo.top, m = Z.padInfo.left, T = Xl(l, G, I);\n  for (let s = 0; s < Z.batchSize; ++s)\n    for (let o = 0; o < Z.inChannels; ++o)\n      for (let B = 0; B < Z.outHeight; ++B) {\n        const C = B * c - i;\n        let n = C;\n        for (; n < 0; )\n          n += W;\n        const X = Math.min(Z.inHeight, V + C);\n        for (let t = 0; t < Z.outWidth; ++t) {\n          const e = t * d - m;\n          let S = e;\n          for (; S < 0; )\n            S += Y;\n          const p = Math.min(Z.inWidth, a + e);\n          let F = Number.NEGATIVE_INFINITY, x = -1;\n          for (let H = n; H < X; H += W) {\n            const K = H - C;\n            for (let z = S; z < p; z += Y) {\n              const k = z - e, L = T.get(s, H, z, o);\n              L > F && (F = L, h ? x = g ? ((s * Z.inHeight + H) * Z.inWidth + z) * Z.inChannels + o : (H * Z.inWidth + z) * Z.inChannels + o : x = K * a + k);\n            }\n          }\n          b.set(x, s, B, t, o);\n        }\n      }\n  return b;\n}\nfunction dB(I, l, G, Z, h, g) {\n  const b = h.strideDepth, c = h.strideHeight, d = h.strideWidth, W = h.dilationDepth, Y = h.dilationHeight, V = h.dilationWidth, a = h.effectiveFilterDepth, i = h.effectiveFilterHeight, m = h.effectiveFilterWidth, T = h.padInfo.front, s = h.padInfo.top, o = h.padInfo.left, B = g === \"max\" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, C = Xl(h.outShape, G), n = C.values, X = h.outShape[1] * h.outShape[2] * h.outShape[3] * h.outShape[4], t = h.outShape[2] * h.outShape[3] * h.outShape[4], e = h.outShape[3] * h.outShape[4], S = h.outShape[4];\n  for (let p = 0; p < h.batchSize; ++p) {\n    const F = p * X, x = p * Z[0];\n    for (let H = 0; H < h.inChannels; ++H)\n      for (let K = 0; K < h.outDepth; ++K) {\n        const z = K * b - T;\n        let k = z;\n        for (; k < 0; )\n          k += W;\n        const L = Math.min(h.inDepth, a + z), v = F + K * t;\n        for (let w = 0; w < h.outHeight; ++w) {\n          const r = w * c - s;\n          let D = r;\n          for (; D < 0; )\n            D += Y;\n          const f = Math.min(h.inHeight, i + r), $ = v + w * e;\n          for (let q = 0; q < h.outWidth; ++q) {\n            const Il = q * d - o;\n            let _ = Il;\n            for (; _ < 0; )\n              _ += V;\n            const gl = Math.min(h.inWidth, m + Il), dl = $ + q * S;\n            let il = B, al = 0, ol = 0;\n            for (let Pl = k; Pl < L; Pl += W) {\n              const Kl = x + Pl * Z[1];\n              for (let ql = D; ql < f; ql += Y) {\n                const Al = Kl + ql * Z[2];\n                for (let xl = _; xl < gl; xl += V) {\n                  const Dl = Al + xl * Z[3], vl = I[Dl + H];\n                  if (g === \"max\" && vl > il ? il = vl : g === \"avg\" && (al += vl, ol++), isNaN(il))\n                    break;\n                }\n                if (isNaN(il))\n                  break;\n              }\n              if (isNaN(il))\n                break;\n            }\n            const nl = dl + H;\n            n[nl] = g === \"avg\" ? al / Math.max(ol, 1) : il;\n          }\n        }\n      }\n  }\n  return C;\n}\nfunction DP(I, l) {\n  const G = Xl(l.outShape, \"int32\"), Z = l.strideDepth, h = l.strideHeight, g = l.strideWidth, b = l.dilationDepth, c = l.dilationHeight, d = l.dilationWidth, W = l.effectiveFilterDepth, Y = l.effectiveFilterHeight, V = l.effectiveFilterWidth, a = l.padInfo.front, i = l.padInfo.top, m = l.padInfo.left;\n  for (let T = 0; T < l.batchSize; ++T)\n    for (let s = 0; s < l.inChannels; ++s)\n      for (let o = 0; o < l.outDepth; ++o) {\n        const B = o * Z - a;\n        let C = B;\n        for (; C < 0; )\n          C += b;\n        const n = Math.min(l.inDepth, W + B);\n        for (let X = 0; X < l.outHeight; ++X) {\n          const t = X * h - i;\n          let e = t;\n          for (; e < 0; )\n            e += c;\n          const S = Math.min(l.inHeight, Y + t);\n          for (let p = 0; p < l.outWidth; ++p) {\n            const F = p * g - m;\n            let x = F;\n            for (; x < 0; )\n              x += d;\n            const H = Math.min(l.inWidth, V + F);\n            let K = Number.NEGATIVE_INFINITY, z = -1;\n            for (let k = C; k < n; k += b) {\n              const L = k - B;\n              for (let v = e; v < S; v += c) {\n                const w = v - t;\n                for (let r = x; r < H; r += d) {\n                  const D = r - F, f = I.get(T, k, v, r, s);\n                  f >= K && (K = f, z = L * Y * V + w * Y + D);\n                }\n              }\n            }\n            G.set(z, T, o, X, p, s);\n          }\n        }\n      }\n  return G;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction fP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l;\n  bl(h, \"avgPool\");\n  const { filterSize: g, strides: b, pad: c, dimRoundingMode: d } = Z, W = 1;\n  u(pG(b, W), () => `Error in avgPool: Either strides or dilations must be 1. Got strides ${b} and dilations '${W}'`);\n  const Y = sI(h.shape, g, b, W, c, d);\n  let V;\n  if (Y.filterWidth === 1 && Y.filterHeight === 1 && Nl(Y.inShape, Y.outShape))\n    V = fI({ inputs: { x: h }, backend: G });\n  else {\n    const a = G.data.get(h.dataId).values, i = Wl(h.shape), m = t9(a, h.shape, h.dtype, i, Y, \"avg\");\n    V = G.makeTensorInfo(Y.outShape, h.dtype, m.values);\n  }\n  return V;\n}\nconst OP = {\n  kernelName: Wc,\n  backendName: \"cpu\",\n  kernelFunc: fP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qP(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { filterSize: g, strides: b, pad: c, dimRoundingMode: d, dataFormat: W } = Z;\n  bl(h, \"avgPool3d\");\n  const Y = WZ(h.shape, g, b, 1, c, d, W), V = G.data.get(h.dataId).values, a = dB(V, h.shape, h.dtype, Wl(h.shape), Y, \"avg\");\n  return G.makeTensorInfo(a.shape, \"float32\", a.values);\n}\nconst $P = {\n  kernelName: Yc,\n  backendName: \"cpu\",\n  kernelFunc: qP\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _P(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g } = l, { filterSize: b, strides: c, pad: d, dimRoundingMode: W } = Z;\n  bl([h, g], \"avgPool3DGrad\");\n  const Y = WZ(g.shape, b, c, 1, d, W), V = Y.strideDepth, a = Y.strideHeight, i = Y.strideWidth, m = Y.filterDepth, T = Y.filterHeight, s = Y.filterWidth, o = Y.dilationDepth, B = Y.dilationHeight, C = Y.dilationWidth, n = Y.effectiveFilterDepth, X = Y.effectiveFilterHeight, t = Y.effectiveFilterWidth, e = n - 1 - Y.padInfo.front, S = t - 1 - Y.padInfo.left, p = X - 1 - Y.padInfo.top, F = Xl(g.shape, \"float32\"), x = 1 / (m * T * s), H = G.bufferSync(h);\n  for (let K = 0; K < Y.batchSize; ++K)\n    for (let z = 0; z < Y.inChannels; ++z)\n      for (let k = 0; k < Y.inDepth; ++k)\n        for (let L = 0; L < Y.inHeight; ++L)\n          for (let v = 0; v < Y.inWidth; ++v) {\n            const w = k - e, r = L - p, D = v - S;\n            let f = 0;\n            for (let $ = 0; $ < n; $ += o) {\n              const q = (w + $) / V;\n              if (!(q < 0 || q >= Y.outDepth || Math.floor(q) !== q))\n                for (let Il = 0; Il < X; Il += B) {\n                  const _ = (r + Il) / a;\n                  if (!(_ < 0 || _ >= Y.outHeight || Math.floor(_) !== _))\n                    for (let gl = 0; gl < t; gl += C) {\n                      const dl = (D + gl) / i;\n                      if (dl < 0 || dl >= Y.outWidth || Math.floor(dl) !== dl)\n                        continue;\n                      const il = H.get(K, q, _, dl, z);\n                      f += il;\n                    }\n                }\n            }\n            F.set(f * x, K, k, L, v, z);\n          }\n  return G.makeTensorInfo(F.shape, F.dtype, F.values);\n}\nconst lJ = {\n  kernelName: lY,\n  backendName: \"cpu\",\n  kernelFunc: _P\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction GJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g } = l, b = g;\n  bl([h, g], \"avgPoolGrad\");\n  const { filterSize: c, strides: d, pad: W } = Z, Y = sI(b.shape, c, d, 1, W), V = Y.strideHeight, a = Y.strideWidth, i = Y.filterHeight, m = Y.filterWidth, T = Y.dilationHeight, s = Y.dilationWidth, o = Y.effectiveFilterHeight, B = Y.effectiveFilterWidth, C = B - 1 - Y.padInfo.left, n = o - 1 - Y.padInfo.top, X = Xl(b.shape, \"float32\"), t = 1 / (i * m), e = G.data.get(h.dataId).values, S = Xl(h.shape, \"float32\", e);\n  for (let p = 0; p < Y.batchSize; ++p)\n    for (let F = 0; F < Y.inChannels; ++F)\n      for (let x = 0; x < Y.inHeight; ++x)\n        for (let H = 0; H < Y.inWidth; ++H) {\n          const K = x - n, z = H - C;\n          let k = 0;\n          for (let L = 0; L < o; L += T) {\n            const v = (K + L) / V;\n            if (!(v < 0 || v >= Y.outHeight || Math.floor(v) !== v))\n              for (let w = 0; w < B; w += s) {\n                const r = (z + w) / a;\n                if (r < 0 || r >= Y.outWidth || Math.floor(r) !== r)\n                  continue;\n                const D = S.get(p, v, r, F);\n                k += D;\n              }\n          }\n          X.set(k * t, p, x, H, F);\n        }\n  return G.makeTensorInfo(X.shape, X.dtype, X.values);\n}\nconst IJ = {\n  kernelName: _W,\n  backendName: \"cpu\",\n  kernelFunc: GJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ZJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, scale: g, offset: b, mean: c, variance: d } = l;\n  u(c.shape.length === d.shape.length, () => \"Batch normalization gradient requires mean and variance to have equal ranks.\"), u(b == null || c.shape.length === b.shape.length, () => \"Batch normalization gradient requires mean and offset to have equal ranks.\"), u(g == null || c.shape.length === g.shape.length, () => \"Batch normalization gradient requires mean and scale to have equal ranks.\"), bl([h, c, d, g, b], \"batchNorm\");\n  let { varianceEpsilon: W } = Z;\n  W == null && (W = 1e-3);\n  const Y = G.data.get(h.dataId).values, V = G.data.get(c.dataId).values, a = G.data.get(d.dataId).values, i = g ? G.data.get(g.dataId).values : new Float32Array([1]), m = b ? G.data.get(b.dataId).values : new Float32Array([0]), T = new Float32Array(Y.length), s = m.length, o = i.length, B = a.length, C = V.length;\n  let n = 0, X = 0, t = 0, e = 0;\n  for (let S = 0; S < Y.length; ++S)\n    T[S] = m[n++] + (Y[S] - V[X++]) * i[t++] / Math.sqrt(a[e++] + W), n >= s && (n = 0), X >= C && (X = 0), t >= o && (t = 0), e >= B && (e = 0);\n  return G.makeTensorInfo(h.shape, h.dtype, T);\n}\nconst hJ = {\n  kernelName: uc,\n  backendName: \"cpu\",\n  kernelFunc: ZJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { blockShape: g, crops: b } = Z;\n  bl([h], \"batchToSpaceND\");\n  const c = g.reduce((o, B) => o * B), d = Dg(h.shape, g, c), W = fg(d.length, g.length), Y = Og(h.shape, g, c), V = JV(b, g.length), a = EV(Y, b, g.length), i = Ll({ inputs: { x: h }, backend: G, attrs: { shape: d } }), m = MG({ inputs: { x: i }, backend: G, attrs: { perm: W } }), T = Ll({ inputs: { x: m }, backend: G, attrs: { shape: Y } }), s = Th({\n    inputs: { x: T },\n    backend: G,\n    attrs: { begin: V, size: a }\n  });\n  return G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(m), G.disposeIntermediateTensorInfo(T), s;\n}\nconst bJ = {\n  kernelName: ac,\n  backendName: \"cpu\",\n  kernelFunc: gJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction cJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, weights: g } = l, { size: b } = Z, c = G.data.get(h.dataId).values, d = G.data.get(g.dataId).values, W = o9(c, d, g.dtype, g.shape, b);\n  return G.makeTensorInfo([b], g.dtype, W);\n}\nconst dJ = {\n  kernelName: GY,\n  backendName: \"cpu\",\n  kernelFunc: cJ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction WJ(I) {\n  const { inputs: l, backend: G } = I, { s0: Z, s1: h } = l, g = G.data.get(Z.dataId).values, b = G.data.get(h.dataId).values, c = sl(Array.from(g), Array.from(b));\n  return G.makeTensorInfo([c.length], \"int32\", Int32Array.from(c));\n}\nconst YJ = {\n  kernelName: yi,\n  backendName: \"cpu\",\n  kernelFunc: WJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst VJ = El(Gg, (I, l) => {\n  const G = l;\n  return I > G.clipValueMax ? G.clipValueMax : I < G.clipValueMin ? G.clipValueMin : I;\n}), aJ = {\n  kernelName: Gg,\n  backendName: \"cpu\",\n  kernelFunc: VJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst iJ = (I) => {\n  const { x: l } = I.inputs, G = I.backend, Z = new Float32Array(Q(l.shape)), h = G.data.get(l.dataId), g = h.complexTensorInfos.real, b = h.complexTensorInfos.imag, c = G.data.get(g.dataId).values, d = G.data.get(b.dataId).values;\n  for (let W = 0; W < c.length; W++) {\n    const Y = c[W], V = d[W];\n    Z[W] = Math.hypot(Y, V);\n  }\n  return G.makeOutput(Z, l.shape, \"float32\");\n}, mJ = {\n  kernelName: ic,\n  backendName: \"cpu\",\n  kernelFunc: iJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Oh(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l, h = G.data.get(Z.dataId).complexTensorInfos.imag, g = G.data.get(h.dataId).values;\n  return G.makeTensorInfo(h.shape, h.dtype, g);\n}\nconst TJ = {\n  kernelName: nY,\n  backendName: \"cpu\",\n  kernelFunc: Oh\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qh(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { axis: h } = Z, g = tl(h, l[0].shape)[0], b = l.map((T) => T.shape);\n  yV(b, g);\n  let c = MI(l.map((T) => T.shape), g);\n  if (Q(c) === 0)\n    return G.makeTensorInfo(c, l[0].dtype, []);\n  const d = l.filter((T) => Q(T.shape) > 0);\n  if (d.length === 1)\n    return fI({ inputs: { x: d[0] }, backend: G });\n  if (d[0].dtype === \"complex64\") {\n    const T = d.map((n) => mh({ inputs: { input: n }, backend: G })), s = d.map((n) => Oh({ inputs: { input: n }, backend: G })), o = qh({ inputs: T, backend: G, attrs: { axis: g } }), B = qh({ inputs: s, backend: G, attrs: { axis: g } }), C = vG({ inputs: { real: o, imag: B }, backend: G });\n    return T.forEach((n) => G.disposeIntermediateTensorInfo(n)), s.forEach((n) => G.disposeIntermediateTensorInfo(n)), G.disposeIntermediateTensorInfo(o), G.disposeIntermediateTensorInfo(B), C;\n  }\n  const W = d.map((T) => {\n    const o = [-1, Q(T.shape.slice(g))];\n    return Ll({ inputs: { x: T }, backend: G, attrs: { shape: o } });\n  }), Y = W.map((T) => ({ vals: G.data.get(T.dataId).values, shape: T.shape }));\n  c = MI(\n    W.map((T) => T.shape),\n    1\n    /* axis */\n  );\n  const V = W[0].shape[0] === 1, a = i2(Y, c, l[0].dtype, V), i = MI(d.map((T) => T.shape), g), m = G.makeTensorInfo(i, l[0].dtype, a);\n  return W.forEach((T) => G.disposeIntermediateTensorInfo(T)), m;\n}\nconst sJ = {\n  kernelName: mc,\n  backendName: \"cpu\",\n  kernelFunc: qh\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction WB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dataFormat: d, dilations: W, dimRoundingMode: Y } = Z;\n  bl([h, g], \"conv2d\");\n  const V = YZ(d), a = CG(h.shape, g.shape, b, W, c, Y, !1, V), i = a.filterHeight, m = a.filterWidth, T = a.dilationHeight, s = a.dilationWidth, o = a.padInfo.left, B = a.padInfo.top, C = a.dataFormat === \"channelsLast\", n = new nG(a.outShape, h.dtype), X = Wl(h.shape), t = Wl(g.shape), e = X[0], S = C ? X[1] : X[2], p = C ? X[2] : 1, F = C ? 1 : X[1], x = n.strides[0], H = C ? n.strides[1] : n.strides[2], K = C ? n.strides[2] : 1, z = C ? 1 : n.strides[1], k = G.data.get(h.dataId).values, L = G.data.get(g.dataId).values, v = n.values;\n  for (let w = 0; w < a.batchSize; ++w) {\n    const r = w * e, D = w * x;\n    for (let f = 0; f < a.outHeight; ++f) {\n      const $ = D + f * H, q = f * a.strideHeight - B;\n      for (let Il = 0; Il < i; ++Il) {\n        const _ = q + Il * T;\n        if (_ < 0 || _ >= a.inHeight)\n          continue;\n        const gl = Il * t[0], dl = r + _ * S;\n        for (let il = 0; il < a.outWidth; ++il) {\n          const al = $ + il * K, ol = il * a.strideWidth - o;\n          for (let nl = 0; nl < m; ++nl) {\n            const Pl = ol + nl * s;\n            if (Pl < 0 || Pl >= a.inWidth)\n              continue;\n            const Kl = gl + nl * t[1], ql = dl + Pl * p;\n            let Al = Kl;\n            for (let xl = 0; xl < a.inChannels; ++xl) {\n              const Dl = k[ql + xl * F];\n              for (let vl = 0; vl < a.outChannels; ++vl)\n                v[al + vl * z] += Dl * L[Al + vl];\n              Al += a.outChannels;\n            }\n          }\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo(n.shape, n.dtype, v);\n}\nconst oJ = {\n  kernelName: Tc,\n  backendName: \"cpu\",\n  kernelFunc: WB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction BJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, dy: g } = l, { strides: b, pad: c, dataFormat: d, dimRoundingMode: W, filterShape: Y } = Z;\n  bl([h, g], \"conv2dBackpropFilter\");\n  const V = YZ(d), a = CG(h.shape, Y, b, 1, c, W, !1, V), { strideHeight: i, strideWidth: m, filterHeight: T, filterWidth: s } = a, o = a.dataFormat === \"channelsLast\", B = new nG(a.filterShape, \"float32\"), C = a.padInfo.left, n = a.padInfo.top, X = G.data.get(h.dataId).values, t = G.data.get(g.dataId).values, e = new nG(h.shape, h.dtype, X), S = new nG(g.shape, g.dtype, t);\n  for (let p = 0; p < T; ++p) {\n    const F = Math.max(0, Math.ceil((n - p) / i)), x = Math.min(a.outHeight, (a.inHeight + n - p) / i);\n    for (let H = 0; H < s; ++H) {\n      const K = Math.max(0, Math.ceil((C - H) / m)), z = Math.min(a.outWidth, (a.inWidth + C - H) / m);\n      for (let k = 0; k < a.inChannels; ++k)\n        for (let L = 0; L < a.outChannels; ++L) {\n          let v = 0;\n          for (let w = 0; w < a.batchSize; ++w)\n            for (let r = F; r < x; ++r) {\n              const D = p + r * i - n;\n              for (let f = K; f < z; ++f) {\n                const $ = H + f * m - C;\n                o ? v += e.get(w, D, $, k) * S.get(w, r, f, L) : v += e.get(w, k, D, $) * S.get(w, L, r, f);\n              }\n            }\n          B.set(v, p, H, k, L);\n        }\n    }\n  }\n  return G.makeTensorInfo(B.shape, B.dtype, B.values);\n}\nconst nJ = {\n  kernelName: hY,\n  backendName: \"cpu\",\n  kernelFunc: BJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction CJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, filter: g } = l, { inputShape: b, strides: c, pad: d, dataFormat: W, dimRoundingMode: Y } = Z;\n  bl([h, g], \"conv2dBackpropInput\");\n  const V = Wl(g.shape), a = Wl(h.shape);\n  let i = YZ(W);\n  const m = CG(b, g.shape, c, 1, d, Y, !1, i), T = new nG(m.inShape, \"float32\"), s = T.values, o = G.data.get(h.dataId).values, B = G.data.get(g.dataId).values, [C, n, X] = V, { batchSize: t, filterHeight: e, filterWidth: S, inChannels: p, inHeight: F, inWidth: x, outChannels: H, outHeight: K, outWidth: z, strideHeight: k, strideWidth: L } = m;\n  i = m.dataFormat;\n  const v = e - 1 - m.padInfo.top, w = S - 1 - m.padInfo.left, r = i === \"channelsLast\", D = T.strides[0], f = r ? T.strides[1] : T.strides[2], $ = r ? T.strides[2] : 1, q = r ? 1 : T.strides[1], Il = a[0], _ = r ? a[1] : a[2], gl = r ? a[2] : 1, dl = r ? 1 : a[1];\n  for (let il = 0; il < t; ++il)\n    for (let al = 0; al < p; ++al)\n      for (let ol = 0; ol < F; ++ol) {\n        const nl = ol - v, Pl = Math.max(0, Math.ceil(nl / k)), Kl = Math.min(K, (e + nl) / k);\n        for (let ql = 0; ql < x; ++ql) {\n          const Al = ql - w, xl = Math.max(0, Math.ceil(Al / L)), Dl = Math.min(z, (S + Al) / L);\n          let vl = 0;\n          for (let oG = Pl; oG < Kl; ++oG) {\n            const aZ = oG * k - nl;\n            for (let $G = xl; $G < Dl; ++$G) {\n              const LZ = $G * L - Al, nI = Il * il + _ * oG + gl * $G, $I = C * (e - 1 - aZ) + n * (S - 1 - LZ) + X * al;\n              for (let iZ = 0; iZ < H; ++iZ) {\n                const mZ = o[nI + dl * iZ], TZ = B[$I + iZ];\n                vl += mZ * TZ;\n              }\n            }\n          }\n          const qI = D * il + f * ol + $ * ql + q * al;\n          s[qI] = vl;\n        }\n      }\n  return G.makeTensorInfo(T.shape, T.dtype, T.values);\n}\nconst XJ = {\n  kernelName: sc,\n  backendName: \"cpu\",\n  kernelFunc: CJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction tJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dilations: d } = Z;\n  bl([h, g], \"conv3d\");\n  const W = EZ(h.shape, g.shape, b, d, c), { filterDepth: Y, filterHeight: V, filterWidth: a, dilationDepth: i, dilationHeight: m, dilationWidth: T, padInfo: s } = W, o = s.front, B = s.left, C = s.top, n = new nG(W.outShape, h.dtype), X = G.data.get(h.dataId).values, t = G.data.get(g.dataId).values, e = n.values, S = Wl(h.shape), p = Wl(g.shape);\n  for (let F = 0; F < W.batchSize; ++F) {\n    const x = F * S[0], H = F * n.strides[0];\n    for (let K = 0; K < W.outDepth; ++K) {\n      const z = H + K * n.strides[1], k = K * W.strideDepth - o;\n      for (let L = 0; L < Y; ++L) {\n        const v = k + L * i;\n        if (v < 0 || v >= W.inDepth)\n          continue;\n        const w = L * p[0], r = x + v * S[1];\n        for (let D = 0; D < W.outHeight; ++D) {\n          const f = z + D * n.strides[2], $ = D * W.strideHeight - C;\n          for (let q = 0; q < V; ++q) {\n            const Il = $ + q * m;\n            if (Il < 0 || Il >= W.inHeight)\n              continue;\n            const _ = w + q * p[1], gl = r + Il * S[2];\n            for (let dl = 0; dl < W.outWidth; ++dl) {\n              const il = f + dl * W.outChannels, al = dl * W.strideWidth - B;\n              for (let ol = 0; ol < a; ++ol) {\n                const nl = al + ol * T;\n                if (nl < 0 || nl >= W.inWidth)\n                  continue;\n                const Pl = _ + ol * p[2], Kl = gl + nl * W.inChannels;\n                let ql = Pl;\n                for (let Al = 0; Al < W.inChannels; ++Al) {\n                  const xl = X[Kl + Al];\n                  for (let Dl = 0; Dl < W.outChannels; ++Dl)\n                    e[il + Dl] += xl * t[ql + Dl];\n                  ql += W.outChannels;\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo(n.shape, n.dtype, n.values);\n}\nconst uJ = {\n  kernelName: oc,\n  backendName: \"cpu\",\n  kernelFunc: tJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction eJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, dy: g } = l, { strides: b, pad: c, filterShape: d } = Z;\n  bl([h, g], \"conv3dBackpropFilterV2\");\n  const W = Wl(h.shape), Y = Wl(g.shape), V = EZ(h.shape, d, b, 1, c), a = V.strideDepth, i = V.strideHeight, m = V.strideWidth, T = V.filterDepth, s = V.filterHeight, o = V.filterWidth, B = new nG(V.filterShape, \"float32\"), C = B.values, [n, X, t, e] = B.strides, S = G.data.get(g.dataId).values, [p, F, x, H] = Y, K = G.data.get(h.dataId).values, [z, k, L, v] = W, w = V.padInfo.front, r = V.padInfo.left, D = V.padInfo.top;\n  for (let f = 0; f < T; ++f) {\n    const $ = Math.max(0, Math.ceil((w - f) / a)), q = Math.min(V.outDepth, (V.inDepth + w - f) / a), Il = f * n;\n    for (let _ = 0; _ < s; ++_) {\n      const gl = Math.max(0, Math.ceil((D - _) / i)), dl = Math.min(V.outHeight, (V.inHeight + D - _) / i), il = _ * X + Il;\n      for (let al = 0; al < o; ++al) {\n        const ol = Math.max(0, Math.ceil((r - al) / m)), nl = Math.min(V.outWidth, (V.inWidth + r - al) / m), Pl = al * t + il;\n        for (let Kl = 0; Kl < V.inChannels; ++Kl) {\n          const ql = Kl * e + Pl;\n          for (let Al = 0; Al < V.outChannels; ++Al) {\n            let xl = 0;\n            for (let Dl = 0; Dl < V.batchSize; ++Dl) {\n              const vl = Dl * z, qI = Dl * p;\n              for (let oG = $; oG < q; ++oG) {\n                const $G = (f + oG * a - w) * k + vl, LZ = oG * F + qI;\n                for (let nI = gl; nI < dl; ++nI) {\n                  const iZ = (_ + nI * i - D) * L + $G, mZ = nI * x + LZ;\n                  for (let TZ = ol; TZ < nl; ++TZ) {\n                    const xd = (al + TZ * m - r) * v + iZ, Ud = TZ * H + mZ;\n                    xl += K[xd + Kl] * S[Ud + Al];\n                  }\n                }\n              }\n            }\n            C[ql + Al] = xl;\n          }\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo(B.shape, B.dtype, B.values);\n}\nconst SJ = {\n  kernelName: gY,\n  backendName: \"cpu\",\n  kernelFunc: eJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction RJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, filter: g } = l, { pad: b, strides: c, inputShape: d } = Z;\n  bl([h], \"conv3dBackpropInputV2\");\n  const W = Wl(h.shape), Y = Wl(g.shape), V = EZ(d, g.shape, c, 1, b), a = new nG(V.inShape, \"float32\"), i = a.values, [m, T, s, o] = a.strides, B = G.data.get(h.dataId).values, [C, n, X, t] = W, e = G.data.get(g.dataId).values, [S, p, F, x] = Y, { batchSize: H, filterDepth: K, filterHeight: z, filterWidth: k, inChannels: L, inDepth: v, inHeight: w, inWidth: r, outChannels: D, outDepth: f, outHeight: $, outWidth: q, strideDepth: Il, strideHeight: _, strideWidth: gl } = V, dl = K - 1 - V.padInfo.front, il = z - 1 - V.padInfo.top, al = k - 1 - V.padInfo.left;\n  for (let ol = 0; ol < H; ++ol)\n    for (let nl = 0; nl < L; ++nl)\n      for (let Pl = 0; Pl < v; ++Pl) {\n        const Kl = Pl - dl, ql = Math.max(0, Math.ceil(Kl / Il)), Al = Math.min(f, (K + Kl) / Il);\n        for (let xl = 0; xl < w; ++xl) {\n          const Dl = xl - il, vl = Math.max(0, Math.ceil(Dl / _)), qI = Math.min($, (z + Dl) / _);\n          for (let oG = 0; oG < r; ++oG) {\n            const aZ = oG - al, $G = Math.max(0, Math.ceil(aZ / gl)), LZ = Math.min(q, (k + aZ) / gl);\n            let nI = 0;\n            for (let $I = ql; $I < Al; ++$I) {\n              const iZ = $I * Il - Kl;\n              for (let mZ = vl; mZ < qI; ++mZ) {\n                const TZ = mZ * _ - Dl;\n                for (let o0 = $G; o0 < LZ; ++o0) {\n                  const xd = o0 * gl - aZ, Ud = C * ol + n * $I + X * mZ + t * o0, Wn = S * (K - 1 - iZ) + p * (z - 1 - TZ) + F * (k - 1 - xd) + x * nl;\n                  for (let ab = 0; ab < D; ++ab) {\n                    const Yn = B[Ud + ab], Vn = e[Wn + ab];\n                    nI += Yn * Vn;\n                  }\n                }\n              }\n            }\n            i[m * ol + T * Pl + s * xl + o * oG + nl] = nI;\n          }\n        }\n      }\n  return G.makeTensorInfo(a.shape, a.dtype, a.values);\n}\nconst pJ = {\n  kernelName: bY,\n  backendName: \"cpu\",\n  kernelFunc: RJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst FJ = El(Ig, (I) => Math.cos(I)), yJ = {\n  kernelName: Ig,\n  backendName: \"cpu\",\n  kernelFunc: FJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst NJ = El(Zg, (I) => Math.cosh(I)), PJ = {\n  kernelName: Zg,\n  backendName: \"cpu\",\n  kernelFunc: NJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction JJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { image: h, boxes: g, boxInd: b } = l, { cropSize: c, method: d, extrapolationValue: W } = Z, [Y, V, a, i] = h.shape, m = g.shape[0], [T, s] = c, o = Xl([m, T, s, i], \"float32\"), B = G.data.get(g.dataId).values, C = G.data.get(b.dataId).values, n = G.data.get(h.dataId).values, X = Wl(h.shape), t = Wl(o.shape);\n  for (let e = 0; e < m; e++) {\n    const S = e * 4, p = B[S], F = B[S + 1], x = B[S + 2], H = B[S + 3], K = C[e];\n    if (K >= Y)\n      continue;\n    const z = T > 1 ? (x - p) * (V - 1) / (T - 1) : 0, k = s > 1 ? (H - F) * (a - 1) / (s - 1) : 0;\n    for (let L = 0; L < T; L++) {\n      const v = T > 1 ? p * (V - 1) + L * z : 0.5 * (p + x) * (V - 1);\n      if (v < 0 || v > V - 1) {\n        for (let w = 0; w < s; w++)\n          for (let r = 0; r < i; r++) {\n            const D = r + w * t[2] + L * t[1] + e * t[0];\n            o.values[D] = W;\n          }\n        continue;\n      }\n      if (d === \"bilinear\") {\n        const w = Math.floor(v), r = Math.ceil(v), D = v - w;\n        for (let f = 0; f < s; f++) {\n          const $ = s > 1 ? F * (a - 1) + f * k : 0.5 * (F + H) * (a - 1);\n          if ($ < 0 || $ > a - 1) {\n            for (let gl = 0; gl < i; gl++) {\n              const dl = gl + f * t[2] + L * t[1] + e * t[0];\n              o.values[dl] = W;\n            }\n            continue;\n          }\n          const q = Math.floor($), Il = Math.ceil($), _ = $ - q;\n          for (let gl = 0; gl < i; gl++) {\n            let dl = gl + q * X[2] + w * X[1] + K * X[0];\n            const il = n[dl];\n            dl = gl + Il * X[2] + w * X[1] + K * X[0];\n            const al = n[dl];\n            dl = gl + q * X[2] + r * X[1] + K * X[0];\n            const ol = n[dl];\n            dl = gl + Il * X[2] + r * X[1] + K * X[0];\n            const nl = n[dl], Pl = il + (al - il) * _, Kl = ol + (nl - ol) * _;\n            dl = gl + f * t[2] + L * t[1] + e * t[0], o.values[dl] = Pl + (Kl - Pl) * D;\n          }\n        }\n      } else\n        for (let w = 0; w < s; ++w) {\n          const r = s > 1 ? F * (a - 1) + w * k : 0.5 * (F + H) * (a - 1);\n          if (r < 0 || r > a - 1) {\n            for (let $ = 0; $ < i; $++) {\n              const q = $ + w * t[2] + L * t[1] + e * t[0];\n              o.values[q] = W;\n            }\n            continue;\n          }\n          const D = Math.round(r), f = Math.round(v);\n          for (let $ = 0; $ < i; $++) {\n            const q = $ + D * X[2] + f * X[1] + K * X[0], Il = $ + w * t[2] + L * t[1] + e * t[0];\n            o.values[Il] = n[q];\n          }\n        }\n    }\n  }\n  return G.makeTensorInfo(o.shape, o.dtype, o.values);\n}\nconst EJ = {\n  kernelName: dY,\n  backendName: \"cpu\",\n  kernelFunc: JJ\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction xJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, exclusive: b, reverse: c } = Z;\n  bl(h, \"cumprod\");\n  const d = Ol([g], h.shape.length);\n  let W = h;\n  d != null && (W = MG({ inputs: { x: h }, backend: G, attrs: { perm: d } }));\n  const Y = GG(1, h.shape.length)[0];\n  if (Y !== W.shape.length - 1)\n    throw new Error(`backend.cumprod in CPU expects an inner-most axis=${W.shape.length - 1} but got axis=${Y}`);\n  const V = DG(W.dtype, \"int32\"), a = jW(Q(W.shape), V), i = G.data.get(W.dataId).values, m = W.shape[W.shape.length - 1], T = c ? (o, B) => o + m - B - 1 : (o, B) => o + B;\n  for (let o = 0; o < i.length; o += m)\n    for (let B = 0; B < m; B++) {\n      const C = T(o, B);\n      if (B === 0)\n        a[C] = b ? 1 : i[C];\n      else {\n        const n = T(o, B - 1);\n        a[C] = b ? i[n] * a[n] : i[C] * a[n];\n      }\n    }\n  const s = G.makeTensorInfo(W.shape, V, a);\n  if (d != null) {\n    const o = xZ(d), B = MG({ inputs: { x: s }, backend: G, attrs: { perm: o } });\n    return G.disposeIntermediateTensorInfo(s), G.disposeIntermediateTensorInfo(W), B;\n  }\n  return s;\n}\nconst UJ = {\n  kernelName: cY,\n  backendName: \"cpu\",\n  kernelFunc: xJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction HJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, exclusive: b, reverse: c } = Z;\n  bl(h, \"cumsum\");\n  const d = Ol([g], h.shape.length);\n  let W = h;\n  d != null && (W = MG({ inputs: { x: h }, backend: G, attrs: { perm: d } }));\n  const Y = GG(1, h.shape.length)[0];\n  if (Y !== W.shape.length - 1)\n    throw new Error(`backend.cumsum in CPU expects an inner-most axis=${W.shape.length - 1} but got axis=${Y}`);\n  const V = DG(W.dtype, \"int32\"), a = SG(Q(W.shape), V), i = G.data.get(W.dataId).values, m = W.shape[W.shape.length - 1], T = c ? (o, B) => o + m - B - 1 : (o, B) => o + B;\n  for (let o = 0; o < i.length; o += m)\n    for (let B = 0; B < m; B++) {\n      const C = T(o, B);\n      if (B === 0)\n        a[C] = b ? 0 : i[C];\n      else {\n        const n = T(o, B - 1);\n        a[C] = b ? i[n] + a[n] : i[C] + a[n];\n      }\n    }\n  const s = G.makeTensorInfo(W.shape, V, a);\n  if (d != null) {\n    const o = xZ(d), B = MG({ inputs: { x: s }, backend: G, attrs: { perm: o } });\n    return G.disposeIntermediateTensorInfo(s), G.disposeIntermediateTensorInfo(W), B;\n  }\n  return s;\n}\nconst KJ = {\n  kernelName: Bc,\n  backendName: \"cpu\",\n  kernelFunc: HJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction AJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, weights: g } = l, { size: b, binaryOutput: c } = Z;\n  if (h.shape.length === 1) {\n    const d = G.data.get(h.dataId).values, W = G.data.get(g.dataId).values, Y = o9(d, W, g.dtype, g.shape, b);\n    return G.makeTensorInfo([b], g.dtype, Y);\n  } else if (h.shape.length === 2) {\n    const d = G.bufferSync(h), W = G.bufferSync(g), Y = Y2(d, W, b, c);\n    return G.makeTensorInfo(Y.shape, g.dtype, Y.values);\n  }\n  throw new Error(`Error in denseBincount: input must be at most rank 2, but got rank${h.shape.length}.`);\n}\nconst kJ = {\n  kernelName: WY,\n  backendName: \"cpu\",\n  kernelFunc: AJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { blockSize: g, dataFormat: b } = Z;\n  u(b === \"NHWC\", () => `Only NHWC dataFormat supported on CPU for depthToSpace. Got ${b}`);\n  const c = h.shape[0], d = h.shape[1], W = h.shape[2], Y = h.shape[3], V = d * g, a = W * g, i = Y / (g * g), m = G.data.get(h.dataId).values, T = new Float32Array(c * V * a * i);\n  let s = 0;\n  for (let o = 0; o < c; ++o)\n    for (let B = 0; B < V; ++B) {\n      const C = Math.floor(B / g), n = B % g;\n      for (let X = 0; X < a; ++X) {\n        const t = Math.floor(X / g), e = X % g, S = (n * g + e) * i;\n        for (let p = 0; p < i; ++p) {\n          const x = p + S + Y * (t + W * (C + d * o));\n          T[s++] = m[x];\n        }\n      }\n    }\n  return G.makeTensorInfo([c, V, a, i], h.dtype, T);\n}\nconst LJ = {\n  kernelName: YY,\n  backendName: \"cpu\",\n  kernelFunc: zJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction YB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dilations: d, dimRoundingMode: W } = Z;\n  bl([h, g], \"depthwiseConv2DNative\");\n  const Y = Wl(h.shape), V = Wl(g.shape);\n  let a = d;\n  a == null && (a = [1, 1]), u(pG(b, a), () => `Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${b} and dilations '${a}'`);\n  const i = CG(\n    h.shape,\n    g.shape,\n    b,\n    a,\n    c,\n    W,\n    !0\n    /* depthwise */\n  ), { filterHeight: m, filterWidth: T, dilationHeight: s, dilationWidth: o, padInfo: B } = i, C = B.left, n = B.top, X = i.outChannels / i.inChannels, t = new nG(i.outShape, h.dtype), e = G.data.get(h.dataId).values, S = G.data.get(g.dataId).values, p = t.values;\n  for (let F = 0; F < i.batchSize; ++F) {\n    const x = F * Y[0], H = F * t.strides[0];\n    for (let K = 0; K < i.outHeight; ++K) {\n      const z = H + K * t.strides[1], k = K * i.strideHeight - n;\n      for (let L = 0; L < m; ++L) {\n        const v = k + L * s;\n        if (v < 0 || v >= i.inHeight)\n          continue;\n        const w = L * V[0], r = x + v * Y[1];\n        for (let D = 0; D < i.outWidth; ++D) {\n          const f = z + D * t.strides[2], $ = D * i.strideWidth - C;\n          for (let q = 0; q < T; ++q) {\n            const Il = $ + q * o;\n            if (Il < 0 || Il >= i.inWidth)\n              continue;\n            const _ = w + q * V[1], gl = r + Il * i.inChannels;\n            let dl = f, il = _;\n            for (let al = 0; al < i.inChannels; ++al) {\n              const ol = e[gl + al];\n              for (let nl = 0; nl < X; ++nl)\n                p[dl + nl] += ol * S[il + nl];\n              dl += X, il += X;\n            }\n          }\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo(t.shape, t.dtype, t.values);\n}\nconst MJ = {\n  kernelName: nc,\n  backendName: \"cpu\",\n  kernelFunc: YB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, dy: g } = l, { strides: b, dilations: c, pad: d, dimRoundingMode: W, filterShape: Y } = Z;\n  bl([h, g], \"depthwiseConv2dNativeBackpropFilter\");\n  const V = CG(\n    h.shape,\n    Y,\n    b,\n    c,\n    d,\n    W,\n    !0\n    /* depthwise */\n  ), { strideHeight: a, strideWidth: i, filterHeight: m, filterWidth: T } = V, s = new nG(V.filterShape, \"float32\"), o = V.padInfo.left, B = V.padInfo.top, C = V.outChannels / V.inChannels, n = G.data.get(h.dataId).values, X = new nG(h.shape, h.dtype, n), t = G.data.get(g.dataId).values, e = new nG(g.shape, g.dtype, t);\n  for (let S = 0; S < m; ++S) {\n    const p = Math.max(0, Math.ceil((B - S) / a)), F = Math.min(V.outHeight, (V.inHeight + B - S) / a);\n    for (let x = 0; x < T; ++x) {\n      const H = Math.max(0, Math.ceil((o - x) / i)), K = Math.min(V.outWidth, (V.inWidth + o - x) / i);\n      for (let z = 0; z < V.outChannels; ++z) {\n        const k = Math.trunc(z / C), L = z % C;\n        let v = 0;\n        for (let w = 0; w < V.batchSize; ++w)\n          for (let r = p; r < F; ++r) {\n            const D = S + r * a - B;\n            for (let f = H; f < K; ++f) {\n              const $ = x + f * i - o;\n              v += X.get(w, D, $, k) * e.get(w, r, f, z);\n            }\n          }\n        s.set(v, S, x, k, L);\n      }\n    }\n  }\n  return G.makeTensorInfo(s.shape, s.dtype, s.values);\n}\nconst QJ = {\n  kernelName: VY,\n  backendName: \"cpu\",\n  kernelFunc: wJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vJ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, filter: g } = l, { strides: b, dilations: c, pad: d, dimRoundingMode: W, inputShape: Y } = Z;\n  bl([h, g], \"depthwiseConv2DNativeBackpropInput\");\n  const V = Wl(h.shape), a = Wl(g.shape), i = CG(\n    Y,\n    g.shape,\n    b,\n    c,\n    d,\n    W,\n    !0\n    /* depthwise */\n  ), m = new nG(i.inShape, \"float32\"), T = m.values, [s, o, B] = m.strides, C = G.data.get(h.dataId).values, [n, X, t] = V, e = G.data.get(g.dataId).values, [S, p, F] = a, { batchSize: x, filterHeight: H, filterWidth: K, inChannels: z, inHeight: k, inWidth: L, outChannels: v, outHeight: w, outWidth: r, strideHeight: D, strideWidth: f } = i, $ = H - 1 - i.padInfo.top, q = K - 1 - i.padInfo.left, Il = v / z;\n  for (let _ = 0; _ < x; ++_)\n    for (let gl = 0; gl < z; ++gl)\n      for (let dl = 0; dl < k; ++dl) {\n        const il = dl - $, al = Math.max(0, Math.ceil(il / D)), ol = Math.min(w, (H + il) / D);\n        for (let nl = 0; nl < L; ++nl) {\n          const Pl = nl - q, Kl = Math.max(0, Math.ceil(Pl / f)), ql = Math.min(r, (K + Pl) / f);\n          let Al = 0;\n          for (let xl = al; xl < ol; ++xl) {\n            const Dl = xl * D - il;\n            for (let vl = Kl; vl < ql; ++vl) {\n              const qI = vl * f - Pl, oG = n * _ + X * xl + t * vl, aZ = S * (H - 1 - Dl) + p * (K - 1 - qI) + F * gl;\n              for (let $G = 0; $G < Il; ++$G) {\n                const LZ = gl * Il + $G, nI = C[oG + LZ], $I = e[aZ + $G];\n                Al += nI * $I;\n              }\n            }\n          }\n          T[s * _ + o * dl + B * nl + gl] = Al;\n        }\n      }\n  return G.makeTensorInfo(m.shape, m.dtype, m.values);\n}\nconst rJ = {\n  kernelName: aY,\n  backendName: \"cpu\",\n  kernelFunc: vJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jJ(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l, h = Q(Z.shape), g = G.data.get(Z.dataId).values, b = Xl([h, h], Z.dtype), c = b.values;\n  for (let W = 0; W < g.length; W++)\n    c[W * h + W] = g[W];\n  const d = [...Z.shape, ...Z.shape];\n  return G.makeTensorInfo(d, b.dtype, b.values);\n}\nconst DJ = {\n  kernelName: Ni,\n  backendName: \"cpu\",\n  kernelFunc: jJ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fJ = {\n  kernelName: Cc,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, backend: l, attrs: G }) => {\n    const { x: Z, filter: h } = I, { strides: g, pad: b, dilations: c } = G, d = l, W = d.data.get(Z.dataId).values, Y = Z.shape.length, V = d.data.get(h.dataId).values, a = h.shape.length, { batchSize: i, inHeight: m, inWidth: T, inChannels: s, outHeight: o, outWidth: B, padInfo: C, strideHeight: n, strideWidth: X, filterHeight: t, filterWidth: e, dilationHeight: S, dilationWidth: p, outShape: F } = wg(Z.shape, h.shape, g, b, \"NHWC\", c), x = Q(F), H = F.length, K = $l(Z.dtype, x);\n    for (let k = 0; k < i; ++k)\n      for (let L = 0; L < o; ++L) {\n        const v = L * n - C.top;\n        for (let w = 0; w < B; ++w) {\n          const r = w * X - C.left;\n          for (let D = 0; D < s; ++D) {\n            let f = Number.MIN_SAFE_INTEGER;\n            for (let q = 0; q < t; ++q) {\n              const Il = v + q * S;\n              if (Il >= 0 && Il < m)\n                for (let _ = 0; _ < e; ++_) {\n                  const gl = r + _ * p;\n                  if (gl >= 0 && gl < T) {\n                    const dl = zI([k, Il, gl, D], Y, Wl(Z.shape)), il = zI([q, _, D], a, Wl(h.shape)), al = W[dl] + V[il];\n                    al > f && (f = al);\n                  }\n                }\n            }\n            const $ = zI([k, L, w, D], H, Wl(F));\n            K[$] = f;\n          }\n        }\n      }\n    return { dataId: d.write(nh(K, Z.dtype), F, Z.dtype), shape: F, dtype: Z.dtype };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst OJ = {\n  kernelName: bW,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, backend: l, attrs: G }) => {\n    const { x: Z, filter: h, dy: g } = I, { strides: b, pad: c, dilations: d } = G, W = l, Y = SI(Z.shape, W.data.get(Z.dataId).values), V = SI(h.shape, W.data.get(h.dataId).values), { batchSize: a, inHeight: i, inWidth: m, inChannels: T, outHeight: s, outWidth: o, padInfo: B, strideHeight: C, strideWidth: n, filterHeight: X, filterWidth: t, dilationHeight: e, dilationWidth: S, outShape: p } = wg(Z.shape, h.shape, b, c, \"NHWC\", d);\n    u(g.rank === p.length, () => `Error in ${bW}, dy must have the same rank as output ${p.length}, but got ${g.rank}`);\n    const F = SI(p, W.data.get(g.dataId).values), x = Ri(h.shape, h.dtype);\n    for (let K = 0; K < a; ++K)\n      for (let z = 0; z < s; ++z) {\n        const k = z * C - B.top;\n        for (let L = 0; L < o; ++L) {\n          const v = L * n - B.left;\n          for (let w = 0; w < T; ++w) {\n            let r = Number.MIN_SAFE_INTEGER, D = 0, f = 0;\n            for (let $ = 0; $ < X; ++$) {\n              const q = k + $ * e;\n              if (q >= 0 && q < i)\n                for (let Il = 0; Il < t; ++Il) {\n                  const _ = v + Il * S;\n                  if (_ >= 0 && _ < m) {\n                    const gl = Y[K][q][_][w] + V[$][Il][w];\n                    gl > r && (r = gl, D = $, f = Il);\n                  }\n                }\n            }\n            x[D][f][w] += F[K][z][L][w];\n          }\n        }\n      }\n    return { dataId: W.write(nh(x, Z.dtype), h.shape, h.dtype), shape: h.shape, dtype: h.dtype };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst qJ = {\n  kernelName: gW,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, backend: l, attrs: G }) => {\n    const { x: Z, filter: h, dy: g } = I, { strides: b, pad: c, dilations: d } = G, W = l, Y = SI(Z.shape, W.data.get(Z.dataId).values), V = SI(h.shape, W.data.get(h.dataId).values), { batchSize: a, inHeight: i, inWidth: m, inChannels: T, outHeight: s, outWidth: o, padInfo: B, strideHeight: C, strideWidth: n, filterHeight: X, filterWidth: t, dilationHeight: e, dilationWidth: S, outShape: p } = wg(Z.shape, h.shape, b, c, \"NHWC\", d);\n    u(g.rank === p.length, () => `Error in ${gW}, dy must have the same rank as output ${p.length}, but got ${g.rank}`);\n    const F = SI(p, W.data.get(g.dataId).values), x = Ri(Z.shape, Z.dtype);\n    for (let K = 0; K < a; ++K)\n      for (let z = 0; z < s; ++z) {\n        const k = z * C - B.top;\n        for (let L = 0; L < o; ++L) {\n          const v = L * n - B.left;\n          for (let w = 0; w < T; ++w) {\n            let r = Number.MIN_SAFE_INTEGER, D = k < 0 ? 0 : k, f = v < 0 ? 0 : v;\n            for (let $ = 0; $ < X; ++$) {\n              const q = k + $ * e;\n              if (q >= 0 && q < i)\n                for (let Il = 0; Il < t; ++Il) {\n                  const _ = v + Il * S;\n                  if (_ >= 0 && _ < m) {\n                    const gl = Y[K][q][_][w] + V[$][Il][w];\n                    gl > r && (r = gl, D = q, f = _);\n                  }\n                }\n            }\n            x[K][D][f][w] += F[K][z][L][w];\n          }\n        }\n      }\n    return { dataId: W.write(nh(x, Z.dtype), Z.shape, Z.dtype), shape: Z.shape, dtype: Z.dtype };\n  }\n};\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $J(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { image: h } = l, { canvas: g, options: b } = Z, { contextOptions: c, imageOptions: d } = b || {}, W = (d == null ? void 0 : d.alpha) || 1, Y = (c == null ? void 0 : c.contextType) || \"2d\";\n  if (Y !== \"2d\")\n    throw new Error(`Context type ${c.contextType} is not supported by the CPU backend.`);\n  const V = g.getContext(Y, (c == null ? void 0 : c.contextAttributes) || {});\n  if (V == null)\n    throw new Error(`Could not get the context with ${Y} type.`);\n  const [a, i] = h.shape.slice(0, 2), m = h.shape.length === 2 ? 1 : h.shape[2], T = G.data.get(h.dataId).values, s = h.dtype === \"float32\" ? 255 : 1, o = new Uint8ClampedArray(i * a * 4);\n  for (let C = 0; C < a * i; ++C) {\n    const n = [0, 0, 0, 255 * W];\n    for (let t = 0; t < m; t++) {\n      const e = T[C * m + t];\n      if (h.dtype === \"float32\") {\n        if (e < 0 || e > 1)\n          throw new Error(`Tensor values for a float32 Tensor must be in the range [0 - 1] but encountered ${e}.`);\n      } else if (h.dtype === \"int32\" && (e < 0 || e > 255))\n        throw new Error(`Tensor values for a int32 Tensor must be in the range [0 - 255] but encountered ${e}.`);\n      m === 1 ? (n[0] = e * s, n[1] = e * s, n[2] = e * s) : n[t] = e * s;\n    }\n    const X = C * 4;\n    o[X + 0] = Math.round(n[0]), o[X + 1] = Math.round(n[1]), o[X + 2] = Math.round(n[2]), o[X + 3] = Math.round(n[3]);\n  }\n  g.width = i, g.height = a;\n  const B = new ImageData(o, i, a);\n  return V.putImageData(B, 0, 0), h;\n}\nconst _J = {\n  kernelName: Nn,\n  backendName: \"cpu\",\n  kernelFunc: $J\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gb(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z;\n  bl(h, \"sum\");\n  let c;\n  h.dtype === \"bool\" ? c = yZ({ inputs: { x: h }, backend: G, attrs: { dtype: \"int32\" } }) : c = fI({ inputs: { x: h }, backend: G });\n  const d = c.shape.length, W = tl(g, c.shape), Y = Ol(W, d);\n  let V = W, a = c;\n  Y != null && (a = MG({ inputs: { x: c }, backend: G, attrs: { perm: Y } }), V = GG(V.length, d)), XG(\"sum\", V, a.shape.length);\n  const [i, m] = sG(a.shape, V), T = DG(a.dtype, \"int32\");\n  let s = Ob(G, i, T);\n  const o = Q(m), B = G.data.get(s.dataId).values, C = G.data.get(a.dataId).values;\n  for (let n = 0; n < B.length; ++n) {\n    const X = n * o;\n    let t = 0;\n    for (let e = 0; e < o; ++e)\n      t += C[X + e];\n    B[n] = t;\n  }\n  if (b) {\n    const n = bG(s.shape, W), X = s;\n    s = Ll({ inputs: { x: s }, backend: G, attrs: { shape: n } }), G.disposeIntermediateTensorInfo(X);\n  }\n  return G.disposeIntermediateTensorInfo(c), Y != null && G.disposeIntermediateTensorInfo(a), s;\n}\nconst lE = {\n  kernelName: _c,\n  backendName: \"cpu\",\n  kernelFunc: gb\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction GE(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { equation: h } = Z, g = l, { allDims: b, summedDims: c, idDims: d } = LV(h, g.length);\n  wV(b.length, d, g);\n  const { path: W, steps: Y } = QV(c, d), V = Y.length;\n  let a = null, i = b.length;\n  const m = [];\n  for (let T = 0; T < V; ++T) {\n    for (const s of Y[T]) {\n      const { permutationIndices: o, expandDims: B } = MV(i, d[s]);\n      let C;\n      vV(o) ? C = g[s] : (C = MG({ inputs: { x: g[s] }, backend: G, attrs: { perm: o } }), m.push(C));\n      const n = C.shape.slice();\n      for (let X = 0; X < B.length; ++X)\n        n.splice(B[X], 0, 1);\n      Nl(C.shape, n) || (C = Ll({ inputs: { x: C }, backend: G, attrs: { shape: n } }), m.push(C)), a === null ? a = C : (a = Fd({ inputs: { a: C, b: a }, backend: G }), m.push(a));\n    }\n    T < V - 1 && (W[T] >= 0 && (a = gb({\n      inputs: { x: a },\n      backend: G,\n      attrs: {\n        axis: W[T] - (b.length - i),\n        keepDims: !1\n      }\n    }), m.push(a)), i--);\n  }\n  for (const T of m)\n    T !== a && G.disposeIntermediateTensorInfo(T);\n  return a;\n}\nconst IE = {\n  kernelName: iY,\n  backendName: \"cpu\",\n  kernelFunc: GE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ZE(I) {\n  const { inputs: l, backend: G } = I, { dy: Z, y: h } = l;\n  bl([Z, h], \"eluGrad\");\n  const g = new Float32Array(Q(h.shape)), b = G.data.get(h.dataId).values, c = G.data.get(Z.dataId).values;\n  for (let d = 0; d < b.length; ++d) {\n    const W = b[d];\n    W >= 0 ? g[d] = c[d] : g[d] = c[d] * (W + 1);\n  }\n  return G.makeTensorInfo(h.shape, \"float32\", g);\n}\nconst hE = {\n  kernelName: mY,\n  backendName: \"cpu\",\n  kernelFunc: ZE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst gE = xV, bE = UV, cE = HV, dE = KV, WE = AV, YE = kV, VE = El(bg, (I) => {\n  const l = Math.sign(I), G = Math.abs(I), Z = 1 / (1 + gE * G);\n  return l * (1 - ((((YE * Z + WE) * Z + dE) * Z + cE) * Z + bE) * Z * Math.exp(-G * G));\n}), aE = {\n  kernelName: bg,\n  backendName: \"cpu\",\n  kernelFunc: VE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _b(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { input: h } = l, { dim: g } = Z, b = h.shape.length, c = h.shape.slice();\n  let d = g;\n  return g < 0 && (u(-(b + 1) <= g, () => `Axis must be in the interval [${-(b + 1)}, ${b}]`), d = b + g + 1), c.splice(d, 0, 1), Ll({ inputs: { x: h }, backend: G, attrs: { shape: c } });\n}\nconst iE = {\n  kernelName: tc,\n  backendName: \"cpu\",\n  kernelFunc: _b\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst mE = ZG((I, l) => I / l), u9 = aG(hg, mE), UW = {\n  kernelName: hg,\n  backendName: \"cpu\",\n  kernelFunc: u9\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction VB(I, l, G) {\n  const Z = I.shape, h = Z[0], g = Z[1], b = G.data.get(I.dataId), c = b.complexTensorInfos.real, d = b.complexTensorInfos.imag, W = [h, g], Y = Q(W), V = eG(\"float32\", Y), a = eG(\"float32\", Y);\n  for (let s = 0; s < h; s++) {\n    const o = Th({\n      inputs: { x: c },\n      backend: G,\n      attrs: { begin: [s, 0], size: [1, g] }\n    }), B = Th({\n      inputs: { x: d },\n      backend: G,\n      attrs: { begin: [s, 0], size: [1, g] }\n    }), C = vG({ inputs: { real: o, imag: B }, backend: G }), { real: n, imag: X } = TE(C, l, G), t = bZ(n, X);\n    for (let e = 0; e < g; e++) {\n      const S = zV(t, e);\n      V[s * g + e] = S.real, a[s * g + e] = S.imag;\n    }\n    G.disposeIntermediateTensorInfo(o), G.disposeIntermediateTensorInfo(B), G.disposeIntermediateTensorInfo(C);\n  }\n  const i = G.makeTensorInfo(W, \"float32\", V), m = G.makeTensorInfo(W, \"float32\", a), T = vG({ inputs: { real: i, imag: m }, backend: G });\n  return G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(m), T;\n}\nfunction TE(I, l, G) {\n  const Z = Q(I.shape), h = G.data.get(I.dataId), g = G.data.get(h.complexTensorInfos.real.dataId).values, b = G.data.get(h.complexTensorInfos.imag.dataId).values;\n  if (sE(Z)) {\n    const c = HW(g, b, Z, l, G), d = [I.shape[0], I.shape[1]];\n    if (l) {\n      const W = G.makeTensorInfo(d, \"float32\", c.real), Y = G.makeTensorInfo(d, \"float32\", c.imag), V = G.makeTensorInfo([], \"float32\", JZ(Z, \"float32\")), a = fI({ inputs: { x: V }, backend: G }), i = UW.kernelFunc({ inputs: { a: W, b: V }, backend: G }), m = UW.kernelFunc({ inputs: { a: Y, b: a }, backend: G }), T = G.data.get(i.dataId).values, s = G.data.get(m.dataId).values;\n      return G.disposeIntermediateTensorInfo(W), G.disposeIntermediateTensorInfo(Y), G.disposeIntermediateTensorInfo(V), G.disposeIntermediateTensorInfo(a), G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(m), { real: T, imag: s };\n    }\n    return c;\n  } else {\n    const c = bZ(g, b), d = oE(c, Z, l);\n    return uT(d);\n  }\n}\nfunction sE(I) {\n  return (I & I - 1) === 0;\n}\nfunction HW(I, l, G, Z, h) {\n  if (G === 1)\n    return { real: I, imag: l };\n  const g = bZ(I, l), b = G / 2, c = eT(g), d = c.real, W = c.imag, Y = [d.length], V = h.makeTensorInfo(Y, \"float32\", d), a = h.makeTensorInfo(Y, \"float32\", W), i = vG({ inputs: { real: V, imag: a }, backend: h }), m = ST(g), T = m.real, s = m.imag, o = [T.length], B = h.makeTensorInfo(o, \"float32\", T), C = h.makeTensorInfo(o, \"float32\", s), n = vG({ inputs: { real: B, imag: C }, backend: h }), X = HW(d, W, b, Z, h), t = X.real, e = X.imag, S = [t.length], p = h.makeTensorInfo(S, \"float32\", t), F = h.makeTensorInfo(S, \"float32\", e), x = vG({\n    inputs: { real: p, imag: F },\n    backend: h\n  }), H = HW(T, s, b, Z, h), K = H.real, z = H.imag, k = [K.length], L = h.makeTensorInfo(k, \"float32\", K), v = h.makeTensorInfo(k, \"float32\", z), w = vG({ inputs: { real: L, imag: v }, backend: h }), r = pT(G, Z), D = [r.real.length], f = h.makeTensorInfo(D, \"float32\", r.real), $ = h.makeTensorInfo(D, \"float32\", r.imag), q = vG({ inputs: { real: f, imag: $ }, backend: h }), Il = Fd({ inputs: { a: q, b: w }, backend: h }), _ = fh({\n    inputs: { a: x, b: Il },\n    backend: h\n  }), gl = X9({\n    inputs: { a: x, b: Il },\n    backend: h\n  }), dl = mh({ inputs: { input: _ }, backend: h }), il = mh({ inputs: { input: gl }, backend: h }), al = Oh({ inputs: { input: _ }, backend: h }), ol = Oh({ inputs: { input: gl }, backend: h }), nl = qh({\n    inputs: [dl, il],\n    backend: h,\n    attrs: { axis: 0 }\n  }), Pl = qh({\n    inputs: [al, ol],\n    backend: h,\n    attrs: { axis: 0 }\n  }), Kl = h.data.get(nl.dataId).values, ql = h.data.get(Pl.dataId).values;\n  return h.disposeIntermediateTensorInfo(V), h.disposeIntermediateTensorInfo(a), h.disposeIntermediateTensorInfo(i), h.disposeIntermediateTensorInfo(B), h.disposeIntermediateTensorInfo(C), h.disposeIntermediateTensorInfo(n), h.disposeIntermediateTensorInfo(p), h.disposeIntermediateTensorInfo(F), h.disposeIntermediateTensorInfo(x), h.disposeIntermediateTensorInfo(L), h.disposeIntermediateTensorInfo(v), h.disposeIntermediateTensorInfo(w), h.disposeIntermediateTensorInfo(f), h.disposeIntermediateTensorInfo($), h.disposeIntermediateTensorInfo(q), h.disposeIntermediateTensorInfo(Il), h.disposeIntermediateTensorInfo(_), h.disposeIntermediateTensorInfo(gl), h.disposeIntermediateTensorInfo(dl), h.disposeIntermediateTensorInfo(al), h.disposeIntermediateTensorInfo(il), h.disposeIntermediateTensorInfo(ol), h.disposeIntermediateTensorInfo(nl), h.disposeIntermediateTensorInfo(Pl), { real: Kl, imag: ql };\n}\nfunction oE(I, l, G) {\n  const Z = new Float32Array(l * 2);\n  for (let h = 0; h < l; h++) {\n    let g = 0, b = 0;\n    for (let c = 0; c < l; c++) {\n      const d = FT(h * c, l, G), W = zV(I, c);\n      g += W.real * d.real - W.imag * d.imag, b += W.real * d.imag + W.imag * d.real;\n    }\n    G && (g /= l, b /= l), RT(Z, g, b, h);\n  }\n  return Z;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction BE(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l, h = Q(Z.shape), g = Z.shape[Z.shape.length - 1], b = h / g, c = Ll({\n    inputs: { x: Z },\n    backend: G,\n    attrs: { shape: [b, g] }\n  }), d = VB(c, !1, G), W = Ll({ inputs: { x: d }, backend: G, attrs: { shape: Z.shape } });\n  return G.disposeIntermediateTensorInfo(c), G.disposeIntermediateTensorInfo(d), W;\n}\nconst nE = {\n  kernelName: TY,\n  backendName: \"cpu\",\n  kernelFunc: BE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction e9(I) {\n  const { backend: l, attrs: G } = I, { shape: Z, value: h, dtype: g } = G, b = g || l0(h), c = $l(b, Q(Z));\n  return XE(c, h, b), l.makeTensorInfo(Z, b, c);\n}\nconst CE = {\n  kernelName: sY,\n  backendName: \"cpu\",\n  kernelFunc: e9\n};\nfunction XE(I, l, G) {\n  I.fill(l);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst tE = {\n  kernelName: oY,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, attrs: l, backend: G }) => {\n    const { image: Z } = I, h = G, g = eG(Z.dtype, Q(Z.shape)), [b, c, d, W] = Z.shape, Y = h.data.get(Z.dataId).values;\n    for (let a = 0; a < b; a++) {\n      const i = a * d * c * W;\n      for (let m = 0; m < c; m++) {\n        const T = m * (d * W);\n        for (let s = 0; s < d; s++) {\n          const o = s * W;\n          for (let B = 0; B < W; B++) {\n            const C = Math.round(d - s - 1), n = i + T + o + B;\n            let X = Y[n];\n            if (C >= 0 && C < d) {\n              const t = C * W, e = i + T + t + B;\n              X = Y[e];\n            }\n            g[n] = X;\n          }\n        }\n      }\n    }\n    return { dataId: h.write(g, Z.shape, Z.dtype), shape: Z.shape, dtype: Z.dtype };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction uE(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g, bias: b, preluActivationWeights: c } = l, { strides: d, pad: W, dataFormat: Y, dilations: V, dimRoundingMode: a, activation: i, leakyreluAlpha: m } = Z;\n  let T = WB({\n    inputs: { x: h, filter: g },\n    backend: G,\n    attrs: { strides: d, pad: W, dataFormat: Y, dilations: V, dimRoundingMode: a }\n  });\n  if (b) {\n    const s = T;\n    if (Y === \"NCHW\" && b.shape.length === 1 && b.shape[0] !== 1) {\n      const o = Ll({ inputs: { x: b }, backend: G, attrs: { shape: [b.shape[0], 1, 1] } });\n      T = fh({ inputs: { a: T, b: o }, backend: G }), G.disposeIntermediateTensorInfo(o);\n    } else\n      T = fh({ inputs: { a: T, b }, backend: G });\n    G.disposeIntermediateTensorInfo(s);\n  }\n  if (i) {\n    const s = T;\n    if (Y === \"NCHW\" && i === \"prelu\" && c.shape.length === 1 && c.shape[0] !== 1) {\n      const o = Ll({\n        inputs: { x: c },\n        backend: G,\n        attrs: { shape: [c.shape[0], 1, 1] }\n      });\n      T = $b(G, T, i, o, m), G.disposeIntermediateTensorInfo(o);\n    } else\n      T = $b(G, T, i, c, m);\n    G.disposeIntermediateTensorInfo(s);\n  }\n  return T;\n}\nconst eE = {\n  kernelName: Jb,\n  backendName: \"cpu\",\n  kernelFunc: uE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction SE(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g, bias: b, preluActivationWeights: c } = l, { strides: d, pad: W, dataFormat: Y, dilations: V, dimRoundingMode: a, activation: i, leakyreluAlpha: m } = Z;\n  let T = YB({\n    inputs: { x: h, filter: g },\n    backend: G,\n    attrs: { strides: d, pad: W, dataFormat: Y, dilations: V, dimRoundingMode: a }\n  });\n  if (b) {\n    const s = T;\n    T = fh({ inputs: { a: T, b }, backend: G }), G.disposeIntermediateTensorInfo(s);\n  }\n  if (i) {\n    const s = T;\n    T = $b(G, T, i, c, m), G.disposeIntermediateTensorInfo(s);\n  }\n  return T;\n}\nconst RE = {\n  kernelName: fi,\n  backendName: \"cpu\",\n  kernelFunc: SE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pE(I) {\n  const { inputs: l, backend: G } = I, { params: Z, indices: h } = l, g = Q(Z.shape), b = h.shape, c = b[b.length - 1], [d, W, Y, V] = uV(Z, h);\n  if (W === 0)\n    return G.makeTensorInfo(d, Z.dtype, []);\n  const a = G.data.get(h.dataId).values, i = G.bufferSync(Z), m = X2(a, i, Z.dtype, W, c, Y, V, Z.shape, g);\n  return G.makeTensorInfo(d, Z.dtype, m.values);\n}\nconst FE = {\n  kernelName: Pi,\n  backendName: \"cpu\",\n  kernelFunc: pE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yE(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, indices: g } = l, { axis: b, batchDims: c } = Z;\n  bl([h, g], \"gatherV2\");\n  const d = tl(b, h.shape)[0], W = G.data.get(g.dataId).values, Y = h.shape[d];\n  for (let n = 0; n < W.length; ++n) {\n    const X = W[n];\n    u(X <= Y - 1 && X >= 0, () => `GatherV2: the index value ${X} is not in [0, ${Y - 1}]`);\n  }\n  let V = c;\n  c == null && (V = 0);\n  const a = Q(g.shape), i = jV(h, g, d, V), m = Ll({\n    inputs: { x: h },\n    backend: G,\n    attrs: {\n      shape: [\n        i.batchSize,\n        i.outerSize,\n        i.dimSize,\n        i.sliceSize\n      ]\n    }\n  }), T = Ll({\n    inputs: { x: g },\n    backend: G,\n    attrs: { shape: [i.batchSize, a / i.batchSize] }\n  }), s = [\n    i.batchSize,\n    i.outerSize,\n    a / i.batchSize,\n    i.sliceSize\n  ], o = G.bufferSync(T), B = G.bufferSync(m), C = t2(B, o, s);\n  return G.disposeIntermediateTensorInfo(m), G.disposeIntermediateTensorInfo(T), G.makeTensorInfo(i.outputShape, C.dtype, C.values);\n}\nconst NE = {\n  kernelName: ec,\n  backendName: \"cpu\",\n  kernelFunc: yE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction PE(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l, h = Q(Z.shape), g = Z.shape[Z.shape.length - 1], b = h / g, c = Ll({\n    inputs: { x: Z },\n    backend: G,\n    attrs: { shape: [b, g] }\n  }), d = VB(c, !0, G), W = Ll({ inputs: { x: d }, backend: G, attrs: { shape: Z.shape } });\n  return G.disposeIntermediateTensorInfo(c), G.disposeIntermediateTensorInfo(d), W;\n}\nconst JE = {\n  kernelName: BY,\n  backendName: \"cpu\",\n  kernelFunc: PE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst EE = El(ig, (I) => Number.isFinite(I) ? 1 : 0, \"bool\"), xE = {\n  kernelName: ig,\n  backendName: \"cpu\",\n  kernelFunc: EE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst UE = El(mg, (I) => Math.abs(I) === 1 / 0 ? 1 : 0, \"bool\"), HE = {\n  kernelName: mg,\n  backendName: \"cpu\",\n  kernelFunc: UE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst KE = El(Tg, (I) => Number.isNaN(I) ? 1 : 0, \"bool\"), AE = {\n  kernelName: Tg,\n  backendName: \"cpu\",\n  kernelFunc: KE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kE(I) {\n  const { backend: l, attrs: G } = I, { start: Z, stop: h, num: g } = G, b = p2(Z, h, g);\n  return l.makeTensorInfo([b.length], \"float32\", b);\n}\nconst zE = {\n  kernelName: Ji,\n  backendName: \"cpu\",\n  kernelFunc: kE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst LE = El(og, (I) => Math.log1p(I)), ME = {\n  kernelName: og,\n  backendName: \"cpu\",\n  kernelFunc: LE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst wE = ZG((I, l) => I && l), QE = aG(yc, wE, null, \"bool\"), vE = {\n  kernelName: yc,\n  backendName: \"cpu\",\n  kernelFunc: QE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst rE = El(Nc, (I) => I ? 0 : 1, \"bool\"), jE = {\n  kernelName: Nc,\n  backendName: \"cpu\",\n  kernelFunc: rE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst DE = ZG((I, l) => I || l), fE = aG(Pc, DE, null, \"bool\"), OE = {\n  kernelName: Pc,\n  backendName: \"cpu\",\n  kernelFunc: fE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qE(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { depthRadius: g, bias: b, alpha: c, beta: d } = Z;\n  bl(h, \"LRN\");\n  const W = h.shape[3], Y = W - 1, V = G.data.get(h.dataId).values, a = Q(h.shape), i = new Float32Array(a);\n  function m(T) {\n    const s = T % W;\n    let o = T - s + Math.max(0, s - g);\n    const B = T - s + Math.min(s + g, Y);\n    let C = 0;\n    for (; o <= B; o++) {\n      const n = V[o];\n      C += n * n;\n    }\n    return C;\n  }\n  for (let T = 0; T < a; T++) {\n    const s = m(T), o = V[T] * Math.pow(b + c * s, -d);\n    i[T] = o;\n  }\n  return G.makeTensorInfo(h.shape, h.dtype, i);\n}\nconst $E = {\n  kernelName: Jc,\n  backendName: \"cpu\",\n  kernelFunc: qE\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _E(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, y: g, dy: b } = l, { depthRadius: c, bias: d, alpha: W, beta: Y } = Z;\n  bl(b, \"LRNGrad\");\n  const V = Q(b.shape), a = b.shape[3], i = G.data.get(b.dataId).values, m = G.data.get(h.dataId).values, T = G.data.get(g.dataId).values, s = new Float32Array(V), o = V;\n  for (let B = 0; B < o; B++) {\n    const C = B % a, n = B - C + Math.max(0, C - c), X = B - C + Math.min(a, C + c + 1);\n    let t = 0;\n    for (let e = n; e < X; e++)\n      t += Math.pow(m[e], 2);\n    t = W * t + d;\n    for (let e = n; e < X; e++) {\n      let S = -2 * W * Y * m[e] * T[B] / t;\n      B === e && (S += Math.pow(t, -Y)), S *= i[B], s[e] += S;\n    }\n  }\n  return G.makeTensorInfo(b.shape, h.dtype, s);\n}\nconst l5 = {\n  kernelName: CY,\n  backendName: \"cpu\",\n  kernelFunc: _E\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction aB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { reductionIndices: g, keepDims: b } = Z, c = G;\n  let d = h.shape;\n  const W = d.length, Y = tl(g, d);\n  let V = Y;\n  const a = Ol(V, W);\n  let i = c.data.get(h.dataId).values;\n  if (a != null) {\n    const n = new Array(W);\n    for (let X = 0; X < n.length; X++)\n      n[X] = d[a[X]];\n    i = n9(i, d, h.dtype, a, n), V = GG(V.length, W), d = n;\n  }\n  bl(h, \"max\"), XG(\"max\", V, W);\n  const [m, T] = sG(d, V), s = Q(T), o = y2(i, s, m, h.dtype), B = c.write(o, m, h.dtype);\n  let C = m;\n  return b && (C = bG(m, Y)), { dataId: B, shape: C, dtype: h.dtype };\n}\nconst G5 = {\n  kernelName: Ec,\n  backendName: \"cpu\",\n  kernelFunc: aB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction I5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l;\n  bl(h, \"maxPool\");\n  const { filterSize: g, strides: b, pad: c, dimRoundingMode: d } = Z, W = 1;\n  u(pG(b, W), () => `Error in maxPool: Either strides or dilations must be 1. Got strides ${b} and dilations '${W}'`);\n  const Y = sI(h.shape, g, b, W, c, d);\n  let V;\n  if (Y.filterWidth === 1 && Y.filterHeight === 1 && Nl(Y.inShape, Y.outShape))\n    V = fI({ inputs: { x: h }, backend: G });\n  else {\n    const a = G.data.get(h.dataId).values, i = Wl(h.shape), m = t9(a, h.shape, h.dtype, i, Y, \"max\");\n    V = G.makeTensorInfo(Y.outShape, h.dtype, m.values);\n  }\n  return V;\n}\nconst Z5 = {\n  kernelName: xc,\n  backendName: \"cpu\",\n  kernelFunc: I5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction h5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { filterSize: g, strides: b, pad: c, dimRoundingMode: d, dataFormat: W } = Z;\n  bl(h, \"maxPool3d\");\n  const Y = WZ(h.shape, g, b, 1, c, d, W), V = G.data.get(h.dataId).values, a = dB(V, h.shape, h.dtype, Wl(h.shape), Y, \"max\");\n  return G.makeTensorInfo(a.shape, \"float32\", a.values);\n}\nconst g5 = {\n  kernelName: Uc,\n  backendName: \"cpu\",\n  kernelFunc: h5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction b5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g } = l, { filterSize: b, strides: c, pad: d, dimRoundingMode: W } = Z;\n  bl([h, g], \"maxPool3DGrad\");\n  const Y = WZ(g.shape, b, c, 1, d, W), V = G.bufferSync(g), a = DP(V, Y), i = Y.strideDepth, m = Y.strideHeight, T = Y.strideWidth, s = Y.dilationDepth, o = Y.dilationHeight, B = Y.dilationWidth, C = Y.effectiveFilterDepth, n = Y.effectiveFilterHeight, X = Y.effectiveFilterWidth, t = C - 1 - Y.padInfo.front, e = X - 1 - Y.padInfo.left, S = n - 1 - Y.padInfo.top, p = Xl(g.shape, \"float32\"), F = G.bufferSync(h);\n  for (let x = 0; x < Y.batchSize; ++x)\n    for (let H = 0; H < Y.inChannels; ++H)\n      for (let K = 0; K < Y.inDepth; ++K)\n        for (let z = 0; z < Y.inHeight; ++z)\n          for (let k = 0; k < Y.inWidth; ++k) {\n            const L = K - t, v = z - S, w = k - e;\n            let r = 0;\n            for (let D = 0; D < C; D += s) {\n              const f = (L + D) / i;\n              if (!(f < 0 || f >= Y.outDepth || Math.floor(f) !== f))\n                for (let $ = 0; $ < n; $ += o) {\n                  const q = (v + $) / m;\n                  if (!(q < 0 || q >= Y.outHeight || Math.floor(q) !== q))\n                    for (let Il = 0; Il < X; Il += B) {\n                      const _ = (w + Il) / T;\n                      if (_ < 0 || _ >= Y.outWidth || Math.floor(_) !== _)\n                        continue;\n                      const gl = C * n * X - 1 - a.get(x, f, q, _, H), dl = D * n * X + $ * X + Il, il = gl === dl ? 1 : 0;\n                      if (il === 0)\n                        continue;\n                      const al = F.get(x, f, q, _, H);\n                      r += al * il;\n                    }\n                }\n            }\n            p.set(r, x, K, z, k, H);\n          }\n  return G.makeTensorInfo(p.shape, p.dtype, p.values);\n}\nconst c5 = {\n  kernelName: tY,\n  backendName: \"cpu\",\n  kernelFunc: b5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction d5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g, output: b } = l, c = g;\n  bl([g, b], \"maxPoolGrad\");\n  const { filterSize: d, strides: W, pad: Y, dimRoundingMode: V } = Z, a = sI(c.shape, d, W, 1, Y, V), i = G.data.get(c.dataId).values, m = Xl(a.outShape, c.dtype, cB(i, c.shape, c.dtype, a).values), T = a.strideHeight, s = a.strideWidth, o = a.dilationHeight, B = a.dilationWidth, C = a.effectiveFilterHeight, n = a.effectiveFilterWidth, X = n - 1 - a.padInfo.left, t = C - 1 - a.padInfo.top, e = Xl(c.shape, \"float32\"), S = G.data.get(h.dataId).values, p = Xl(h.shape, \"float32\", S);\n  for (let F = 0; F < a.batchSize; ++F)\n    for (let x = 0; x < a.inChannels; ++x)\n      for (let H = 0; H < a.inHeight; ++H)\n        for (let K = 0; K < a.inWidth; ++K) {\n          const z = H - t, k = K - X;\n          let L = 0;\n          for (let v = 0; v < C; v += o) {\n            const w = (z + v) / T;\n            if (!(w < 0 || w >= a.outHeight || Math.floor(w) !== w))\n              for (let r = 0; r < n; r += B) {\n                const D = (k + r) / s;\n                if (D < 0 || D >= a.outWidth || Math.floor(D) !== D)\n                  continue;\n                const f = C * n - 1 - m.get(F, w, D, x), $ = v * n + r, q = f === $ ? 1 : 0;\n                if (q === 0)\n                  continue;\n                const Il = p.get(F, w, D, x);\n                L += Il * q;\n              }\n          }\n          e.set(L, F, H, K, x);\n        }\n  return G.makeTensorInfo(e.shape, e.dtype, e.values);\n}\nconst W5 = {\n  kernelName: XY,\n  backendName: \"cpu\",\n  kernelFunc: d5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Y5(I, l, G, Z, h) {\n  const g = Wl(l), b = t9(I, l, G, g, h, \"max\"), c = cB(I, l, G, h, !0, Z);\n  return [b.values, c.values];\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst V5 = {\n  kernelName: Ei,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, attrs: l, backend: G }) => {\n    const { x: Z } = I, { filterSize: h, strides: g, pad: b, includeBatchInIndex: c } = l, d = G;\n    bl(Z, \"MaxPoolWithArgmax\");\n    const W = d.data.get(Z.dataId).values, Y = sI(Z.shape, h, g, [1, 1], b), [V, a] = Y5(W, Z.shape, Z.dtype, c, Y), i = d.write(V, Y.outShape, Z.dtype), m = d.write(a, Y.outShape, Z.dtype);\n    return [\n      { dataId: i, shape: Y.outShape, dtype: Z.dtype },\n      { dataId: m, shape: Y.outShape, dtype: \"int32\" }\n    ];\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction a5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z, c = tl(g, h.shape), W = sG(h.shape, c)[1], Y = Q(W), V = [], a = G.makeTensorInfo([], \"float32\", new Float32Array([Y]));\n  V.push(a);\n  const i = yZ({ inputs: { x: h }, backend: G, attrs: { dtype: \"float32\" } });\n  V.push(i);\n  const m = u9({ inputs: { a: i, b: a }, backend: G });\n  V.push(m);\n  const T = gb({ inputs: { x: m }, backend: G, attrs: { axis: g, keepDims: b } });\n  return V.forEach((s) => G.disposeIntermediateTensorInfo(s)), T;\n}\nconst i5 = {\n  kernelName: Hc,\n  backendName: \"cpu\",\n  kernelFunc: a5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction m5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z;\n  bl(h, \"min\");\n  const c = tl(g, h.shape);\n  let d = c;\n  const W = Ol(d, h.shape.length);\n  let Y = h;\n  W != null && (Y = MG({ inputs: { x: h }, backend: G, attrs: { perm: W } }), d = GG(d.length, h.shape.length)), XG(\"min\", d, Y.shape.length);\n  const [V, a] = sG(Y.shape, d), i = Q(a), m = SG(Q(V), Y.dtype), T = G.data.get(Y.dataId).values;\n  for (let o = 0; o < m.length; ++o) {\n    const B = o * i;\n    let C = T[B];\n    for (let n = 0; n < i; ++n) {\n      const X = T[B + n];\n      (Number.isNaN(X) || X < C) && (C = X);\n    }\n    m[o] = C;\n  }\n  W != null && G.disposeIntermediateTensorInfo(Y);\n  const s = G.makeTensorInfo(V, Y.dtype, m);\n  if (b) {\n    const o = bG(V, c), B = Ll({ inputs: { x: s }, backend: G, attrs: { shape: o } });\n    return G.disposeIntermediateTensorInfo(s), B;\n  }\n  return s;\n}\nconst T5 = {\n  kernelName: Kc,\n  backendName: \"cpu\",\n  kernelFunc: m5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction s5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { paddings: g, mode: b } = Z;\n  bl(h, \"mirrorPad\");\n  const c = g.map(\n    (C, n) => C[0] + h.shape[n] + C[1]\n    /* afterPad */\n  ), d = g.map((C) => C[0]), W = g.map((C, n) => C[0] + h.shape[n]), Y = b === \"reflect\" ? 0 : 1, V = G.data.get(h.dataId).values, a = h.shape.length, i = Wl(h.shape), m = Q(c), T = c.length, s = Wl(c), o = eG(h.dtype, m);\n  for (let C = 0; C < m; C++) {\n    let n = G0(C, T, s);\n    for (let t = 0; t < T; t++)\n      n[t] < d[t] ? n[t] = d[t] * 2 - n[t] - Y : n[t] >= W[t] && (n[t] = (W[t] - 1) * 2 - n[t] + Y);\n    n = n.map((t, e) => t - d[e]);\n    const X = zI(n, a, i);\n    o[C] = V[X];\n  }\n  return { dataId: G.write(o, c, h.dtype), shape: c, dtype: h.dtype };\n}\nconst o5 = {\n  kernelName: Ac,\n  backendName: \"cpu\",\n  kernelFunc: s5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst B5 = ZG((I, l) => {\n  const G = I % l;\n  return I < 0 && l < 0 || I >= 0 && l >= 0 ? G : (G + l) % l;\n}), n5 = aG(Cg, B5), C5 = {\n  kernelName: Cg,\n  backendName: \"cpu\",\n  kernelFunc: n5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction iB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { logits: h } = l, { dim: g } = Z, b = h.shape.length;\n  let c = g;\n  if (c === -1 && (c = b - 1), c !== b - 1)\n    throw Error(`Softmax along a non-last dimension is not yet supported. Logits was rank ${b} and dim was ${c}`);\n  const d = tl([c], h.shape), W = aB({\n    inputs: { x: h },\n    backend: G,\n    attrs: { reductionIndices: d, keepDims: !1 }\n  }), Y = bG(W.shape, d), V = Ll({ inputs: { x: W }, backend: G, attrs: { shape: Y } }), a = X9({ inputs: { a: h, b: V }, backend: G }), i = o2({ inputs: { x: a }, backend: G }), m = gb({ inputs: { x: i }, backend: G, attrs: { axis: d, keepDims: !1 } }), T = Ll({ inputs: { x: m }, backend: G, attrs: { shape: Y } }), s = u9({ inputs: { a: i, b: T }, backend: G });\n  return G.disposeIntermediateTensorInfo(W), G.disposeIntermediateTensorInfo(V), G.disposeIntermediateTensorInfo(a), G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(m), G.disposeIntermediateTensorInfo(T), s;\n}\nconst X5 = {\n  kernelName: Id,\n  backendName: \"cpu\",\n  kernelFunc: iB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction t5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { logits: h } = l, { numSamples: g, seed: b, normalized: c } = Z;\n  bl(h, \"multinomial\");\n  const d = c ? h : iB({ inputs: { logits: h }, backend: G, attrs: { dim: -1 } }), W = d.shape[0], Y = d.shape[1], V = G.data.get(d.dataId).values, a = [W, g], i = SG(Q(a), \"int32\");\n  for (let m = 0; m < W; ++m) {\n    const T = m * Y, s = new Float32Array(Y - 1);\n    s[0] = V[T];\n    for (let C = 1; C < s.length; ++C)\n      s[C] = s[C - 1] + V[T + C];\n    const o = WV.alea(b.toString()), B = m * g;\n    for (let C = 0; C < g; ++C) {\n      const n = o();\n      i[B + C] = s.length;\n      for (let X = 0; X < s.length; X++)\n        if (n < s[X]) {\n          i[B + C] = X;\n          break;\n        }\n    }\n  }\n  return c || G.disposeIntermediateTensorInfo(d), G.makeTensorInfo(a, \"int32\", i);\n}\nconst u5 = {\n  kernelName: xi,\n  backendName: \"cpu\",\n  kernelFunc: t5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst e5 = BV;\nfunction S5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { boxes: h, scores: g } = l, { maxOutputSize: b, iouThreshold: c, scoreThreshold: d } = Z;\n  bl(h, \"NonMaxSuppression\");\n  const W = G.data.get(h.dataId).values, Y = G.data.get(g.dataId).values, { selectedIndices: V } = e5(W, Y, b, c, d);\n  return G.makeTensorInfo([V.length], \"int32\", new Int32Array(V));\n}\nconst R5 = {\n  kernelName: uY,\n  backendName: \"cpu\",\n  kernelFunc: S5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst p5 = nV;\nfunction F5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { boxes: h, scores: g } = l, { maxOutputSize: b, iouThreshold: c, scoreThreshold: d, padToMaxOutputSize: W } = Z;\n  bl(h, \"NonMaxSuppressionPadded\");\n  const Y = G.data.get(h.dataId).values, V = G.data.get(g.dataId).values, { selectedIndices: a, validOutputs: i } = p5(Y, V, b, c, d, W);\n  return [\n    G.makeTensorInfo([a.length], \"int32\", new Int32Array(a)),\n    G.makeTensorInfo([], \"int32\", new Int32Array([i]))\n  ];\n}\nconst y5 = {\n  kernelName: eY,\n  backendName: \"cpu\",\n  kernelFunc: F5\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst N5 = CV;\nfunction P5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { boxes: h, scores: g } = l, { maxOutputSize: b, iouThreshold: c, scoreThreshold: d, softNmsSigma: W } = Z;\n  bl(h, \"NonMaxSuppressionWithScore\");\n  const Y = G.data.get(h.dataId).values, V = G.data.get(g.dataId).values, a = b, i = c, m = d, T = W, { selectedIndices: s, selectedScores: o } = N5(Y, V, a, i, m, T);\n  return [\n    G.makeTensorInfo([s.length], \"int32\", new Int32Array(s)),\n    G.makeTensorInfo([o.length], \"float32\", new Float32Array(o))\n  ];\n}\nconst J5 = {\n  kernelName: SY,\n  backendName: \"cpu\",\n  kernelFunc: P5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction E5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { indices: h } = l, { dtype: g, depth: b, onValue: c, offValue: d } = Z;\n  bl(h, \"oneHot\");\n  const W = Q(h.shape), Y = new Float32Array(W * b);\n  Y.fill(d);\n  const V = G.data.get(h.dataId).values;\n  for (let a = 0; a < W; ++a)\n    V[a] >= 0 && V[a] < b && (Y[a * b + V[a]] = c);\n  return G.makeTensorInfo([...h.shape, b], g, Y);\n}\nconst x5 = {\n  kernelName: Mc,\n  backendName: \"cpu\",\n  kernelFunc: E5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lc(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  if (Z.dtype === \"string\")\n    throw new Error(\"zerosLike is not supported for string tensors\");\n  if (Z.dtype === \"complex64\") {\n    const h = mh({ inputs: { input: Z }, backend: G }), g = lc({ inputs: { x: h }, backend: G }), b = Oh({ inputs: { input: Z }, backend: G }), c = lc({ inputs: { x: b }, backend: G }), d = vG({ inputs: { real: g, imag: c }, backend: G });\n    return G.disposeIntermediateTensorInfo(h), G.disposeIntermediateTensorInfo(g), G.disposeIntermediateTensorInfo(b), G.disposeIntermediateTensorInfo(c), d;\n  } else\n    return e9({ backend: G, attrs: { shape: Z.shape, value: 0, dtype: Z.dtype } });\n}\nconst U5 = {\n  kernelName: gd,\n  backendName: \"cpu\",\n  kernelFunc: lc\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mB(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  if (Z.dtype === \"string\")\n    throw new Error(\"onesLike is not supported for string tensors\");\n  if (Z.dtype === \"complex64\") {\n    const h = mh({ inputs: { input: Z }, backend: G }), g = mB({ inputs: { x: h }, backend: G }), b = Oh({ inputs: { input: Z }, backend: G }), c = lc({ inputs: { x: b }, backend: G }), d = vG({ inputs: { real: g, imag: c }, backend: G });\n    return G.disposeIntermediateTensorInfo(h), G.disposeIntermediateTensorInfo(g), G.disposeIntermediateTensorInfo(b), G.disposeIntermediateTensorInfo(c), d;\n  } else\n    return e9({ backend: G, attrs: { shape: Z.shape, value: 1, dtype: Z.dtype } });\n}\nconst H5 = {\n  kernelName: Lc,\n  backendName: \"cpu\",\n  kernelFunc: mB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction TB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { axis: h } = Z;\n  if (l.length === 1)\n    return _b({ inputs: { input: l[0] }, backend: G, attrs: { dim: h } });\n  const g = l[0].shape, b = l[0].dtype;\n  l.forEach((Y) => {\n    vW(g, Y.shape, \"All tensors passed to stack must have matching shapes\"), u(b === Y.dtype, () => \"All tensors passed to stack must have matching dtypes\");\n  });\n  const c = [], d = l.map((Y) => {\n    const V = _b({ inputs: { input: Y }, backend: G, attrs: { dim: h } });\n    return c.push(V), V;\n  }), W = qh({ inputs: d, backend: G, attrs: { axis: h } });\n  return c.forEach((Y) => G.disposeIntermediateTensorInfo(Y)), W;\n}\nconst K5 = {\n  kernelName: wc,\n  backendName: \"cpu\",\n  kernelFunc: TB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction A5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { paddings: g, constantValue: b } = Z;\n  bl(h, \"pad\");\n  const c = g.map(\n    (B, C) => B[0] + h.shape[C] + B[1]\n    /* afterPad */\n  ), d = g.map((B) => B[0]), W = G.data.get(h.dataId).values, Y = Q(h.shape), V = h.shape.length, a = Wl(h.shape), i = Q(c), m = c.length, T = Wl(c), s = eG(h.dtype, i);\n  b !== 0 && s.fill(b);\n  for (let B = 0; B < Y; B++) {\n    const n = G0(B, V, a).map((t, e) => t + d[e]), X = zI(n, m, T);\n    s[X] = W[B];\n  }\n  return { dataId: G.write(s, c, h.dtype), shape: c, dtype: h.dtype };\n}\nconst sB = {\n  kernelName: Qc,\n  backendName: \"cpu\",\n  kernelFunc: A5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst k5 = ZG((I, l) => Math.pow(I, l)), z5 = aG(tg, k5), L5 = {\n  kernelName: tg,\n  backendName: \"cpu\",\n  kernelFunc: z5\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction M5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { paramsNestedSplits: h, paramsDenseValues: g, indices: b } = l, c = h.map((s) => G.data.get(s.dataId).values), d = h.map((s) => s.shape), W = G.data.get(g.dataId).values, Y = G.data.get(b.dataId).values, [V, a, i] = U2(c, d, W, g.shape, g.dtype, Y, b.shape), m = V.map((s) => G.makeTensorInfo([s.length], \"int32\", s)), T = G.makeTensorInfo(i, g.dtype, a);\n  return m.concat([T]);\n}\nconst w5 = {\n  kernelName: Ui,\n  backendName: \"cpu\",\n  kernelFunc: M5\n};\n/**\n * @license\n * Copyright 2022 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Q5(I) {\n  const { inputs: l, backend: G } = I, { starts: Z, limits: h, deltas: g } = l, b = G.data.get(Z.dataId).values, c = G.data.get(h.dataId).values, d = G.data.get(g.dataId).values, [W, Y] = H2(b, Z.shape, Z.dtype, c, h.shape, d, g.shape), V = G.makeTensorInfo([W.length], \"int32\", W), a = G.makeTensorInfo([Y.length], Z.dtype, Y);\n  return [V, a];\n}\nconst v5 = {\n  kernelName: Hi,\n  backendName: \"cpu\",\n  kernelFunc: Q5\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction r5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { shape: h, values: g, defaultValue: b, rowPartitionTensors: c } = l, { rowPartitionTypes: d } = Z, W = G.data.get(h.dataId).values, Y = G.data.get(g.dataId).values, V = G.data.get(b.dataId).values, a = c.map((s) => G.data.get(s.dataId).values), i = c.map((s) => s.shape), [m, T] = K2(W, h.shape, Y, g.shape, g.dtype, V, b.shape, a, i, d);\n  return G.makeTensorInfo(m, g.dtype, T);\n}\nconst j5 = {\n  kernelName: Ki,\n  backendName: \"cpu\",\n  kernelFunc: r5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction D5(I) {\n  const { backend: l, attrs: G } = I, { start: Z, stop: h, dtype: g, step: b } = G, c = A2(Z, h, b, g);\n  return l.makeTensorInfo([c.length], g, c);\n}\nconst f5 = {\n  kernelName: RY,\n  backendName: \"cpu\",\n  kernelFunc: D5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst O5 = El(ug, (I) => 1 / I), q5 = {\n  kernelName: ug,\n  backendName: \"cpu\",\n  kernelFunc: O5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $5(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h } = l, { alignCorners: g, halfPixelCenters: b, size: c } = Z;\n  bl(h, \"resizeBilinear\");\n  const d = Wl(h.shape), [W, Y] = c, [V, a, i, m] = h.shape, T = G.data.get(h.dataId).values, s = new Float32Array(Q([V, W, Y, m])), o = [\n    g && W > 1 ? a - 1 : a,\n    g && Y > 1 ? i - 1 : i\n  ], B = [\n    g && W > 1 ? W - 1 : W,\n    g && Y > 1 ? Y - 1 : Y\n  ];\n  let C = 0;\n  const n = o[0] / B[0], X = o[1] / B[1];\n  for (let t = 0; t < V; t++)\n    for (let e = 0; e < W; e++) {\n      let S;\n      b ? S = n * (e + 0.5) - 0.5 : S = n * e;\n      const p = Math.max(0, Math.floor(S)), F = S - p, x = Math.min(a - 1, Math.ceil(S)), H = t * d[0] + p * d[1], K = t * d[0] + x * d[1];\n      for (let z = 0; z < Y; z++) {\n        let k;\n        b ? k = X * (z + 0.5) - 0.5 : k = X * z;\n        const L = Math.max(0, Math.floor(k)), v = k - L, w = Math.min(i - 1, Math.ceil(k)), r = H + L * d[2], D = K + L * d[2], f = H + w * d[2], $ = K + w * d[2];\n        for (let q = 0; q < m; q++) {\n          const Il = T[r + q], _ = T[D + q], gl = T[f + q], dl = T[$ + q], il = Il + (gl - Il) * v, al = _ + (dl - _) * v, ol = il + (al - il) * F;\n          s[C++] = ol;\n        }\n      }\n    }\n  return G.makeTensorInfo([V, W, Y, m], \"float32\", s);\n}\nconst _5 = {\n  kernelName: fc,\n  backendName: \"cpu\",\n  kernelFunc: $5\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h, dy: g } = l, { alignCorners: b } = Z;\n  bl([g, h], \"resizeBilinearGrad\");\n  const c = Wl(h.shape), [d, W, Y, V] = h.shape, [, a, i] = g.shape, m = new Float32Array(d * W * Y * V), T = [\n    b && a > 1 ? W - 1 : W,\n    b && i > 1 ? Y - 1 : Y\n  ], s = [\n    b && a > 1 ? a - 1 : a,\n    b && i > 1 ? i - 1 : i\n  ], o = T[0] / s[0], B = T[1] / s[1], C = G.data.get(g.dataId).values;\n  let n = 0;\n  for (let X = 0; X < d; X++) {\n    const t = X * c[0];\n    for (let e = 0; e < a; e++) {\n      const S = e * o, p = Math.floor(S), F = Math.min(Math.ceil(S), W - 1), x = t + p * c[1], H = t + F * c[1], K = S - p, z = 1 - K;\n      for (let k = 0; k < i; k++) {\n        const L = k * B, v = Math.floor(L), w = Math.min(Math.ceil(L), Y - 1), r = L - v, D = 1 - r, f = x + v * c[2], $ = x + w * c[2], q = H + v * c[2], Il = H + w * c[2], _ = z * D, gl = z * r, dl = K * D, il = K * r;\n        for (let al = 0; al < V; al++) {\n          const ol = C[n++];\n          m[f + al] += ol * _, m[$ + al] += ol * gl, m[q + al] += ol * dl, m[Il + al] += ol * il;\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo([d, Y, W, V], \"float32\", m);\n}\nconst Gx = {\n  kernelName: yY,\n  backendName: \"cpu\",\n  kernelFunc: lx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ix(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h } = l, { alignCorners: g, halfPixelCenters: b, size: c } = Z;\n  bl(h, \"resizeNearestNeighbor\");\n  const d = Wl(h.shape), [W, Y] = c, [V, a, i, m] = h.shape, T = G.data.get(h.dataId).values, s = new Float32Array(V * W * Y * m), o = [\n    g && W > 1 ? a - 1 : a,\n    g && Y > 1 ? i - 1 : i\n  ], B = [\n    g && W > 1 ? W - 1 : W,\n    g && Y > 1 ? Y - 1 : Y\n  ], C = o[0] / B[0], n = o[1] / B[1];\n  let X = 0;\n  for (let t = 0; t < V; t++) {\n    const e = t * d[0];\n    for (let S = 0; S < W; S++) {\n      const p = b ? C * (S + 0.5) : C * S;\n      let F = Math.min(a - 1, g ? Math.round(p) : Math.floor(p));\n      b && (F = Math.max(0, F));\n      const x = e + F * d[1];\n      for (let H = 0; H < Y; H++) {\n        const K = b ? n * (H + 0.5) : n * H;\n        let z = Math.min(i - 1, g ? Math.round(K) : Math.floor(K));\n        b && (z = Math.max(0, z));\n        const k = x + z * d[2];\n        for (let L = 0; L < m; L++) {\n          const v = T[k + L];\n          s[X++] = v;\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo([V, W, Y, m], h.dtype, s);\n}\nconst Zx = {\n  kernelName: Dc,\n  backendName: \"cpu\",\n  kernelFunc: Ix\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction hx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h, dy: g } = l, { alignCorners: b } = Z;\n  bl([g, h], \"resizeNearestNeighborGrad\");\n  const c = Wl(h.shape), d = Wl(g.shape), [W, Y, V, a] = h.shape, [, i, m] = g.shape, T = new Float32Array(W * Y * V * a), s = G.data.get(g.dataId).values, o = [\n    b && i > 1 ? Y - 1 : Y,\n    b && m > 1 ? V - 1 : V\n  ], B = [\n    b && i > 1 ? i - 1 : i,\n    b && m > 1 ? m - 1 : m\n  ], C = o[0] / B[0], n = o[1] / B[1], X = 1 / C, t = 1 / n, e = Math.ceil(X) * 2 + 2, S = Math.ceil(t) * 2 + 2;\n  for (let p = 0; p < W; p++) {\n    const F = p * c[0];\n    for (let x = 0; x < Y; x++) {\n      const H = F + x * c[1], K = Math.floor(x * X), z = Math.floor(K - e / 2);\n      for (let k = 0; k < V; k++) {\n        const L = H + k * c[2], v = Math.floor(k * t), w = Math.floor(v - S / 2);\n        for (let r = 0; r < a; r++) {\n          let D = 0;\n          for (let f = 0; f < e; f++) {\n            const $ = f + z;\n            if ($ < 0 || $ >= i)\n              continue;\n            const q = F + $ * d[1], Il = $ * C, _ = Math.min(Y - 1, b ? Math.round(Il) : Math.floor(Il));\n            if (x === _)\n              for (let gl = 0; gl < S; gl++) {\n                const dl = gl + w;\n                if (dl < 0 || dl >= m)\n                  continue;\n                const il = q + dl * d[2], al = dl * n, ol = Math.min(V - 1, b ? Math.round(al) : Math.floor(al));\n                k === ol && (D += s[il + r]);\n              }\n          }\n          T[L + r] = D;\n        }\n      }\n    }\n  }\n  return G.makeTensorInfo(h.shape, h.dtype, T);\n}\nconst gx = {\n  kernelName: FY,\n  backendName: \"cpu\",\n  kernelFunc: hx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction bx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { dims: g } = Z;\n  bl(h, \"reverse\");\n  const b = h.shape.length, c = tl(g, h.shape);\n  if (b === 0)\n    return fI({ inputs: { x: h }, backend: G });\n  const d = new nG(h.shape, h.dtype), W = G.bufferSync(h);\n  for (let Y = 0; Y < d.size; Y++) {\n    const V = d.indexToLoc(Y), a = V.slice();\n    c.forEach((i) => a[i] = h.shape[i] - 1 - a[i]), d.set(W.get(...a), ...V);\n  }\n  return G.makeTensorInfo(d.shape, d.dtype, d.values);\n}\nconst cx = {\n  kernelName: Oc,\n  backendName: \"cpu\",\n  kernelFunc: bx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst dx = {\n  kernelName: HY,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, attrs: l, backend: G }) => {\n    const { image: Z } = I, { radians: h, fillValue: g, center: b } = l, c = G, d = eG(Z.dtype, Q(Z.shape)), [W, Y, V, a] = Z.shape, [i, m] = PV(b, Y, V), T = 255, s = Math.sin(h), o = Math.cos(h), B = c.data.get(Z.dataId).values;\n    for (let n = 0; n < W; n++) {\n      const X = n * V * Y * a;\n      for (let t = 0; t < Y; t++) {\n        const e = t * (V * a);\n        for (let S = 0; S < V; S++) {\n          const p = S * a;\n          for (let F = 0; F < a; F++) {\n            const x = [W, t, S, F], H = x[2], K = x[1];\n            let z = (H - i) * o - (K - m) * s, k = (H - i) * s + (K - m) * o;\n            z = Math.round(z + i), k = Math.round(k + m);\n            let L = g;\n            if (typeof g != \"number\" && (F === 3 ? L = T : L = g[F]), z >= 0 && z < V && k >= 0 && k < Y) {\n              const w = k * (V * a), r = z * a, D = X + w + r + F;\n              L = B[D];\n            }\n            const v = X + e + p + F;\n            d[v] = L;\n          }\n        }\n      }\n    }\n    return { dataId: c.write(d, Z.shape, Z.dtype), shape: Z.shape, dtype: Z.dtype };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Wx = El(Rg, (I) => {\n  const l = Math.floor(I);\n  return I - l < 0.5 ? Math.floor(I) : I - l > 0.5 ? Math.ceil(I) : l % 2 === 0 ? l : l + 1;\n}), Yx = {\n  kernelName: Rg,\n  backendName: \"cpu\",\n  kernelFunc: Wx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Vx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { indices: h, updates: g } = l, { shape: b } = Z, { sliceRank: c, numUpdates: d, sliceSize: W, strides: Y, outputSize: V } = uh(g, h, b), a = !0, i = G.bufferSync(h), m = G.bufferSync(g), T = $Z(i, m, b, V, W, d, c, Y, 0, a);\n  return G.makeTensorInfo(b, T.dtype, T.values);\n}\nconst ax = {\n  kernelName: Ai,\n  backendName: \"cpu\",\n  kernelFunc: Vx\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ix(I, l) {\n  let G = 0, Z = I.length, h = 0;\n  for (; G < Z; )\n    h = Math.floor((G + Z) / 2), I[h] < l ? G = h + 1 : Z = h;\n  return Z;\n}\nfunction mx(I, l) {\n  let G = 0, Z = I.length, h = 0;\n  for (; G < Z; )\n    h = Math.floor((G + Z) / 2), I[h] <= l ? G = h + 1 : Z = h;\n  return Z;\n}\nfunction Tx(I, l, G, Z, h, g) {\n  const b = $l(\"int32\", G * h);\n  for (let c = 0; c < G; ++c) {\n    const d = I.slice(c * Z, (c + 1) * Z), W = c * h;\n    for (let Y = 0; Y < h; ++Y)\n      b[W + Y] = g === \"left\" ? ix(d, l[Y + W]) : mx(d, l[Y + W]);\n  }\n  return b;\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { sortedSequence: h, values: g } = l, { side: b } = Z, c = G.data.get(h.dataId).values, d = G.data.get(g.dataId).values, W = Tx(c, d, h.shape[0], h.shape[1], g.shape[1], b);\n  return G.makeTensorInfo(g.shape, \"int32\", W);\n}\nconst ox = {\n  kernelName: zi,\n  backendName: \"cpu\",\n  kernelFunc: sx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Bx(I) {\n  const { inputs: l, backend: G } = I, { condition: Z, t: h, e: g } = l;\n  bl([Z, h, g], \"select\");\n  const b = Z.shape.length, c = G.data.get(Z.dataId).values, d = G.data.get(h.dataId).values, W = G.data.get(g.dataId).values, Y = DG(h.dtype, g.dtype), V = SG(Q(h.shape), Y);\n  let a = 0;\n  const i = b === 0 || b > 1 || h.shape.length === 1 ? 1 : Q(h.shape.slice(1));\n  for (let m = 0; m < c.length; m++)\n    for (let T = 0; T < i; T++)\n      c[m] === 1 ? V[a++] = d[m] : V[a++] = W[m];\n  return G.makeTensorInfo(h.shape, Y, V);\n}\nconst nx = {\n  kernelName: qc,\n  backendName: \"cpu\",\n  kernelFunc: Bx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Cx = Td, Xx = sd, tx = El(Fg, (I) => I >= 0 ? Xx * I : Cx * (Math.exp(I) - 1)), ux = {\n  kernelName: Fg,\n  backendName: \"cpu\",\n  kernelFunc: tx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ex = El(Pg, (I) => I < 0 ? -1 : I > 0 ? 1 : 0), Sx = {\n  kernelName: Pg,\n  backendName: \"cpu\",\n  kernelFunc: ex\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Rx = El(yg, (I) => Math.sin(I)), px = {\n  kernelName: yg,\n  backendName: \"cpu\",\n  kernelFunc: Rx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Fx = El(Ng, (I) => Math.sinh(I)), yx = {\n  kernelName: Ng,\n  backendName: \"cpu\",\n  kernelFunc: Fx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Nx = 11920928955078125e-23, wa = Math.log(Nx) + 2, Px = El(Eg, (I) => {\n  const l = I > -wa, G = I < wa, Z = Math.exp(I);\n  let h;\n  return G ? h = Z : l ? h = I : h = Math.log(1 + Z), h;\n}), Jx = {\n  kernelName: Eg,\n  backendName: \"cpu\",\n  kernelFunc: Px\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ex(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { blockShape: g, paddings: b } = Z;\n  bl([h], \"spaceToBatchND\");\n  const c = Q(g), d = [[0, 0]];\n  d.push(...b);\n  for (let t = 1 + g.length; t < h.shape.length; ++t)\n    d.push([0, 0]);\n  const W = sB.kernelFunc({\n    inputs: { x: h },\n    backend: G,\n    attrs: { paddings: d, constantValue: 0 }\n  }), Y = Dg(W.shape, g, c, !1), V = fg(Y.length, g.length, !1), a = Og(W.shape, g, c, !1), T = Ll({ inputs: { x: W }, backend: G, attrs: { shape: Y } }), B = MG({ inputs: { x: T }, backend: G, attrs: { perm: V } }), X = Ll({ inputs: { x: B }, backend: G, attrs: { shape: a } });\n  return G.disposeIntermediateTensorInfo(W), G.disposeIntermediateTensorInfo(T), G.disposeIntermediateTensorInfo(B), X;\n}\nconst xx = {\n  kernelName: ld,\n  backendName: \"cpu\",\n  kernelFunc: Ex\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ux(I) {\n  const { inputs: l, backend: G } = I, { indices: Z, values: h, denseShape: g, defaultValue: b } = l;\n  if (g.shape.length !== 1)\n    throw new Error(`Dense shape must be a vector, saw:\n        ${g.shape}`);\n  if (Z.shape.length !== 2)\n    throw new Error(`Indices must be a matrix, saw:\n        ${Z.shape}`);\n  if (h.shape.length !== 1)\n    throw new Error(`Values must be a vector, saw:\n        ${h.shape}`);\n  if (b.shape.length !== 0)\n    throw new Error(`Default value must be a scalar, saw:\n        ${b.shape}`);\n  const c = G.data.get(Z.dataId).values, d = G.data.get(h.dataId).values, W = G.data.get(g.dataId).values, Y = G.data.get(b.dataId).values[0], [V, a, i, m, T] = M2(c, Z.shape, Z.dtype, d, h.dtype, W, Y);\n  return [\n    G.makeTensorInfo(a, Z.dtype, V),\n    G.makeTensorInfo([a[0]], h.dtype, i),\n    G.makeTensorInfo([m.length], \"bool\", new Uint8Array(m.map((s) => Number(s)))),\n    G.makeTensorInfo([T.length], Z.dtype, new Int32Array(T))\n  ];\n}\nconst Hx = {\n  kernelName: Li,\n  backendName: \"cpu\",\n  kernelFunc: Ux\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Kx(I) {\n  const { inputs: l, backend: G } = I, { inputIndices: Z, inputShape: h, newShape: g } = l;\n  if (Z.shape.length !== 2)\n    throw new Error(`Input indices should be a matrix but received shape\n        ${Z.shape}`);\n  if (h.shape.length !== 1)\n    throw new Error(`Input shape should be a vector but received shape\n        ${h.shape}`);\n  if (g.shape.length !== 1)\n    throw new Error(`Target shape should be a vector but received shape ${g.shape}`);\n  const b = Array.from(G.data.get(h.dataId).values), c = G.data.get(Z.dataId).values, d = Array.from(G.data.get(g.dataId).values), [W, Y, V] = w2(c, Z.shape, Z.dtype, b, d);\n  return [\n    G.makeTensorInfo(Y, Z.dtype, W),\n    G.makeTensorInfo([V.length], g.dtype, new Int32Array(V))\n  ];\n}\nconst Ax = {\n  kernelName: Mi,\n  backendName: \"cpu\",\n  kernelFunc: Kx\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kx(I) {\n  const { inputs: l, backend: G } = I, { data: Z, indices: h, segmentIds: g } = l;\n  if (Z.shape.length < 1)\n    throw new Error(\"Data should be at least 1 dimensional but received scalar\");\n  if (h.shape.length !== 1)\n    throw new Error(`Indices should be a vector but received shape\n          ${h.shape}`);\n  if (g.shape.length !== 1)\n    throw new Error(`Segment ids should be a vector but received shape\n          ${g.shape}`);\n  if (h.shape[0] !== g.shape[0])\n    throw new Error(\"segmentIds and indices should have same size.\");\n  const b = G.data.get(Z.dataId).values, c = G.data.get(h.dataId).values, d = G.data.get(g.dataId).values, [W, Y] = C9(b, Z.shape, Z.dtype, c, d, !0);\n  return G.makeTensorInfo(Y, Z.dtype, W);\n}\nconst zx = {\n  kernelName: wi,\n  backendName: \"cpu\",\n  kernelFunc: kx\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Lx(I) {\n  const { inputs: l, backend: G } = I, { data: Z, indices: h, segmentIds: g } = l;\n  if (Z.shape.length < 1)\n    throw new Error(\"Data should be at least 1 dimensional but received scalar\");\n  if (h.shape.length !== 1)\n    throw new Error(`Indices should be a vector but received shape\n         ${h.shape}`);\n  if (g.shape.length !== 1)\n    throw new Error(`Segment ids should be a vector but received shape\n         ${g.shape}`);\n  if (h.shape[0] !== g.shape[0])\n    throw new Error(\"segmentIds and indices should have same size.\");\n  const b = G.data.get(Z.dataId).values, c = G.data.get(h.dataId).values, d = G.data.get(g.dataId).values, [W, Y] = C9(b, Z.shape, Z.dtype, c, d);\n  return G.makeTensorInfo(Y, Z.dtype, W);\n}\nconst Mx = {\n  kernelName: Qi,\n  backendName: \"cpu\",\n  kernelFunc: Lx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { sparseIndices: h, sparseValues: g, defaultValue: b } = l, { outputShape: c } = Z, { sliceRank: d, numUpdates: W, sliceSize: Y, strides: V, outputSize: a } = uh(g, h, c), i = !1, m = G.bufferSync(h);\n  let T;\n  switch (g.dtype) {\n    case \"bool\": {\n      const s = G.bufferSync(g), o = !!G.data.get(b.dataId).values[0];\n      T = $Z(m, s, c, a, Y, W, d, V, o, i);\n      break;\n    }\n    case \"float32\": {\n      const s = G.bufferSync(g), o = G.data.get(b.dataId).values[0];\n      T = $Z(m, s, c, a, Y, W, d, V, o, i);\n      break;\n    }\n    case \"int32\": {\n      const s = G.bufferSync(g), o = G.data.get(b.dataId).values[0];\n      T = $Z(m, s, c, a, Y, W, d, V, o, i);\n      break;\n    }\n    case \"string\": {\n      const s = G.bufferSync(g), o = eZ(G.data.get(b.dataId).values[0]);\n      T = $Z(m, s, c, a, Y, W, d, V, o, i);\n      break;\n    }\n    default:\n      throw new Error(`Unsupported type ${g.dtype}`);\n  }\n  return G.makeTensorInfo(c, T.dtype, T.values);\n}\nconst Qx = {\n  kernelName: vi,\n  backendName: \"cpu\",\n  kernelFunc: wx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vx(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { numOrSizeSplits: g, axis: b } = Z, c = tl(b, h.shape)[0], d = rV(h, g, c), W = new Array(h.shape.length).fill(0), Y = h.shape.slice();\n  return d.map((V) => {\n    const a = [...Y];\n    a[c] = V;\n    const i = Th({ inputs: { x: h }, backend: G, attrs: { begin: W, size: a } });\n    return W[c] += V, i;\n  });\n}\nconst rx = {\n  kernelName: Gd,\n  backendName: \"cpu\",\n  kernelFunc: vx\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst jx = {\n  kernelName: NY,\n  backendName: \"cpu\",\n  kernelFunc: ({ inputs: I, backend: l }) => {\n    const { x: G } = I, Z = l;\n    bl(G, \"square\");\n    const h = Z.data.get(G.dataId).values, g = new Float32Array(h.length);\n    for (let c = 0; c < h.length; ++c) {\n      const d = h[c];\n      g[c] = d * d;\n    }\n    return { dataId: Z.write(g, G.shape, G.dtype), shape: G.shape, dtype: G.dtype };\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Dx = El(zg, (I, l) => {\n  const G = l;\n  return isNaN(I) ? NaN : I > 0 ? 1 : G.alpha;\n}), fx = {\n  kernelName: zg,\n  backendName: \"cpu\",\n  kernelFunc: Dx\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ox(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { begin: g, end: b, strides: c, beginMask: d, endMask: W, ellipsisMask: Y, newAxisMask: V, shrinkAxisMask: a } = Z;\n  bl(h, \"stridedSlice\");\n  const { finalShapeSparse: i, finalShape: m, isIdentity: T, sliceDim0: s, isSimpleSlice: o, begin: B, end: C, strides: n } = FV(h.shape, g, b, c, d, W, Y, V, a);\n  let X;\n  if (T)\n    X = Ll({ inputs: { x: h }, backend: G, attrs: { shape: m } });\n  else if (s || o) {\n    u(h.shape.length >= 1, () => `Input must have rank at least 1, got: ${h.shape.length}`);\n    const t = SV(B, C, n), e = Th({ inputs: { x: h }, backend: G, attrs: { begin: B, size: t } });\n    X = Ll({ inputs: { x: e }, backend: G, attrs: { shape: m } }), G.disposeIntermediateTensorInfo(e);\n  } else {\n    const t = G.bufferSync(h), e = r2(i, t, n, B);\n    X = G.makeTensorInfo(m, e.dtype, e.values);\n  }\n  return X;\n}\nconst qx = {\n  kernelName: JY,\n  backendName: \"cpu\",\n  kernelFunc: Ox\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $x(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { separator: h, nGramWidths: g, leftPad: b, rightPad: c, padWidth: d, preserveShortSequences: W } = Z, { data: Y, dataSplits: V } = l, a = G.data.get(Y.dataId).values, i = G.data.get(V.dataId).values, [m, T] = j2(a, i, h, g, b, c, d, W);\n  return [\n    G.makeTensorInfo([m.length], \"string\", m),\n    G.makeTensorInfo(V.shape, \"int32\", T)\n  ];\n}\nconst _x = {\n  kernelName: ri,\n  backendName: \"cpu\",\n  kernelFunc: $x\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lU(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { skipEmpty: h } = Z, { input: g, delimiter: b } = l;\n  if (g.dtype !== \"string\")\n    throw new Error(\"Input must be of datatype string\");\n  if (g.shape.length !== 1)\n    throw new Error(`Input must be a vector, got shape: ${g.shape}`);\n  if (b.shape.length !== 0)\n    throw new Error(`Delimiter must be a scalar, got shape: ${b.shape}`);\n  const c = G.data.get(g.dataId).values, d = G.data.get(b.dataId).values[0], [W, Y, V] = D2(c, d, h), a = Y.length;\n  return [\n    G.makeTensorInfo([a, 2], \"int32\", W),\n    G.makeTensorInfo([a], \"string\", Y),\n    G.makeTensorInfo([2], \"int32\", new Int32Array(V))\n  ];\n}\nconst GU = {\n  kernelName: ji,\n  backendName: \"cpu\",\n  kernelFunc: lU\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction IU(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { numBuckets: h } = Z, { input: g } = l;\n  if (g.dtype !== \"string\")\n    throw new Error(\"Input must be of datatype string\");\n  if (h <= 0)\n    throw new Error(\"Number of buckets must be at least 1\");\n  const b = G.data.get(g.dataId).values, c = f2(b, h);\n  return G.makeTensorInfo(g.shape, \"int32\", c);\n}\nconst ZU = {\n  kernelName: Di,\n  backendName: \"cpu\",\n  kernelFunc: IU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hU = El(Kg, (I) => Math.tan(I)), gU = {\n  kernelName: Kg,\n  backendName: \"cpu\",\n  kernelFunc: hU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bU = El(Ag, (I) => Math.tanh(I)), cU = {\n  kernelName: Ag,\n  backendName: \"cpu\",\n  kernelFunc: bU\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction dU(I) {\n  const { inputs: l, backend: G } = I, { tensor: Z, indices: h, updates: g } = l, { sliceRank: b, numUpdates: c, sliceSize: d, strides: W, outputSize: Y } = uh(g, h, Z.shape), V = !1, a = G.bufferSync(h), i = G.bufferSync(g), m = G.bufferSync(Z), T = $Z(a, i, Z.shape, Y, d, c, b, W, m, V);\n  return G.makeTensorInfo(Z.shape, T.dtype, T.values);\n}\nconst WU = {\n  kernelName: ki,\n  backendName: \"cpu\",\n  kernelFunc: dU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction YU(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { reps: g } = Z;\n  bl(h, \"tile\");\n  const b = q2(G.bufferSync(h), g);\n  return G.makeTensorInfo(b.shape, b.dtype, b.values);\n}\nconst VU = {\n  kernelName: kg,\n  backendName: \"cpu\",\n  kernelFunc: YU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction aU(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { k: g, sorted: b } = Z;\n  bl(h, \"topk\");\n  const c = G.data.get(h.dataId).values, [d, W] = _2(c, h.shape, h.dtype, g, b);\n  return [\n    G.makeTensorInfo(d.shape, d.dtype, d.values),\n    G.makeTensorInfo(W.shape, W.dtype, W.values)\n  ];\n}\nconst iU = {\n  kernelName: EY,\n  backendName: \"cpu\",\n  kernelFunc: aU\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mU(I) {\n  const { inputs: l, attrs: G, backend: Z } = I, { image: h, transforms: g } = l, { interpolation: b, fillMode: c, fillValue: d, outputShape: W } = G, [Y, V, a, i] = h.shape, [m, T] = W ?? [V, a], s = [Y, m, T, i], o = Wl(h.shape), B = o[0], C = o[1], n = o[2], X = Wl(s), t = X[0], e = X[1], S = X[2], p = eG(h.dtype, Q(s));\n  p.fill(d);\n  const F = Z.data.get(h.dataId).values, x = Z.data.get(g.dataId).values;\n  for (let K = 0; K < Y; ++K) {\n    const z = g.shape[0] === 1 ? x : x.subarray(K * 8, K * 8 + 8);\n    for (let k = 0; k < m; ++k)\n      for (let L = 0; L < T; ++L)\n        for (let v = 0; v < i; ++v) {\n          let w;\n          const r = z[6] * L + z[7] * k + 1;\n          if (r === 0)\n            continue;\n          const D = (z[0] * L + z[1] * k + z[2]) / r, f = (z[3] * L + z[4] * k + z[5]) / r, $ = Qa(D, a, c), q = Qa(f, V, c);\n          switch (b) {\n            case \"nearest\":\n              w = CU(F, V, a, B, C, n, K, q, $, v, d);\n              break;\n            case \"bilinear\":\n              w = XU(F, V, a, B, C, n, K, q, $, v, d);\n              break;\n            default:\n              throw new Error(`Error in Transform: Expect 'nearest' or 'bilinear', but got ${b}`);\n          }\n          const Il = K * t + k * e + L * S + v;\n          p[Il] = w;\n        }\n    return Z.makeTensorInfo(s, h.dtype, p);\n  }\n  return { dataId: Z.write(p, s, h.dtype), shape: h.shape, dtype: h.dtype };\n}\nconst TU = {\n  kernelName: xY,\n  backendName: \"cpu\",\n  kernelFunc: mU\n};\nfunction Qa(I, l, G) {\n  switch (G) {\n    case \"reflect\":\n      return sU(I, l);\n    case \"wrap\":\n      return oU(I, l);\n    case \"nearest\":\n      return nU(I, l);\n    case \"constant\":\n    default:\n      return BU(I);\n  }\n}\nfunction sU(I, l) {\n  let G = I;\n  if (G < 0)\n    if (l <= 1)\n      G = 0;\n    else {\n      const Z = 2 * l;\n      G < Z && (G = Z * Math.trunc(-G / Z) + G), G = G < -l ? G + Z : -G - 1;\n    }\n  else if (G > l - 1)\n    if (l <= 1)\n      G = 0;\n    else {\n      const Z = 2 * l;\n      G -= Z * Math.trunc(G / Z), G >= l && (G = Z - G - 1);\n    }\n  return Zh(0, G, l - 1);\n}\nfunction oU(I, l) {\n  let G = I;\n  if (G < 0)\n    if (l <= 1)\n      G = 0;\n    else {\n      const Z = l - 1;\n      G += l * (Math.trunc(-G / Z) + 1);\n    }\n  else if (G > l - 1)\n    if (l <= 1)\n      G = 0;\n    else {\n      const Z = l - 1;\n      G -= l * Math.trunc(G / Z);\n    }\n  return Zh(0, G, l - 1);\n}\nfunction BU(I, l) {\n  return I;\n}\nfunction nU(I, l) {\n  return Zh(0, I, l - 1);\n}\nfunction p0(I, l, G, Z, h, g, b, c, d, W, Y) {\n  const V = b * Z + c * h + d * g + W;\n  return 0 <= c && c < l && 0 <= d && d < G ? I[V] : Y;\n}\nfunction CU(I, l, G, Z, h, g, b, c, d, W, Y) {\n  const V = Math.round(c), a = Math.round(d);\n  return p0(I, l, G, Z, h, g, b, V, a, W, Y);\n}\nfunction XU(I, l, G, Z, h, g, b, c, d, W, Y) {\n  const V = Math.floor(c), a = Math.floor(d), i = V + 1, m = a + 1, T = (m - d) * p0(I, l, G, Z, h, g, b, V, a, W, Y) + (d - a) * p0(I, l, G, Z, h, g, b, V, m, W, Y), s = (m - d) * p0(I, l, G, Z, h, g, b, i, a, W, Y) + (d - a) * p0(I, l, G, Z, h, g, b, i, m, W, Y);\n  return (i - c) * T + (c - V) * s;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction tU(I) {\n  const { inputs: l, attrs: G, backend: Z } = I, { axis: h } = G, { x: g } = l;\n  bl(g, \"unique\");\n  const b = Z.data.get(g.dataId).values, { outputValues: c, outputShape: d, indices: W } = lB(b, h, g.shape, g.dtype);\n  return [\n    Z.makeTensorInfo(d, g.dtype, c),\n    Z.makeTensorInfo([W.length], \"int32\", W)\n  ];\n}\nconst uU = {\n  kernelName: UY,\n  backendName: \"cpu\",\n  kernelFunc: tU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction eU(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { value: h } = l;\n  let { axis: g } = Z;\n  g < 0 && (g += h.shape.length);\n  const b = h.shape.length, c = h.shape[g], d = new Array(b - 1);\n  let W = 0;\n  for (let i = 0; i < b; i++)\n    i !== g && (d[W++] = h.shape[i]);\n  const Y = new Array(b).fill(0), V = h.shape.slice();\n  V[g] = 1;\n  const a = new Array(c);\n  for (let i = 0; i < a.length; i++) {\n    Y[g] = i;\n    const m = Th({ inputs: { x: h }, backend: G, attrs: { begin: Y, size: V } });\n    a[i] = Ll({ inputs: { x: m }, backend: G, attrs: { shape: d } }), G.disposeIntermediateTensorInfo(m);\n  }\n  return a;\n}\nconst SU = {\n  kernelName: Zd,\n  backendName: \"cpu\",\n  kernelFunc: eU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction RU(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, segmentIds: g } = l, { numSegments: b } = Z;\n  bl(h, \"unsortedSegmentSum\");\n  const c = h.shape.length, d = g.shape.length, W = [], Y = [], V = c - d;\n  let a = g;\n  for (let m = 0; m < V; ++m) {\n    const T = _b({ inputs: { input: a }, backend: G, attrs: { dim: m + 1 } });\n    a = T, Y.push(T);\n  }\n  for (let m = 0; m < b; ++m) {\n    const T = JZ(m, \"int32\"), s = G.makeTensorInfo([], \"int32\", T), o = T2({ inputs: { a: s, b: a }, backend: G }), B = yZ({ inputs: { x: o }, backend: G, attrs: { dtype: \"float32\" } }), C = Fd({ inputs: { a: B, b: h }, backend: G }), n = gb({ inputs: { x: C }, backend: G, attrs: { axis: 0, keepDims: !1 } });\n    W.push(n), Y.push(s), Y.push(o), Y.push(B), Y.push(C), Y.push(n);\n  }\n  const i = TB({ inputs: W, backend: G, attrs: { axis: 0 } });\n  return Y.forEach((m) => G.disposeIntermediateTensorInfo(m)), i;\n}\nconst pU = {\n  kernelName: hd,\n  backendName: \"cpu\",\n  kernelFunc: RU\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst FU = [\n  tP,\n  IN,\n  eP,\n  RP,\n  dN,\n  FP,\n  NP,\n  JP,\n  xP,\n  HP,\n  AP,\n  zP,\n  MP,\n  vP,\n  jP,\n  OP,\n  $P,\n  lJ,\n  IJ,\n  CP,\n  hJ,\n  bJ,\n  dJ,\n  YN,\n  YJ,\n  bN,\n  aN,\n  aJ,\n  ZN,\n  mJ,\n  sJ,\n  oJ,\n  nJ,\n  XJ,\n  uJ,\n  SJ,\n  pJ,\n  yJ,\n  PJ,\n  EJ,\n  UJ,\n  KJ,\n  kJ,\n  LJ,\n  MJ,\n  QJ,\n  rJ,\n  DJ,\n  fJ,\n  OJ,\n  qJ,\n  _J,\n  IE,\n  iP,\n  hE,\n  iN,\n  aE,\n  mN,\n  iE,\n  sN,\n  nE,\n  CE,\n  tE,\n  BN,\n  CN,\n  eE,\n  RE,\n  FE,\n  NE,\n  tN,\n  eN,\n  hN,\n  JE,\n  TJ,\n  xE,\n  HE,\n  AE,\n  mP,\n  RN,\n  FN,\n  zE,\n  NN,\n  ME,\n  vE,\n  jE,\n  OE,\n  $E,\n  l5,\n  G5,\n  JN,\n  Z5,\n  g5,\n  c5,\n  W5,\n  V5,\n  i5,\n  T5,\n  xN,\n  o5,\n  C5,\n  u5,\n  HN,\n  AN,\n  R5,\n  y5,\n  J5,\n  zN,\n  x5,\n  H5,\n  K5,\n  sB,\n  L5,\n  sP,\n  wN,\n  w5,\n  v5,\n  j5,\n  f5,\n  gN,\n  UW,\n  q5,\n  oP,\n  BP,\n  nP,\n  _5,\n  Gx,\n  Zx,\n  gx,\n  cx,\n  dx,\n  Yx,\n  qN,\n  ax,\n  ox,\n  nx,\n  ux,\n  _N,\n  Sx,\n  px,\n  yx,\n  lP,\n  X5,\n  Jx,\n  xx,\n  Hx,\n  Ax,\n  zx,\n  Mx,\n  Qx,\n  rx,\n  ZP,\n  jx,\n  gP,\n  cP,\n  fx,\n  qx,\n  _x,\n  GU,\n  ZU,\n  VP,\n  lE,\n  gU,\n  cU,\n  WU,\n  VU,\n  iU,\n  TU,\n  LN,\n  uU,\n  SU,\n  pU,\n  U5\n];\nfor (const I of FU)\n  Oi(I);\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fZ = {}, Cb = {\n  alpha: !1,\n  antialias: !1,\n  premultipliedAlpha: !1,\n  preserveDrawingBuffer: !1,\n  depth: !1,\n  stencil: !1,\n  failIfMajorPerformanceCaveat: !0\n};\nfunction yU(I, l) {\n  fZ[I] = l;\n}\nfunction NI(I, l) {\n  if (!(I in fZ) || l != null) {\n    const Z = PU(I, l);\n    if (Z !== null)\n      fZ[I] = Z;\n    else\n      return console.log(\"Could not get context for WebGL version\", I), null;\n  }\n  const G = fZ[I];\n  return G == null || G.isContextLost() ? (delete fZ[I], NI(I)) : (G.disable(G.DEPTH_TEST), G.disable(G.STENCIL_TEST), G.disable(G.BLEND), G.disable(G.DITHER), G.disable(G.POLYGON_OFFSET_FILL), G.disable(G.SAMPLE_COVERAGE), G.enable(G.SCISSOR_TEST), G.enable(G.CULL_FACE), G.cullFace(G.BACK), fZ[I]);\n}\nfunction NU(I) {\n  if (!A().getBool(\"IS_SAFARI\") && typeof OffscreenCanvas < \"u\" && I === 2)\n    return new OffscreenCanvas(300, 150);\n  if (typeof document < \"u\")\n    return document.createElement(\"canvas\");\n  throw new Error(\"Cannot create a canvas in this context\");\n}\nfunction PU(I, l) {\n  if (I !== 1 && I !== 2)\n    throw new Error(\"Cannot get WebGL rendering context, WebGL is disabled.\");\n  const G = l ?? NU(I);\n  return G.addEventListener(\"webglcontextlost\", (Z) => {\n    Z.preventDefault(), delete fZ[I];\n  }, !1), A().getBool(\"SOFTWARE_WEBGL_ENABLED\") && (Cb.failIfMajorPerformanceCaveat = !1), I === 1 ? (\n    // tslint:disable-next-line\n    G.getContext(\"webgl\", Cb) || G.getContext(\"experimental-webgl\", Cb)\n  ) : G.getContext(\"webgl2\", Cb);\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nvar z0;\n(function(I) {\n  I[I.DENSE = 0] = \"DENSE\", I[I.SHARED_BATCH = 1] = \"SHARED_BATCH\";\n})(z0 || (z0 = {}));\nvar lI;\n(function(I) {\n  I[I.RENDER = 0] = \"RENDER\", I[I.UPLOAD = 1] = \"UPLOAD\", I[I.PIXELS = 2] = \"PIXELS\", I[I.DOWNLOAD = 3] = \"DOWNLOAD\";\n})(lI || (lI = {}));\nvar BG;\n(function(I) {\n  I[I.UNPACKED_FLOAT16 = 0] = \"UNPACKED_FLOAT16\", I[I.UNPACKED_FLOAT32 = 1] = \"UNPACKED_FLOAT32\", I[I.PACKED_4X1_UNSIGNED_BYTE = 2] = \"PACKED_4X1_UNSIGNED_BYTE\", I[I.PACKED_2X2_FLOAT32 = 3] = \"PACKED_2X2_FLOAT32\", I[I.PACKED_2X2_FLOAT16 = 4] = \"PACKED_2X2_FLOAT16\";\n})(BG || (BG = {}));\nfunction bb(I, l) {\n  return [l, I];\n}\nfunction JU(I, l) {\n  return I * l;\n}\nfunction Xb(I) {\n  const l = Q(I), G = Math.ceil(l / 4);\n  return GW(G);\n}\nfunction W0(I, l) {\n  return [\n    Math.max(1, Math.ceil(l / 2)),\n    Math.max(1, Math.ceil(I / 2))\n  ];\n}\nfunction EU(I, l) {\n  const [G, Z] = W0(I, l);\n  return G * Z * 4;\n}\nfunction S9(I, l) {\n  const G = I;\n  let Z, h, g, b, c, d, W, Y, V, a;\n  return A().getNumber(\"WEBGL_VERSION\") === 2 ? (Z = G.R32F, h = G.R16F, g = G.RGBA16F, b = G.RGBA32F, c = G.RED, W = 4, Y = 1, V = G.HALF_FLOAT, a = G.FLOAT, d = G.RGBA8) : (Z = I.RGBA, h = I.RGBA, g = I.RGBA, b = G.RGBA, c = I.RGBA, W = 4, Y = 4, V = l != null ? l.HALF_FLOAT_OES : null, a = I.FLOAT, d = I.RGBA), {\n    internalFormatFloat: Z,\n    internalFormatHalfFloat: h,\n    internalFormatPackedHalfFloat: g,\n    internalFormatPackedFloat: b,\n    textureFormatFloat: c,\n    downloadTextureFormat: d,\n    downloadUnpackNumChannels: W,\n    defaultNumChannels: Y,\n    textureTypeHalfFloat: V,\n    textureTypeFloat: a\n  };\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Zl(I, l) {\n  const G = l();\n  return A().getBool(\"DEBUG\") && xU(I), G;\n}\nfunction xU(I) {\n  const l = I.getError();\n  if (l !== I.NO_ERROR)\n    throw new Error(\"WebGL Error: \" + AU(I, l));\n}\nconst UU = 596e-10, HU = 65504;\nfunction KU(I) {\n  return !!(A().getBool(\"WEBGL_RENDER_FLOAT32_ENABLED\") || I === 0 || UU < Math.abs(I) && Math.abs(I) < HU);\n}\nfunction AU(I, l) {\n  switch (l) {\n    case I.NO_ERROR:\n      return \"NO_ERROR\";\n    case I.INVALID_ENUM:\n      return \"INVALID_ENUM\";\n    case I.INVALID_VALUE:\n      return \"INVALID_VALUE\";\n    case I.INVALID_OPERATION:\n      return \"INVALID_OPERATION\";\n    case I.INVALID_FRAMEBUFFER_OPERATION:\n      return \"INVALID_FRAMEBUFFER_OPERATION\";\n    case I.OUT_OF_MEMORY:\n      return \"OUT_OF_MEMORY\";\n    case I.CONTEXT_LOST_WEBGL:\n      return \"CONTEXT_LOST_WEBGL\";\n    default:\n      return `Unknown error code ${l}`;\n  }\n}\nfunction tb(I, l) {\n  return VZ(I, () => I.getExtension(l), 'Extension \"' + l + '\" not supported on this browser.');\n}\nfunction kU(I, l) {\n  const G = VZ(I, () => I.createShader(I.VERTEX_SHADER), \"Unable to create vertex WebGLShader.\");\n  if (Zl(I, () => I.shaderSource(G, l)), Zl(I, () => I.compileShader(G)), I.getShaderParameter(G, I.COMPILE_STATUS) === !1)\n    throw console.log(I.getShaderInfoLog(G)), new Error(\"Failed to compile vertex shader.\");\n  return G;\n}\nfunction zU(I, l) {\n  const G = VZ(I, () => I.createShader(I.FRAGMENT_SHADER), \"Unable to create fragment WebGLShader.\");\n  if (Zl(I, () => I.shaderSource(G, l)), Zl(I, () => I.compileShader(G)), A().get(\"ENGINE_COMPILE_ONLY\"))\n    return G;\n  if (I.getShaderParameter(G, I.COMPILE_STATUS) === !1)\n    throw oB(l, I.getShaderInfoLog(G)), new Error(\"Failed to compile fragment shader.\");\n  return G;\n}\nconst LU = /ERROR: [0-9]+:([0-9]+):/g;\nfunction oB(I, l) {\n  const G = LU.exec(l);\n  if (G == null) {\n    console.log(`Couldn't parse line number in error: ${l}`), console.log(I);\n    return;\n  }\n  const Z = +G[1], h = I.split(`\n`), g = h.length.toString().length + 2, b = h.map((V, a) => Kh((a + 1).toString(), g) + V);\n  let c = 0;\n  for (let V = 0; V < b.length; V++)\n    c = Math.max(b[V].length, c);\n  const d = b.slice(0, Z - 1), W = b.slice(Z - 1, Z), Y = b.slice(Z);\n  console.log(d.join(`\n`)), console.log(l.split(`\n`)[0]), console.log(`%c ${Kh(W[0], c)}`, \"border:1px solid red; background-color:#e3d2d2; color:#a61717\"), console.log(Y.join(`\n`));\n}\nfunction MU(I) {\n  return VZ(I, () => I.createProgram(), \"Unable to create WebGLProgram.\");\n}\nfunction wU(I, l) {\n  if (Zl(I, () => I.linkProgram(l)), !A().get(\"ENGINE_COMPILE_ONLY\") && I.getProgramParameter(l, I.LINK_STATUS) === !1)\n    throw console.log(I.getProgramInfoLog(l)), new Error(\"Failed to link vertex and fragment shaders.\");\n}\nfunction fd(I, l) {\n  if (Zl(I, () => I.validateProgram(l)), I.getProgramParameter(l, I.VALIDATE_STATUS) === !1)\n    throw console.log(I.getProgramInfoLog(l)), new Error(\"Shader program validation failed.\");\n}\nfunction QU(I, l) {\n  const G = VZ(I, () => I.createBuffer(), \"Unable to create WebGLBuffer\");\n  return Zl(I, () => I.bindBuffer(I.ARRAY_BUFFER, G)), Zl(I, () => I.bufferData(I.ARRAY_BUFFER, l, I.STATIC_DRAW)), G;\n}\nfunction vU(I, l) {\n  const G = VZ(I, () => I.createBuffer(), \"Unable to create WebGLBuffer\");\n  return Zl(I, () => I.bindBuffer(I.ELEMENT_ARRAY_BUFFER, G)), Zl(I, () => I.bufferData(I.ELEMENT_ARRAY_BUFFER, l, I.STATIC_DRAW)), G;\n}\nfunction rU(I) {\n  return VZ(I, () => I.createTexture(), \"Unable to create WebGLTexture.\");\n}\nfunction jU(I, l) {\n  const G = A().getNumber(\"WEBGL_MAX_TEXTURE_SIZE\");\n  if (I <= 0 || l <= 0) {\n    const Z = `[${I}x${l}]`;\n    throw new Error(\"Requested texture size \" + Z + \" is invalid.\");\n  }\n  if (I > G || l > G) {\n    const Z = `[${I}x${l}]`, h = `[${G}x${G}]`;\n    throw new Error(\"Requested texture size \" + Z + \" greater than WebGL maximum on this browser / GPU \" + h + \".\");\n  }\n}\nfunction DU(I) {\n  return VZ(I, () => I.createFramebuffer(), \"Unable to create WebGLFramebuffer.\");\n}\nfunction va(I, l, G, Z, h, g, b) {\n  const c = I.getAttribLocation(l, G);\n  return c === -1 ? !1 : (Zl(I, () => I.bindBuffer(I.ARRAY_BUFFER, Z)), Zl(I, () => I.vertexAttribPointer(c, h, I.FLOAT, !1, g, b)), Zl(I, () => I.enableVertexAttribArray(c)), !0);\n}\nfunction fU(I, l, G) {\n  lH(I, G), Zl(I, () => I.activeTexture(I.TEXTURE0 + G)), Zl(I, () => I.bindTexture(I.TEXTURE_2D, l));\n}\nfunction OU(I, l, G) {\n  return VZ(I, () => I.getUniformLocation(l, G), 'uniform \"' + G + '\" not present in program.');\n}\nfunction qU(I, l, G) {\n  return I.getUniformLocation(l, G);\n}\nfunction $U(I, l, G, Z) {\n  Zl(I, () => fU(I, l, Z)), Zl(I, () => I.uniform1i(G, Z));\n}\nfunction Od(I, l, G) {\n  Zl(I, () => I.bindFramebuffer(I.FRAMEBUFFER, G)), Zl(I, () => I.framebufferTexture2D(I.FRAMEBUFFER, I.COLOR_ATTACHMENT0, I.TEXTURE_2D, l, 0));\n}\nfunction ra(I, l) {\n  Zl(I, () => I.bindFramebuffer(I.FRAMEBUFFER, l)), Zl(I, () => I.framebufferTexture2D(I.FRAMEBUFFER, I.COLOR_ATTACHMENT0, I.TEXTURE_2D, null, 0));\n}\nfunction ub(I) {\n  const l = I.checkFramebufferStatus(I.FRAMEBUFFER);\n  if (l !== I.FRAMEBUFFER_COMPLETE)\n    throw new Error(\"Error binding framebuffer: \" + _U(I, l));\n}\nfunction _U(I, l) {\n  switch (l) {\n    case I.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n      return \"FRAMEBUFFER_INCOMPLETE_ATTACHMENT\";\n    case I.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n      return \"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\";\n    case I.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n      return \"FRAMEBUFFER_INCOMPLETE_DIMENSIONS\";\n    case I.FRAMEBUFFER_UNSUPPORTED:\n      return \"FRAMEBUFFER_UNSUPPORTED\";\n    default:\n      return `unknown error ${l}`;\n  }\n}\nfunction VZ(I, l, G) {\n  const Z = Zl(I, () => l());\n  if (Z == null)\n    throw new Error(G);\n  return Z;\n}\nfunction lH(I, l) {\n  const G = I.MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1, Z = l + I.TEXTURE0;\n  if (Z < I.TEXTURE0 || Z > G) {\n    const h = `[gl.TEXTURE0, gl.TEXTURE${G}]`;\n    throw new Error(`textureUnit must be in ${h}.`);\n  }\n}\nfunction $h(I, l = 2) {\n  return Q(I.slice(0, I.length - l));\n}\nfunction _h(I) {\n  if (I.length === 0)\n    throw Error(\"Cannot get rows and columns of an empty shape array.\");\n  return [\n    I.length > 1 ? I[I.length - 2] : 1,\n    I[I.length - 1]\n  ];\n}\nfunction eb(I) {\n  let l = [1, 1, 1];\n  return I.length === 0 || I.length === 1 && I[0] === 1 || (l = [$h(I), ..._h(I)]), l;\n}\nfunction GH(I, l = !1) {\n  let G = A().getNumber(\"WEBGL_MAX_TEXTURE_SIZE\"), Z = A().getNumber(\"WEBGL_MAX_SIZE_FOR_NARROW_TEXTURE\");\n  Z === 1 / 0 && A().getBool(\"WEBGL_AUTO_SQUARIFY_NARROW_TEXTURE_SHAPE\") && (Z = G / 2), l && (G = G * 2, Z = Z * 2, I = I.map((c, d) => d >= I.length - 2 ? QW(I[d]) : I[d]), I.length === 1 && (I = [2, I[0]])), I.length !== 2 && (I = PZ(I).newShape);\n  let h = Q(I), g = null;\n  I.length <= 1 && h <= G ? g = [1, h] : I.length === 2 && I[0] <= G && I[1] <= G ? g = I : I.length === 3 && I[0] * I[1] <= G && I[2] <= G ? g = [I[0] * I[1], I[2]] : I.length === 3 && I[0] <= G && I[1] * I[2] <= G ? g = [I[0], I[1] * I[2]] : I.length === 4 && I[0] * I[1] * I[2] <= G && I[3] <= G ? g = [I[0] * I[1] * I[2], I[3]] : I.length === 4 && I[0] <= G && I[1] * I[2] * I[3] <= G && (g = [I[0], I[1] * I[2] * I[3]]);\n  const b = g != null && Math.max(...g) > Z && Math.min(...g) <= (l ? 2 : 1) && Math.min(...g) > 0;\n  if (g == null || b)\n    if (l) {\n      const c = $h(I);\n      let d = 2, W = 2;\n      I.length && ([d, W] = _h(I)), h = c * (d / 2) * (W / 2), g = GW(h).map((Y) => Y * 2);\n    } else\n      g = GW(h);\n  return g;\n}\nfunction Sb(I) {\n  return I % 2 === 0;\n}\nfunction Gc(I, l) {\n  if (I = I.slice(-2), l = l.slice(-2), Nl(I, l) || !I.length || !l.length || I[0] === 0 || I[1] === 0 || l[0] === 0 || l[1] === 0)\n    return !0;\n  if (I.length !== l.length) {\n    const G = I[I.length - 1], Z = l[l.length - 1];\n    if (G === Z || Sb(G) && Sb(Z) && (I[0] === 1 || l[0] === 1))\n      return !0;\n  }\n  return I[1] === l[1] && Sb(I[0]) && Sb(l[0]);\n}\nlet qd, $d;\nfunction IH(I) {\n  if (qd == null) {\n    const l = NI(I);\n    qd = l.getParameter(l.MAX_TEXTURE_SIZE);\n  }\n  return qd;\n}\nfunction ZH(I) {\n  if ($d == null) {\n    const l = NI(I);\n    $d = l.getParameter(l.MAX_TEXTURE_IMAGE_UNITS);\n  }\n  return Math.min(16, $d);\n}\nfunction hH(I) {\n  if (I === 0)\n    return 0;\n  let l;\n  const G = NI(I);\n  return iI(G, \"EXT_disjoint_timer_query_webgl2\") && I === 2 ? l = 2 : iI(G, \"EXT_disjoint_timer_query\") ? l = 1 : l = 0, l;\n}\nfunction iI(I, l) {\n  return I.getExtension(l) != null;\n}\nfunction ja(I) {\n  try {\n    if (NI(I) != null)\n      return !0;\n  } catch (l) {\n    return console.log(\"Error when getting WebGL context: \", l), !1;\n  }\n  return !1;\n}\nfunction gH(I) {\n  if (I === 0)\n    return !1;\n  const l = NI(I);\n  if (I === 1) {\n    if (!iI(l, \"OES_texture_float\"))\n      return !1;\n  } else if (!iI(l, \"EXT_color_buffer_float\"))\n    return !1;\n  return KW(l);\n}\nfunction bH(I) {\n  if (I === 0)\n    return !1;\n  const l = NI(I);\n  if (I === 1) {\n    if (!iI(l, \"OES_texture_float\") || !iI(l, \"WEBGL_color_buffer_float\"))\n      return !1;\n  } else {\n    if (iI(l, \"EXT_color_buffer_float\"))\n      return KW(l);\n    const Z = \"EXT_color_buffer_half_float\";\n    if (iI(l, Z)) {\n      const h = l.getExtension(Z);\n      return cH(l, h);\n    }\n    return !1;\n  }\n  return KW(l);\n}\nfunction KW(I) {\n  const l = S9(I), G = I.createTexture();\n  I.bindTexture(I.TEXTURE_2D, G), I.texImage2D(I.TEXTURE_2D, 0, l.internalFormatFloat, 1, 1, 0, l.textureFormatFloat, l.textureTypeFloat, null);\n  const g = I.createFramebuffer();\n  I.bindFramebuffer(I.FRAMEBUFFER, g), I.framebufferTexture2D(I.FRAMEBUFFER, I.COLOR_ATTACHMENT0, I.TEXTURE_2D, G, 0);\n  const b = I.checkFramebufferStatus(I.FRAMEBUFFER) === I.FRAMEBUFFER_COMPLETE;\n  return I.bindTexture(I.TEXTURE_2D, null), I.bindFramebuffer(I.FRAMEBUFFER, null), I.deleteTexture(G), I.deleteFramebuffer(g), b;\n}\nfunction cH(I, l) {\n  const G = S9(I, l), Z = I.createTexture();\n  I.bindTexture(I.TEXTURE_2D, Z), I.texImage2D(I.TEXTURE_2D, 0, G.internalFormatHalfFloat, 1, 1, 0, G.textureFormatFloat, G.textureTypeHalfFloat, null);\n  const b = I.createFramebuffer();\n  I.bindFramebuffer(I.FRAMEBUFFER, b), I.framebufferTexture2D(I.FRAMEBUFFER, I.COLOR_ATTACHMENT0, I.TEXTURE_2D, Z, 0);\n  const c = I.checkFramebufferStatus(I.FRAMEBUFFER) === I.FRAMEBUFFER_COMPLETE;\n  return I.bindTexture(I.TEXTURE_2D, null), I.bindFramebuffer(I.FRAMEBUFFER, null), I.deleteTexture(Z), I.deleteFramebuffer(b), c;\n}\nfunction dH(I) {\n  return I !== 2 ? !1 : NI(I).fenceSync != null;\n}\nfunction cb(I, l) {\n  Array.isArray(I) || (I = [I]), I.forEach((G) => {\n    G != null && u(G.dtype !== \"complex64\", () => `${l} does not support complex64 tensors in the WebGL backend.`);\n  });\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst cl = A();\ncl.registerFlag(\"HAS_WEBGL\", () => cl.getNumber(\"WEBGL_VERSION\") > 0);\ncl.registerFlag(\"WEBGL_VERSION\", () => ja(2) ? 2 : ja(1) ? 1 : 0);\ncl.registerFlag(\"WEBGL_CHECK_NUMERICAL_PROBLEMS\", () => !1);\ncl.registerFlag(\"WEBGL_BUFFER_SUPPORTED\", () => cl.get(\"WEBGL_VERSION\") === 2);\ncl.registerFlag(\"WEBGL_CPU_FORWARD\", () => !0);\ncl.registerFlag(\"WEBGL_FORCE_F16_TEXTURES\", () => !1);\ncl.registerFlag(\"WEBGL_PACK\", () => cl.getBool(\"HAS_WEBGL\"));\ncl.registerFlag(\"WEBGL_PACK_NORMALIZATION\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_CLIP\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_DEPTHWISECONV\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_BINARY_OPERATIONS\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_UNARY_OPERATIONS\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_ARRAY_OPERATIONS\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_IMAGE_OPERATIONS\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_REDUCE\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_LAZILY_UNPACK\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_CONV_IM2COL\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_PACK_CONV2DTRANSPOSE\", () => cl.getBool(\"WEBGL_PACK\"));\ncl.registerFlag(\"WEBGL_MAX_TEXTURE_SIZE\", () => IH(cl.getNumber(\"WEBGL_VERSION\")));\ncl.registerFlag(\"WEBGL_MAX_TEXTURES_IN_SHADER\", () => ZH(cl.getNumber(\"WEBGL_VERSION\")));\ncl.registerFlag(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\", () => {\n  const I = cl.getNumber(\"WEBGL_VERSION\");\n  return I === 0 ? 0 : hH(I);\n});\ncl.registerFlag(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE\", () => cl.getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\") > 0 && !im());\ncl.registerFlag(\"WEBGL_RENDER_FLOAT32_CAPABLE\", () => gH(cl.getNumber(\"WEBGL_VERSION\")));\ncl.registerFlag(\"WEBGL_RENDER_FLOAT32_ENABLED\", () => cl.getBool(\"WEBGL_FORCE_F16_TEXTURES\") ? !1 : cl.getBool(\"WEBGL_RENDER_FLOAT32_CAPABLE\"));\ncl.registerFlag(\"WEBGL_DOWNLOAD_FLOAT_ENABLED\", () => bH(cl.getNumber(\"WEBGL_VERSION\")));\ncl.registerFlag(\"WEBGL_FENCE_API_ENABLED\", () => dH(cl.getNumber(\"WEBGL_VERSION\")));\ncl.registerFlag(\"WEBGL_SIZE_UPLOAD_UNIFORM\", () => cl.getBool(\"WEBGL_RENDER_FLOAT32_ENABLED\") ? 4 : 0);\ncl.registerFlag(\"WEBGL_DELETE_TEXTURE_THRESHOLD\", () => -1, (I) => {\n  if (typeof I != \"number\")\n    throw new Error(`WEBGL_DELETE_TEXTURE_THRESHOLD must be a number but got ${I}.`);\n  if (I < 0 && I !== -1)\n    throw new Error(`WEBGL_DELETE_TEXTURE_THRESHOLD must be -1 (indicating never delete) or at least 0, but got ${I}.`);\n});\ncl.registerFlag(\"WEBGL_FLUSH_THRESHOLD\", () => im() ? 1 : -1, (I) => {\n  if (typeof I != \"number\")\n    throw new Error(`WEBGL_FLUSH_THRESHOLD must be a number but got ${I}.`);\n  if (I < 0 && I !== -1)\n    throw new Error(`WEBGL_FLUSH_THRESHOLD must be -1 (indicating never manual flush) or at least 0, but got ${I}.`);\n});\ncl.registerFlag(\"CPU_HANDOFF_SIZE_THRESHOLD\", () => 128);\ncl.registerFlag(\"WEBGL_USE_SHAPES_UNIFORMS\", () => !1);\ncl.registerFlag(\"TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD\", () => 1e5);\ncl.registerFlag(\"TOPK_K_CPU_HANDOFF_THRESHOLD\", () => 128);\ncl.registerFlag(\"WEBGL_EXP_CONV\", () => !1);\ncl.registerFlag(\"SOFTWARE_WEBGL_ENABLED\", () => cl.getBool(\"IS_TEST\"));\ncl.registerFlag(\"WEBGL_MAX_SIZE_FOR_NARROW_TEXTURE\", () => 1 / 0);\ncl.registerFlag(\"WEBGL_AUTO_SQUARIFY_NARROW_TEXTURE_SHAPE\", () => !1);\ncl.registerFlag(\"WEBGL2_ISNAN_CUSTOM\", () => !1);\ncl.registerFlag(\"ENGINE_COMPILE_ONLY\", () => !1);\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction KG() {\n  let I, l, G, Z, h, g, b, c, d, W;\n  return A().getNumber(\"WEBGL_VERSION\") === 2 ? (I = \"#version 300 es\", l = \"in\", G = \"out\", Z = \"in\", h = \"texture\", g = \"outputColor\", b = \"out vec4 outputColor;\", c = A().getBool(\"WEBGL2_ISNAN_CUSTOM\") ? `\n      bool isnan_custom(float val) {\n        uint floatToUint = floatBitsToUint(val);\n        return (floatToUint & 0x7fffffffu) > 0x7f800000u;\n      }\n\n      bvec4 isnan_custom(vec4 val) {\n        return bvec4(isnan_custom(val.x),\n          isnan_custom(val.y), isnan_custom(val.z), isnan_custom(val.w));\n      }\n\n      #define isnan(value) isnan_custom(value)\n    ` : \"\", d = \"\", W = `\n      #define round(value) newRound(value)\n      int newRound(float value) {\n        return int(floor(value + 0.5));\n      }\n\n      ivec4 newRound(vec4 value) {\n        return ivec4(floor(value + vec4(0.5)));\n      }\n    `) : (I = \"\", l = \"attribute\", G = \"varying\", Z = \"varying\", h = \"texture2D\", g = \"gl_FragColor\", b = \"\", c = `\n      #define isnan(value) isnan_custom(value)\n      bool isnan_custom(float val) {\n        return (val > 0. || val < 1. || val == 0.) ? false : true;\n      }\n      bvec4 isnan_custom(vec4 val) {\n        return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w));\n      }\n    `, d = `\n      uniform float INFINITY;\n\n      bool isinf(float val) {\n        return abs(val) == INFINITY;\n      }\n      bvec4 isinf(vec4 val) {\n        return equal(abs(val), vec4(INFINITY));\n      }\n    `, W = `\n      int round(float value) {\n        return int(floor(value + 0.5));\n      }\n\n      ivec4 round(vec4 value) {\n        return ivec4(floor(value + vec4(0.5)));\n      }\n    `), {\n    version: I,\n    attribute: l,\n    varyingVs: G,\n    varyingFs: Z,\n    texture2D: h,\n    output: g,\n    defineOutput: b,\n    defineSpecialNaN: c,\n    defineSpecialInf: d,\n    defineRound: W\n  };\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Rh(I, l, G = \"index\") {\n  const Z = Wl(l);\n  return Z.map((h, g) => {\n    const b = `int ${I[g]} = ${G} / ${h}`, c = g === Z.length - 1 ? `int ${I[g + 1]} = ${G} - ${I[g]} * ${h}` : `index -= ${I[g]} * ${h}`;\n    return `${b}; ${c};`;\n  }).join(\"\");\n}\nfunction yd(I, l, G = \"index\") {\n  const Z = Wl(l);\n  return Z.map((h, g) => {\n    const b = `int ${I[g]} = ${G} / outShapeStrides[${g}]`, c = g === Z.length - 1 ? `int ${I[g + 1]} = ${G} - ${I[g]} * outShapeStrides[${g}]` : `index -= ${I[g]} * outShapeStrides[${g}]`;\n    return `${b}; ${c};`;\n  }).join(\"\");\n}\nfunction WH(I, l) {\n  const G = I.length, Z = I.map((g) => `${l}[${g}]`), h = new Array(G - 1);\n  h[G - 2] = Z[G - 1];\n  for (let g = G - 3; g >= 0; --g)\n    h[g] = `(${h[g + 1]} * ${Z[g + 1]})`;\n  return h;\n}\nfunction YH(I, l, G = \"index\") {\n  const Z = I.map((g, b) => b), h = WH(Z, l);\n  return h.map((g, b) => {\n    const c = `int ${I[b]} = ${G} / ${h[b]}`, d = b === h.length - 1 ? `int ${I[b + 1]} = ${G} - ${I[b]} * ${h[b]}` : `index -= ${I[b]} * ${h[b]}`;\n    return `${c}; ${d};`;\n  }).join(\"\");\n}\nfunction R9(I) {\n  const l = Wl(I).map((G) => G.toString());\n  return `\n  int getFlatIndex(ivec3 coords) {\n    return coords.x * ${l[0]} + coords.y * ${l[1]} + coords.z;\n  }\n`;\n}\nfunction p9() {\n  return `\n  int getFlatIndex(ivec3 coords) {\n    return coords.x * outShapeStrides[0] + coords.y * outShapeStrides[1] + coords.z;\n  }\n`;\n}\nconst BB = `\n  const float FLOAT_MAX = 1.70141184e38;\n  const float FLOAT_MIN = 1.17549435e-38;\n\n  lowp vec4 encode_float(highp float v) {\n    if (isnan(v)) {\n      return vec4(255, 255, 255, 255);\n    }\n\n    highp float av = abs(v);\n\n    if(av < FLOAT_MIN) {\n      return vec4(0.0, 0.0, 0.0, 0.0);\n    } else if(v > FLOAT_MAX) {\n      return vec4(0.0, 0.0, 128.0, 127.0) / 255.0;\n    } else if(v < -FLOAT_MAX) {\n      return vec4(0.0, 0.0,  128.0, 255.0) / 255.0;\n    }\n\n    highp vec4 c = vec4(0,0,0,0);\n\n    highp float e = floor(log2(av));\n    highp float m = exp2(fract(log2(av))) - 1.0;\n\n    c[2] = floor(128.0 * m);\n    m -= c[2] / 128.0;\n    c[1] = floor(32768.0 * m);\n    m -= c[1] / 32768.0;\n    c[0] = floor(8388608.0 * m);\n\n    highp float ebias = e + 127.0;\n    c[3] = floor(ebias / 2.0);\n    ebias -= c[3] * 2.0;\n    c[2] += floor(ebias) * 128.0;\n\n    c[3] += 128.0 * step(0.0, -v);\n\n    return c / 255.0;\n  }\n`;\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst { getBroadcastDims: nB } = lR;\nfunction VH(I, l, G) {\n  const Z = [];\n  if (I.forEach((i) => {\n    const m = Q(i.shapeInfo.logicalShape);\n    if (i.shapeInfo.isUniform ? Z.push(`uniform float ${i.name}${m > 1 ? `[${m}]` : \"\"};`) : (Z.push(`uniform sampler2D ${i.name};`), Z.push(`uniform int offset${i.name};`)), G.enableShapeUniforms) {\n      const { uniformShape: T } = F9(G.packedInputs, i.shapeInfo.logicalShape, i.shapeInfo.texShape);\n      switch (T.length) {\n        case 1:\n          Z.push(`uniform int ${i.name}Shape;`);\n          break;\n        case 2:\n          Z.push(`uniform ivec2 ${i.name}Shape;`);\n          break;\n        case 3:\n          Z.push(`uniform ivec3 ${i.name}Shape;`);\n          break;\n        case 4:\n          Z.push(`uniform ivec4 ${i.name}Shape;`);\n          break;\n      }\n      Z.push(`uniform ivec2 ${i.name}TexShape;`);\n    }\n  }), G.enableShapeUniforms) {\n    switch (l.logicalShape.length) {\n      case 1:\n        Z.push(\"uniform int outShape;\");\n        break;\n      case 2:\n        Z.push(\"uniform ivec2 outShape;\"), Z.push(\"uniform int outShapeStrides;\");\n        break;\n      case 3:\n        Z.push(\"uniform ivec3 outShape;\"), Z.push(\"uniform ivec2 outShapeStrides;\");\n        break;\n      case 4:\n        Z.push(\"uniform ivec4 outShape;\"), Z.push(\"uniform ivec3 outShapeStrides;\");\n        break;\n    }\n    Z.push(\"uniform ivec2 outTexShape;\");\n  }\n  G.customUniforms && G.customUniforms.forEach((i) => {\n    Z.push(`uniform ${i.type} ${i.name}${i.arrayIndex ? `[${i.arrayIndex}]` : \"\"};`);\n  });\n  const h = Z.join(`\n`), g = I.map((i) => aH(i, l, G.packedInputs, G.enableShapeUniforms)).join(`\n`), b = l.texShape, c = KG(), d = TH(c);\n  let W, Y, V = BH(c);\n  return l.isPacked ? (W = iH(l.logicalShape, b, G.enableShapeUniforms), Y = oH(c)) : (W = mH(l.logicalShape, b, G.enableShapeUniforms), Y = sH(c)), G.packedInputs && (V += tH), [\n    V,\n    d,\n    Y,\n    h,\n    W,\n    g,\n    G.userCode\n  ].join(`\n`);\n}\nfunction Y0(I, l = !1) {\n  const G = I.shapeInfo.logicalShape;\n  switch (G.length) {\n    case 0:\n      return xH(I, l);\n    case 1:\n      return HH(I, l);\n    case 2:\n      return AH(I, l);\n    case 3:\n      return zH(I, l);\n    case 4:\n      return MH(I, l);\n    case 5:\n      return wH(I);\n    case 6:\n      return QH(I);\n    default:\n      throw new Error(`${G.length}-D input sampling is not yet supported`);\n  }\n}\nfunction CB(I, l) {\n  switch (I.shapeInfo.logicalShape.length) {\n    case 0:\n      return EH(I);\n    case 1:\n      return UH(I, l);\n    case 2:\n      return KH(I, l);\n    case 3:\n      return kH(I, l);\n    default:\n      return LH(I, l);\n  }\n}\nfunction aH(I, l, G = !1, Z) {\n  let h = \"\";\n  G ? h += CB(I, Z) : h += Y0(I, Z);\n  const g = I.shapeInfo.logicalShape, b = l.logicalShape;\n  return g.length <= b.length && (G ? h += vH(I, l) : h += rH(I, l)), h;\n}\nfunction iH(I, l, G) {\n  switch (I.length) {\n    case 0:\n      return XB();\n    case 1:\n      return uH(I, l, G);\n    case 2:\n      return PH(I, l, G);\n    case 3:\n      return SH(I, l, G);\n    default:\n      return pH(I, l, G);\n  }\n}\nfunction mH(I, l, G) {\n  switch (I.length) {\n    case 0:\n      return XB();\n    case 1:\n      return eH(I, l, G);\n    case 2:\n      return JH(I, l, G);\n    case 3:\n      return RH(I, l, G);\n    case 4:\n      return FH(I, l, G);\n    case 5:\n      return yH(I, l);\n    case 6:\n      return NH(I, l);\n    default:\n      throw new Error(`${I.length}-D output sampling is not yet supported`);\n  }\n}\nfunction TH(I) {\n  return `\n    float sampleTexture(sampler2D textureSampler, vec2 uv) {\n      return ${I.texture2D}(textureSampler, uv).r;\n    }\n  `;\n}\nfunction sH(I) {\n  return `\n    void setOutput(float val) {\n      ${I.output} = vec4(val, 0, 0, 0);\n    }\n  `;\n}\nfunction oH(I) {\n  return `\n    void setOutput(vec4 val) {\n      ${I.output} = val;\n    }\n  `;\n}\nfunction BH(I) {\n  return `${I.version}\n    precision highp float;\n    precision highp int;\n    precision highp sampler2D;\n    ${I.varyingFs} vec2 resultUV;\n    ${I.defineOutput}\n    const vec2 halfCR = vec2(0.5, 0.5);\n\n    struct ivec5\n    {\n      int x;\n      int y;\n      int z;\n      int w;\n      int u;\n    };\n\n    struct ivec6\n    {\n      int x;\n      int y;\n      int z;\n      int w;\n      int u;\n      int v;\n    };\n\n    uniform float NAN;\n    ${I.defineSpecialNaN}\n    ${I.defineSpecialInf}\n    ${I.defineRound}\n\n    int imod(int x, int y) {\n      return x - y * (x / y);\n    }\n\n    int idiv(int a, int b, float sign) {\n      int res = a / b;\n      int mod = imod(a, b);\n      if (sign < 0. && mod != 0) {\n        res -= 1;\n      }\n      return res;\n    }\n\n    //Based on the work of Dave Hoskins\n    //https://www.shadertoy.com/view/4djSRW\n    #define HASHSCALE1 443.8975\n    float random(float seed){\n      vec2 p = resultUV * seed;\n      vec3 p3  = fract(vec3(p.xyx) * HASHSCALE1);\n      p3 += dot(p3, p3.yzx + 19.19);\n      return fract((p3.x + p3.y) * p3.z);\n    }\n\n    ${nH}\n    ${CH}\n    ${XH}\n  `;\n}\nconst nH = `\nvec2 uvFromFlat(int texNumR, int texNumC, int index) {\n  int texR = index / texNumC;\n  int texC = index - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\nvec2 packedUVfrom1D(int texNumR, int texNumC, int index) {\n  int texelIndex = index / 2;\n  int texR = texelIndex / texNumC;\n  int texC = texelIndex - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n`, CH = `\nvec2 packedUVfrom2D(int texelsInLogicalRow, int texNumR,\n  int texNumC, int row, int col) {\n  int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2);\n  int texR = texelIndex / texNumC;\n  int texC = texelIndex - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n`, XH = `\nvec2 packedUVfrom3D(int texNumR, int texNumC,\n    int texelsInBatch, int texelsInLogicalRow, int b,\n    int row, int col) {\n  int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2);\n  int texR = index / texNumC;\n  int texC = index - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n`, tH = `\n  float getChannel(vec4 frag, vec2 innerDims) {\n    vec2 modCoord = mod(innerDims, 2.);\n    return modCoord.x == 0. ?\n      (modCoord.y == 0. ? frag.r : frag.g) :\n      (modCoord.y == 0. ? frag.b : frag.a);\n  }\n  float getChannel(vec4 frag, int dim) {\n    float modCoord = mod(float(dim), 2.);\n    return modCoord == 0. ? frag.r : frag.g;\n  }\n`;\nfunction XB() {\n  return `\n    int getOutputCoords() {\n      return 0;\n    }\n  `;\n}\nfunction uH(I, l, G) {\n  const Z = [Math.ceil(l[0] / 2), Math.ceil(l[1] / 2)];\n  return Z[0] === 1 ? G ? `\n      int getOutputCoords() {\n        return 2 * int(resultUV.x * ceil(float(outTexShape[1]) / 2.0));\n      }\n    ` : `\n      int getOutputCoords() {\n        return 2 * int(resultUV.x * ${Z[1]}.0);\n      }\n    ` : Z[1] === 1 ? G ? `\n      int getOutputCoords() {\n        return 2 * int(resultUV.y * ceil(float(outTexShape[0]) / 2.0));\n      }\n    ` : `\n      int getOutputCoords() {\n        return 2 * int(resultUV.y * ${Z[0]}.0);\n      }\n    ` : G ? `\n    int getOutputCoords() {\n      ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(packedTexShape[0], packedTexShape[1]));\n      return 2 * (resTexRC.x * packedTexShape[1] + resTexRC.y);\n    }\n  ` : `\n    int getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${Z[0]}, ${Z[1]}));\n      return 2 * (resTexRC.x * ${Z[1]} + resTexRC.y);\n    }\n  `;\n}\nfunction eH(I, l, G) {\n  return l[0] === 1 ? G ? `\n      int getOutputCoords() {\n        return int(resultUV.x * float(outTexShape[1]));\n      }\n    ` : `\n      int getOutputCoords() {\n        return int(resultUV.x * ${l[1]}.0);\n      }\n    ` : l[1] === 1 ? G ? `\n      int getOutputCoords() {\n        return int(resultUV.y * float(outTexShape[0]));\n      }\n    ` : `\n      int getOutputCoords() {\n        return int(resultUV.y * ${l[0]}.0);\n      }\n    ` : G ? `\n    int getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(outTexShape[0], outTexShape[1]));\n      return resTexRC.x * outTexShape[1] + resTexRC.y;\n    }\n  ` : `\n    int getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${l[0]}, ${l[1]}));\n      return resTexRC.x * ${l[1]} + resTexRC.y;\n    }\n  `;\n}\nfunction SH(I, l, G) {\n  if (G)\n    return `\n    ivec3 getOutputCoords() {\n      ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n      int texelsInLogicalRow = int(ceil(float(outShape[2]) / 2.0));\n      int texelsInBatch = texelsInLogicalRow * int(ceil(float(outShape[1]) / 2.0));\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(packedTexShape[0], packedTexShape[1]));\n      int index = resTexRC.x * packedTexShape[1] + resTexRC.y;\n\n      int b = index / texelsInBatch;\n      index -= b * texelsInBatch;\n\n      int r = 2 * (index / texelsInLogicalRow);\n      int c = imod(index, texelsInLogicalRow) * 2;\n\n      return ivec3(b, r, c);\n    }\n  `;\n  const Z = [Math.ceil(l[0] / 2), Math.ceil(l[1] / 2)], h = Math.ceil(I[2] / 2), g = h * Math.ceil(I[1] / 2);\n  return `\n    ivec3 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${Z[0]}, ${Z[1]}));\n      int index = resTexRC.x * ${Z[1]} + resTexRC.y;\n\n      int b = index / ${g};\n      index -= b * ${g};\n\n      int r = 2 * (index / ${h});\n      int c = imod(index, ${h}) * 2;\n\n      return ivec3(b, r, c);\n    }\n  `;\n}\nfunction RH(I, l, G) {\n  if (G)\n    return `\n  ivec3 getOutputCoords() {\n    ivec2 resTexRC = ivec2(resultUV.yx *\n                           vec2(outTexShape[0], outTexShape[1]));\n    int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n    ${yd([\"r\", \"c\", \"d\"], I)}\n    return ivec3(r, c, d);\n  }\n`;\n  const Z = Rh([\"r\", \"c\", \"d\"], I);\n  return `\n    ivec3 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${l[0]}, ${l[1]}));\n      int index = resTexRC.x * ${l[1]} + resTexRC.y;\n      ${Z}\n      return ivec3(r, c, d);\n    }\n  `;\n}\nfunction pH(I, l, G) {\n  if (G)\n    return `\n    ivec4 getOutputCoords() {\n      ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(packedTexShape[0], packedTexShape[1]));\n      int index = resTexRC.x * packedTexShape[1] + resTexRC.y;\n\n      int texelsInLogicalRow = int(ceil(float(outShape[3]) / 2.0));\n      int texelsInBatch = texelsInLogicalRow * int(ceil(float(outShape[2]) / 2.0));\n      int texelsInBatchN = texelsInBatch * outShape[1];\n\n      int b2 = index / texelsInBatchN;\n      index -= b2 * texelsInBatchN;\n\n      int b = index / texelsInBatch;\n      index -= b * texelsInBatch;\n\n      int r = 2 * (index / texelsInLogicalRow);\n      int c = imod(index, texelsInLogicalRow) * 2;\n\n      return ivec4(b2, b, r, c);\n    }\n  `;\n  const Z = [Math.ceil(l[0] / 2), Math.ceil(l[1] / 2)], h = Math.ceil(I[I.length - 1] / 2), g = h * Math.ceil(I[I.length - 2] / 2);\n  let b = g, c = \"\", d = \"b, r, c\";\n  for (let W = 2; W < I.length - 1; W++)\n    b *= I[I.length - W - 1], c = `\n      int b${W} = index / ${b};\n      index -= b${W} * ${b};\n    ` + c, d = `b${W}, ` + d;\n  return `\n    ivec${I.length} getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${Z[0]}, ${Z[1]}));\n      int index = resTexRC.x * ${Z[1]} + resTexRC.y;\n\n      ${c}\n\n      int b = index / ${g};\n      index -= b * ${g};\n\n      int r = 2 * (index / ${h});\n      int c = imod(index, ${h}) * 2;\n\n      return ivec${I.length}(${d});\n    }\n  `;\n}\nfunction FH(I, l, G) {\n  if (G)\n    return `\n    ivec4 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n        vec2(outTexShape[0], outTexShape[1]));\n      int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n      ${yd([\"r\", \"c\", \"d\", \"d2\"], I)}\n      return ivec4(r, c, d, d2);\n    }\n  `;\n  const Z = Rh([\"r\", \"c\", \"d\", \"d2\"], I);\n  return `\n    ivec4 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n        vec2(${l[0]}, ${l[1]}));\n      int index = resTexRC.x * ${l[1]} + resTexRC.y;\n      ${Z}\n      return ivec4(r, c, d, d2);\n    }\n  `;\n}\nfunction yH(I, l) {\n  const G = Rh([\"r\", \"c\", \"d\", \"d2\", \"d3\"], I);\n  return `\n    ivec5 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx * vec2(${l[0]},\n                             ${l[1]}));\n\n      int index = resTexRC.x * ${l[1]} + resTexRC.y;\n\n      ${G}\n\n      ivec5 outShape = ivec5(r, c, d, d2, d3);\n      return outShape;\n    }\n  `;\n}\nfunction NH(I, l) {\n  const G = Rh([\"r\", \"c\", \"d\", \"d2\", \"d3\", \"d4\"], I);\n  return `\n    ivec6 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n        vec2(${l[0]}, ${l[1]}));\n      int index = resTexRC.x * ${l[1]} + resTexRC.y;\n\n      ${G}\n\n      ivec6 result = ivec6(r, c, d, d2, d3, d4);\n      return result;\n    }\n  `;\n}\nfunction PH(I, l, G) {\n  const Z = [Math.ceil(l[0] / 2), Math.ceil(l[1] / 2)];\n  if (Nl(I, l))\n    return G ? `\n      ivec2 getOutputCoords() {\n        ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n        return 2 * ivec2(resultUV.yx * vec2(packedTexShape[0], packedTexShape[1]));\n      }\n    ` : `\n      ivec2 getOutputCoords() {\n        return 2 * ivec2(resultUV.yx * vec2(${Z[0]}, ${Z[1]}));\n      }\n    `;\n  const h = Math.ceil(I[1] / 2);\n  return G ? `\n    ivec2 getOutputCoords() {\n      ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n      int texelsInLogicalRow = int(ceil(float(outShape[1]) / 2.0));\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(packedTexShape[0], packedTexShape[1]));\n\n      int index = resTexRC.x * packedTexShape[1] + resTexRC.y;\n      int r = 2 * (index / texelsInLogicalRow);\n      int c = imod(index, texelsInLogicalRow) * 2;\n\n      return ivec2(r, c);\n    }\n  ` : `\n    ivec2 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${Z[0]}, ${Z[1]}));\n\n      int index = resTexRC.x * ${Z[1]} + resTexRC.y;\n      int r = 2 * (index / ${h});\n      int c = imod(index, ${h}) * 2;\n\n      return ivec2(r, c);\n    }\n  `;\n}\nfunction JH(I, l, G) {\n  return Nl(I, l) ? G ? `\n      ivec2 getOutputCoords() {\n        return ivec2(resultUV.yx * vec2(outTexShape[0], outTexShape[1]));\n      }\n    ` : `\n      ivec2 getOutputCoords() {\n        return ivec2(resultUV.yx * vec2(${l[0]}, ${l[1]}));\n      }\n    ` : I[1] === 1 ? G ? `\n      ivec2 getOutputCoords() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n                               vec2(outTexShape[0], outTexShape[1]));\n        int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n        return ivec2(index, 0);\n      }\n    ` : `\n      ivec2 getOutputCoords() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n                               vec2(${l[0]}, ${l[1]}));\n        int index = resTexRC.x * ${l[1]} + resTexRC.y;\n        return ivec2(index, 0);\n      }\n    ` : I[0] === 1 ? G ? `\n      ivec2 getOutputCoords() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n                               vec2(outTexShape[0], outTexShape[1]));\n        int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n        return ivec2(0, index);\n      }\n    ` : `\n      ivec2 getOutputCoords() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n                               vec2(${l[0]}, ${l[1]}));\n        int index = resTexRC.x * ${l[1]} + resTexRC.y;\n        return ivec2(0, index);\n      }\n    ` : G ? `\n    ivec2 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(outTexShape[0], outTexShape[1]));\n      int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n      int r = index / outShape[1];\n      int c = index - r * outShape[1];\n      return ivec2(r, c);\n    }\n  ` : `\n    ivec2 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${l[0]}, ${l[1]}));\n      int index = resTexRC.x * ${l[1]} + resTexRC.y;\n      int r = index / ${I[1]};\n      int c = index - r * ${I[1]};\n      return ivec2(r, c);\n    }\n  `;\n}\nfunction ph(I) {\n  return `offset${I}`;\n}\nfunction EH(I) {\n  const l = I.name, G = \"get\" + l.charAt(0).toUpperCase() + l.slice(1), Z = KG();\n  return `\n    vec4 ${G}() {\n      return ${Z.texture2D}(${l}, halfCR);\n    }\n  `;\n}\nfunction xH(I, l) {\n  const G = I.name, Z = \"get\" + G.charAt(0).toUpperCase() + G.slice(1);\n  if (I.shapeInfo.isUniform)\n    return `float ${Z}() {return ${G};}`;\n  const [h, g] = I.shapeInfo.texShape;\n  if (h === 1 && g === 1)\n    return `\n      float ${Z}() {\n        return sampleTexture(${G}, halfCR);\n      }\n    `;\n  const b = ph(G);\n  if (l)\n    return `\n    float ${Z}() {\n      vec2 uv = uvFromFlat(${G}TexShape[0], ${G}TexShape[1], ${b});\n      return sampleTexture(${G}, uv);\n    }\n  `;\n  const [c, d] = I.shapeInfo.texShape;\n  return `\n    float ${Z}() {\n      vec2 uv = uvFromFlat(${c}, ${d}, ${b});\n      return sampleTexture(${G}, uv);\n    }\n  `;\n}\nfunction UH(I, l) {\n  const G = I.name, Z = \"get\" + G.charAt(0).toUpperCase() + G.slice(1), h = I.shapeInfo.texShape, g = KG();\n  if (l)\n    return `\n    vec4 ${Z}(int index) {\n      ivec2 packedTexShape = ivec2(ceil(float(${G}TexShape[0]) / 2.0), ceil(float(${G}TexShape[1]) / 2.0));\n      vec2 uv = packedUVfrom1D(\n        packedTexShape[0], packedTexShape[1], index);\n      return ${g.texture2D}(${G}, uv);\n    }\n  `;\n  const b = [Math.ceil(h[0] / 2), Math.ceil(h[1] / 2)];\n  return `\n    vec4 ${Z}(int index) {\n      vec2 uv = packedUVfrom1D(\n        ${b[0]}, ${b[1]}, index);\n      return ${g.texture2D}(${G}, uv);\n    }\n  `;\n}\nfunction HH(I, l) {\n  const G = I.name, Z = \"get\" + G.charAt(0).toUpperCase() + G.slice(1);\n  if (I.shapeInfo.isUniform)\n    return `\n      float ${Z}(int index) {\n        ${V0(I)}\n      }\n    `;\n  const h = I.shapeInfo.texShape, g = h[0], b = h[1];\n  if (b === 1 && g === 1)\n    return `\n      float ${Z}(int index) {\n        return sampleTexture(${G}, halfCR);\n      }\n    `;\n  const c = ph(G);\n  return b === 1 ? l ? `\n      float ${Z}(int index) {\n        vec2 uv = vec2(0.5, (float(index + ${c}) + 0.5) / float(${G}TexShape[0]));\n        return sampleTexture(${G}, uv);\n      }\n    ` : `\n      float ${Z}(int index) {\n        vec2 uv = vec2(0.5, (float(index + ${c}) + 0.5) / ${g}.0);\n        return sampleTexture(${G}, uv);\n      }\n    ` : g === 1 ? l ? `\n      float ${Z}(int index) {\n        vec2 uv = vec2((float(index + ${c}) + 0.5) / float(${G}TexShape[1]), 0.5);\n        return sampleTexture(${G}, uv);\n      }\n    ` : `\n      float ${Z}(int index) {\n        vec2 uv = vec2((float(index + ${c}) + 0.5) / ${b}.0, 0.5);\n        return sampleTexture(${G}, uv);\n      }\n    ` : l ? `\n    float ${Z}(int index) {\n      vec2 uv = uvFromFlat(${G}TexShape[0], ${G}TexShape[1], index + ${c});\n      return sampleTexture(${G}, uv);\n    }\n  ` : `\n    float ${Z}(int index) {\n      vec2 uv = uvFromFlat(${g}, ${b}, index + ${c});\n      return sampleTexture(${G}, uv);\n    }\n  `;\n}\nfunction KH(I, l) {\n  const G = I.shapeInfo.logicalShape, Z = I.name, h = \"get\" + Z.charAt(0).toUpperCase() + Z.slice(1), g = I.shapeInfo.texShape, b = g[0], c = g[1], d = KG();\n  if (g != null && Nl(G, g))\n    return l ? `\n      vec4 ${h}(int row, int col) {\n        vec2 uv = (vec2(col, row) + halfCR) / vec2(${Z}TexShape[1], ${Z}TexShape[0]);\n\n        return ${d.texture2D}(${Z}, uv);\n      }\n    ` : `\n      vec4 ${h}(int row, int col) {\n        vec2 uv = (vec2(col, row) + halfCR) / vec2(${c}.0, ${b}.0);\n\n        return ${d.texture2D}(${Z}, uv);\n      }\n    `;\n  if (l)\n    return `\n    vec4 ${h}(int row, int col) {\n      ivec2 packedTexShape = ivec2(ceil(float(${Z}TexShape[0]) / 2.0), ceil(float(${Z}TexShape[1]) / 2.0));\n      int valuesPerRow = int(ceil(float(${Z}Shape[1]) / 2.0));\n      vec2 uv = packedUVfrom2D(valuesPerRow, packedTexShape[0], packedTexShape[1], row, col);\n      return ${d.texture2D}(${Z}, uv);\n    }\n  `;\n  const W = [Math.ceil(g[0] / 2), Math.ceil(g[1] / 2)], Y = Math.ceil(G[1] / 2);\n  return `\n    vec4 ${h}(int row, int col) {\n      vec2 uv = packedUVfrom2D(${Y}, ${W[0]}, ${W[1]}, row, col);\n      return ${d.texture2D}(${Z}, uv);\n    }\n  `;\n}\nfunction AH(I, l) {\n  const G = I.shapeInfo.logicalShape, Z = I.name, h = \"get\" + Z.charAt(0).toUpperCase() + Z.slice(1), g = I.shapeInfo.texShape;\n  if (g != null && Nl(G, g)) {\n    if (l)\n      return `\n      float ${h}(int row, int col) {\n        vec2 uv = (vec2(col, row) + halfCR) / vec2(${Z}TexShape[1], ${Z}TexShape[0]);\n        return sampleTexture(${Z}, uv);\n      }\n    `;\n    const a = g[0], i = g[1];\n    return `\n    float ${h}(int row, int col) {\n      vec2 uv = (vec2(col, row) + halfCR) / vec2(${i}.0, ${a}.0);\n      return sampleTexture(${Z}, uv);\n    }\n  `;\n  }\n  const { newShape: b, keptDims: c } = PZ(G), d = b;\n  if (d.length < G.length) {\n    const a = a0(I, d), i = [\"row\", \"col\"];\n    return `\n      ${Y0(a, l)}\n      float ${h}(int row, int col) {\n        return ${h}(${i0(i, c)});\n      }\n    `;\n  }\n  if (I.shapeInfo.isUniform)\n    return `\n      float ${h}(int row, int col) {\n        int index = round(dot(vec2(row, col), vec2(${G[1]}, 1)));\n        ${V0(I)}\n      }\n    `;\n  const W = g[0], Y = g[1], V = ph(Z);\n  return Y === 1 ? l ? `\n      float ${h}(int row, int col) {\n        float index = dot(vec3(row, col, ${V}), vec3(${Z}Shape[1], 1, 1));\n        vec2 uv = vec2(0.5, (index + 0.5) / float(${Z}TexShape[0]));\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n    float ${h}(int row, int col) {\n      float index = dot(vec3(row, col, ${V}), vec3(${G[1]}, 1, 1));\n      vec2 uv = vec2(0.5, (index + 0.5) / ${W}.0);\n      return sampleTexture(${Z}, uv);\n    }\n  ` : W === 1 ? l ? `\n      float ${h}(int row, int col) {\n        float index = dot(vec3(row, col, ${V}), vec3(${Z}Shape[1], 1, 1));\n        vec2 uv = vec2((index + 0.5) / float(${Z}TexShape[1]), 0.5);\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n    float ${h}(int row, int col) {\n      float index = dot(vec3(row, col, ${V}), vec3(${G[1]}, 1, 1));\n      vec2 uv = vec2((index + 0.5) / ${Y}.0, 0.5);\n      return sampleTexture(${Z}, uv);\n    }\n  ` : l ? `\n      float ${h}(int row, int col) {\n        // Explicitly use integer operations as dot() only works on floats.\n        int index = row * ${Z}Shape[1] + col + ${V};\n        vec2 uv = uvFromFlat(${Z}TexShape[0], ${Z}TexShape[1], index);\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n  float ${h}(int row, int col) {\n    // Explicitly use integer operations as dot() only works on floats.\n    int index = row * ${G[1]} + col + ${V};\n    vec2 uv = uvFromFlat(${W}, ${Y}, index);\n    return sampleTexture(${Z}, uv);\n  }\n`;\n}\nfunction kH(I, l) {\n  const G = I.shapeInfo.logicalShape, Z = I.name, h = \"get\" + Z.charAt(0).toUpperCase() + Z.slice(1), g = I.shapeInfo.texShape, b = [Math.ceil(g[0] / 2), Math.ceil(g[1] / 2)];\n  if (G[0] === 1) {\n    const a = G.slice(1), i = [1, 2], m = a0(I, a), T = [\"b\", \"row\", \"col\"];\n    return `\n        ${CB(m, l)}\n        vec4 ${h}(int b, int row, int col) {\n          return ${h}(${i0(T, i)});\n        }\n      `;\n  }\n  const c = KG();\n  if (l)\n    return `\n    vec4 ${h}(int b, int row, int col) {\n      ivec2 packedTexShape = ivec2(ceil(float(${Z}TexShape[0]) / 2.0), ceil(float(${Z}TexShape[1]) / 2.0));\n      int valuesPerRow = int(ceil(float(${Z}Shape[2]) / 2.0));\n      int texelsInBatch = valuesPerRow * int(ceil(float(${Z}Shape[1]) / 2.0));\n      vec2 uv = packedUVfrom3D(\n        packedTexShape[0], packedTexShape[1], texelsInBatch, valuesPerRow, b, row, col);\n      return ${c.texture2D}(${Z}, uv);\n    }\n  `;\n  const d = b[0], W = b[1], Y = Math.ceil(G[2] / 2), V = Y * Math.ceil(G[1] / 2);\n  return `\n    vec4 ${h}(int b, int row, int col) {\n      vec2 uv = packedUVfrom3D(\n        ${d}, ${W}, ${V}, ${Y}, b, row, col);\n      return ${c.texture2D}(${Z}, uv);\n    }\n  `;\n}\nfunction zH(I, l) {\n  const G = I.shapeInfo.logicalShape, Z = I.name, h = \"get\" + Z.charAt(0).toUpperCase() + Z.slice(1), g = G[1] * G[2], b = G[2], { newShape: c, keptDims: d } = PZ(G), W = c;\n  if (W.length < G.length) {\n    const T = a0(I, W), s = [\"row\", \"col\", \"depth\"];\n    return `\n        ${Y0(T, l)}\n        float ${h}(int row, int col, int depth) {\n          return ${h}(${i0(s, d)});\n        }\n      `;\n  }\n  if (I.shapeInfo.isUniform)\n    return `\n      float ${h}(int row, int col, int depth) {\n        int index = round(dot(vec3(row, col, depth),\n                          vec3(${g}, ${b}, 1)));\n        ${V0(I)}\n      }\n    `;\n  const Y = I.shapeInfo.texShape, V = Y[0], a = Y[1], i = I.shapeInfo.flatOffset;\n  if (a === g && i == null)\n    return l ? `\n      float ${h}(int row, int col, int depth) {\n        int stride1 = ${Z}Shape[2];\n        float texR = float(row);\n        float texC = dot(vec2(col, depth), vec2(stride1, 1));\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${Z}TexShape[1], ${Z}TexShape[0]);\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n        float ${h}(int row, int col, int depth) {\n          float texR = float(row);\n          float texC = dot(vec2(col, depth), vec2(${b}, 1));\n          vec2 uv = (vec2(texC, texR) + halfCR) /\n                     vec2(${a}.0, ${V}.0);\n          return sampleTexture(${Z}, uv);\n        }\n      `;\n  if (a === b && i == null)\n    return l ? `\n      float ${h}(int row, int col, int depth) {\n        float texR = dot(vec2(row, col), vec2(${Z}Shape[1], 1));\n        float texC = float(depth);\n        vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${Z}TexShape[1], ${Z}TexShape[0]);\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n    float ${h}(int row, int col, int depth) {\n      float texR = dot(vec2(row, col), vec2(${G[1]}, 1));\n      float texC = float(depth);\n      vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${a}.0, ${V}.0);\n      return sampleTexture(${Z}, uv);\n    }\n  `;\n  const m = ph(Z);\n  return l ? `\n    float ${h}(int row, int col, int depth) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int stride0 = ${Z}Shape[1] * ${Z}Shape[2];\n      int stride1 = ${Z}Shape[2];\n      int index = row * stride0 + col * stride1 + depth + ${m};\n      vec2 uv = uvFromFlat(${Z}TexShape[0], ${Z}TexShape[1], index);\n      return sampleTexture(${Z}, uv);\n    }\n    ` : `\n      float ${h}(int row, int col, int depth) {\n        // Explicitly use integer operations as dot() only works on floats.\n        int index = row * ${g} + col * ${b} + depth + ${m};\n        vec2 uv = uvFromFlat(${V}, ${a}, index);\n        return sampleTexture(${Z}, uv);\n      }\n  `;\n}\nfunction LH(I, l) {\n  const G = I.name, Z = \"get\" + G.charAt(0).toUpperCase() + G.slice(1), h = KG();\n  if (l)\n    return `\n    vec4 ${Z}(int b2, int b, int row, int col) {\n      int valuesPerRow = int(ceil(float(${G}Shape[3]) / 2.0));\n      int texelsInBatch = valuesPerRow * int(ceil(float(${G}Shape[2]) / 2.0));\n      int index = b * texelsInBatch + (row / 2) * valuesPerRow + (col / 2);\n      texelsInBatch *= ${G}Shape[1];\n      index = b2 * texelsInBatch + index;\n      ivec2 packedTexShape = ivec2(ceil(float(${G}TexShape[0]) / 2.0), ceil(float(${G}TexShape[1]) / 2.0));\n      int texR = index / packedTexShape[1];\n      int texC = index - texR * packedTexShape[1];\n      vec2 uv = (vec2(texC, texR) + halfCR) / vec2(packedTexShape[1], packedTexShape[0]); return ${h.texture2D}(${G}, uv);\n    }\n  `;\n  const g = I.shapeInfo.logicalShape, b = g.length, c = I.shapeInfo.texShape, d = [Math.ceil(c[0] / 2), Math.ceil(c[1] / 2)], W = d[0], Y = d[1], V = Math.ceil(g[b - 1] / 2);\n  let a = V * Math.ceil(g[b - 2] / 2), i = \"int b, int row, int col\", m = `b * ${a} + (row / 2) * ${V} + (col / 2)`;\n  for (let T = 2; T < b - 1; T++)\n    i = `int b${T}, ` + i, a *= g[b - T - 1], m = `b${T} * ${a} + ` + m;\n  return `\n    vec4 ${Z}(${i}) {\n      int index = ${m};\n      int texR = index / ${Y};\n      int texC = index - texR * ${Y};\n      vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${Y}, ${W});\n      return ${h.texture2D}(${G}, uv);\n    }\n  `;\n}\nfunction MH(I, l) {\n  const G = I.shapeInfo.logicalShape, Z = I.name, h = \"get\" + Z.charAt(0).toUpperCase() + Z.slice(1), g = G[3], b = G[2] * g, c = G[1] * b, { newShape: d, keptDims: W } = PZ(G);\n  if (d.length < G.length) {\n    const B = a0(I, d), C = [\"row\", \"col\", \"depth\", \"depth2\"];\n    return `\n      ${Y0(B, l)}\n      float ${h}(int row, int col, int depth, int depth2) {\n        return ${h}(${i0(C, W)});\n      }\n    `;\n  }\n  if (I.shapeInfo.isUniform)\n    return `\n      float ${h}(int row, int col, int depth, int depth2) {\n        int index = round(dot(vec4(row, col, depth, depth2),\n                          vec4(${c}, ${b}, ${g}, 1)));\n        ${V0(I)}\n      }\n    `;\n  const Y = I.shapeInfo.flatOffset, V = I.shapeInfo.texShape, a = V[0], i = V[1], m = `int stride2 = ${Z}Shape[3];`, T = `int stride1 = ${Z}Shape[2] * stride2;`, s = `int stride0 = ${Z}Shape[1] * stride1;`;\n  if (i === c && Y == null)\n    return l ? `\n      float ${h}(int row, int col, int depth, int depth2) {\n        ${m}\n        ${T}\n        float texR = float(row);\n        float texC =\n            dot(vec3(col, depth, depth2),\n                vec3(stride1, stride2, 1));\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${Z}TexShape[1], ${Z}TexShape[0]);\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n      float ${h}(int row, int col, int depth, int depth2) {\n        float texR = float(row);\n        float texC =\n            dot(vec3(col, depth, depth2),\n                vec3(${b}, ${g}, 1));\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${i}.0, ${a}.0);\n        return sampleTexture(${Z}, uv);\n      }\n    `;\n  if (i === g && Y == null)\n    return l ? `\n      float ${h}(int row, int col, int depth, int depth2) {\n        float texR = dot(vec3(row, col, depth),\n                         vec3(${Z}Shape[1] * ${Z}Shape[2], ${Z}Shape[2], 1));\n        float texC = float(depth2);\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${Z}TexShape[1], ${Z}TexShape[0]);\n        return sampleTexture(${Z}, uv);\n      }\n    ` : `\n      float ${h}(int row, int col, int depth, int depth2) {\n        float texR = dot(vec3(row, col, depth),\n                         vec3(${G[1] * G[2]}, ${G[2]}, 1));\n        float texC = float(depth2);\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${i}.0, ${a}.0);\n        return sampleTexture(${Z}, uv);\n      }\n    `;\n  const o = ph(Z);\n  return l ? `\n    float ${h}(int row, int col, int depth, int depth2) {\n      // Explicitly use integer operations as dot() only works on floats.\n      ${m}\n      ${T}\n      ${s}\n      int index = row * stride0 + col * stride1 +\n          depth * stride2 + depth2;\n      vec2 uv = uvFromFlat(${Z}TexShape[0], ${Z}TexShape[1], index + ${o});\n      return sampleTexture(${Z}, uv);\n    }\n  ` : `\n    float ${h}(int row, int col, int depth, int depth2) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int index = row * ${c} + col * ${b} +\n          depth * ${g} + depth2;\n      vec2 uv = uvFromFlat(${a}, ${i}, index + ${o});\n      return sampleTexture(${Z}, uv);\n    }\n  `;\n}\nfunction wH(I) {\n  const l = I.shapeInfo.logicalShape, G = I.name, Z = \"get\" + G.charAt(0).toUpperCase() + G.slice(1), h = l[4], g = l[3] * h, b = l[2] * g, c = l[1] * b, { newShape: d, keptDims: W } = PZ(l);\n  if (d.length < l.length) {\n    const T = a0(I, d), s = [\"row\", \"col\", \"depth\", \"depth2\", \"depth3\"];\n    return `\n      ${Y0(T)}\n      float ${Z}(int row, int col, int depth, int depth2, int depth3) {\n        return ${Z}(${i0(s, W)});\n      }\n    `;\n  }\n  if (I.shapeInfo.isUniform)\n    return `\n      float ${Z}(int row, int col, int depth, int depth2, int depth3) {\n        float index = dot(\n          vec4(row, col, depth, depth2),\n          vec4(${c}, ${b}, ${g}, ${h})) +\n          depth3;\n        ${V0(I)}\n      }\n    `;\n  const Y = I.shapeInfo.flatOffset, V = I.shapeInfo.texShape, a = V[0], i = V[1];\n  if (i === c && Y == null)\n    return `\n      float ${Z}(int row, int col, int depth, int depth2, int depth3) {\n        int texR = row;\n        float texC = dot(vec4(col, depth, depth2, depth3),\n                         vec4(${b}, ${g}, ${h}, 1));\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${i}.0, ${a}.0);\n        return sampleTexture(${G}, uv);\n      }\n    `;\n  if (i === h && Y == null)\n    return `\n      float ${Z}(int row, int col, int depth, int depth2, int depth3) {\n        float texR = dot(\n          vec4(row, col, depth, depth2),\n          vec4(${l[1] * l[2] * l[3]},\n               ${l[2] * l[3]}, ${l[3]}, 1));\n        int texC = depth3;\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${i}.0, ${a}.0);\n        return sampleTexture(${G}, uv);\n      }\n    `;\n  const m = ph(G);\n  return `\n    float ${Z}(int row, int col, int depth, int depth2, int depth3) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int index = row * ${c} + col * ${b} + depth * ${g} +\n          depth2 * ${h} + depth3 + ${m};\n      vec2 uv = uvFromFlat(${a}, ${i}, index);\n      return sampleTexture(${G}, uv);\n    }\n  `;\n}\nfunction QH(I) {\n  const l = I.shapeInfo.logicalShape, G = I.name, Z = \"get\" + G.charAt(0).toUpperCase() + G.slice(1), { newShape: h, keptDims: g } = PZ(l);\n  if (h.length < l.length) {\n    const s = a0(I, h), o = [\"row\", \"col\", \"depth\", \"depth2\", \"depth3\", \"depth4\"];\n    return `\n      ${Y0(s)}\n      float ${Z}(int row, int col, int depth,\n                    int depth2, int depth3, int depth4) {\n        return ${Z}(${i0(o, g)});\n      }\n    `;\n  }\n  const b = l[5], c = l[4] * b, d = l[3] * c, W = l[2] * d, Y = l[1] * W;\n  if (I.shapeInfo.isUniform)\n    return `\n      float ${Z}(int row, int col, int depth,\n                  int depth2, int depth3, int depth4) {\n        int index = round(dot(\n          vec4(row, col, depth, depth2),\n          vec4(${Y}, ${W}, ${d}, ${c})) +\n          dot(\n            vec2(depth3, depth4),\n            vec2(${b}, 1)));\n        ${V0(I)}\n      }\n    `;\n  const V = I.shapeInfo.flatOffset, a = I.shapeInfo.texShape, i = a[0], m = a[1];\n  if (m === Y && V == null)\n    return `\n      float ${Z}(int row, int col, int depth,\n                    int depth2, int depth3, int depth4) {\n        int texR = row;\n        float texC = dot(vec4(col, depth, depth2, depth3),\n          vec4(${W}, ${d}, ${c}, ${b})) +\n               float(depth4);\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${m}.0, ${i}.0);\n        return sampleTexture(${G}, uv);\n      }\n    `;\n  if (m === b && V == null)\n    return `\n      float ${Z}(int row, int col, int depth,\n                    int depth2, int depth3, int depth4) {\n        float texR = dot(vec4(row, col, depth, depth2),\n          vec4(${l[1] * l[2] * l[3] * l[4]},\n               ${l[2] * l[3] * l[4]},\n               ${l[3] * l[4]},\n               ${l[4]})) + float(depth3);\n        int texC = depth4;\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${m}.0, ${i}.0);\n        return sampleTexture(${G}, uv);\n      }\n    `;\n  const T = ph(G);\n  return `\n    float ${Z}(int row, int col, int depth,\n                  int depth2, int depth3, int depth4) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int index = row * ${Y} + col * ${W} + depth * ${d} +\n          depth2 * ${c} + depth3 * ${b} + depth4 + ${T};\n      vec2 uv = uvFromFlat(${i}, ${m}, index);\n      return sampleTexture(${G}, uv);\n    }\n  `;\n}\nfunction V0(I) {\n  const l = I.name, G = Q(I.shapeInfo.logicalShape);\n  return G < 2 ? `return ${l};` : `\n    for (int i = 0; i < ${G}; i++) {\n      if (i == index) {\n        return ${l}[i];\n      }\n    }\n  `;\n}\nfunction vH(I, l) {\n  const G = I.name, Z = G.charAt(0).toUpperCase() + G.slice(1), h = \"get\" + Z + \"AtOutCoords\", g = I.shapeInfo.logicalShape.length, b = l.logicalShape.length, c = nB(I.shapeInfo.logicalShape, l.logicalShape), d = Ul(b), W = b - g;\n  let Y;\n  const V = [\"x\", \"y\", \"z\", \"w\", \"u\", \"v\"];\n  g === 0 ? Y = \"\" : b < 2 && c.length >= 1 ? Y = \"coords = 0;\" : Y = c.map((B) => `coords.${V[B + W]} = 0;`).join(`\n`);\n  let a = \"\";\n  b < 2 && g > 0 ? a = \"coords\" : a = I.shapeInfo.logicalShape.map((B, C) => `coords.${V[C + W]}`).join(\", \");\n  let i = \"return outputValue;\";\n  const T = Q(I.shapeInfo.logicalShape) === 1, o = Q(l.logicalShape) === 1;\n  if (g === 1 && !T && !o)\n    i = `\n      return vec4(outputValue.xy, outputValue.xy);\n    `;\n  else if (T && !o)\n    b === 1 ? i = `\n        return vec4(outputValue.x, outputValue.x, 0., 0.);\n      ` : i = `\n        return vec4(outputValue.x);\n      `;\n  else if (c.length) {\n    const B = g - 2, C = g - 1;\n    c.indexOf(B) > -1 && c.indexOf(C) > -1 ? i = \"return vec4(outputValue.x);\" : c.indexOf(B) > -1 ? i = \"return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);\" : c.indexOf(C) > -1 && (i = \"return vec4(outputValue.xx, outputValue.zz);\");\n  }\n  return `\n    vec4 ${h}() {\n      ${d} coords = getOutputCoords();\n      ${Y}\n      vec4 outputValue = get${Z}(${a});\n      ${i}\n    }\n  `;\n}\nfunction rH(I, l) {\n  const G = I.name, Z = G.charAt(0).toUpperCase() + G.slice(1), h = \"get\" + Z + \"AtOutCoords\", g = l.texShape, b = I.shapeInfo.texShape, c = I.shapeInfo.logicalShape.length, d = l.logicalShape.length;\n  if (!I.shapeInfo.isUniform && c === d && I.shapeInfo.flatOffset == null && Nl(b, g))\n    return `\n      float ${h}() {\n        return sampleTexture(${G}, resultUV);\n      }\n    `;\n  const W = Ul(d), Y = nB(I.shapeInfo.logicalShape, l.logicalShape), V = d - c;\n  let a;\n  const i = [\"x\", \"y\", \"z\", \"w\", \"u\", \"v\"];\n  c === 0 ? a = \"\" : d < 2 && Y.length >= 1 ? a = \"coords = 0;\" : a = Y.map((T) => `coords.${i[T + V]} = 0;`).join(`\n`);\n  let m = \"\";\n  return d < 2 && c > 0 ? m = \"coords\" : m = I.shapeInfo.logicalShape.map((T, s) => `coords.${i[s + V]}`).join(\", \"), `\n    float ${h}() {\n      ${W} coords = getOutputCoords();\n      ${a}\n      return get${Z}(${m});\n    }\n  `;\n}\nfunction Ul(I) {\n  if (I <= 1)\n    return \"int\";\n  if (I === 2)\n    return \"ivec2\";\n  if (I === 3)\n    return \"ivec3\";\n  if (I === 4)\n    return \"ivec4\";\n  if (I === 5)\n    return \"ivec5\";\n  if (I === 6)\n    return \"ivec6\";\n  throw Error(`GPU for rank ${I} is not yet supported`);\n}\nfunction F9(I, l, G) {\n  const { newShape: Z, keptDims: h } = PZ(l), g = l.length, b = I && g === 3 && l[0] === 1, c = b ? l.slice(1) : Z, d = !I && g > 1 && !Nl(l, G) && Z.length < g || b;\n  return { useSqueezeShape: d, uniformShape: d ? c : l, keptDims: h };\n}\nfunction a0(I, l) {\n  const G = JSON.parse(JSON.stringify(I));\n  return G.shapeInfo.logicalShape = l, G;\n}\nfunction i0(I, l) {\n  return l.map((G) => I[G]).join(\", \");\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jH(I, l, G, Z) {\n  const h = G.map((Y, V) => {\n    const a = {\n      logicalShape: Y.shape,\n      texShape: Y.isUniform ? null : Y.texData.texShape,\n      isUniform: Y.isUniform,\n      isPacked: Y.isUniform ? !1 : Y.texData.isPacked,\n      flatOffset: null\n    };\n    return Y.texData != null && Y.texData.slice != null && Y.texData.slice.flatOffset > 0 && (a.flatOffset = Y.texData.slice.flatOffset), { name: l.variableNames[V], shapeInfo: a };\n  }), g = h.map((Y) => Y.shapeInfo), b = {\n    logicalShape: Z.shape,\n    texShape: Z.texData.texShape,\n    isUniform: !1,\n    isPacked: Z.texData.isPacked,\n    flatOffset: null\n  }, c = VH(h, b, l), d = zU(I.gl, c), W = I.createProgram(d);\n  return A().get(\"ENGINE_COMPILE_ONLY\") ? {\n    program: l,\n    fragmentShader: d,\n    source: c,\n    webGLProgram: W,\n    inShapeInfos: g,\n    outShapeInfo: b,\n    variablesLocations: null,\n    customUniformLocations: null,\n    infLoc: null,\n    nanLoc: null,\n    outShapeLocation: null,\n    outShapeStridesLocation: null,\n    outTexShapeLocation: null\n  } : (I.buildVao(W), Object.assign({\n    program: l,\n    fragmentShader: d,\n    source: c,\n    webGLProgram: W,\n    inShapeInfos: g,\n    outShapeInfo: b\n  }, tB(I, l, W)));\n}\nfunction tB(I, l, G) {\n  const Z = [], h = [];\n  let g, b, c, d = null, W = null;\n  W = I.getUniformLocation(G, \"NAN\", !1), A().getNumber(\"WEBGL_VERSION\") === 1 && (d = I.getUniformLocation(G, \"INFINITY\", !1));\n  const Y = !1;\n  for (const V of l.variableNames) {\n    const a = {\n      name: V,\n      uniform: I.getUniformLocation(G, V, Y),\n      offset: I.getUniformLocation(G, `offset${V}`, Y)\n    };\n    l.enableShapeUniforms && (a.shape = I.getUniformLocation(G, `${V}Shape`, Y), a.texShape = I.getUniformLocation(G, `${V}TexShape`, Y)), Z.push(a);\n  }\n  if (l.enableShapeUniforms && (g = I.getUniformLocation(G, \"outShape\", Y), c = I.getUniformLocation(G, \"outShapeStrides\", Y), b = I.getUniformLocation(G, \"outTexShape\", Y)), l.customUniforms)\n    for (const V of l.customUniforms)\n      h.push(I.getUniformLocation(G, V.name, Y));\n  return {\n    variablesLocations: Z,\n    customUniformLocations: h,\n    infLoc: d,\n    nanLoc: W,\n    outShapeLocation: g,\n    outShapeStridesLocation: c,\n    outTexShapeLocation: b\n  };\n}\nfunction Da(I, l) {\n  if (I.length !== l.length)\n    throw Error(`Binary was compiled with ${I.length} inputs, but was executed with ${l.length} inputs`);\n  I.forEach((G, Z) => {\n    const h = G.logicalShape, g = l[Z], b = g.shape;\n    if (!Nl(h, b))\n      throw Error(`Binary was compiled with different shapes than the current args. Shapes ${h} and ${b} must match`);\n    if (G.isUniform && g.isUniform)\n      return;\n    const c = G.texShape, d = g.isUniform ? null : g.texData.texShape;\n    if (!Nl(c, d))\n      throw Error(`Binary was compiled with different texture shapes than the current args. Shape ${c} and ${d} must match`);\n  });\n}\nfunction DH(I, l, G, Z, h) {\n  l.program.enableShapeUniforms || (Da(l.inShapeInfos, G), Da([l.outShapeInfo], [Z]));\n  const g = Z.texData.texture, b = Z.texData.texShape;\n  Z.texData.isPacked ? I.setOutputPackedMatrixTexture(g.texture, b[0], b[1]) : I.setOutputMatrixTexture(g.texture, b[0], b[1]), I.setProgram(l.webGLProgram), I.bindVertexArray(l.webGLProgram.vao), A().getNumber(\"WEBGL_VERSION\") === 1 && l.infLoc !== null && I.gl.uniform1f(l.infLoc, 1 / 0), l.nanLoc !== null && I.gl.uniform1f(l.nanLoc, NaN);\n  for (let d = 0; d < G.length; ++d) {\n    const W = G[d], { uniform: Y, offset: V, shape: a, texShape: i } = l.variablesLocations[d];\n    if (a) {\n      const { uniformShape: m } = F9(l.program.packedInputs, W.shape, W.texData.texShape);\n      switch (m.length) {\n        case 1:\n          I.gl.uniform1iv(a, new Int32Array(m));\n          break;\n        case 2:\n          I.gl.uniform2iv(a, new Int32Array(m));\n          break;\n        case 3:\n          I.gl.uniform3iv(a, new Int32Array(m));\n          break;\n        case 4:\n          I.gl.uniform4iv(a, new Int32Array(m));\n          break;\n      }\n    }\n    if (i && I.gl.uniform2i(i, W.texData.texShape[0], W.texData.texShape[1]), Y != null) {\n      if (W.isUniform) {\n        if (Q(W.shape) < 2)\n          I.gl.uniform1f(Y, W.uniformValues[0]);\n        else {\n          let m = W.uniformValues;\n          m instanceof Float32Array || (m = new Float32Array(m)), I.gl.uniform1fv(Y, m);\n        }\n        continue;\n      }\n      W.texData.slice != null && V != null && I.gl.uniform1i(V, W.texData.slice.flatOffset), I.setInputMatrixTexture(W.texData.texture.texture, Y, d);\n    }\n  }\n  const c = l.outShapeLocation;\n  if (c)\n    switch (Z.shape.length) {\n      case 1:\n        I.gl.uniform1iv(c, new Int32Array(Z.shape));\n        break;\n      case 2:\n        I.gl.uniform2iv(c, new Int32Array(Z.shape));\n        break;\n      case 3:\n        I.gl.uniform3iv(c, new Int32Array(Z.shape));\n        break;\n      case 4:\n        I.gl.uniform4iv(c, new Int32Array(Z.shape));\n        break;\n    }\n  if (l.outShapeStridesLocation) {\n    const d = Wl(Z.shape);\n    switch (Z.shape.length) {\n      case 2:\n        I.gl.uniform1iv(l.outShapeStridesLocation, new Int32Array(d));\n        break;\n      case 3:\n        I.gl.uniform2iv(l.outShapeStridesLocation, new Int32Array(d));\n        break;\n      case 4:\n        I.gl.uniform3iv(l.outShapeStridesLocation, new Int32Array(d));\n        break;\n    }\n  }\n  if (l.outTexShapeLocation && I.gl.uniform2i(l.outTexShapeLocation, Z.texData.texShape[0], Z.texData.texShape[1]), l.program.customUniforms && h)\n    for (let d = 0; d < l.program.customUniforms.length; ++d) {\n      const W = l.program.customUniforms[d], Y = l.customUniformLocations[d], V = h[d];\n      if (W.type === \"float\")\n        I.gl.uniform1fv(Y, V);\n      else if (W.type === \"vec2\")\n        I.gl.uniform2fv(Y, V);\n      else if (W.type === \"vec3\")\n        I.gl.uniform3fv(Y, V);\n      else if (W.type === \"vec4\")\n        I.gl.uniform4fv(Y, V);\n      else if (W.type === \"int\")\n        I.gl.uniform1iv(Y, V);\n      else if (W.type === \"ivec2\")\n        I.gl.uniform2iv(Y, V);\n      else if (W.type === \"ivec3\")\n        I.gl.uniform3iv(Y, V);\n      else if (W.type === \"ivec4\")\n        I.gl.uniform4iv(Y, V);\n      else\n        throw Error(`uniform type ${W.type} is not supported yet.`);\n    }\n  I.executeProgram();\n}\nfunction fH(I, l, G) {\n  let Z = \"\";\n  l.concat(G).forEach((b) => {\n    const c = b.texData != null && b.texData.slice != null && b.texData.slice.flatOffset > 0;\n    if (I.enableShapeUniforms && !b.isUniform) {\n      const d = b.texData.texShape, { useSqueezeShape: W, uniformShape: Y, keptDims: V } = F9(I.packedInputs, b.shape, d);\n      let a = \"\", i = \"\", m = \"\";\n      if (Y.length === 1 && I.packedInputs) {\n        const X = [Math.ceil(d[0] / 2), Math.ceil(d[1] / 2)];\n        a = `${X[0] > 1}_${X[1] > 1}`;\n      } else if (Y.length === 2 && !I.packedInputs)\n        i = `${Y[0] > 1}_${Y[1] > 1}`;\n      else if (Y.length > 2 && !I.packedInputs) {\n        const X = Wl(Y);\n        m = `${X[0] === d[1]}_${X[X.length - 1] === d[1]}`;\n      }\n      const T = b.shape.length, s = Y.length === 2 && Nl(b.shape, d), o = Q(b.shape) === 1, B = rh(b.shape, G.shape), C = !I.packedInputs && T === G.shape.length && Nl(d, G.texData.texShape), n = I.packedInputs || Y.length > 2 ? \"\" : `${d[0] > 1}_${d[1] > 1}`;\n      Z += `${T}_${C}_${W ? V : \"\"}_${Y.length}_${o}_${B}_${s}_${a}_${i}_${m}_${n}_${c}`;\n    } else {\n      const d = b.isUniform ? \"uniform\" : b.texData.texShape;\n      Z += `${b.shape}_${d}_${c}`;\n    }\n  });\n  const h = I.userCode;\n  let g = I.constructor.name;\n  return g += \"_\" + Z + \"_\" + h + `${A().getNumber(\"WEBGL_VERSION\")}`, g;\n}\nfunction yG(I) {\n  return A().getBool(\"WEBGL_USE_SHAPES_UNIFORMS\") && I <= 4;\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass OH {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.packedInputs = !1, this.packedOutput = !0, this.outPackingScheme = z0.DENSE, this.customUniforms = [{ name: \"texShape\", type: \"ivec2\" }];\n    const G = KG();\n    this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length), this.userCode = `\n      ivec3 outCoordsFromFlatIndex(int index) {\n        ${this.enableShapeUniforms ? yd([\"r\", \"c\", \"d\"], l) : Rh([\"r\", \"c\", \"d\"], l)}\n        return ivec3(r, c, d);\n      }\n\n      void main() {\n        ivec2 resTexRC = ivec2(resultUV.yx * vec2(texShape[0], texShape[1]));\n        int index = 4 * (resTexRC.x * texShape[1] + resTexRC.y);\n\n        vec4 result = vec4(0.);\n\n        for (int i=0; i<4; i++) {\n          int flatIndex = index + i;\n          ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n          result[i] = getA(rc.x, rc.y, rc.z);\n        }\n\n        ${G.output} = result;\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass qH {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.outPackingScheme = z0.DENSE, this.customUniforms = [{ name: \"texShape\", type: \"ivec2\" }];\n    const G = KG();\n    this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length), this.userCode = `\n      ivec3 outCoordsFromFlatIndex(int index) {\n        ${this.enableShapeUniforms ? yd([\"r\", \"c\", \"d\"], l) : Rh([\"r\", \"c\", \"d\"], l)}\n        return ivec3(r, c, d);\n      }\n\n      void main() {\n        ivec2 resTexRC = ivec2(resultUV.yx * vec2(texShape[0], texShape[1]));\n        int index = 4 * (resTexRC.x * texShape[1] + resTexRC.y);\n\n        vec4 result = vec4(0.);\n\n        for (int i=0; i<4; i++) {\n          int flatIndex = index + i;\n          ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n          result[i] = getChannel(getA(rc.x, rc.y, rc.z), vec2(rc.y, rc.z));\n        }\n\n        ${G.output} = result;\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass $H {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.outTexUsage = lI.DOWNLOAD;\n    const G = KG();\n    this.outputShape = l, this.userCode = `\n      ${BB}\n\n      void main() {\n        float x = getAAtOutCoords();\n        ${G.output} = encode_float(x);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass _H {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !1, this.outTexUsage = lI.DOWNLOAD;\n    const G = KG();\n    this.outputShape = l, this.userCode = `\n      ${BB}\n\n      void main() {\n        ivec3 coords = getOutputCoords();\n        float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z));\n        ${G.output} = encode_float(x);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst lK = {\n  R: 0,\n  G: 1,\n  B: 2,\n  A: 3\n};\nclass fa {\n  constructor(l, G = !1, Z = \"RGBA\") {\n    this.variableNames = [\"A\"], this.customUniforms = [{ name: \"texShape\", type: \"ivec2\" }];\n    const h = KG();\n    this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length);\n    let g = \"result\";\n    G && (g = \"floor(result * 255. + 0.5)\");\n    let b = \"\";\n    for (let c = 0; c < Z.length; c++) {\n      const d = Z[c];\n      b += `\n          if(offset == ${c}) {\n            result = values[${lK[d]}];\n          }`;\n    }\n    this.userCode = `\n      ${this.enableShapeUniforms ? p9() : R9(l)}\n\n      void main() {\n        ivec3 coords = getOutputCoords();\n        int flatIndex = getFlatIndex(coords);\n        float result = 0.;\n        int offset = imod(flatIndex, ${Z.length});\n\n        flatIndex = idiv(flatIndex, ${Z.length}, 1.);\n\n        int r = flatIndex / texShape[1];\n        if (r < texShape[0]) {\n          int c = imod(flatIndex, texShape[1]);\n          vec2 uv = (vec2(c, r) + halfCR) / vec2(texShape[1], texShape[0]);\n          vec4 values = ${h.texture2D}(A, uv);\n          ${b}\n        }\n        ${h.output} = vec4(${g}, 0., 0., 0.);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass GK {\n  constructor(l, G = !1) {\n    this.variableNames = [\"A\"], this.packedInputs = !1, this.packedOutput = !0, this.customUniforms = [{ name: \"texShape\", type: \"ivec2\" }];\n    const Z = KG();\n    this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length);\n    let h = \"\", g = \"result\";\n    G && (g = \"floor(result * 255. + 0.5)\");\n    for (let b = 0; b <= 1; b++)\n      for (let c = 0; c <= 1; c++) {\n        const d = b * 2 + c;\n        h += `\n          localCoords = coords;\n          if(localCoords[2] + ${c} < ${this.enableShapeUniforms ? \"outShape[2]\" : `${l[2]}`}) {\n          localCoords[2] += ${c};\n          if (localCoords[1] + ${b} < ${this.enableShapeUniforms ? \"outShape[1]\" : `${l[1]}`}) {\n            localCoords[1] += ${b};\n\n            flatIndex = getFlatIndex(localCoords);\n            offset = imod(flatIndex, 4);\n\n            flatIndex = idiv(flatIndex, 4, 1.);\n\n            int r = flatIndex / texShape[1];\n            int c = imod(flatIndex, texShape[1]);\n            vec2 uv = (vec2(c, r) + halfCR) / vec2(texShape[1], texShape[0]);\n            values = ${Z.texture2D}(A, uv);\n\n            if (offset == 0) {\n              result[${d}] = values[0];\n            } else if (offset == 1) {\n              result[${d}] = values[1];\n            } else if (offset == 2) {\n              result[${d}] = values[2];\n            } else {\n              result[${d}] = values[3];\n            }\n          }\n        }\n        `;\n      }\n    this.userCode = `\n        ${this.enableShapeUniforms ? p9() : R9(l)}\n\n        void main() {\n          ivec3 coords = getOutputCoords();\n\n          vec4 result = vec4(0.);\n          int flatIndex, r, c, offset;\n          ivec3 localCoords;\n          vec2 uv;\n          vec4 values;\n\n          ${h}\n\n          ${Z.output} = ${g};\n        }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction IK(I) {\n  const l = KG(), G = `${l.version}\n    precision highp float;\n    ${l.attribute} vec3 clipSpacePos;\n    ${l.attribute} vec2 uv;\n    ${l.varyingVs} vec2 resultUV;\n\n    void main() {\n      gl_Position = vec4(clipSpacePos, 1);\n      resultUV = uv;\n    }`;\n  return kU(I, G);\n}\nfunction ZK(I) {\n  const l = new Float32Array([-1, 1, 0, 0, 1, -1, -1, 0, 0, 0, 1, 1, 0, 1, 1, 1, -1, 0, 1, 0]);\n  return QU(I, l);\n}\nfunction hK(I) {\n  const l = new Uint16Array([0, 1, 2, 2, 1, 3]);\n  return vU(I, l);\n}\nfunction db(I, l, G, Z, h, g) {\n  jU(l, G);\n  const b = rU(I), c = I.TEXTURE_2D;\n  return Zl(I, () => I.bindTexture(c, b)), Zl(I, () => I.texParameteri(c, I.TEXTURE_WRAP_S, I.CLAMP_TO_EDGE)), Zl(I, () => I.texParameteri(c, I.TEXTURE_WRAP_T, I.CLAMP_TO_EDGE)), Zl(I, () => I.texParameteri(c, I.TEXTURE_MIN_FILTER, I.NEAREST)), Zl(I, () => I.texParameteri(c, I.TEXTURE_MAG_FILTER, I.NEAREST)), A().getNumber(\"WEBGL_VERSION\") === 1 ? Zl(I, () => I.texImage2D(c, 0, Z, l, G, 0, h, g, null)) : Zl(I, () => I.texStorage2D(c, 1, Z, l, G)), Zl(I, () => I.bindTexture(I.TEXTURE_2D, null)), { texture: b, texShape: [G, l] };\n}\nfunction uB(I) {\n  return I.internalFormatFloat;\n}\nfunction gK(I, l, G, Z) {\n  const [h, g] = bb(l, G);\n  return db(I, h, g, uB(Z), Z.textureFormatFloat, I.FLOAT);\n}\nfunction eB(I) {\n  return I.internalFormatHalfFloat;\n}\nfunction bK(I, l, G, Z) {\n  const [h, g] = bb(l, G);\n  return db(I, h, g, eB(Z), Z.textureFormatFloat, Z.textureTypeHalfFloat);\n}\nfunction SB(I) {\n  return I.downloadTextureFormat;\n}\nfunction cK(I, l, G, Z) {\n  const [h, g] = bb(l, G);\n  return db(I, h, g, SB(Z), I.RGBA, I.UNSIGNED_BYTE);\n}\nfunction RB(I) {\n  return I.internalFormatPackedFloat;\n}\nfunction dK(I, l, G, Z) {\n  const [h, g] = W0(l, G);\n  return db(I, h, g, RB(Z), I.RGBA, I.FLOAT);\n}\nfunction pB(I) {\n  return I.internalFormatPackedHalfFloat;\n}\nfunction WK(I, l, G, Z) {\n  const [h, g] = W0(l, G);\n  return db(I, h, g, pB(Z), I.RGBA, Z.textureTypeHalfFloat);\n}\nfunction YK(I, l, G) {\n  return Zl(I, () => I.bindBuffer(I.ARRAY_BUFFER, G)), va(I, l, \"clipSpacePos\", G, 3, 20, 0) && va(I, l, \"uv\", G, 2, 20, 12);\n}\nfunction VK(I, l, G, Z, h, g) {\n  Zl(I, () => I.bindTexture(I.TEXTURE_2D, l));\n  let b, c, d;\n  h instanceof Uint8Array ? (b = new Uint8Array(G * Z * 4), c = I.UNSIGNED_BYTE, d = I.RGBA) : (b = new Float32Array(G * Z * 4), c = I.FLOAT, d = g.internalFormatPackedFloat), b.set(h), A().getNumber(\"WEBGL_VERSION\") === 2 ? Zl(I, () => I.texSubImage2D(I.TEXTURE_2D, 0, 0, 0, G, Z, I.RGBA, c, b)) : Zl(I, () => I.texImage2D(I.TEXTURE_2D, 0, d, G, Z, 0, I.RGBA, c, b)), Zl(I, () => I.bindTexture(I.TEXTURE_2D, null));\n}\nfunction aK(I, l, G) {\n  Zl(I, () => I.bindTexture(I.TEXTURE_2D, l)), G.data instanceof Uint8Array ? A().getNumber(\"WEBGL_VERSION\") === 2 ? Zl(I, () => I.texSubImage2D(I.TEXTURE_2D, 0, 0, 0, G.width, G.height, I.RGBA, I.UNSIGNED_BYTE, G.data)) : Zl(I, () => I.texImage2D(I.TEXTURE_2D, 0, I.RGBA, G.width, G.height, 0, I.RGBA, I.UNSIGNED_BYTE, G.data)) : A().getNumber(\"WEBGL_VERSION\") === 2 ? Zl(I, () => I.texSubImage2D(I.TEXTURE_2D, 0, 0, 0, I.RGBA, I.UNSIGNED_BYTE, G)) : Zl(I, () => I.texImage2D(I.TEXTURE_2D, 0, I.RGBA, I.RGBA, I.UNSIGNED_BYTE, G)), Zl(I, () => I.bindTexture(I.TEXTURE_2D, null));\n}\nfunction iK(I, l, G, Z) {\n  const h = I.createBuffer();\n  Zl(I, () => I.bindBuffer(I.PIXEL_PACK_BUFFER, h));\n  const c = 4 * 4 * l * G;\n  return Zl(I, () => I.bufferData(I.PIXEL_PACK_BUFFER, c, I.STREAM_READ)), Zl(I, () => I.readPixels(0, 0, G, l, I.RGBA, I.FLOAT, 0)), Zl(I, () => I.bindBuffer(I.PIXEL_PACK_BUFFER, null)), h;\n}\nfunction mK(I, l, G) {\n  const Z = I, h = new Float32Array(G);\n  return Z.bindBuffer(Z.PIXEL_PACK_BUFFER, l), Z.getBufferSubData(Z.PIXEL_PACK_BUFFER, 0, h), Z.bindBuffer(Z.PIXEL_PACK_BUFFER, null), h;\n}\nfunction TK(I, l, G, Z) {\n  const [h, g] = bb(l, G), b = 4, c = new Uint8Array(JU(l * G, b));\n  return Zl(I, () => I.readPixels(0, 0, h, g, Z.downloadTextureFormat, I.UNSIGNED_BYTE, c)), new Float32Array(c.buffer);\n}\nfunction sK(I, l, G, Z, h, g, b, c) {\n  const d = I, W = new Float32Array(EU(g, b));\n  return d.bindBuffer(d.PIXEL_PACK_BUFFER, l), d.getBufferSubData(d.PIXEL_PACK_BUFFER, 0, W), d.bindBuffer(d.PIXEL_PACK_BUFFER, null), W;\n}\nfunction oK(I, l, G) {\n  const Z = new Float32Array(l * G * 4);\n  return Zl(I, () => I.readPixels(0, 0, G, l, I.RGBA, I.FLOAT, Z)), Z;\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass _d {\n  constructor(l) {\n    this.outputTexture = null, this.program = null, this.disposed = !1, this.itemsToPoll = [];\n    const G = A().getNumber(\"WEBGL_VERSION\");\n    if (l != null ? (this.gl = l, yU(G, l)) : this.gl = NI(G), l = this.gl, A().getNumber(\"WEBGL_VERSION\") === 2) {\n      const g = l;\n      this.createVertexArray = () => Zl(g, () => g.createVertexArray()), this.bindVertexArray = (b) => Zl(g, () => g.bindVertexArray(b)), this.deleteVertexArray = (b) => Zl(g, () => g.deleteVertexArray(b)), this.getVertexArray = () => Zl(g, () => g.getParameter(g.VERTEX_ARRAY_BINDING));\n    } else if (l != null) {\n      const g = l.getExtension(\"OES_vertex_array_object\");\n      if (g == null)\n        throw new Error(\"All WebGL1 implementations are expected to offer OES_vertex_array_object.\");\n      this.createVertexArray = () => Zl(l, () => g.createVertexArrayOES()), this.bindVertexArray = (b) => Zl(l, () => g.bindVertexArrayOES(b)), this.deleteVertexArray = (b) => Zl(l, () => g.deleteVertexArrayOES(b)), this.getVertexArray = () => Zl(l, () => l.getParameter(g.VERTEX_ARRAY_BINDING_OES));\n    }\n    let Z = \"WEBGL_color_buffer_float\";\n    const h = \"EXT_color_buffer_half_float\";\n    if (this.parallelCompilationExtension = this.gl.getExtension(\"KHR_parallel_shader_compile\"), A().getNumber(\"WEBGL_VERSION\") === 1) {\n      const g = \"OES_texture_float\", b = \"OES_texture_half_float\";\n      if (this.textureFloatExtension = tb(this.gl, g), iI(this.gl, b))\n        this.textureHalfFloatExtension = tb(this.gl, b);\n      else if (A().get(\"WEBGL_FORCE_F16_TEXTURES\"))\n        throw new Error(\"GL context does not support half float textures, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.\");\n      if (this.colorBufferFloatExtension = this.gl.getExtension(Z), iI(this.gl, h))\n        this.colorBufferHalfFloatExtension = tb(this.gl, h);\n      else if (A().get(\"WEBGL_FORCE_F16_TEXTURES\"))\n        throw new Error(\"GL context does not support color renderable half floats, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.\");\n    } else if (Z = \"EXT_color_buffer_float\", iI(this.gl, Z))\n      this.colorBufferFloatExtension = this.gl.getExtension(Z);\n    else if (iI(this.gl, h))\n      this.colorBufferHalfFloatExtension = this.gl.getExtension(h);\n    else\n      throw new Error(\"GL context does not support color renderable floats\");\n    this.vertexBuffer = ZK(this.gl), this.indexBuffer = hK(this.gl), this.framebuffer = DU(this.gl), this.textureConfig = S9(this.gl, this.textureHalfFloatExtension);\n  }\n  get debug() {\n    return A().getBool(\"DEBUG\");\n  }\n  dispose() {\n    if (this.disposed)\n      return;\n    this.program != null && console.warn(\"Disposing a GPGPUContext that still has a bound WebGLProgram. This is probably a resource leak, delete the program with GPGPUContext.deleteProgram before disposing.\"), this.outputTexture != null && console.warn(\"Disposing a GPGPUContext that still has a bound output matrix texture.  This is probably a resource leak, delete the output matrix texture with GPGPUContext.deleteMatrixTexture before disposing.\");\n    const l = this.gl;\n    Zl(l, () => l.finish()), Zl(l, () => l.bindFramebuffer(l.FRAMEBUFFER, null)), Zl(l, () => l.deleteFramebuffer(this.framebuffer)), Zl(l, () => l.bindBuffer(l.ARRAY_BUFFER, null)), Zl(l, () => l.bindBuffer(l.ELEMENT_ARRAY_BUFFER, null)), Zl(l, () => l.deleteBuffer(this.indexBuffer)), this.disposed = !0;\n  }\n  createFloat32MatrixTexture(l, G) {\n    return this.throwIfDisposed(), gK(this.gl, l, G, this.textureConfig);\n  }\n  createFloat16MatrixTexture(l, G) {\n    return this.throwIfDisposed(), bK(this.gl, l, G, this.textureConfig);\n  }\n  createUnsignedBytesMatrixTexture(l, G) {\n    return this.throwIfDisposed(), cK(this.gl, l, G, this.textureConfig);\n  }\n  uploadPixelDataToTexture(l, G) {\n    this.throwIfDisposed(), aK(this.gl, l, G);\n  }\n  uploadDenseMatrixToTexture(l, G, Z, h) {\n    this.throwIfDisposed(), VK(this.gl, l, G, Z, h, this.textureConfig);\n  }\n  createFloat16PackedMatrixTexture(l, G) {\n    return this.throwIfDisposed(), WK(this.gl, l, G, this.textureConfig);\n  }\n  createPackedMatrixTexture(l, G) {\n    return this.throwIfDisposed(), dK(this.gl, l, G, this.textureConfig);\n  }\n  deleteMatrixTexture(l) {\n    this.throwIfDisposed(), this.outputTexture === l && (ra(this.gl, this.framebuffer), this.outputTexture = null), Zl(this.gl, () => this.gl.deleteTexture(l));\n  }\n  downloadByteEncodedFloatMatrixFromOutputTexture(l, G, Z) {\n    return this.downloadMatrixDriver(l, () => TK(this.gl, G, Z, this.textureConfig));\n  }\n  downloadPackedMatrixFromBuffer(l, G, Z, h, g, b) {\n    return sK(this.gl, l, G, Z, h, g, b, this.textureConfig);\n  }\n  downloadFloat32MatrixFromBuffer(l, G) {\n    return mK(this.gl, l, G);\n  }\n  createBufferFromTexture(l, G, Z) {\n    this.bindTextureToFrameBuffer(l);\n    const h = iK(this.gl, G, Z, this.textureConfig);\n    return this.unbindTextureToFrameBuffer(), h;\n  }\n  createAndWaitForFence() {\n    const l = this.createFence(this.gl);\n    return this.pollFence(l);\n  }\n  createFence(l) {\n    let G, Z;\n    if (A().getBool(\"WEBGL_FENCE_API_ENABLED\")) {\n      const h = l, g = h.fenceSync(h.SYNC_GPU_COMMANDS_COMPLETE, 0);\n      l.flush(), Z = () => {\n        const b = h.clientWaitSync(g, 0, 0);\n        return b === h.ALREADY_SIGNALED || b === h.CONDITION_SATISFIED;\n      }, G = g;\n    } else A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\") > 0 ? (G = this.beginQuery(), this.endQuery(), Z = () => this.isQueryAvailable(G, A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\"))) : Z = () => !0;\n    return { query: G, isFencePassed: Z };\n  }\n  downloadMatrixFromPackedTexture(l, G, Z) {\n    return this.downloadMatrixDriver(l, () => oK(this.gl, G, Z));\n  }\n  createProgram(l) {\n    this.throwIfDisposed();\n    const G = this.gl;\n    this.vertexShader == null && (this.vertexShader = IK(G));\n    const Z = MU(G);\n    Zl(G, () => G.attachShader(Z, this.vertexShader)), Zl(G, () => G.attachShader(Z, l)), wU(G, Z);\n    const h = Object.assign(Z, { vao: this.createVertexArray() });\n    return this.debug && fd(G, h), h;\n  }\n  buildVao(l) {\n    this.setProgram(l), this.bindVertexArray(l.vao);\n    const G = this.gl;\n    Zl(G, () => G.bindBuffer(G.ELEMENT_ARRAY_BUFFER, this.indexBuffer)), YK(G, l, this.vertexBuffer);\n  }\n  deleteProgram(l) {\n    this.throwIfDisposed(), l === this.program && (this.program = null), l != null && (Zl(this.gl, () => this.gl.deleteProgram(l)), this.deleteVertexArray(l.vao));\n  }\n  setProgram(l) {\n    this.throwIfDisposed(), this.program = l, this.program != null && this.debug && fd(this.gl, this.program), Zl(this.gl, () => this.gl.useProgram(l));\n  }\n  getUniformLocation(l, G, Z = !0) {\n    return this.throwIfDisposed(), Z ? OU(this.gl, l, G) : qU(this.gl, l, G);\n  }\n  getAttributeLocation(l, G) {\n    return this.throwIfDisposed(), Zl(this.gl, () => this.gl.getAttribLocation(l, G));\n  }\n  getUniformLocationNoThrow(l, G) {\n    return this.throwIfDisposed(), this.gl.getUniformLocation(l, G);\n  }\n  setInputMatrixTexture(l, G, Z) {\n    this.throwIfDisposed(), this.throwIfNoProgram(), $U(this.gl, l, G, Z);\n  }\n  setOutputMatrixTexture(l, G, Z) {\n    this.setOutputMatrixTextureDriver(l, Z, G);\n  }\n  setOutputPackedMatrixTexture(l, G, Z) {\n    this.throwIfDisposed();\n    const [h, g] = W0(G, Z);\n    this.setOutputMatrixTextureDriver(l, h, g);\n  }\n  setOutputMatrixWriteRegion(l, G, Z, h) {\n    this.setOutputMatrixWriteRegionDriver(Z, l, h, G);\n  }\n  setOutputPackedMatrixWriteRegion(l, G, Z, h) {\n    throw new Error(\"setOutputPackedMatrixWriteRegion not implemented.\");\n  }\n  debugValidate() {\n    this.program != null && fd(this.gl, this.program), ub(this.gl);\n  }\n  executeProgram() {\n    this.throwIfDisposed(), this.throwIfNoProgram();\n    const l = this.gl;\n    if (this.debug) {\n      const G = this.getVertexArray();\n      console.assert(G === this.program.vao, \"VAO changed between setProgram and executeProgram!\"), this.debugValidate();\n    }\n    Zl(l, () => l.drawElements(l.TRIANGLES, 6, l.UNSIGNED_SHORT, 0));\n  }\n  blockUntilAllProgramsCompleted() {\n    this.throwIfDisposed(), Zl(this.gl, () => this.gl.finish());\n  }\n  getQueryTimerExtension() {\n    return this.disjointQueryTimerExtension == null && (this.disjointQueryTimerExtension = tb(this.gl, A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\") === 2 ? \"EXT_disjoint_timer_query_webgl2\" : \"EXT_disjoint_timer_query\")), this.disjointQueryTimerExtension;\n  }\n  getQueryTimerExtensionWebGL2() {\n    return this.getQueryTimerExtension();\n  }\n  getQueryTimerExtensionWebGL1() {\n    return this.getQueryTimerExtension();\n  }\n  beginQuery() {\n    if (A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\") === 2) {\n      const Z = this.gl, h = this.getQueryTimerExtensionWebGL2(), g = Z.createQuery();\n      return Z.beginQuery(h.TIME_ELAPSED_EXT, g), g;\n    }\n    const l = this.getQueryTimerExtensionWebGL1(), G = l.createQueryEXT();\n    return l.beginQueryEXT(l.TIME_ELAPSED_EXT, G), G;\n  }\n  endQuery() {\n    if (A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\") === 2) {\n      const G = this.gl, Z = this.getQueryTimerExtensionWebGL2();\n      G.endQuery(Z.TIME_ELAPSED_EXT);\n      return;\n    }\n    const l = this.getQueryTimerExtensionWebGL1();\n    l.endQueryEXT(l.TIME_ELAPSED_EXT);\n  }\n  async waitForQueryAndGetTime(l) {\n    return await H9(() => this.disposed || // while testing contexts are created / disposed\n    // in rapid succession, so without this check we\n    // may poll for the query timer indefinitely\n    this.isQueryAvailable(l, A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\"))), this.getQueryTime(l, A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION\"));\n  }\n  getQueryTime(l, G) {\n    if (G === 0)\n      return null;\n    if (G === 2) {\n      const Z = this.gl;\n      return Z.getQueryParameter(l, Z.QUERY_RESULT) / 1e6;\n    } else {\n      const Z = this.getQueryTimerExtensionWebGL1();\n      return Z.getQueryObjectEXT(l, Z.QUERY_RESULT_EXT) / 1e6;\n    }\n  }\n  isQueryAvailable(l, G) {\n    if (G === 0)\n      return !0;\n    if (G === 2) {\n      const Z = this.gl, h = this.getQueryTimerExtensionWebGL2(), g = Z.getQueryParameter(l, Z.QUERY_RESULT_AVAILABLE);\n      return this.disjoint == null && (this.disjoint = this.gl.getParameter(h.GPU_DISJOINT_EXT)), g && !this.disjoint;\n    } else {\n      const Z = this.getQueryTimerExtensionWebGL1(), h = Z.getQueryObjectEXT(l, Z.QUERY_RESULT_AVAILABLE_EXT);\n      return this.disjoint == null && (this.disjoint = this.gl.getParameter(Z.GPU_DISJOINT_EXT)), h && !this.disjoint;\n    }\n  }\n  pollFence(l) {\n    return new Promise((G) => {\n      this.addItemToPoll(() => l.isFencePassed(), () => G());\n    });\n  }\n  pollItems() {\n    const l = BK(this.itemsToPoll.map((G) => G.isDoneFn));\n    for (let G = 0; G <= l; ++G) {\n      const { resolveFn: Z } = this.itemsToPoll[G];\n      Z();\n    }\n    this.itemsToPoll = this.itemsToPoll.slice(l + 1);\n  }\n  addItemToPoll(l, G) {\n    if (this.itemsToPoll.push({ isDoneFn: l, resolveFn: G }), this.itemsToPoll.length > 1)\n      return;\n    let Z;\n    \"setTimeoutCustom\" in A().platform && (Z = A().platform.setTimeoutCustom.bind(A().platform)), H9(() => (this.pollItems(), this.itemsToPoll.length === 0), () => 0, null, Z);\n  }\n  bindTextureToFrameBuffer(l) {\n    this.throwIfDisposed(), Od(this.gl, l, this.framebuffer), this.debug && ub(this.gl);\n  }\n  unbindTextureToFrameBuffer() {\n    this.outputTexture != null ? (Od(this.gl, this.outputTexture, this.framebuffer), this.debug && ub(this.gl)) : ra(this.gl, this.framebuffer);\n  }\n  downloadMatrixDriver(l, G) {\n    this.bindTextureToFrameBuffer(l);\n    const Z = G();\n    return this.unbindTextureToFrameBuffer(), Z;\n  }\n  setOutputMatrixTextureDriver(l, G, Z) {\n    this.throwIfDisposed();\n    const h = this.gl;\n    Od(h, l, this.framebuffer), this.debug && ub(h), this.outputTexture = l, Zl(h, () => h.viewport(0, 0, G, Z)), Zl(h, () => h.scissor(0, 0, G, Z));\n  }\n  setOutputMatrixWriteRegionDriver(l, G, Z, h) {\n    this.throwIfDisposed(), Zl(this.gl, () => this.gl.scissor(l, G, Z, h));\n  }\n  throwIfDisposed() {\n    if (this.disposed)\n      throw new Error(\"Attempted to use disposed GPGPUContext.\");\n  }\n  throwIfNoProgram() {\n    if (this.program == null)\n      throw new Error(\"No GPU program is currently set.\");\n  }\n}\nfunction BK(I) {\n  let l = 0;\n  for (; l < I.length && I[l](); ++l)\n    ;\n  return l - 1;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst { addImpl: nK, bincountImpl: FB, bincountReduceImpl: CK, bitwiseAndImpl: XK, castImpl: tK, ceilImpl: uK, concatImpl: eK, equalImpl: SK, expImpl: RK, expm1Impl: pK, floorImpl: FK, gatherNdImpl: yK, gatherV2Impl: NK, greaterImpl: PK, greaterEqualImpl: JK, lessImpl: EK, lessEqualImpl: xK, linSpaceImpl: UK, logImpl: HK, maxImpl: KK, maximumImpl: AK, minimumImpl: kK, multiplyImpl: zK, negImpl: LK, notEqualImpl: MK, prodImpl: wK, raggedGatherImpl: QK, raggedRangeImpl: vK, raggedTensorToTensorImpl: rK, rangeImpl: jK, rsqrtImpl: DK, scatterImpl: fK, sigmoidImpl: OK, simpleAbsImpl: yB, sliceImpl: qK, sparseFillEmptyRowsImpl: $K, sparseReshapeImpl: _K, sparseSegmentReductionImpl: NB, sqrtImpl: l1, staticRegexReplaceImpl: G1, stridedSliceImpl: I1, stringNGramsImpl: Z1, stringSplitImpl: h1, stringToHashBucketFastImpl: g1, subImpl: b1, tileImpl: c1, topKImpl: d1, transposeImpl: y9, uniqueImpl: W1 } = aP;\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction PB(I, l) {\n  return [\"x\", \"y\", \"z\", \"w\", \"u\", \"v\"].slice(0, l).map((G) => `${I}.${G}`);\n}\nfunction xG(I, l) {\n  return l === 1 ? [I] : PB(I, l);\n}\nfunction Y1(I, l) {\n  if (I === 1)\n    return \"rc\";\n  let G = \"\";\n  for (let Z = 0; Z < I; Z++)\n    G += l[Z], Z < I - 1 && (G += \",\");\n  return G;\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass V1 {\n  constructor(l) {\n    if (this.variableNames = [\"A\"], this.packedInputs = !1, this.packedOutput = !0, this.outputShape = l, this.rank = l.length, this.enableShapeUniforms = yG(this.outputShape.length), this.rank === 0)\n      this.userCode = `\n        void main() {\n          setOutput(vec4(getA(), 0., 0., 0.));\n        }\n      `;\n    else {\n      const G = xG(\"rc\", this.rank), Z = Ul(this.rank), h = this.getOutOfBoundsCondition(G), g = this.getSetup(G), b = this.getOutput(G);\n      this.userCode = `\n        void main() {\n          ${Z} rc = getOutputCoords();\n\n          if(${h}) {\n            setOutput(vec4(0));\n          } else {\n            ${g}\n\n            setOutput(vec4(${b}));\n          }\n        }\n      `;\n    }\n  }\n  getSourceCoordsArr(l) {\n    const G = [];\n    for (let Z = 0; Z <= 1; Z++)\n      for (let h = 0; h <= 1; h++) {\n        let g = `${Z === 0 ? \"r\" : \"rp1\"}, ${h === 0 ? \"c\" : \"cp1\"}`;\n        for (let b = 2; b < this.rank; b++)\n          g = `${l[l.length - 1 - b]},` + g;\n        G.push(g);\n      }\n    return G;\n  }\n  getOutOfBoundsCondition(l) {\n    if (this.rank === 1)\n      return `rc > ${this.enableShapeUniforms ? \"outShape\" : this.outputShape[0]}`;\n    let G = \"\";\n    for (let Z = this.rank - 2; Z < this.rank; Z++)\n      G += `${l[Z]} >= ${this.enableShapeUniforms ? `outShape[${Z}]` : this.outputShape[Z]}`, Z < this.rank - 1 && (G += \"||\");\n    return G;\n  }\n  getSetup(l) {\n    if (this.rank === 1)\n      return \"\";\n    const G = l.slice(-2), Z = this.enableShapeUniforms ? `outShape[${this.rank} - 1]` : this.outputShape[this.rank - 1], h = this.enableShapeUniforms ? `outShape[${this.rank} - 2]` : this.outputShape[this.rank - 2];\n    return `\n      int r = ${G[0]};\n      int c = ${G[1]};\n      int rp1 = r + 1;\n      int cp1 = c + 1;\n\n      bool cEdge = cp1 >= ${Z};\n      bool rEdge = rp1 >= ${h};\n    `;\n  }\n  getOutput(l) {\n    const G = this.getSourceCoordsArr(l);\n    return this.rank === 1 ? `getA(rc), (rc + 1 >= ${this.enableShapeUniforms ? \"outShape\" : this.outputShape[0]} ? 0. : getA(rc + 1)), 0, 0` : `getA(${G[0]}),\n            cEdge ? 0. : getA(${G[1]}),\n            rEdge ? 0. : getA(${G[2]}),\n            rEdge || cEdge ? 0. : getA(${G[3]})`;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass JB {\n  constructor(l, G) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [{ name: \"inputShape\", type: \"ivec3\" }], this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length);\n    let Z = \"\";\n    for (let h = 0; h < 4; h++) {\n      let g = \"thisRC = rc;\";\n      h % 2 === 1 && (g += \"thisRC.z += 1;\"), h > 1 && (g += \"thisRC.y += 1;\"), Z += `\n        ${g}\n        ${h > 0 ? \"if(thisRC.y < rows && thisRC.z < cols){\" : \"\"}\n          int flatIndex = getFlatIndex(thisRC);\n\n          ivec3 inputRC = inputCoordsFromReshapedOutCoords(flatIndex);\n          vec2 inputRCInnerDims = vec2(float(inputRC.y),float(inputRC.z));\n\n          result[${h}] =\n            getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims);\n        ${h > 0 ? \"}\" : \"\"}\n      `;\n    }\n    this.userCode = `\n      ${a1(G, this.enableShapeUniforms)}\n      ${this.enableShapeUniforms ? p9() : R9(l)}\n\n      void main() {\n        ivec3 rc = getOutputCoords();\n\n        vec4 result = vec4(0.);\n\n        ivec3 thisRC;\n        int rows = ${this.enableShapeUniforms ? \"outShape[1]\" : l[1]};\n        int cols = ${this.enableShapeUniforms ? \"outShape[2]\" : l[2]};\n\n        ${Z}\n\n        setOutput(result);\n      }\n    `;\n  }\n}\nfunction a1(I, l) {\n  return `\n    ivec3 inputCoordsFromReshapedOutCoords(int index) {\n      ${l ? YH([\"r\", \"c\", \"d\"], \"inputShape\") : Rh([\"r\", \"c\", \"d\"], I)}\n      return ivec3(r, c, d);\n    }\n  `;\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass i1 {\n  constructor(l) {\n    this.gpgpu = l, this.numUsedTextures = 0, this.numFreeTextures = 0, this._numBytesAllocated = 0, this._numBytesFree = 0, this.freeTextures = {}, this.usedTextures = {}, this.logEnabled = !1;\n  }\n  acquireTexture(l, G, Z) {\n    const h = qa(G, Z), g = $a(l, h, Z);\n    g in this.freeTextures || (this.freeTextures[g] = []), g in this.usedTextures || (this.usedTextures[g] = []);\n    const b = Oa(l, h, this.gpgpu.gl, this.gpgpu.textureConfig, Z);\n    if (this.freeTextures[g].length > 0) {\n      this.numFreeTextures--, this.numUsedTextures++, this._numBytesFree -= b, this.log();\n      const d = this.freeTextures[g].pop();\n      return this.usedTextures[g].push(d), d;\n    }\n    let c;\n    return h === BG.PACKED_2X2_FLOAT32 ? c = this.gpgpu.createPackedMatrixTexture(l[0], l[1]) : h === BG.PACKED_2X2_FLOAT16 ? c = this.gpgpu.createFloat16PackedMatrixTexture(l[0], l[1]) : h === BG.UNPACKED_FLOAT32 ? c = this.gpgpu.createFloat32MatrixTexture(l[0], l[1]) : h === BG.UNPACKED_FLOAT16 ? c = this.gpgpu.createFloat16MatrixTexture(l[0], l[1]) : h === BG.PACKED_4X1_UNSIGNED_BYTE && (c = this.gpgpu.createUnsignedBytesMatrixTexture(l[0], l[1])), this.usedTextures[g].push(c), this.numUsedTextures++, this._numBytesAllocated += b, this.log(), c;\n  }\n  releaseTexture(l, G, Z, h) {\n    if (this.freeTextures == null)\n      return;\n    const g = qa(Z, h), b = $a(G, g, h);\n    b in this.freeTextures || (this.freeTextures[b] = []);\n    const c = Oa(G, g, this.gpgpu.gl, this.gpgpu.textureConfig, h), d = A().getNumber(\"WEBGL_DELETE_TEXTURE_THRESHOLD\");\n    d !== -1 && this._numBytesAllocated > d ? (this.gpgpu.deleteMatrixTexture(l.texture), this._numBytesAllocated -= c) : (this.freeTextures[b].push(l), this.numFreeTextures++, this._numBytesFree += c), this.numUsedTextures--;\n    const W = this.usedTextures[b], Y = W && W.indexOf(l);\n    if (Y == null || Y < 0)\n      throw new Error(\"Cannot release a texture that was never provided by this texture manager\");\n    W[Y] = W[W.length - 1], W.pop(), this.log();\n  }\n  log() {\n    if (!this.logEnabled)\n      return;\n    const l = this.numFreeTextures + this.numUsedTextures;\n    console.log(\"Free/Used\", `${this.numFreeTextures} / ${this.numUsedTextures}`, `(${l})`);\n    const G = this._numBytesFree / this._numBytesAllocated;\n    console.log(`Bytes allocated: ${this._numBytesAllocated}`), console.log(`Bytes unused: ${this._numBytesFree} (${Math.round(100 * G)}%)`);\n  }\n  get numBytesAllocated() {\n    return this._numBytesAllocated;\n  }\n  get numBytesFree() {\n    return this._numBytesFree;\n  }\n  getNumUsedTextures() {\n    return this.numUsedTextures;\n  }\n  getNumFreeTextures() {\n    return this.numFreeTextures;\n  }\n  dispose() {\n    if (this.freeTextures != null) {\n      for (const l in this.freeTextures)\n        this.freeTextures[l].forEach((G) => {\n          this.gpgpu.deleteMatrixTexture(G.texture);\n        });\n      for (const l in this.usedTextures)\n        this.usedTextures[l].forEach((G) => {\n          this.gpgpu.deleteMatrixTexture(G.texture);\n        });\n      this.freeTextures = null, this.usedTextures = null, this.numUsedTextures = 0, this.numFreeTextures = 0, this._numBytesAllocated = 0, this._numBytesFree = 0;\n    }\n  }\n}\nfunction m1(I, l) {\n  const G = I;\n  if (l === G.R32F)\n    return 4;\n  if (l === G.R16F)\n    return 2;\n  if (l === G.RGBA32F)\n    return 16;\n  if (l === I.RGBA)\n    return 16;\n  if (l === G.RGBA16F)\n    return 8;\n  if (l === G.RGBA8)\n    return 4;\n  throw new Error(`Unknown internal format ${l}`);\n}\nfunction Oa(I, l, G, Z, h) {\n  const g = T1(l, Z);\n  let b;\n  if (h) {\n    const [d, W] = W0(I[0], I[1]);\n    b = d * W;\n  } else {\n    const [d, W] = bb(I[0], I[1]);\n    b = d * W;\n  }\n  const c = m1(G, g);\n  return b * c;\n}\nfunction T1(I, l) {\n  switch (I) {\n    case BG.PACKED_2X2_FLOAT32:\n      return RB(l);\n    case BG.PACKED_2X2_FLOAT16:\n      return pB(l);\n    case BG.UNPACKED_FLOAT32:\n      return uB(l);\n    case BG.UNPACKED_FLOAT16:\n      return eB(l);\n    case BG.PACKED_4X1_UNSIGNED_BYTE:\n      return SB(l);\n    default:\n      throw new Error(`Unknown physical texture type ${I}`);\n  }\n}\nfunction s1(I) {\n  return A().getBool(\"WEBGL_RENDER_FLOAT32_ENABLED\") ? I ? BG.PACKED_2X2_FLOAT32 : BG.UNPACKED_FLOAT32 : I ? BG.PACKED_2X2_FLOAT16 : BG.UNPACKED_FLOAT16;\n}\nfunction qa(I, l) {\n  if (I === lI.UPLOAD)\n    return BG.PACKED_2X2_FLOAT32;\n  if (I === lI.RENDER || I == null)\n    return s1(l);\n  if (I === lI.DOWNLOAD || I === lI.PIXELS)\n    return BG.PACKED_4X1_UNSIGNED_BYTE;\n  throw new Error(`Unknown logical texture type ${I}`);\n}\nfunction $a(I, l, G) {\n  return `${I[0]}_${I[1]}_${l}_${G}`;\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass kI {\n  constructor(l, G) {\n    this.variableNames = [\"A\"], this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length), this.userCode = `\n      float unaryOperation(float x) {\n        ${G}\n      }\n\n      void main() {\n        float x = getAAtOutCoords();\n        float y = unaryOperation(x);\n\n        setOutput(y);\n      }\n    `;\n  }\n}\nconst BI = \"if (isnan(x)) return x;\", o1 = \"return x;\", _a = \"return abs(x);\", B1 = \"return (x >= 0.0) ? x : (exp(x) - 1.0);\", n1 = BI + `\n  return (x < 0.0) ? 0.0 : x;\n`, C1 = BI + `\n  return (x < 0.0) ? 0.0 : min(6.0, x);\n`, sZ = \"return x;\", X1 = \"return 1.0 / (1.0 + exp(-1.0 * x));\";\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst t1 = \"return x;\", u1 = `\n  vec4 result;\n\n  result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n  result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n  result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n  result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n  return result;\n`, e1 = `\n  vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`, S1 = `\n  vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`, R1 = \"return 1.0 / (1.0 + exp(-1.0 * x));\";\nclass nZ {\n  constructor(l, G) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length), this.userCode = `\n      vec4 unaryOperation(vec4 x) {\n        ${G}\n      }\n\n      void main() {\n        vec4 x = getAAtOutCoords();\n        vec4 y = unaryOperation(x);\n\n        setOutput(y);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass p1 {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !1, this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length);\n    const G = l.length, Z = xG(\"rc\", G), h = Ul(G), g = Y1(G, Z), b = Z.slice(-2), c = G <= 1 ? \"rc\" : `vec2(${b.join(\",\")})`;\n    this.userCode = `\n      void main() {\n        ${h} rc = getOutputCoords();\n        vec4 packedInput = getA(${g});\n\n        setOutput(getChannel(packedInput, ${c}));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst F1 = GT, y1 = 1e-7, N1 = 1e-4, Rb = {};\nfunction P1(I) {\n  return I in Rb || (Rb[I] = {}), Rb[I];\n}\nconst J1 = A().getNumber(\"CPU_HANDOFF_SIZE_THRESHOLD\"), E1 = 600;\nfunction x1() {\n  return A().global.screen == null ? 1024 : A().global.screen.height * A().global.screen.width * window.devicePixelRatio * E1 / 1024 / 1024;\n}\nclass Nd extends wW {\n  nextDataId() {\n    return Nd.nextDataId++;\n  }\n  constructor(l) {\n    if (super(), this.pendingRead = /* @__PURE__ */ new WeakMap(), this.pendingDisposal = /* @__PURE__ */ new WeakSet(), this.dataRefCount = /* @__PURE__ */ new WeakMap(), this.numBytesInGPU = 0, this.uploadWaitMs = 0, this.downloadWaitMs = 0, this.lastGlFlushTime = 0, this.warnedAboutMemory = !1, this.pendingDeletes = 0, this.disposed = !1, !A().getBool(\"HAS_WEBGL\"))\n      throw new Error(\"WebGL is not supported on this device\");\n    let G;\n    if (l != null) {\n      if (l instanceof _d)\n        G = l;\n      else {\n        const Z = NI(A().getNumber(\"WEBGL_VERSION\"), l);\n        G = new _d(Z);\n      }\n      this.binaryCache = {}, this.gpgpuCreatedLocally = !1;\n    } else {\n      const Z = NI(A().getNumber(\"WEBGL_VERSION\"));\n      G = new _d(Z), this.binaryCache = P1(A().getNumber(\"WEBGL_VERSION\")), this.gpgpuCreatedLocally = !0;\n    }\n    this.gpgpu = G, this.canvas = this.gpgpu.gl.canvas, this.textureManager = new i1(this.gpgpu), this.numMBBeforeWarning = x1(), this.texData = new ti(this, EI());\n  }\n  numDataIds() {\n    return this.texData.numDataIds() - this.pendingDeletes;\n  }\n  // Writes a new entry to the data store with a WebGL texture, and registers it\n  // to the texture manager.\n  writeTexture(l, G, Z, h, g, b) {\n    const c = this.makeTensorInfo(G, Z), d = this.texData.get(c.dataId);\n    d.isPacked = !1, d.texture = { texture: l, texShape: [h, g] }, d.texShape = [h, g];\n    const W = eb(G), Y = new fa(W, !1, b), V = this.runWebGLProgram(Y, [c], Z, [[h, g]]);\n    return V.shape = G, d.texture = null, this.disposeIntermediateTensorInfo(c), V.dataId;\n  }\n  write(l, G, Z) {\n    if ((A().getBool(\"WEBGL_CHECK_NUMERICAL_PROBLEMS\") || A().getBool(\"DEBUG\")) && this.checkNumericalProblems(l), Z === \"complex64\" && l != null)\n      throw new Error(\"Cannot write to a complex64 dtype. Please use tf.complex(real, imag).\");\n    const h = { id: this.nextDataId() };\n    return this.texData.set(h, { shape: G, dtype: Z, values: l, usage: lI.UPLOAD, refCount: 1 }), h;\n  }\n  /** Return refCount of a `TensorData`. */\n  refCount(l) {\n    return this.texData.has(l) ? this.texData.get(l).refCount : 0;\n  }\n  /** Increase refCount of a `TextureData`. */\n  incRef(l) {\n    const G = this.texData.get(l);\n    G.refCount++;\n  }\n  /** Decrease refCount of a `TextureData`. */\n  decRef(l) {\n    if (this.texData.has(l)) {\n      const G = this.texData.get(l);\n      G.refCount--;\n    }\n  }\n  move(l, G, Z, h, g) {\n    if (A().getBool(\"DEBUG\") && this.checkNumericalProblems(G), h === \"complex64\")\n      throw new Error(\"Cannot write to a complex64 dtype. Please use tf.complex(real, imag).\");\n    this.texData.set(l, { shape: Z, dtype: h, values: G, usage: lI.UPLOAD, refCount: g });\n  }\n  disposeIntermediateTensorInfo(l) {\n    this.disposeData(l.dataId);\n  }\n  readSync(l) {\n    const G = this.texData.get(l), { values: Z, dtype: h, complexTensorInfos: g, slice: b, shape: c, isPacked: d } = G;\n    if (b != null) {\n      let a;\n      d ? a = new nZ(c, sZ) : a = new kI(c, sZ);\n      const i = this.runWebGLProgram(a, [{ dataId: l, shape: c, dtype: h }], h), m = this.readSync(i.dataId);\n      return this.disposeIntermediateTensorInfo(i), m;\n    }\n    if (Z != null)\n      return this.convertAndCacheOnCPU(l);\n    if (h === \"string\")\n      return Z;\n    const W = this.activeTimers != null;\n    let Y;\n    W && (Y = AG());\n    let V;\n    if (h === \"complex64\") {\n      const a = this.readSync(g.real.dataId), i = this.readSync(g.imag.dataId);\n      V = bZ(a, i);\n    } else\n      V = this.getValuesFromTexture(l);\n    return W && (this.downloadWaitMs += AG() - Y), this.convertAndCacheOnCPU(l, V);\n  }\n  async read(l) {\n    if (this.pendingRead.has(l)) {\n      const m = this.pendingRead.get(l);\n      return new Promise((T) => m.push(T));\n    }\n    const G = this.texData.get(l), { values: Z, shape: h, slice: g, dtype: b, complexTensorInfos: c, isPacked: d } = G;\n    if (g != null) {\n      let m;\n      d ? m = new nZ(h, sZ) : m = new kI(h, sZ);\n      const T = this.runWebGLProgram(m, [{ dataId: l, shape: h, dtype: b }], b), s = this.read(T.dataId);\n      return this.disposeIntermediateTensorInfo(T), s;\n    }\n    if (Z != null)\n      return this.convertAndCacheOnCPU(l);\n    if (A().getBool(\"DEBUG\") && !A().getBool(\"WEBGL_DOWNLOAD_FLOAT_ENABLED\") && A().getNumber(\"WEBGL_VERSION\") === 2)\n      throw new Error(\"tensor.data() with WEBGL_DOWNLOAD_FLOAT_ENABLED=false and WEBGL_VERSION=2 not yet supported.\");\n    let W = null, Y;\n    if (b !== \"complex64\" && A().get(\"WEBGL_BUFFER_SUPPORTED\")) {\n      Y = this.decode(l);\n      const m = this.texData.get(Y.dataId);\n      W = this.gpgpu.createBufferFromTexture(m.texture.texture, ...Xb(h));\n    }\n    this.pendingRead.set(l, []), b !== \"complex64\" && await this.gpgpu.createAndWaitForFence();\n    let V;\n    if (b === \"complex64\") {\n      const m = await Promise.all([\n        this.read(c.real.dataId),\n        this.read(c.imag.dataId)\n      ]), T = m[0], s = m[1];\n      V = bZ(T, s);\n    } else if (W == null)\n      V = this.getValuesFromTexture(l);\n    else {\n      const m = Q(h);\n      V = this.gpgpu.downloadFloat32MatrixFromBuffer(W, m);\n    }\n    if (Y != null && this.disposeIntermediateTensorInfo(Y), W != null) {\n      const m = this.gpgpu.gl;\n      Zl(m, () => m.deleteBuffer(W));\n    }\n    const a = this.convertAndCacheOnCPU(l, V), i = this.pendingRead.get(l);\n    return this.pendingRead.delete(l), i.forEach((m) => m(a)), this.pendingDisposal.has(l) && (this.pendingDisposal.delete(l), this.disposeData(l) && EI().removeDataId(l, this), this.pendingDeletes--), a;\n  }\n  /**\n   * Read tensor to a new texture that is densely packed for ease of use.\n   * @param dataId The source tensor.\n   * @param options\n   *     customTexShape: Optional. If set, will use the user defined texture\n   *     shape to create the texture.\n   */\n  readToGPU(l, G = {}) {\n    const Z = this.texData.get(l), { values: h, shape: g, slice: b, dtype: c, isPacked: d, texture: W } = Z;\n    if (c === \"complex64\")\n      throw new Error(\"Does not support reading texture for complex64 dtype.\");\n    if (b != null) {\n      let i;\n      d ? i = new nZ(g, sZ) : i = new kI(g, sZ);\n      const m = this.runWebGLProgram(i, [{ dataId: l, shape: g, dtype: c }], c), T = this.readToGPU(m, G);\n      return this.disposeIntermediateTensorInfo(m), T;\n    }\n    if (W == null)\n      throw h != null ? new Error(\"Data is not on GPU but on CPU.\") : new Error(\"There is no data on GPU or CPU.\");\n    const Y = this.decode(l, G.customTexShape), V = EI().makeTensorFromTensorInfo(Y), a = this.texData.get(Y.dataId);\n    return Object.assign({ tensorRef: V }, a.texture);\n  }\n  bufferSync(l) {\n    const G = this.readSync(l.dataId);\n    if (l.dtype === \"string\")\n      try {\n        const Z = G.map((h) => eZ(h));\n        return Xl(l.shape, l.dtype, Z);\n      } catch {\n        throw new Error(\"Failed to decode encoded string bytes into utf-8\");\n      }\n    return Xl(l.shape, l.dtype, G);\n  }\n  checkNumericalProblems(l) {\n    if (l != null)\n      for (let G = 0; G < l.length; G++) {\n        const Z = l[G];\n        if (!KU(Z))\n          throw A().getBool(\"WEBGL_RENDER_FLOAT32_CAPABLE\") ? Error(`The value ${Z} cannot be represented with your current settings. Consider enabling float32 rendering: 'tf.env().set('WEBGL_RENDER_FLOAT32_ENABLED', true);'`) : Error(`The value ${Z} cannot be represented on this device.`);\n      }\n  }\n  getValuesFromTexture(l) {\n    const { shape: G, dtype: Z, isPacked: h } = this.texData.get(l), g = Q(G);\n    if (A().getBool(\"WEBGL_DOWNLOAD_FLOAT_ENABLED\")) {\n      const a = this.decode(l), i = this.texData.get(a.dataId), m = this.gpgpu.downloadMatrixFromPackedTexture(i.texture.texture, ...Xb(G)).subarray(0, g);\n      return this.disposeIntermediateTensorInfo(a), m;\n    }\n    const b = A().getBool(\"WEBGL_PACK\") && h === !0, c = b ? eb(G) : G, d = b ? new _H(c) : new $H(c), W = this.runWebGLProgram(d, [{ shape: c, dtype: Z, dataId: l }], \"float32\"), Y = this.texData.get(W.dataId), V = this.gpgpu.downloadByteEncodedFloatMatrixFromOutputTexture(Y.texture.texture, Y.texShape[0], Y.texShape[1]).subarray(0, g);\n    return this.disposeIntermediateTensorInfo(W), V;\n  }\n  timerAvailable() {\n    return A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE\") > 0;\n  }\n  time(l) {\n    const G = this.activeTimers, Z = [];\n    let h = !1;\n    this.programTimersStack == null ? (this.programTimersStack = Z, h = !0) : this.activeTimers.push(Z), this.activeTimers = Z, l();\n    const g = hh(this.activeTimers.map((d) => d.query)).filter((d) => d != null), b = hh(this.activeTimers.map((d) => d.name)).filter((d) => d != null);\n    this.activeTimers = G, h && (this.programTimersStack = null);\n    const c = {\n      uploadWaitMs: this.uploadWaitMs,\n      downloadWaitMs: this.downloadWaitMs,\n      kernelMs: null,\n      wallMs: null\n      // will be filled by the engine\n    };\n    return (async () => {\n      if (A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE\") > 0) {\n        const d = await Promise.all(g);\n        c.kernelMs = on(d), c.getExtraProfileInfo = () => d.map((W, Y) => ({ name: b[Y], ms: W })).map((W) => `${W.name}: ${W.ms}`).join(\", \");\n      } else\n        c.kernelMs = {\n          error: \"WebGL query timers are not supported in this environment.\"\n        };\n      return this.uploadWaitMs = 0, this.downloadWaitMs = 0, c;\n    })();\n  }\n  memory() {\n    return {\n      unreliable: !1,\n      numBytesInGPU: this.numBytesInGPU,\n      numBytesInGPUAllocated: this.textureManager.numBytesAllocated,\n      numBytesInGPUFree: this.textureManager.numBytesFree\n    };\n  }\n  startTimer() {\n    return A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE\") > 0 ? this.gpgpu.beginQuery() : { startMs: AG(), endMs: null };\n  }\n  endTimer(l) {\n    return A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE\") > 0 ? (this.gpgpu.endQuery(), l) : (l.endMs = AG(), l);\n  }\n  async getQueryTime(l) {\n    if (A().getNumber(\"WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE\") > 0)\n      return this.gpgpu.waitForQueryAndGetTime(l);\n    const G = l;\n    return G.endMs - G.startMs;\n  }\n  /**\n   * Decrease the RefCount on the dataId and dispose the memory if the dataId\n   * has 0 refCount. If there are pending read on the data, the disposal would\n   * added to the pending delete queue. Return true if the dataId is removed\n   * from backend or the backend does not contain the dataId, false if the\n   * dataId is not removed. Memory may or may not be released even when dataId\n   * is removed, which also depends on dataRefCount, see `releaseGPU`.\n   * @param dataId\n   * @oaram force Optional, remove the data regardless of refCount\n   */\n  disposeData(l, G = !1) {\n    if (this.pendingDisposal.has(l))\n      return !1;\n    if (!this.texData.has(l))\n      return !0;\n    if (G ? this.texData.get(l).refCount = 0 : this.texData.get(l).refCount--, !G && this.texData.get(l).refCount > 0)\n      return !1;\n    if (this.pendingRead.has(l))\n      return this.pendingDisposal.add(l), this.pendingDeletes++, !1;\n    this.releaseGPUData(l);\n    const { complexTensorInfos: Z } = this.texData.get(l);\n    return Z != null && (this.disposeData(Z.real.dataId, G), this.disposeData(Z.imag.dataId, G)), this.texData.delete(l), !0;\n  }\n  releaseGPUData(l) {\n    const { texture: G, dtype: Z, texShape: h, usage: g, isPacked: b, slice: c } = this.texData.get(l), d = c && c.origDataId || l, W = this.dataRefCount.get(d);\n    W > 1 ? this.dataRefCount.set(d, W - 1) : (this.dataRefCount.delete(d), G != null && (this.numBytesInGPU -= this.computeBytes(h, Z), this.textureManager.releaseTexture(G, h, g, b)));\n    const Y = this.texData.get(l);\n    Y.texture = null, Y.texShape = null, Y.isPacked = !1, Y.slice = null;\n  }\n  getTexture(l) {\n    return this.uploadToGPU(l), this.texData.get(l).texture.texture;\n  }\n  /**\n   * Returns internal information for the specific data bucket. Used in unit\n   * tests.\n   */\n  getDataInfo(l) {\n    return this.texData.get(l);\n  }\n  /*\n  Tests whether all the inputs to an op are small and on the CPU. This heuristic\n  determines when it would be faster to execute a kernel on the CPU. WebGL\n  kernels opt into running this check and forwarding when appropriate.\n  TODO(https://github.com/tensorflow/tfjs/issues/872): Develop a more\n  sustainable strategy for optimizing backend execution of ops.\n   */\n  shouldExecuteOnCPU(l, G = J1) {\n    return A().getBool(\"WEBGL_CPU_FORWARD\") && l.every((Z) => this.texData.get(Z.dataId).texture == null && Q(Z.shape) < G);\n  }\n  getGPGPUContext() {\n    return this.gpgpu;\n  }\n  where(l) {\n    _G(\"tf.where() in webgl locks the UI thread. Call tf.whereAsync() instead\");\n    const G = l.dataSync();\n    return F1(l.shape, G);\n  }\n  packedUnaryOp(l, G, Z) {\n    const h = new nZ(l.shape, G), g = this.compileAndRun(h, [l], Z);\n    return EI().makeTensorFromTensorInfo(g);\n  }\n  // TODO(msoulanille) remove this once the backend has been modularized\n  // a copy is needed here to break a circular dependency.\n  // Also remove the op from unary_op.\n  abs(l) {\n    if (this.shouldExecuteOnCPU([l]) && l.dtype !== \"complex64\") {\n      const h = yB(this.texData.get(l.dataId).values);\n      return this.makeOutput(l.shape, l.dtype, h);\n    }\n    if (A().getBool(\"WEBGL_PACK_UNARY_OPERATIONS\"))\n      return this.packedUnaryOp(l, _a, l.dtype);\n    const G = new kI(l.shape, _a), Z = this.compileAndRun(G, [l]);\n    return EI().makeTensorFromTensorInfo(Z);\n  }\n  makeTensorInfo(l, G, Z) {\n    let h;\n    if (G === \"string\" && Z != null && Z.length > 0 && v0(Z[0])) {\n      const g = Z.map((b) => XZ(b));\n      h = this.write(g, l, G);\n    } else\n      h = this.write(Z, l, G);\n    return this.texData.get(h).usage = null, { dataId: h, shape: l, dtype: G };\n  }\n  makeOutput(l, G, Z) {\n    return EI().makeTensorFromTensorInfo(this.makeTensorInfo(l, G, Z), this);\n  }\n  unpackTensor(l) {\n    const G = new p1(l.shape);\n    return this.runWebGLProgram(G, [l], l.dtype);\n  }\n  packTensor(l) {\n    const G = new V1(l.shape);\n    return this.runWebGLProgram(G, [l], l.dtype, null, !0);\n  }\n  packedReshape(l, G) {\n    const Z = [\n      $h(l.shape),\n      ..._h(l.shape)\n    ], h = {\n      dtype: l.dtype,\n      shape: Z,\n      dataId: l.dataId\n    }, g = [\n      $h(G),\n      ..._h(G)\n    ], b = new JB(g, Z), c = !0, d = [Z], W = this.runWebGLProgram(b, [h], l.dtype, d, c);\n    return { dataId: W.dataId, shape: G, dtype: W.dtype };\n  }\n  decode(l, G) {\n    const Z = this.texData.get(l), { isPacked: h, shape: g, dtype: b } = Z;\n    if (G != null) {\n      const a = Q(g), i = G[0] * G[1] * 4;\n      u(a <= i, () => \"customTexShape is too small. Row * Column * 4 should be equal or larger than the size of the tensor data.\");\n    }\n    const c = eb(g);\n    let d;\n    h ? d = new qH(c) : d = new OH(c);\n    const W = !0, Y = [G ?? Xb(c)], V = this.runWebGLProgram(d, [{ shape: c, dtype: b, dataId: l }], b, Y, W, G);\n    return { dtype: b, shape: g, dataId: V.dataId };\n  }\n  runWebGLProgram(l, G, Z, h, g = !1, b) {\n    const c = this.makeTensorInfo(l.outputShape, Z), d = this.texData.get(c.dataId);\n    if (l.packedOutput && (d.isPacked = !0), l.outPackingScheme === z0.DENSE) {\n      const o = b ?? Xb(l.outputShape);\n      d.texShape = o.map((B) => B * 2);\n    }\n    if (l.outTexUsage != null && (d.usage = l.outTexUsage), Q(c.shape) === 0)\n      return d.values = eG(c.dtype, 0), c;\n    const W = [], Y = G.map((o) => {\n      if (o.dtype === \"complex64\")\n        throw new Error(\"GPGPUProgram does not support complex64 input. For complex64 dtypes, please separate the program into real and imaginary parts.\");\n      let B = this.texData.get(o.dataId);\n      if (B.texture == null) {\n        if (!l.packedInputs && Q(o.shape) <= A().getNumber(\"WEBGL_SIZE_UPLOAD_UNIFORM\"))\n          return {\n            shape: o.shape,\n            texData: null,\n            isUniform: !0,\n            uniformValues: B.values\n          };\n        l.packedInputs && (B.isPacked = !0, B.shape = o.shape);\n      }\n      if (this.uploadToGPU(o.dataId), !!B.isPacked != !!l.packedInputs)\n        o = B.isPacked ? this.unpackTensor(o) : this.packTensor(o), W.push(o), B = this.texData.get(o.dataId);\n      else if (B.isPacked && !Gc(B.shape, o.shape)) {\n        const C = o, n = o.shape;\n        o.shape = B.shape, o = this.packedReshape(o, n), W.push(o), B = this.texData.get(o.dataId), C.shape = n;\n      }\n      return { shape: o.shape, texData: B, isUniform: !1 };\n    });\n    this.uploadToGPU(c.dataId);\n    const V = { shape: c.shape, texData: d, isUniform: !1 }, a = fH(l, Y, V), i = this.getAndSaveBinary(a, () => jH(this.gpgpu, l, Y, V)), m = this.activeTimers != null;\n    let T;\n    m && (T = this.startTimer()), A().get(\"ENGINE_COMPILE_ONLY\") || DH(this.gpgpu, i, Y, V, h), W.forEach((o) => this.disposeIntermediateTensorInfo(o)), m && (T = this.endTimer(T), this.activeTimers.push({ name: l.constructor.name, query: this.getQueryTime(T) }));\n    const s = A().getNumber(\"WEBGL_FLUSH_THRESHOLD\");\n    if (s > 0) {\n      const o = AG();\n      o - this.lastGlFlushTime > s && (this.gpgpu.gl.flush(), this.lastGlFlushTime = o);\n    }\n    if (!A().getBool(\"WEBGL_LAZILY_UNPACK\") && d.isPacked && g === !1) {\n      const o = this.unpackTensor(c);\n      return this.disposeIntermediateTensorInfo(c), o;\n    }\n    return c;\n  }\n  compileAndRun(l, G, Z, h, g = !1) {\n    return Z = Z || G[0].dtype, this.runWebGLProgram(l, G, Z, h, g);\n  }\n  getAndSaveBinary(l, G) {\n    return l in this.binaryCache || (this.binaryCache[l] = G()), this.binaryCache[l];\n  }\n  getTextureManager() {\n    return this.textureManager;\n  }\n  dispose() {\n    this.disposed || (A().getBool(\"IS_TEST\") || Object.keys(this.binaryCache).forEach((G) => {\n      this.gpgpu.deleteProgram(this.binaryCache[G].webGLProgram), delete this.binaryCache[G];\n    }), this.textureManager.dispose(), this.canvas != null && typeof HTMLCanvasElement < \"u\" && this.canvas instanceof HTMLCanvasElement ? this.canvas.remove() : this.canvas = null, this.gpgpuCreatedLocally && (this.gpgpu.program = null, this.gpgpu.dispose()), this.disposed = !0);\n  }\n  floatPrecision() {\n    return this.floatPrecisionValue == null && (this.floatPrecisionValue = U(() => {\n      if (!A().get(\"WEBGL_RENDER_FLOAT32_ENABLED\")) {\n        const l = A().getBool(\"DEBUG\");\n        A().set(\"DEBUG\", !1);\n        const G = this.abs(yl(1e-8)).dataSync()[0];\n        if (A().set(\"DEBUG\", l), G > 0)\n          return 32;\n      }\n      return 16;\n    })), this.floatPrecisionValue;\n  }\n  /** Returns the smallest representable number.  */\n  epsilon() {\n    return this.floatPrecision() === 32 ? y1 : N1;\n  }\n  uploadToGPU(l) {\n    const G = this.texData.get(l), { shape: Z, dtype: h, values: g, texture: b, usage: c, isPacked: d } = G;\n    if (b != null)\n      return;\n    const W = this.activeTimers != null;\n    let Y;\n    W && (Y = AG());\n    let V = G.texShape;\n    if (V == null && (V = GH(Z, d), G.texShape = V), g != null) {\n      const a = eb(Z);\n      let i, m = V[1], T = V[0];\n      const s = g instanceof Uint8Array || g instanceof Uint8ClampedArray;\n      (d || !s) && ([m, T] = W0(V[0], V[1])), d ? i = new GK(a, s) : i = new fa(a, s);\n      const o = s ? [T, m] : V, B = this.makeTensorInfo(o, h), C = this.texData.get(B.dataId);\n      s ? C.usage = lI.PIXELS : C.usage = lI.UPLOAD, C.texShape = o, this.gpgpu.uploadDenseMatrixToTexture(this.getTexture(B.dataId), m, T, g);\n      const n = [[T, m]], t = this.runWebGLProgram(i, [B], h, n, !0), e = this.texData.get(t.dataId);\n      G.texShape = e.texShape, G.isPacked = e.isPacked, G.usage = e.usage, A().get(\"ENGINE_COMPILE_ONLY\") ? this.disposeData(t.dataId) : (G.texture = e.texture, G.values = null, this.texData.delete(t.dataId)), this.disposeIntermediateTensorInfo(B), W && (this.uploadWaitMs += AG() - Y);\n    } else {\n      const a = this.acquireTexture(V, c, h, d);\n      G.texture = a;\n    }\n  }\n  convertAndCacheOnCPU(l, G) {\n    const Z = this.texData.get(l), { dtype: h } = Z;\n    return G != null && (Z.values = U1(G, h)), Z.values;\n  }\n  acquireTexture(l, G, Z, h) {\n    if (this.numBytesInGPU += this.computeBytes(l, Z), !this.warnedAboutMemory && this.numBytesInGPU > this.numMBBeforeWarning * 1024 * 1024) {\n      const g = (this.numBytesInGPU / 1024 / 1024).toFixed(2);\n      this.warnedAboutMemory = !0, console.warn(`High memory usage in GPU: ${g} MB, most likely due to a memory leak`);\n    }\n    return this.textureManager.acquireTexture(l, G, h);\n  }\n  computeBytes(l, G) {\n    return l[0] * l[1] * Nb(G);\n  }\n  checkCompileCompletion() {\n    for (const [, l] of Object.entries(this.binaryCache))\n      this.checkCompletion_(l);\n  }\n  async checkCompileCompletionAsync() {\n    const l = [];\n    if (this.gpgpu.parallelCompilationExtension) {\n      for (const [, G] of Object.entries(this.binaryCache))\n        l.push(this.checkCompletionAsync_(G));\n      return Promise.all(l);\n    } else {\n      for (const [, G] of Object.entries(this.binaryCache)) {\n        const Z = new Promise((h) => {\n          try {\n            this.checkCompletion_(G), h(!0);\n          } catch (g) {\n            throw g;\n          }\n        });\n        l.push(Z);\n      }\n      return Promise.all(l);\n    }\n  }\n  async checkCompletionAsync_(l) {\n    return this.gpgpu.gl.getProgramParameter(l.webGLProgram, this.gpgpu.parallelCompilationExtension.COMPLETION_STATUS_KHR) ? this.checkCompletion_(l) : (await BT(), this.checkCompletionAsync_(l));\n  }\n  checkCompletion_(l) {\n    if (this.gpgpu.gl.getProgramParameter(l.webGLProgram, this.gpgpu.gl.LINK_STATUS) === !1)\n      throw console.log(this.gpgpu.gl.getProgramInfoLog(l.webGLProgram)), this.gpgpu.gl.getShaderParameter(l.fragmentShader, this.gpgpu.gl.COMPILE_STATUS) === !1 ? (oB(l.source, this.gpgpu.gl.getShaderInfoLog(l.fragmentShader)), new Error(\"Failed to compile fragment shader.\")) : new Error(\"Failed to link vertex and fragment shaders.\");\n    return !0;\n  }\n  getUniformLocations() {\n    for (const l of Object.values(this.binaryCache)) {\n      this.gpgpu.buildVao(l.webGLProgram);\n      const { variablesLocations: G, customUniformLocations: Z, infLoc: h, nanLoc: g, outShapeLocation: b, outShapeStridesLocation: c, outTexShapeLocation: d } = tB(this.gpgpu, l.program, l.webGLProgram);\n      l.variablesLocations = G, l.customUniformLocations = Z, l.infLoc = h, l.nanLoc = g, l.outShapeLocation = b, l.outShapeStridesLocation = c, l.outTexShapeLocation = d;\n    }\n  }\n  /**\n   * Create a TF.js tensor out of an existing WebGL texture. A new texture will\n   * be created.\n   */\n  createTensorFromGPUData(l, G, Z) {\n    l.channels = l.channels || \"RGBA\";\n    const { texture: h, height: g, width: b, channels: c } = l, d = EI().backend;\n    if (!d.gpgpu.gl.isTexture(h))\n      throw new Error(\"The texture is invalid. Also, please make sure the texture and the TFJS WebGL backend are using the same canvas. If you want to use your own custom canvas, you have to create and use the custom TFJS WebGL backend created from the canvas through 'new tf.MathBackendWebGL(customCanvas)'.\");\n    const W = d.writeTexture(h, G, Z, g, b, c);\n    return EI().makeTensorFromDataId(W, G, Z, d);\n  }\n}\nNd.nextDataId = 0;\nfunction U1(I, l) {\n  if (l === \"float32\" || l === \"complex64\")\n    return I;\n  if (l === \"int32\" || l === \"bool\") {\n    const G = l === \"int32\" ? new Int32Array(I.length) : new Uint8Array(I.length);\n    for (let Z = 0; Z < G.length; ++Z)\n      G[Z] = Math.round(I[Z]);\n    return G;\n  } else\n    throw new Error(`Unknown dtype ${l}`);\n}\n/**\n * @license\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nmm() && om(\n  \"webgl\",\n  () => new Nd(),\n  2\n  /* priority */\n);\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst N9 = `\n  if (isnan(a)) return a;\n  if (isnan(b)) return b;\n`;\nclass sh {\n  constructor(l, G, Z) {\n    this.variableNames = [\"A\", \"B\"], this.outputShape = sl(G, Z), this.enableShapeUniforms = yG(this.outputShape.length), this.userCode = `\n      float binaryOperation(float a, float b) {\n        ${l}\n      }\n\n      void main() {\n        float a = getAAtOutCoords();\n        float b = getBAtOutCoords();\n        setOutput(binaryOperation(a, b));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Fh = `\n  result.r = isNaN.r ? NAN : result.r;\n  result.g = isNaN.g ? NAN : result.g;\n  result.b = isNaN.b ? NAN : result.b;\n  result.a = isNaN.a ? NAN : result.a;\n`;\nclass m0 {\n  constructor(l, G, Z, h = !1) {\n    this.variableNames = [\"A\", \"B\"], this.supportsBroadcasting = !0, this.packedInputs = !0, this.packedOutput = !0, this.outputShape = sl(G, Z);\n    const g = this.outputShape.length;\n    this.enableShapeUniforms = yG(g);\n    let b = \"\";\n    if (h)\n      if (g === 0 || Q(this.outputShape) === 1)\n        b = `\n          result.y = 0.;\n          result.z = 0.;\n          result.w = 0.;\n        `;\n      else if (b = `\n          ${Ul(g)} coords = getOutputCoords();\n        `, g === 1)\n        this.enableShapeUniforms ? b += `\n            result.y = (coords + 1) >= outShape ? 0. : result.y;\n            result.z = 0.;\n            result.w = 0.;\n          ` : b += `\n            result.y = (coords + 1) >= ${this.outputShape[0]} ? 0. : result.y;\n            result.z = 0.;\n            result.w = 0.;\n          `;\n      else {\n        const d = xG(\"coords\", g);\n        this.enableShapeUniforms ? b += `\n            bool nextRowOutOfBounds =\n              (${d[g - 2]} + 1) >= outShape[${g} - 2];\n            bool nextColOutOfBounds =\n              (${d[g - 1]} + 1) >= outShape[${g} - 1];\n            result.y = nextColOutOfBounds ? 0. : result.y;\n            result.z = nextRowOutOfBounds ? 0. : result.z;\n            result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w;\n          ` : b += `\n            bool nextRowOutOfBounds =\n              (${d[g - 2]} + 1) >= ${this.outputShape[g - 2]};\n            bool nextColOutOfBounds =\n              (${d[g - 1]} + 1) >= ${this.outputShape[g - 1]};\n            result.y = nextColOutOfBounds ? 0. : result.y;\n            result.z = nextRowOutOfBounds ? 0. : result.z;\n            result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w;\n          `;\n      }\n    this.userCode = `\n      vec4 binaryOperation(vec4 a, vec4 b) {\n        ${l}\n      }\n\n      void main() {\n        vec4 a = getAAtOutCoords();\n        vec4 b = getBAtOutCoords();\n\n        vec4 result = binaryOperation(a, b);\n        ${b}\n\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction OG(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  return G.incRef(Z.dataId), { dataId: Z.dataId, shape: Z.shape, dtype: Z.dtype };\n}\nconst H1 = {\n  kernelName: ag,\n  backendName: \"webgl\",\n  kernelFunc: OG\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zZ(I) {\n  const { inputs: l, backend: G } = I, { real: Z, imag: h } = l, g = G.makeTensorInfo(Z.shape, \"complex64\"), b = G.texData.get(g.dataId), c = OG({ inputs: { x: Z }, backend: G }), d = OG({ inputs: { x: h }, backend: G });\n  return b.complexTensorInfos = { real: c, imag: d }, g;\n}\nconst K1 = {\n  kernelName: ZY,\n  backendName: \"webgl\",\n  kernelFunc: zZ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst EB = \"return (a < 0.) ? b * a : a;\", xB = `\n  vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n  return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n`;\nfunction A1(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { alpha: g } = Z, b = G.makeTensorInfo([], \"float32\", JZ(g, \"float32\")), c = A().getBool(\"WEBGL_PACK_BINARY_OPERATIONS\") ? new m0(xB, h.shape, b.shape) : new sh(EB, h.shape, b.shape), d = G.runWebGLProgram(c, [h, b], \"float32\");\n  return G.disposeIntermediateTensorInfo(b), d;\n}\nconst k1 = {\n  kernelName: Rc,\n  backendName: \"webgl\",\n  kernelFunc: A1\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst UB = \"return (a < 0.) ? b * a : a;\", HB = `\n  vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n  return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n`;\nfunction z1(I) {\n  const { inputs: l, backend: G } = I, { x: Z, alpha: h } = l, g = A().getBool(\"WEBGL_PACK_BINARY_OPERATIONS\") ? new m0(HB, Z.shape, h.shape) : new sh(UB, Z.shape, h.shape);\n  return G.runWebGLProgram(g, [Z, h], \"float32\");\n}\nconst L1 = {\n  kernelName: vc,\n  backendName: \"webgl\",\n  kernelFunc: z1\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst T0 = \"if (isnan(x)) return x;\";\nfunction Rl({ opSnippet: I, packedOpSnippet: l, cpuKernelImpl: G, dtype: Z }) {\n  return ({ inputs: h, backend: g }) => {\n    const { x: b } = h, c = g, d = Z || b.dtype;\n    if (c.shouldExecuteOnCPU([b]) && G != null) {\n      const V = c.texData.get(b.dataId), a = G(V.values, d);\n      return c.makeTensorInfo(b.shape, d, a);\n    }\n    const W = A().getBool(\"WEBGL_PACK_UNARY_OPERATIONS\") && l != null;\n    let Y;\n    return W ? Y = new nZ(b.shape, l) : Y = new kI(b.shape, I), c.runWebGLProgram(Y, [b], d);\n  };\n}\nfunction tG({ opSnippet: I, packedOpSnippet: l, checkOutOfBounds: G = !1, supportsComplex: Z = !1, cpuKernelImpl: h, dtype: g }) {\n  return ({ inputs: b, backend: c }) => {\n    const { a: d, b: W } = b, Y = c;\n    if (Z && d.dtype === \"complex64\") {\n      const m = Y.texData.get(d.dataId), T = Y.texData.get(W.dataId), [s, o] = [\n        [m.complexTensorInfos.real, T.complexTensorInfos.real],\n        [m.complexTensorInfos.imag, T.complexTensorInfos.imag]\n      ].map((C) => {\n        const [n, X] = C, t = {\n          dataId: n.dataId,\n          dtype: n.dtype,\n          shape: d.shape\n        }, e = {\n          dataId: X.dataId,\n          dtype: X.dtype,\n          shape: W.shape\n        }, S = new sh(I, d.shape, W.shape);\n        return Y.runWebGLProgram(S, [t, e], DG(n.dtype, X.dtype));\n      }), B = zZ({ inputs: { real: s, imag: o }, backend: Y });\n      return Y.disposeIntermediateTensorInfo(s), Y.disposeIntermediateTensorInfo(o), B;\n    }\n    const V = g || DG(d.dtype, W.dtype);\n    if ((d.dtype === \"string\" || W.dtype === \"string\" || Y.shouldExecuteOnCPU([d, W])) && h != null) {\n      const m = Y.texData.get(d.dataId).values, T = Y.texData.get(W.dataId).values, s = d.dtype === \"string\" ? (\n        // tslint:disable-next-line: no-any\n        cZ(m)\n      ) : m, o = d.dtype === \"string\" ? (\n        // tslint:disable-next-line: no-any\n        cZ(T)\n      ) : T, [B, C] = h(d.shape, W.shape, s, o, V), n = Y.makeTensorInfo(C, V), X = Y.texData.get(n.dataId);\n      return X.values = B, n;\n    }\n    const a = A().getBool(\"WEBGL_PACK_BINARY_OPERATIONS\") && l != null;\n    let i;\n    return a ? i = new m0(l, d.shape, W.shape, G) : i = new sh(I, d.shape, W.shape), Y.runWebGLProgram(i, [d, W], V);\n  };\n}\nfunction L0(I, l = !1) {\n  if (I === \"linear\")\n    return l ? t1 : o1;\n  if (I === \"relu\")\n    return l ? e1 : n1;\n  if (I === \"elu\")\n    return l ? u1 : B1;\n  if (I === \"relu6\")\n    return l ? S1 : C1;\n  if (I === \"prelu\")\n    return l ? HB : UB;\n  if (I === \"leakyrelu\")\n    return l ? xB : EB;\n  if (I === \"sigmoid\")\n    return l ? R1 : X1;\n  throw new Error(`Activation ${I} has not been implemented for the WebGL backend.`);\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass KB {\n  constructor(l, G, Z, h = !1, g = !1, b = !1, c = null, d = !1, W = !1) {\n    this.variableNames = [\"matrixA\", \"matrixB\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = Z, this.enableShapeUniforms = yG(this.outputShape.length);\n    const Y = h ? l[1] : l[2], V = Math.ceil(Y / 2), a = h ? \"i * 2, rc.y\" : \"rc.y, i * 2\", i = g ? \"rc.z, i * 2\" : \"i * 2, rc.z\", m = h ? [\"a.xxyy\", \"a.zzww\"] : [\"a.xxzz\", \"a.yyww\"], T = g ? [\"b.xzxz\", \"b.ywyw\"] : [\"b.xyxy\", \"b.zwzw\"];\n    let s = \"\", o = \"\";\n    c && (d ? s = `vec4 activation(vec4 a) {\n          vec4 b = getPreluActivationWeightsAtOutCoords();\n          ${c}\n        }` : W ? s = `vec4 activation(vec4 a) {\n          vec4 b = getLeakyreluAlphaAtOutCoords();\n          ${c}\n        }` : s = `vec4 activation(vec4 x) {\n          ${c}\n        }`, o = \"result = activation(result);\");\n    const B = b ? \"result += getBiasAtOutCoords();\" : \"\";\n    b && this.variableNames.push(\"bias\"), d && this.variableNames.push(\"preluActivationWeights\"), W && this.variableNames.push(\"leakyreluAlpha\");\n    let C = \"rc.x\", n = \"rc.x\";\n    l[0] < G[0] ? C = `imod(rc.x, ${l[0]})` : G[0] < l[0] && (n = `imod(rc.x, ${G[0]})`), this.userCode = `\n      ${s}\n      // Don't use uniform for sharedDimensionPacked for performance.\n      const float sharedDimension = ${V}.0;\n\n      vec4 dot2x2ARowBCol(ivec3 rc) {\n        vec4 result = vec4(0);\n        int batchA = ${C};\n        int batchB = ${n};\n        for (int i = 0; i < ${V}; i++) {\n          vec4 a = getMatrixA(batchA, ${a});\n          vec4 b = getMatrixB(batchB, ${i});\n\n          // These swizzled products need to be separately added.\n          // See: https://github.com/tensorflow/tfjs/issues/1735\n          result += (${m[0]} * ${T[0]});\n          result += (${m[1]} * ${T[1]});\n        }\n        return result;\n      }\n\n      void main() {\n        ivec3 rc = getOutputCoords();\n        vec4 result = dot2x2ARowBCol(rc);\n\n        ${B}\n\n        ${o}\n\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst li = {\n  REAL: \"return areal * breal - aimag * bimag;\",\n  IMAG: \"return areal * bimag + aimag * breal;\"\n};\nclass Gi {\n  constructor(l, G, Z) {\n    this.variableNames = [\"AReal\", \"AImag\", \"BReal\", \"BImag\"], this.outputShape = sl(G, Z), this.userCode = `\n      float binaryOpComplex(\n          float areal, float aimag, float breal, float bimag) {\n        ${l}\n      }\n\n      void main() {\n        float areal = getARealAtOutCoords();\n        float aimag = getAImagAtOutCoords();\n        float breal = getBRealAtOutCoords();\n        float bimag = getBImagAtOutCoords();\n        setOutput(binaryOpComplex(areal, aimag, breal, bimag));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ii = \"return a * b;\";\nfunction P9(I) {\n  const { inputs: l, backend: G } = I, { a: Z, b: h } = l, g = DG(Z.dtype, h.dtype);\n  if (Z.dtype === \"complex64\") {\n    const c = G.texData.get(Z.dataId), d = G.texData.get(h.dataId), W = new Gi(li.REAL, Z.shape, h.shape), Y = new Gi(li.IMAG, Z.shape, h.shape), V = [\n      {\n        dataId: c.complexTensorInfos.real.dataId,\n        dtype: c.complexTensorInfos.real.dtype,\n        shape: Z.shape\n      },\n      {\n        dataId: c.complexTensorInfos.imag.dataId,\n        dtype: c.complexTensorInfos.imag.dtype,\n        shape: Z.shape\n      },\n      {\n        dataId: d.complexTensorInfos.real.dataId,\n        dtype: d.complexTensorInfos.real.dtype,\n        shape: h.shape\n      },\n      {\n        dataId: d.complexTensorInfos.imag.dataId,\n        dtype: d.complexTensorInfos.imag.dtype,\n        shape: h.shape\n      }\n    ], a = G.runWebGLProgram(W, V, \"float32\"), i = G.runWebGLProgram(Y, V, \"float32\"), m = zZ({ inputs: { real: a, imag: i }, backend: G });\n    return G.disposeIntermediateTensorInfo(a), G.disposeIntermediateTensorInfo(i), m;\n  }\n  if (G.shouldExecuteOnCPU([Z, h])) {\n    const c = G.texData.get(Z.dataId), d = G.texData.get(h.dataId), [W, Y] = zK(Z.shape, h.shape, c.values, d.values, g), V = G.makeTensorInfo(Y, g), a = G.texData.get(V.dataId);\n    return a.values = W, V;\n  }\n  let b;\n  return A().getBool(\"WEBGL_PACK_BINARY_OPERATIONS\") ? b = new m0(Ii, Z.shape, h.shape) : b = new sh(Ii, Z.shape, h.shape), G.runWebGLProgram(b, [Z, h], g);\n}\nconst M1 = {\n  kernelName: Xg,\n  backendName: \"webgl\",\n  kernelFunc: P9\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction w1(I, l, G) {\n  const Z = [\n    $h(I.shape),\n    ..._h(I.shape)\n  ], h = {\n    dtype: I.dtype,\n    shape: Z,\n    dataId: I.dataId\n  }, g = [\n    $h(l),\n    ..._h(l)\n  ], b = new JB(g, Z), c = !0, d = [Z], W = G.runWebGLProgram(b, [h], I.dtype, d, c);\n  return { dataId: W.dataId, shape: l, dtype: W.dtype };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ll(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { shape: g } = Z, b = G, c = Q(h.shape), d = ui(g, c), W = Q(d);\n  u(c === W, () => `The new shape (${d}) has ${W} elements and the old shape (${h.shape}) has ${c} elements. The new shape and old shape must have the same number of elements.`);\n  const Y = b.texData.get(h.dataId);\n  return Y.isPacked && !Gc(h.shape, d) && !(Y.texture !== null && Gc(Y.shape, d)) ? w1(h, d, b) : (b.incRef(h.dataId), { dataId: h.dataId, shape: d, dtype: h.dtype });\n}\nconst Q1 = {\n  kernelName: jc,\n  backendName: \"webgl\",\n  kernelFunc: ll\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Zi {\n  constructor(l, G) {\n    this.variableNames = [\"x\"];\n    const { windowSize: Z, batchSize: h, inSize: g, outSize: b } = l;\n    this.outputShape = [h, b];\n    const c = Math.floor(Z / 4) * 4, d = Z % 4;\n    let W = \"sumValue += dot(values, ones);\";\n    if (G != null) {\n      const V = 1 / G;\n      W = `sumValue += dot(values * ${Mh(V) ? V.toPrecision(2) : V}, ones);`;\n    }\n    let Y = \"\";\n    g % Z > 0 && (Y = `\n        if (inIdx < 0 || inIdx >= ${g}) {\n          return 0.0;\n        }\n      `), this.userCode = `\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float getValue(int batch, int inIdx) {\n        ${Y}\n        return getX(batch, inIdx);\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = outIdx * ${Z};\n\n        float sumValue = 0.0;\n\n        for (int i = 0; i < ${c}; i += 4) {\n          int inIdx = inOffset + i;\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            getValue(batch, inIdx + 3)\n          );\n\n          ${W}\n        }\n\n        int inIdx = inOffset + ${c};\n        if (${d === 1}) {\n          vec4 values = vec4(getValue(batch, inIdx), 0.0, 0.0, 0.0);\n\n          ${W}\n        } else if (${d === 2}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1), 0.0, 0.0);\n\n          ${W}\n        } else if (${d === 3}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2), 0.0);\n\n          ${W}\n        }\n        setOutput(sumValue);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass v1 {\n  constructor(l, G) {\n    this.variableNames = [\"x\"];\n    const { windowSize: Z, batchSize: h, inSize: g, outSize: b } = l;\n    this.outputShape = [h, b];\n    let c = \"0.0\", d = \"\";\n    G === \"prod\" ? c = \"1.0\" : G === \"min\" ? (c = \"1.0 / 1e-20\", d = \"min\") : G === \"max\" && (c = \"-1.0 / 1e-20\", d = \"max\");\n    let W = `${G}(${G}(${G}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;\n    G === \"sum\" ? W = \"sumValue\" : G === \"prod\" ? W = \"prodValue\" : G === \"all\" ? W = \"allValue\" : G === \"any\" && (W = \"anyValue\");\n    const Y = Math.floor(Z / 4) * 4, V = Z % 4;\n    let a = `\n      if (${G === \"sum\"}) {\n        sumValue += dot(values, ones);\n      } else if (${G === \"prod\"}) {\n        vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]);\n        prodValue *= tmp[0] * tmp[1];\n      } else {\n        minMaxValue = ${d}(values, minMaxValue);\n        if (${G === \"min\"} || ${G === \"max\"}) {\n          minMaxValue = ${d}(values, minMaxValue);\n          bvec4 isNaN = isnan(values);\n          if (isNaN.r || isNaN.g || isNaN.b || isNaN.a) {\n            minMaxValue = vec4(NAN);\n          }\n        }\n      }\n    `, i = \"vec4\";\n    G === \"all\" ? (c = \"1.0\", a = `\n        bool reducedAllValue = all(values);\n        float floatedReducedAllValue = float(reducedAllValue);\n        allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0);\n      `, i = \"bvec4\") : G === \"any\" && (c = \"0.0\", a = `\n        bool reducedAnyValue = any(values);\n        float floatedReducedAnyValue = float(reducedAnyValue);\n        anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0);\n      `, i = \"bvec4\");\n    let m = \"\";\n    g % Z > 0 && (m = `\n        if (inIdx < 0 || inIdx >= ${g}) {\n          return initializationValue;\n        }\n      `), this.userCode = `\n      const float initializationValue = ${c};\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float getValue(int batch, int inIdx) {\n        ${m}\n        return getX(batch, inIdx);\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = outIdx * ${Z};\n\n        vec4 minMaxValue = vec4(${c});\n        float prodValue = 1.0;\n        float sumValue = 0.0;\n        float allValue = 1.0;\n        float anyValue = 0.0;\n\n        for (int i = 0; i < ${Y}; i += 4) {\n          int inIdx = inOffset + i;\n          ${i} values = ${i}(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            getValue(batch, inIdx + 3)\n          );\n\n          ${a}\n        }\n\n        int inIdx = inOffset + ${Y};\n        if (${V === 1}) {\n          ${i} values = ${i}(\n            getValue(batch, inIdx),\n            initializationValue,\n            initializationValue,\n            initializationValue\n          );\n\n          ${a}\n        } else if (${V === 2}) {\n          ${i} values = ${i}(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            initializationValue,\n            initializationValue\n          );\n\n          ${a}\n        } else if (${V === 3}) {\n          ${i} values = ${i}(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            initializationValue\n          );\n\n          ${a}\n        }\n        setOutput(${W});\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction r1(I) {\n  const l = [];\n  for (; l.length === 0 || l[l.length - 1].outSize !== 1; ) {\n    const G = l.length ? l[l.length - 1].outSize : I[1], Z = md(G);\n    l.push({\n      inSize: G,\n      windowSize: Z,\n      outSize: Math.ceil(G / Z)\n    });\n  }\n  return l;\n}\nfunction yh(I, l, G, Z) {\n  const h = r1(I.shape);\n  let g = I;\n  for (let b = 0; b < h.length; b++) {\n    const { inSize: c, windowSize: d, outSize: W } = h[b];\n    let Y, V;\n    G === \"mean\" ? Y = b === 0 ? new Zi({ windowSize: d, inSize: c, batchSize: I.shape[0], outSize: W }, c) : new Zi({ windowSize: d, inSize: c, batchSize: I.shape[0], outSize: W }) : Y = new v1({ windowSize: d, inSize: c, batchSize: I.shape[0], outSize: W }, G), V = g, g = Z.runWebGLProgram(Y, [g], l), V.dataId !== I.dataId && Z.disposeIntermediateTensorInfo(V);\n  }\n  return g;\n}\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass j1 {\n  constructor(l, G) {\n    this.variableNames = [\"A\"];\n    const Z = new Array(l.length);\n    for (let b = 0; b < Z.length; b++)\n      Z[b] = l[G[b]];\n    this.outputShape = Z, this.rank = Z.length;\n    const h = Ul(this.rank), g = D1(G);\n    this.userCode = `\n    void main() {\n      ${h} resRC = getOutputCoords();\n      setOutput(getA(${g}));\n    }\n    `;\n  }\n}\nfunction D1(I) {\n  const l = I.length;\n  if (l > 6)\n    throw Error(`Transpose for rank ${l} is not yet supported`);\n  const G = [\"resRC.x\", \"resRC.y\", \"resRC.z\", \"resRC.w\", \"resRC.u\", \"resRC.v\"], Z = new Array(l);\n  for (let h = 0; h < I.length; h++)\n    Z[I[h]] = G[h];\n  return Z.join();\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass f1 {\n  constructor(l, G) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0;\n    const Z = new Array(l.length);\n    for (let Y = 0; Y < Z.length; Y++)\n      Z[Y] = l[G[Y]];\n    if (this.outputShape = Z, this.rank = Z.length, this.rank > 6)\n      throw Error(`Packed transpose for rank ${this.rank} is not yet supported.`);\n    const h = Ul(this.rank), g = PB(\"rc\", this.rank), b = new Array(this.rank);\n    for (let Y = 0; Y < G.length; Y++)\n      b[G[Y]] = g[Y];\n    const c = `vec2(${b.slice(-2).join()})`, d = `++${g[this.rank - 1]} < ${Z[this.rank - 1]}`, W = `getChannel(getA(${b.join()}), ${c})`;\n    this.userCode = `\n    void main() {\n      ${h} rc = getOutputCoords();\n      vec4 result = vec4(0.);\n      result[0] = ${W};\n      if(${d}) {\n        result[1] = ${W};\n      }\n      --${g[this.rank - 1]};\n      if(++${g[this.rank - 2]} < ${Z[this.rank - 2]}) {\n        result[2] = ${W};\n        if(${d}) {\n          result[3] = ${W};\n        }\n      }\n      setOutput(result);\n    }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Pd(I, l, G) {\n  const Z = A().getBool(\"WEBGL_PACK_ARRAY_OPERATIONS\") ? new f1(I.shape, l) : new j1(I.shape, l);\n  return G.runWebGLProgram(Z, [I], I.dtype);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction O1(I, l, G, Z) {\n  const h = l, g = I.shape.length, b = tl(h, I.shape);\n  let c = b;\n  const d = Ol(c, g), W = d != null;\n  let Y = I;\n  W && (Y = Pd(I, d, Z), c = GG(c.length, g)), XG(\"sum\", c, g);\n  const [V, a] = sG(Y.shape, c);\n  let i = V;\n  G && (i = bG(V, b));\n  const m = Q(a), s = Q(I.shape) / m, o = ll({ inputs: { x: Y }, attrs: { shape: [s, m] }, backend: Z }), B = AY(I.dtype), C = yh(o, B, \"sum\", Z), n = ll({ inputs: { x: C }, attrs: { shape: i }, backend: Z });\n  return Z.disposeIntermediateTensorInfo(o), Z.disposeIntermediateTensorInfo(C), W && Z.disposeIntermediateTensorInfo(Y), n;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Jd(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z;\n  return O1(h, g, b, G);\n}\nconst q1 = {\n  kernelName: _c,\n  backendName: \"webgl\",\n  kernelFunc: Jd\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction HG(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { perm: g } = Z, b = G, c = h.shape.length, d = new Array(c);\n  for (let Y = 0; Y < d.length; Y++)\n    d[Y] = h.shape[g[Y]];\n  let W;\n  if (b.shouldExecuteOnCPU([h])) {\n    const V = b.texData.get(h.dataId).values, a = y9(V, h.shape, h.dtype, g, d);\n    W = b.makeTensorInfo(d, h.dtype);\n    const i = b.texData.get(W.dataId);\n    i.values = a;\n  } else\n    W = Pd(h, g, b);\n  return W;\n}\nconst $1 = {\n  kernelName: Ah,\n  backendName: \"webgl\",\n  kernelFunc: HG\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst AB = 1e3;\nfunction Ic({ a: I, b: l, transposeA: G, transposeB: Z, backend: h, bias: g = null, preluActivationWeights: b = null, leakyreluAlpha: c = 0, activation: d = null }) {\n  const W = I.shape.length, Y = l.shape.length, V = G ? I.shape[W - 2] : I.shape[W - 1], a = Z ? l.shape[Y - 1] : l.shape[Y - 2], i = G ? I.shape[W - 1] : I.shape[W - 2], m = Z ? l.shape[Y - 2] : l.shape[Y - 1], T = I.shape.slice(0, -2), s = l.shape.slice(0, -2), o = Q(T), B = Q(s), n = sl(I.shape.slice(0, -2), l.shape.slice(0, -2)).concat([i, m]);\n  u(V === a, () => `Error in matMul: inner shapes (${V}) and (${a}) of Tensors with shapes ${I.shape} and ${l.shape} and transposeA=${G} and transposeB=${Z} must match.`);\n  const X = G ? [o, V, i] : [o, i, V], t = Z ? [B, m, a] : [B, a, m], e = ll({ inputs: { x: I }, backend: h, attrs: { shape: X } }), S = ll({ inputs: { x: l }, backend: h, attrs: { shape: t } }), p = [e, S], F = Math.max(o, B), x = G ? e.shape[1] : e.shape[2], H = g != null, K = b != null, z = d === \"leakyrelu\", k = d != null ? L0(d, !0) : null, L = H || K || z || k != null;\n  let v;\n  if ((i === 1 || m === 1) && x > AB && L === !1) {\n    let r = e, D = S;\n    G && (r = HG({ inputs: { x: e }, backend: h, attrs: { perm: [0, 2, 1] } }), p.push(r)), Z && (D = HG({ inputs: { x: S }, backend: h, attrs: { perm: [0, 2, 1] } }), p.push(D));\n    const f = m !== 1, $ = m === 1;\n    let q = r;\n    f && (q = ll({\n      inputs: { x: r },\n      backend: h,\n      attrs: { shape: [F, x, 1] }\n    }), p.push(q));\n    const Il = m === 1 ? 2 : 1;\n    let _ = D;\n    $ && (_ = ll({\n      inputs: { x: D },\n      backend: h,\n      attrs: { shape: [F, 1, x] }\n    }), p.push(_));\n    const gl = P9({ inputs: { a: q, b: _ }, backend: h });\n    v = Jd({ inputs: { x: gl }, backend: h, attrs: { axis: Il, keepDims: !0 } }), p.push(gl);\n  } else {\n    const r = DG(I.dtype, l.dtype), D = new KB(X, t, [F, i, m], G, Z, H, k, K, z), f = [e, S];\n    if (g != null && f.push(g), K && f.push(b), z) {\n      const $ = h.makeTensorInfo([], \"float32\", JZ(c, \"float32\"));\n      f.push($), p.push($);\n    }\n    v = h.runWebGLProgram(D, f, r);\n  }\n  const w = ll({ inputs: { x: v }, backend: h, attrs: { shape: n } });\n  p.push(v);\n  for (const r of p)\n    h.disposeIntermediateTensorInfo(r);\n  return w;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _1(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { a: h, b: g, bias: b, preluActivationWeights: c } = l, { transposeA: d, transposeB: W, activation: Y, leakyreluAlpha: V } = Z;\n  return Ic({\n    a: h,\n    b: g,\n    transposeA: d,\n    transposeB: W,\n    backend: G,\n    bias: b,\n    preluActivationWeights: c,\n    leakyreluAlpha: V,\n    activation: Y\n  });\n}\nconst lA = {\n  kernelName: Pb,\n  backendName: \"webgl\",\n  kernelFunc: _1\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hi = \"return abs(x);\";\nfunction GA(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  if (G.shouldExecuteOnCPU([Z]) && Z.dtype !== \"complex64\") {\n    const g = G.texData.get(Z.dataId), b = yB(g.values);\n    return G.makeTensorInfo(Z.shape, Z.dtype, b);\n  }\n  let h;\n  return A().getBool(\"WEBGL_PACK_UNARY_OPERATIONS\") ? h = new nZ(Z.shape, hi) : h = new kI(Z.shape, hi), G.runWebGLProgram(h, [Z], Z.dtype);\n}\nconst IA = {\n  kernelName: bc,\n  backendName: \"webgl\",\n  kernelFunc: GA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ZA = BI + `\n  if (abs(x) > 1.) {\n    return NAN;\n  }\n  return acos(x);\n`, hA = Rl({ opSnippet: ZA }), gA = {\n  kernelName: r0,\n  backendName: \"webgl\",\n  kernelFunc: hA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bA = BI + `\n  if (x < 1.0) return NAN;\nreturn log(x + sqrt(x * x - 1.0));`, cA = Rl({ opSnippet: bA }), dA = {\n  kernelName: j0,\n  backendName: \"webgl\",\n  kernelFunc: cA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst gi = \"return a + b;\", WA = tG({\n  opSnippet: gi,\n  packedOpSnippet: gi,\n  supportsComplex: !0,\n  cpuKernelImpl: nK\n}), YA = {\n  kernelName: I0,\n  backendName: \"webgl\",\n  kernelFunc: WA\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass VA {\n  constructor(l, G) {\n    this.outputShape = [], this.outputShape = l, this.variableNames = G.map((g, b) => `T${b}`);\n    const Z = [];\n    this.variableNames.forEach((g) => {\n      Z.push(`float v${g} = get${g}AtOutCoords();`);\n    });\n    const h = this.variableNames.map((g) => `v${g}`).join(\" + \");\n    this.userCode = `\n      void main() {\n        ${Z.join(`\n        `)}\n\n        float result = ${h};\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass aA {\n  constructor(l, G) {\n    this.outputShape = [], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = l, this.variableNames = G.map((g, b) => `T${b}`);\n    const Z = [];\n    this.variableNames.forEach((g) => {\n      Z.push(`vec4 v${g} = get${g}AtOutCoords();`);\n    });\n    const h = this.variableNames.map((g) => `v${g}`).join(\" + \");\n    this.userCode = `\n      void main() {\n        ${Z.join(`\n        `)}\n\n        vec4 result = ${h};\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction yb(I) {\n  const { inputs: l, backend: G } = I, Z = l;\n  if (Z.length === 1)\n    return OG({ inputs: { x: Z[0] }, backend: G });\n  if (Z.length > A().getNumber(\"WEBGL_MAX_TEXTURES_IN_SHADER\")) {\n    const d = Math.floor(Z.length / 2), W = yb({ inputs: Z.slice(0, d), backend: G }), Y = yb({ inputs: Z.slice(d), backend: G });\n    return yb({ inputs: [W, Y], backend: G });\n  }\n  const h = Z.map((d) => d.dtype).reduce((d, W) => DG(d, W)), g = Z.map((d) => d.shape), c = A().getBool(\"WEBGL_PACK\") ? new aA(Z[0].shape, g) : new VA(Z[0].shape, g);\n  return G.runWebGLProgram(c, Z, h);\n}\nconst iA = {\n  kernelName: OW,\n  backendName: \"webgl\",\n  kernelFunc: yb\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z, c = h.shape.length, d = tl(g, h.shape);\n  let W = d;\n  const Y = Ol(W, c);\n  let V = h;\n  Y != null && (V = HG({ inputs: { x: h }, backend: G, attrs: { perm: Y } }), W = GG(W.length, c)), XG(\"all\", W, c);\n  const [a, i] = sG(V.shape, W), m = Q(i), T = ll({ inputs: { x: V }, backend: G, attrs: { shape: [-1, m] } }), s = yh(T, T.dtype, \"all\", G);\n  let o;\n  if (b) {\n    const B = bG(a, d);\n    o = ll({ inputs: { x: s }, backend: G, attrs: { shape: B } });\n  } else\n    o = ll({ inputs: { x: s }, backend: G, attrs: { shape: a } });\n  return G.disposeIntermediateTensorInfo(T), G.disposeIntermediateTensorInfo(s), Y != null && G.disposeIntermediateTensorInfo(V), o;\n}\nconst TA = {\n  kernelName: qW,\n  backendName: \"webgl\",\n  kernelFunc: mA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z, c = h.shape.length, d = tl(g, h.shape);\n  let W = d;\n  const Y = Ol(W, c);\n  let V = h;\n  Y != null && (V = HG({ inputs: { x: h }, backend: G, attrs: { perm: Y } }), W = GG(W.length, c)), XG(\"any\", W, c);\n  const [a, i] = sG(V.shape, W), m = Q(i), T = ll({ inputs: { x: V }, backend: G, attrs: { shape: [-1, m] } }), s = yh(T, T.dtype, \"any\", G);\n  let o;\n  if (b) {\n    const B = bG(a, d);\n    o = ll({ inputs: { x: s }, backend: G, attrs: { shape: B } });\n  } else\n    o = ll({ inputs: { x: s }, backend: G, attrs: { shape: a } });\n  return G.disposeIntermediateTensorInfo(T), G.disposeIntermediateTensorInfo(s), Y != null && G.disposeIntermediateTensorInfo(V), o;\n}\nconst oA = {\n  kernelName: $W,\n  backendName: \"webgl\",\n  kernelFunc: sA\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass BA {\n  constructor(l, G, Z) {\n    this.variableNames = [\"A\"];\n    const { windowSize: h, batchSize: g, outSize: b } = l;\n    Z || this.variableNames.push(\"bestIndicesA\"), this.outputShape = [g, b];\n    const c = G === \"max\" ? \">\" : \"<\", d = Z ? \"inOffset + i;\" : \"round(getBestIndicesA(batch, inOffset + i));\";\n    this.userCode = `\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = outIdx * ${h};\n\n        int bestIndex = inOffset;\n        float bestValue = getA(batch, bestIndex);\n\n        for (int i = 0; i < ${h}; i++) {\n          int inIdx = ${d};\n          float candidate = getA(batch, inIdx);\n          if (candidate ${c} bestValue) {\n            bestValue = candidate;\n            bestIndex = inIdx;\n          }\n        }\n        setOutput(float(bestIndex));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass nA {\n  constructor(l, G, Z, h) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, u(l.length > 2, () => `Packed arg${Z.charAt(0).toUpperCase() + Z.slice(1)} supports only inputs with rank above 2.`);\n    const g = l[l.length - 1], b = Math.ceil(g / G);\n    this.outputShape = l.slice(0, -1), b > 1 && this.outputShape.push(b), h || this.variableNames.push(\"bestIndicesA\");\n    const c = this.outputShape, d = c.length, W = Ul(d), Y = xG(\"coords\", d);\n    let V, a;\n    if (b === 1) {\n      a = d + 1;\n      const S = Ul(a);\n      V = `\n        ${S} sourceLocR = ${S}(${Y.join()}, 0);\n        ++${Y[d - 1]};\n        ${S} sourceLocG = ${S}(${Y.join()}, 0);\n        ++${Y[d - 2]};\n        ${S} sourceLocA = ${S}(${Y.join()}, 0);\n        --${Y[d - 1]};\n        ${S} sourceLocB = ${S}(${Y.join()}, 0);\n        --${Y[d - 2]};`;\n    } else\n      a = d, V = `\n        ${W} sourceLocR = coords;\n        ++${Y[d - 1]};\n        ${W} sourceLocG = coords;\n        ++${Y[d - 2]};\n        ${W} sourceLocA = coords;\n        --${Y[d - 1]};\n        ${W} sourceLocB = coords;\n        --${Y[d - 2]};`;\n    const i = [\"x\", \"y\", \"z\", \"w\", \"u\", \"v\"].slice(0, a), m = \".\" + i[a - 1], T = i.map((S) => \"int \" + S), s = xG(\"sourceLocR\", a - 1).concat(\"inIdx.r\"), o = xG(\"sourceLocG\", a - 1).concat(\"inIdx.g\"), B = xG(\"sourceLocB\", a - 1).concat(\"inIdx.b\"), C = xG(\"sourceLocA\", a - 1).concat(\"inIdx.a\"), n = Z === \"max\" ? \"greaterThan\" : \"lessThan\", X = h ? \"\" : `\n          inIdx = round(vec4(getBestIndicesAChannel(${s.join()}),\n                             getBestIndicesAChannel(${o.join()}),\n                             getBestIndicesAChannel(${B.join()}),\n                             getBestIndicesAChannel(${C.join()})));`, t = `vec4(\n            getAChannel(${s.join()}),\n            hasNextCol ? getAChannel(${o.join()}) : 0.,\n            hasNextRow ? getAChannel(${B.join()}) : 0.,\n            hasNextRow && hasNextCol ? getAChannel(${C.join()}) : 0.)`, e = h ? \"\" : `\n      float getBestIndicesAChannel(${T.join()}) {\n        return getChannel(getBestIndicesA(${i.join()}),\n                                          vec2(${i.slice(-2).join()}));\n      }`;\n    this.userCode = `\n      float getAChannel(${T.join()}) {\n        return getChannel(getA(${i.join()}),\n                               vec2(${i.slice(-2).join()}));\n      }\n      ${e}\n      void main() {\n        ${W} coords = getOutputCoords();\n        bool hasNextCol = ${Y[d - 1]} < ${c[d - 1] - 1};\n        bool hasNextRow = ${Y[d - 2]} < ${c[d - 2] - 1};\n        ${V}\n        ivec4 srcIdx = ivec4(sourceLocR${m}, sourceLocG${m},\n          sourceLocB${m}, sourceLocA${m}) * ${G};\n        ivec4 inIdx = srcIdx;\n        vec4 bestIndex = vec4(inIdx);\n        vec4 bestValue = ${t};\n\n        for (int i = 0; i < ${G}; i++) {\n          inIdx = srcIdx;\n          ${X}\n          vec4 candidate = ${t};\n          bvec4 nan = isnan(candidate);\n          bvec4 replace = bvec4(\n            vec4(${n}(candidate, bestValue)) * (vec4(1.0) - vec4(nan)));\n\n          bestValue = vec4(replace.x  ? candidate.x : bestValue.x,\n                           replace.y  ? candidate.y : bestValue.y,\n                           replace.z  ? candidate.z : bestValue.z,\n                           replace.w  ? candidate.w : bestValue.w);\n          bestIndex = mix(bestIndex, vec4(inIdx), vec4(replace));\n          srcIdx++;\n        }\n        setOutput(bestIndex);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kB(I, l, G, Z = null) {\n  let h = l.shape[0], g = l.shape[1];\n  Z != null && (h = Z.shape[0], g = Z.shape[1]);\n  const b = md(g), c = { windowSize: b, inSize: g, batchSize: h, outSize: Math.ceil(g / b) }, d = new BA(c, G, Z == null), W = [l];\n  Z != null && W.push(Z);\n  const Y = I.runWebGLProgram(d, W, \"int32\");\n  if (Y.shape[1] === 1)\n    return Y;\n  const V = kB(I, l, G, Y);\n  return I.disposeIntermediateTensorInfo(Y), V;\n}\nfunction zB(I, l, G, Z = null) {\n  const h = Z != null ? Z.shape : l.shape, g = h[h.length - 1], b = md(g), c = new nA(h, b, G, Z == null), d = Z == null ? [l] : [l, Z], W = I.runWebGLProgram(c, d, \"int32\");\n  if (W.shape.length === l.shape.length) {\n    const Y = zB(I, l, G, W);\n    return I.disposeIntermediateTensorInfo(W), Y;\n  }\n  return W;\n}\nfunction LB(I, l, G, Z) {\n  const h = [G];\n  if (XG(\"arg\" + Z.charAt(0).toUpperCase() + Z.slice(1), h, l.shape.length), !A().getBool(\"WEBGL_PACK_REDUCE\") || l.shape.length <= 2) {\n    const g = [], b = I.texData.get(l.dataId), c = b !== null && b.isPacked;\n    let d = l;\n    c && (d = I.unpackTensor(l), g.push(d));\n    const [W, Y] = sG(d.shape, h), V = Q(Y), a = ll({ inputs: { x: d }, backend: I, attrs: { shape: [-1, V] } });\n    g.push(a);\n    const i = kB(I, a, Z);\n    g.push(i);\n    const m = ll({ inputs: { x: i }, backend: I, attrs: { shape: W } });\n    return g.forEach((T) => I.disposeIntermediateTensorInfo(T)), m;\n  }\n  return zB(I, l, Z);\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction CA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g } = Z;\n  let b = tl(g, h.shape);\n  const c = Ol(b, h.shape.length);\n  let d = h;\n  const W = [];\n  c != null && (d = HG({ inputs: { x: h }, backend: G, attrs: { perm: c } }), W.push(d), b = GG(b.length, d.shape.length)), XG(\"argMax\", [b[0]], d.shape.length);\n  const Y = LB(G, d, b[0], \"max\");\n  return W.forEach((V) => G.disposeIntermediateTensorInfo(V)), Y;\n}\nconst XA = {\n  kernelName: cc,\n  backendName: \"webgl\",\n  kernelFunc: CA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction tA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g } = Z;\n  let b = tl(g, h.shape);\n  const c = Ol(b, h.shape.length);\n  let d = h;\n  const W = [];\n  c != null && (d = HG({ inputs: { x: h }, backend: G, attrs: { perm: c } }), W.push(d), b = GG(b.length, d.shape.length)), XG(\"argMin\", [b[0]], d.shape.length);\n  const Y = LB(G, d, b[0], \"min\");\n  return W.forEach((V) => G.disposeIntermediateTensorInfo(V)), Y;\n}\nconst uA = {\n  kernelName: dc,\n  backendName: \"webgl\",\n  kernelFunc: tA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst eA = BI + `\n  if (abs(x) > 1.) {\n    return NAN;\n  }\n  return asin(x);\n`, SA = Rl({ opSnippet: eA }), RA = {\n  kernelName: D0,\n  backendName: \"webgl\",\n  kernelFunc: SA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst pA = BI + \"return log(x + sqrt(x * x + 1.0));\", FA = Rl({ opSnippet: pA }), yA = {\n  kernelName: f0,\n  backendName: \"webgl\",\n  kernelFunc: FA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst NA = BI + `\n  return atan(x);\n`, PA = Rl({ opSnippet: NA }), JA = {\n  kernelName: O0,\n  backendName: \"webgl\",\n  kernelFunc: PA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst EA = N9 + `\n  return atan(a, b);\n`, xA = `\n  vec4 result = atan(a, b);\n  bvec4 isNaNA = isnan(a);\n  bvec4 isNaNB = isnan(b);\n  bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w);\n  ` + Fh + `\n  return result;\n`, UA = tG({ opSnippet: EA, packedOpSnippet: xA }), HA = {\n  kernelName: $0,\n  backendName: \"webgl\",\n  kernelFunc: UA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst KA = BI + `\n  if ((x < -1.0) || (x > 1.0)) return NAN;\nreturn (log(1.0 + x) - log(1.0 - x)) / 2.0;`, AA = Rl({ opSnippet: KA }), kA = {\n  kernelName: q0,\n  backendName: \"webgl\",\n  kernelFunc: AA\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass M0 {\n  constructor(l, G, Z, h = !1, g = !1) {\n    if (this.variableNames = [\"x\"], G === \"avg\" && Z)\n      throw new Error(\"Cannot compute positions for average pool.\");\n    const b = l.filterWidth, c = l.strideHeight, d = l.strideWidth, W = l.dilationHeight, Y = l.dilationWidth, V = l.effectiveFilterHeight, a = l.effectiveFilterWidth, i = l.padInfo.top, m = l.padInfo.left;\n    this.outputShape = l.outShape;\n    const T = G === \"avg\", s = `((batch  * ${l.inHeight} + xR) * ${l.inWidth} + xC) * ${l.inChannels} + d`, o = `(xR * ${l.inWidth} + xC) * ${l.inChannels} + d`;\n    let B = \"0.0\";\n    if (T || (B = \"-1.0 / 1e-20\"), Z) {\n      const S = \">=\";\n      this.userCode = `\n        const ivec2 strides = ivec2(${c}, ${d});\n        const ivec2 pads = ivec2(${i}, ${m});\n\n        void main() {\n          ivec4 coords = getOutputCoords();\n          int batch = coords[0];\n          int d = coords[3];\n\n          ivec2 xRCCorner = coords.yz * strides - pads;\n          int xRCorner = xRCCorner.x;\n          int xCCorner = xRCCorner.y;\n\n          // max/min x(?, ?, d) to get y(yR, yC, d).\n          // ? = to be determined\n          float minMaxValue = 0.0;\n          float minMaxValueFound = 0.0;\n          int minMaxPosition = 0;\n          float avgValue = 0.0;\n\n          for (int wR = 0; wR < ${V};\n              wR += ${W}) {\n            int xR = xRCorner + wR;\n\n            if (xR < 0 || xR >= ${l.inHeight}) {\n              continue;\n            }\n\n            for (int wC = 0; wC < ${a};\n                wC += ${Y}) {\n              int xC = xCCorner + wC;\n\n              if (xC < 0 || xC >= ${l.inWidth}) {\n                continue;\n              }\n\n              float value = getX(batch, xR, xC, d);\n\n              // If a min / max value has already been found, use it. If not,\n              // use the current value.\n              float currMinMaxValue = mix(\n                  value, minMaxValue, minMaxValueFound);\n              if (value ${S} currMinMaxValue) {\n                minMaxValue = value;\n                minMaxValueFound = 1.0;\n                minMaxPosition = ${h ? g ? s : o : `wR * ${a} + wC`};\n              }\n            }\n          }\n          setOutput(float(minMaxPosition));\n        }\n      `;\n      return;\n    }\n    const C = \"max\";\n    let n = `${G}(${G}(${G}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;\n    G === \"avg\" && (n = \"avgValue / max(count, 1.0)\");\n    const X = Math.floor(b / 4) * 4, t = b % 4, e = `\n      if (${T}) {\n        avgValue += dot(values, ones);\n      } else {\n        minMaxValue = ${C}(values, minMaxValue);\n      }\n    `;\n    this.userCode = `\n      const ivec2 strides = ivec2(${c}, ${d});\n      const ivec2 pads = ivec2(${i}, ${m});\n      const float initializationValue = ${B};\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float count = 0.0;\n\n      float getValue(int batch, int xR, int xC, int d) {\n        if (xC < 0 || xC >= ${l.inWidth}) {\n          return initializationValue;\n        }\n        count += 1.0;\n        return getX(batch, xR, xC, d);\n      }\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d = coords[3];\n\n        ivec2 xRCCorner = coords.yz * strides - pads;\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // max/min x(?, ?, d) to get y(yR, yC, d).\n        // ? = to be determined\n        vec4 minMaxValue = vec4(${B});\n        float avgValue = 0.0;\n        count = 0.0;\n\n        for (int wR = 0; wR < ${V};\n            wR += ${W}) {\n          int xR = xRCorner + wR;\n\n          if (xR < 0 || xR >= ${l.inHeight}) {\n            continue;\n          }\n\n          for (int wC = 0; wC < ${X}; wC += 4) {\n            int xC = xCCorner + wC * ${Y};\n\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              getValue(batch, xR, xC + ${Y}, d),\n              getValue(batch, xR, xC + 2 * ${Y}, d),\n              getValue(batch, xR, xC + 3 * ${Y}, d)\n            );\n\n            ${e}\n          }\n\n          int xC = xCCorner + ${X};\n          if (${t === 1}) {\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              initializationValue,\n              initializationValue,\n              initializationValue\n            );\n\n            ${e}\n          } else if (${t === 2}) {\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              getValue(batch, xR, xC + ${Y}, d),\n              initializationValue,\n              initializationValue\n            );\n\n            ${e}\n          } else if (${t === 3}) {\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              getValue(batch, xR, xC + ${Y}, d),\n              getValue(batch, xR, xC + 2 * ${Y}, d),\n              initializationValue\n            );\n\n            ${e}\n          }\n        }\n        setOutput(${n});\n      }\n    `;\n  }\n}\nclass J9 {\n  constructor(l, G, Z, h = !1, g = !1) {\n    if (this.variableNames = [\"x\"], G === \"avg\" && Z)\n      throw new Error(\"Cannot compute positions for average pool.\");\n    const b = l.filterWidth, c = l.strideDepth, d = l.strideHeight, W = l.strideWidth, Y = l.dilationDepth, V = l.dilationHeight, a = l.dilationWidth, i = l.effectiveFilterDepth, m = l.effectiveFilterHeight, T = l.effectiveFilterWidth, s = l.padInfo.front, o = l.padInfo.top, B = l.padInfo.left;\n    this.outputShape = l.outShape;\n    const C = G === \"avg\";\n    let n = \"0.0\";\n    if (C || (n = \"-1.0 / 1e-20\"), Z) {\n      const F = \">=\";\n      this.userCode = `\n        const ivec3 strides =\n            ivec3(${c}, ${d}, ${W});\n        const ivec3 pads = ivec3(${s}, ${o}, ${B});\n\n        void main() {\n          ivec5 coords = getOutputCoords();\n          int batch = coords.x;\n          int ch = coords.u;\n\n          ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n          int xDCorner = xCorner.x;\n          int xRCorner = xCorner.y;\n          int xCCorner = xCorner.z;\n\n          // max/min x(?, ?, ?, ch) to get y(yD, yR, yC, ch).\n          // ? = to be determined\n          float minMaxValue = 0.0;\n          float minMaxValueFound = 0.0;\n          int minMaxPosition = 0;\n\n          for (int wD = 0; wD < ${i};\n              wD += ${Y}) {\n            int xD = xDCorner + wD;\n\n            if (xD < 0 || xD >= ${l.inDepth}) {\n              continue;\n            }\n\n            for (int wR = 0; wR < ${m};\n                wR += ${V}) {\n              int xR = xRCorner + wR;\n\n              if (xR < 0 || xR >= ${l.inHeight}) {\n                continue;\n              }\n\n              for (int wC = 0; wC < ${T};\n                  wC += ${a}) {\n                int xC = xCCorner + wC;\n\n                if (xC < 0 || xC >= ${l.inWidth}) {\n                  continue;\n                }\n\n                float value = getX(batch, xD, xR, xC, ch);\n\n                // If a min / max value has already been found, use it. If not,\n                // use the current value.\n                float currMinMaxValue = mix(\n                    value, minMaxValue, minMaxValueFound);\n                if (value ${F} currMinMaxValue) {\n                  minMaxValue = value;\n                  minMaxValueFound = 1.0;\n                  minMaxPosition = ${h ? g ? `(((batch * ${l.inDepth} + xD) * ${l.inHeight} + xR) * ${l.inWidth} + xC) * ${l.inChannels} + ch` : `((xD * ${l.inHeight} + xR) * ${l.inWidth} + xC) * ${l.inChannels} + ch` : `wD * ${m} * ${T} +\n                      wR * ${T} + wC`};\n                }\n              }\n            }\n          }\n          setOutput(float(minMaxPosition));\n        }\n      `;\n      return;\n    }\n    const X = \"max\";\n    let t = `${G}(${G}(${G}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;\n    G === \"avg\" && (t = \"avgValue / max(count, 1.0)\");\n    const e = Math.floor(b / 4) * 4, S = b % 4, p = `\n      if (${C}) {\n        avgValue += dot(values, ones);\n      } else {\n        minMaxValue = ${X}(values, minMaxValue);\n      }\n    `;\n    this.userCode = `\n      const ivec3 strides =\n        ivec3(${c}, ${d}, ${W});\n      const ivec3 pads = ivec3(${s}, ${o}, ${B});\n      const float initializationValue = ${n};\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float count = 0.0;\n\n      float getValue(int batch, int xD, int xR, int xC, int ch) {\n        if (xC < 0 || xC >= ${l.inWidth}) {\n          return initializationValue;\n        }\n        count += 1.0;\n        return getX(batch, xD, xR, xC, ch);\n      }\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int ch = coords.u;\n\n        ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n        int xDCorner = xCorner.x;\n        int xRCorner = xCorner.y;\n        int xCCorner = xCorner.z;\n\n        // max/min x(?, ?, ?, d) to get y(yD, yR, yC, ch).\n        // ? = to be determined\n        vec4 minMaxValue = vec4(${n});\n        float avgValue = 0.0;\n        count = 0.0;\n\n        for (int wD = 0; wD < ${i};\n            wD += ${Y}) {\n          int xD = xDCorner + wD;\n\n          if (xD < 0 || xD >= ${l.inDepth}) {\n            continue;\n          }\n\n          for (int wR = 0; wR < ${m};\n            wR += ${V}) {\n            int xR = xRCorner + wR;\n\n            if (xR < 0 || xR >= ${l.inHeight}) {\n              continue;\n            }\n\n            for (int wC = 0; wC < ${e}; wC += 4) {\n              int xC = xCCorner + wC * ${a};\n\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                getValue(batch, xD, xR, xC + ${a}, ch),\n                getValue(batch, xD, xR, xC + 2 * ${a}, ch),\n                getValue(batch, xD, xR, xC + 3 * ${a}, ch)\n              );\n\n              ${p}\n            }\n\n            int xC = xCCorner + ${e};\n            if (${S === 1}) {\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                initializationValue,\n                initializationValue,\n                initializationValue\n              );\n\n              ${p}\n            } else if (${S === 2}) {\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                getValue(batch, xD, xR, xC + ${a}, ch),\n                initializationValue,\n                initializationValue\n              );\n\n              ${p}\n            } else if (${S === 3}) {\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                getValue(batch, xD, xR, xC + ${a}, ch),\n                getValue(batch, xD, xR, xC + 2 * ${a}, ch),\n                initializationValue\n              );\n\n              ${p}\n            }\n          }\n        }\n        setOutput(${t});\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l;\n  cb(h, \"avgPool\");\n  const { filterSize: g, strides: b, pad: c, dimRoundingMode: d } = Z, W = 1;\n  u(pG(b, W), () => `Error in avgPool: Either strides or dilations must be 1. Got strides ${b} and dilations '${W}'`);\n  const Y = sI(h.shape, g, b, W, c, d);\n  if (Y.filterWidth === 1 && Y.filterHeight === 1 && Nl(Y.inShape, Y.outShape))\n    return OG({ inputs: { x: h }, backend: G });\n  const V = new M0(Y, \"avg\", !1);\n  return G.runWebGLProgram(V, [h], \"float32\");\n}\nconst LA = {\n  kernelName: Wc,\n  backendName: \"webgl\",\n  kernelFunc: zA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction MA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { filterSize: g, strides: b, pad: c, dimRoundingMode: d, dataFormat: W } = Z, Y = [1, 1, 1], V = WZ(h.shape, g, b, Y, c, d, W), a = new J9(V, \"avg\", !1);\n  return G.runWebGLProgram(a, [h], \"float32\");\n}\nconst wA = {\n  kernelName: Yc,\n  backendName: \"webgl\",\n  kernelFunc: MA\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass QA {\n  constructor(l) {\n    this.variableNames = [\"dy\"], this.outputShape = l.inShape;\n    const G = l.filterHeight, Z = l.filterWidth, h = l.strideHeight, g = l.strideWidth, b = l.dilationHeight, c = l.dilationWidth, d = l.effectiveFilterHeight, W = l.effectiveFilterWidth, Y = d - 1 - l.padInfo.top, V = W - 1 - l.padInfo.left, a = 1 / (G * Z);\n    this.userCode = `\n      const ivec2 pads = ivec2(${Y}, ${V});\n      const float avgMultiplier = float(${a});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n\n        ivec2 dyRCCorner = coords.yz - pads;\n        int dyRCorner = dyRCCorner.x;\n        int dyCCorner = dyRCCorner.y;\n\n        // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${d};\n            wR += ${b}) {\n          float dyR = float(dyRCorner + wR) / ${h}.0;\n\n          if (dyR < 0.0 || dyR >= ${l.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          for (int wC = 0; wC < ${W};\n            wC+= ${c}) {\n            float dyC = float(dyCCorner + wC) / ${g}.0;\n\n            if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            float dyValue = getDy(b, idyR, idyC, d);\n\n            dotProd += dyValue * avgMultiplier;\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\nclass vA {\n  constructor(l) {\n    this.variableNames = [\"dy\"], this.outputShape = l.inShape;\n    const G = l.filterDepth, Z = l.filterHeight, h = l.filterWidth, g = l.strideDepth, b = l.strideHeight, c = l.strideWidth, d = l.dilationDepth, W = l.dilationHeight, Y = l.dilationWidth, V = l.effectiveFilterDepth, a = l.effectiveFilterHeight, i = l.effectiveFilterWidth, m = V - 1 - l.padInfo.front, T = a - 1 - l.padInfo.top, s = i - 1 - l.padInfo.left, o = 1 / (G * Z * h);\n    this.userCode = `\n      const ivec3 pads = ivec3(${m}, ${T}, ${s});\n      const float avgMultiplier = float(${o});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int ch = coords.u;\n\n        ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n        int dyDCorner = dyCorner.x;\n        int dyRCorner = dyCorner.y;\n        int dyCCorner = dyCorner.z;\n\n        // Convolve dy(?, ?, ?, d) with pos mask(:, :, :, ch) to get\n        // dx(xD, xR, xC, ch).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n\n        for (int wD = 0; wD < ${V};\n            wD += ${d}) {\n          float dyD = float(dyDCorner + wD) / ${g}.0;\n\n          if (dyD < 0.0 || dyD >= ${l.outDepth}.0 || fract(dyD) > 0.0) {\n            continue;\n          }\n          int idyD = int(dyD);\n\n          for (int wR = 0; wR < ${a};\n              wR += ${W}) {\n            float dyR = float(dyRCorner + wR) / ${b}.0;\n\n            if (dyR < 0.0 || dyR >= ${l.outHeight}.0 ||\n                fract(dyR) > 0.0) {\n              continue;\n            }\n            int idyR = int(dyR);\n\n            for (int wC = 0; wC < ${i};\n                wC += ${Y}) {\n              float dyC = float(dyCCorner + wC) / ${c}.0;\n\n              if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                  fract(dyC) > 0.0) {\n                continue;\n              }\n              int idyC = int(dyC);\n\n              float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n\n              dotProd += dyValue * avgMultiplier;\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction rA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g } = l, b = g, { filterSize: c, strides: d, pad: W, dimRoundingMode: Y } = Z, V = [1, 1, 1], a = WZ(b.shape, c, d, V, W, Y), i = new vA(a);\n  return G.runWebGLProgram(i, [h], b.dtype);\n}\nconst jA = {\n  kernelName: lY,\n  backendName: \"webgl\",\n  kernelFunc: rA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction DA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g } = l, b = g;\n  cb([h, g], \"avgPoolGrad\");\n  const { filterSize: c, strides: d, pad: W } = Z, Y = sI(b.shape, c, d, 1, W), V = new QA(Y);\n  return G.runWebGLProgram(V, [h], b.dtype);\n}\nconst fA = {\n  kernelName: _W,\n  backendName: \"webgl\",\n  kernelFunc: DA\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction OA(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { a: h, b: g } = l, { transposeA: b, transposeB: c } = Z;\n  return Ic({ a: h, b: g, transposeA: b, transposeB: c, backend: G });\n}\nconst qA = {\n  kernelName: Vc,\n  backendName: \"webgl\",\n  kernelFunc: OA\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass $A {\n  constructor(l, G, Z, h, g, b) {\n    this.outputShape = [], this.variableNames = [\"x\", \"mean\", \"variance\"], sl(l, G), sl(l, Z);\n    let c = \"0.0\";\n    h != null && (sl(l, h), this.variableNames.push(\"offset\"), c = \"getOffsetAtOutCoords()\");\n    let d = \"1.0\";\n    g != null && (sl(l, g), this.variableNames.push(\"scale\"), d = \"getScaleAtOutCoords()\"), this.outputShape = l, this.userCode = `\n      void main() {\n        float x = getXAtOutCoords();\n        float mean = getMeanAtOutCoords();\n        float variance = getVarianceAtOutCoords();\n        float offset = ${c};\n        float scale = ${d};\n        float inv = scale * inversesqrt(variance + float(${b}));\n        setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1)));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass _A {\n  constructor(l, G, Z, h, g, b) {\n    this.packedInputs = !0, this.packedOutput = !0, this.variableNames = [\"x\", \"mean\", \"variance\"], sl(l, G), sl(l, Z);\n    let c = \"vec4(0.0)\";\n    h != null && (sl(l, h), this.variableNames.push(\"offset\"), c = \"getOffsetAtOutCoords()\");\n    let d = \"vec4(1.0)\";\n    g != null && (sl(l, g), this.variableNames.push(\"scale\"), d = \"getScaleAtOutCoords()\"), this.outputShape = l, this.userCode = `\n      void main() {\n        vec4 offset = ${c};\n        vec4 scale = ${d};\n\n        vec4 x = getXAtOutCoords();\n        vec4 mean = getMeanAtOutCoords();\n        vec4 variance = getVarianceAtOutCoords();\n\n        vec4 inv = scale * inversesqrt(variance + vec4(${b}));\n\n        setOutput((x - mean) * inv + offset);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst lk = ({ inputs: I, backend: l, attrs: G }) => {\n  const { x: Z, mean: h, variance: g, offset: b, scale: c } = I;\n  u(h.shape.length === g.shape.length, () => \"Batch normalization gradient requires mean and variance to have equal ranks.\"), u(b == null || h.shape.length === b.shape.length, () => \"Batch normalization gradient requires mean and offset to have equal ranks.\"), u(c == null || h.shape.length === c.shape.length, () => \"Batch normalization gradient requires mean and scale to have equal ranks.\");\n  let { varianceEpsilon: d } = G;\n  d == null && (d = 1e-3);\n  const W = [Z, h, g];\n  let Y = null;\n  b != null && (Y = b.shape, W.push(b));\n  let V = null;\n  c != null && (V = c.shape, W.push(c));\n  const a = A().getBool(\"WEBGL_PACK_NORMALIZATION\") ? new _A(Z.shape, h.shape, g.shape, Y, V, d) : new $A(Z.shape, h.shape, g.shape, Y, V, d);\n  return l.runWebGLProgram(a, W, W[0].dtype);\n}, Gk = {\n  kernelName: uc,\n  backendName: \"webgl\",\n  kernelFunc: lk\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Ik {\n  constructor(l) {\n    this.variableNames = [\"source\"], this.outputShape = l, this.rank = l.length;\n    const G = Ul(this.rank);\n    this.customUniforms = [{ name: \"start\", arrayIndex: this.rank, type: \"int\" }];\n    const Z = Zk(this.rank);\n    let h;\n    const g = l.map((b, c) => `sourceLoc.${AW[c]} = start[${c}] + coords.${AW[c]};`);\n    h = `\n        ${G} sourceLoc;\n        ${G} coords = getOutputCoords();\n        ${g.join(`\n`)}\n      `, this.userCode = `\n      void main() {\n        ${h}\n        setOutput(getSource(${Z}));\n      }\n    `;\n  }\n}\nconst AW = [\"x\", \"y\", \"z\", \"w\", \"u\", \"v\"];\nfunction Zk(I) {\n  if (I === 1)\n    return \"sourceLoc\";\n  if (I <= 6)\n    return AW.slice(0, I).map((l) => \"sourceLoc.\" + l).join(\",\");\n  throw Error(`Slicing for rank ${I} is not yet supported`);\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass hk {\n  constructor(l) {\n    this.variableNames = [\"source\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = l, this.rank = l.length, this.customUniforms = [{ name: \"start\", arrayIndex: this.rank, type: \"int\" }];\n    const G = Ul(this.rank), Z = xG(\"coords\", this.rank), h = xG(\"sourceLoc\", this.rank), g = this.rank === 1 ? \"sourceLoc\" : `vec2(${h.slice(-2).join()})`, b = `getChannel(getSource(${h.join()}), ${g})`, c = `\n      result.x = ${b};\n      if (++${Z[this.rank - 1]} < ${l[this.rank - 1]}) {\n        ++${h[this.rank - 1]};\n        result.y = ${b};\n        --${h[this.rank - 1]};\n      }\n    `, d = this.rank === 1 ? \"\" : `\n      --${Z[this.rank - 1]};\n      if (++${Z[this.rank - 2]} < ${l[this.rank - 2]}) {\n        ++${h[this.rank - 2]};\n        result.z = ${b};\n        if (++${Z[this.rank - 1]} < ${l[this.rank - 1]}) {\n          ++${h[this.rank - 1]};\n          result.w = ${b};\n        }\n      }\n    `, W = this.rank <= 4 ? `sourceLoc = coords +\n            ${G}(${l.map((Y, V) => `start[${V}]`).join()});` : l.map((Y, V) => `${h[V]} = ${Z[V]} + start[${V}];`).join(`\n`);\n    this.userCode = `\n      void main() {\n        ${G} coords = getOutputCoords();\n        ${G} sourceLoc;\n        ${W}\n        vec4 result = vec4(0.);\n        ${c}\n        ${d}\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction gk(I, l, G, Z) {\n  const h = Z.texData.get(I.dataId), g = Z.makeTensorInfo(G, I.dtype), b = Z.texData.get(g.dataId);\n  Object.assign(b, h), b.refCount = 1, b.shape = G, b.dtype = I.dtype;\n  let c = pV(l, Wl(I.shape));\n  h.slice && (c += h.slice.flatOffset), b.slice = {\n    flatOffset: c,\n    // Point to the original dataId, which is used to do ref counting.\n    origDataId: h.slice && h.slice.origDataId || I.dataId\n  };\n  const d = Z.dataRefCount.get(b.slice.origDataId) || 1;\n  return Z.dataRefCount.set(b.slice.origDataId, d + 1), g;\n}\nfunction s0(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { begin: g, size: b } = Z, [c, d] = id(h, g, b);\n  if (eV(h, c, d), Q(d) === 0)\n    return G.makeTensorInfo(d, h.dtype, []);\n  if (G.shouldExecuteOnCPU([h]) || h.dtype === \"string\") {\n    const V = G.texData.get(h.dataId), a = qK(V.values, c, d, h.shape, h.dtype);\n    return G.makeTensorInfo(d, h.dtype, a);\n  }\n  const { isPacked: W } = G.texData.get(h.dataId), Y = RV(h.shape, c, d);\n  if (W || !Y) {\n    const V = A().getBool(\"WEBGL_PACK_ARRAY_OPERATIONS\") ? new hk(d) : new Ik(d), a = [c];\n    return G.runWebGLProgram(V, [h], h.dtype, a);\n  }\n  return G.uploadToGPU(h.dataId), gk(h, c, d, G);\n}\nconst bk = {\n  kernelName: $c,\n  backendName: \"webgl\",\n  kernelFunc: s0\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ck = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { blockShape: g, crops: b } = Z;\n  u(h.shape.length <= 4, () => \"batchToSpaceND for rank > 4 with a WebGL backend not implemented yet\");\n  const c = g.reduce((B, C) => B * C), d = Dg(h.shape, g, c), W = fg(d.length, g.length), Y = Og(h.shape, g, c), V = JV(b, g.length), a = EV(Y, b, g.length), i = [], m = ll({ inputs: { x: h }, backend: G, attrs: { shape: d } }), T = HG({ inputs: { x: m }, backend: G, attrs: { perm: W } }), s = ll({\n    inputs: { x: T },\n    backend: G,\n    attrs: { shape: Y }\n  }), o = s0({\n    inputs: { x: s },\n    backend: G,\n    attrs: { begin: V, size: a }\n  });\n  return i.push(m), i.push(T), i.push(s), i.forEach((B) => G.disposeIntermediateTensorInfo(B)), o;\n}, dk = {\n  kernelName: ac,\n  backendName: \"webgl\",\n  kernelFunc: ck\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Wk(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, weights: g } = l, { size: b } = Z, c = G.readSync(h.dataId), d = G.readSync(g.dataId), W = FB(c, d, g.dtype, g.shape, b);\n  return G.makeTensorInfo([b], g.dtype, W);\n}\nconst Yk = {\n  kernelName: GY,\n  backendName: \"webgl\",\n  kernelFunc: Wk\n};\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Vk = `\n  int r = int(a.r) & int(b.r);\n  int g = int(a.g) & int(b.g);\n  int rb = int(a.b) & int(b.b);\n  int ra = int(a.a) & int(b.a);\n  return vec4(r, g, rb, ra);\n`, ak = `\n  return float(int(a.r) & int(b.r));\n`;\nfunction ik(I) {\n  const { inputs: l, backend: G } = I, { a: Z, b: h } = l, g = A().getBool(\"WEBGL_PACK_BINARY_OPERATIONS\"), b = A().getNumber(\"WEBGL_VERSION\");\n  if (G.shouldExecuteOnCPU([Z, h]) || b === 1) {\n    const d = G.texData.get(Z.dataId).values, W = G.texData.get(h.dataId).values, [Y, V] = XK(Z.shape, h.shape, d, W, Z.dtype), a = G.makeTensorInfo(V, Z.dtype), i = G.texData.get(a.dataId);\n    return i.values = Y, a;\n  }\n  let c;\n  return g ? c = new m0(Vk, Z.shape, h.shape, !1) : c = new sh(ak, Z.shape, h.shape), G.runWebGLProgram(c, [Z, h], Z.dtype);\n}\nconst mk = {\n  kernelName: IY,\n  backendName: \"webgl\",\n  kernelFunc: ik\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Tk(I) {\n  const { inputs: l, backend: G } = I, { s0: Z, s1: h } = l, g = G.readSync(Z.dataId), b = G.readSync(h.dataId), c = sl(Array.from(g), Array.from(b));\n  return G.makeTensorInfo([c.length], \"int32\", Int32Array.from(c));\n}\nconst sk = {\n  kernelName: yi,\n  backendName: \"webgl\",\n  kernelFunc: Tk\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ok = \"return float(a != b);\", MB = tG({ opSnippet: ok, cpuKernelImpl: MK, dtype: \"bool\" }), Bk = {\n  kernelName: zc,\n  backendName: \"webgl\",\n  kernelFunc: MB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Wb(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l, h = G.texData.get(Z.dataId);\n  return OG({ inputs: { x: h.complexTensorInfos.real }, backend: G });\n}\nconst nk = {\n  kernelName: pY,\n  backendName: \"webgl\",\n  kernelFunc: Wb\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ck = \"return float(int(x));\";\nfunction Xk(I, l) {\n  const G = new kI(I.shape, Ck), Z = l.runWebGLProgram(G, [I], \"int32\");\n  return { dataId: Z.dataId, shape: Z.shape, dtype: Z.dtype };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kW(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { dtype: g } = Z;\n  if (g === \"complex64\") {\n    if (h.dtype === \"complex64\")\n      return OG({ inputs: { x: h }, backend: G });\n    const b = mG(h.shape), c = kW({ inputs: { x: h }, backend: G, attrs: { dtype: \"float32\" } }), d = zZ({ inputs: { real: c, imag: b }, backend: G });\n    return b.dispose(), G.disposeIntermediateTensorInfo(c), d;\n  }\n  if (h.dtype === \"complex64\") {\n    const b = Wb({ inputs: { input: h }, backend: G }), c = kW({ inputs: { x: b }, backend: G, attrs: { dtype: g } });\n    return G.disposeIntermediateTensorInfo(b), c;\n  }\n  if (!ei(h.dtype, g)) {\n    const b = OG({ inputs: { x: h }, backend: G });\n    return { dataId: b.dataId, shape: b.shape, dtype: g };\n  }\n  if (G.shouldExecuteOnCPU([h])) {\n    const b = G.texData.get(h.dataId).values, [c, d, W] = tK(b, h.shape, h.dtype, g);\n    return G.makeTensorInfo(c, d, W);\n  }\n  if (g === \"int32\")\n    return Xk(h, G);\n  if (g === \"bool\") {\n    const b = G.makeTensorInfo([], \"bool\", eG(\"bool\", 1)), d = MB({ inputs: { a: h, b }, backend: G });\n    return G.disposeIntermediateTensorInfo(b), d;\n  }\n  throw new Error(`Error in Cast: failed to cast ${h.dtype} to ${g}`);\n}\nconst tk = {\n  kernelName: _0,\n  backendName: \"webgl\",\n  kernelFunc: kW\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bi = \"return ceil(x);\", uk = Rl({ opSnippet: bi, packedOpSnippet: bi, cpuKernelImpl: uK }), ek = {\n  kernelName: lg,\n  backendName: \"webgl\",\n  kernelFunc: uk\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Sk {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.customUniforms = [\n      { name: \"minVal\", type: \"float\" },\n      { name: \"maxVal\", type: \"float\" }\n    ], this.outputShape = l, this.userCode = `\n\n      void main() {\n        float value = getAAtOutCoords();\n        if (isnan(value)) {\n          setOutput(value);\n          return;\n        }\n\n        setOutput(clamp(value, minVal, maxVal));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Rk {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [\n      { name: \"minVal\", type: \"float\" },\n      { name: \"maxVal\", type: \"float\" }\n    ], this.outputShape = l, this.userCode = `\n      void main() {\n        vec4 value = getAAtOutCoords();\n\n        if (any(isnan(value))) {\n          setOutput(value);\n          return;\n        }\n\n        setOutput(clamp(value, vec4(minVal), vec4(maxVal)));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pk(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { clipValueMin: g, clipValueMax: b } = Z;\n  let c;\n  A().getBool(\"WEBGL_PACK_CLIP\") ? c = new Rk(h.shape) : c = new Sk(h.shape);\n  const d = [[g], [b]];\n  return G.runWebGLProgram(c, [h], h.dtype, d);\n}\nconst Fk = {\n  kernelName: Gg,\n  backendName: \"webgl\",\n  kernelFunc: pk\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass yk {\n  constructor(l) {\n    this.variableNames = [\"real\", \"imag\"], this.outputShape = l, this.userCode = `\n      void main() {\n        float re = abs(getRealAtOutCoords());\n        float im = abs(getImagAtOutCoords());\n        float mx = max(re, im);\n\n        // sadly the length function in glsl is not underflow-safe\n        // (at least not on Intel GPUs). So the safe solution is\n        // to ensure underflow-safety in all cases.\n        setOutput(\n          mx == 0.0 ? 0.0 : mx * length(vec2(1, min(re, im)/mx))\n        );\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ci(I, l) {\n  return {\n    dataId: l.dataId,\n    dtype: l.dtype,\n    shape: I.shape\n  };\n}\nfunction Nk(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l, h = G.texData.get(Z.dataId), g = new yk(Z.shape), b = [\n    ci(Z, h.complexTensorInfos.real),\n    ci(Z, h.complexTensorInfos.imag)\n  ];\n  return G.runWebGLProgram(g, b, b[0].dtype);\n}\nconst Pk = {\n  kernelName: ic,\n  backendName: \"webgl\",\n  kernelFunc: Nk\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Jk {\n  // Concats 2d tensors along axis=1. See comments in MathBackendWebGL.concat().\n  constructor(l) {\n    this.outputShape = [], this.outputShape = MI(\n      l,\n      1\n      /* axis */\n    ), this.variableNames = l.map((b, c) => `T${c}`);\n    const G = new Array(l.length - 1);\n    G[0] = l[0][1];\n    for (let b = 1; b < G.length; b++)\n      G[b] = G[b - 1] + l[b][1];\n    const Z = [`if (yC < ${G[0]}) setOutput(getT0(yR, yC));`];\n    for (let b = 1; b < G.length; b++) {\n      const c = G[b - 1];\n      Z.push(`else if (yC < ${G[b]}) setOutput(getT${b}(yR, yC-${c}));`);\n    }\n    const h = G.length, g = G[G.length - 1];\n    Z.push(`else setOutput(getT${h}(yR, yC-${g}));`), this.userCode = `\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int yR = coords.x;\n        int yC = coords.y;\n\n        ${Z.join(`\n        `)}\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Ek {\n  constructor(l, G) {\n    this.packedInputs = !0, this.packedOutput = !0, this.outputShape = [], this.outputShape = MI(l, G);\n    const Z = this.outputShape, h = Z.length, g = Ul(h), b = xG(\"coords\", h), c = [\"x\", \"y\", \"z\", \"w\", \"u\", \"v\"].slice(0, h);\n    this.variableNames = l.map((T, s) => `T${s}`);\n    const d = new Array(l.length - 1);\n    d[0] = l[0][G];\n    for (let T = 1; T < d.length; T++)\n      d[T] = d[T - 1] + l[T][G];\n    const W = c[G], Y = c.slice(-2), V = c.join();\n    let a = `if (${W} < ${d[0]}) {\n        return getChannel(\n            getT0(${V}), vec2(${Y.join()}));\n        }`;\n    for (let T = 1; T < d.length; T++) {\n      const s = d[T - 1];\n      a += `\n        if (${W} < ${d[T]}  && ${W} >= ${d[T - 1]}) {\n          return getChannel(\n            getT${T}(${pb(c, W, s)}),\n            vec2(${pb(Y, W, s)}));\n        }`;\n    }\n    const i = d.length, m = d[d.length - 1];\n    a += `\n        return getChannel(\n          getT${i}(${pb(c, W, m)}),\n          vec2(${pb(Y, W, m)}));`, this.userCode = `\n      float getValue(${c.map((T) => \"int \" + T)}) {\n        ${a}\n      }\n\n      void main() {\n        ${g} coords = getOutputCoords();\n        vec4 result = vec4(getValue(${b}), 0., 0., 0.);\n\n        ${b[h - 1]} = ${b[h - 1]} + 1;\n        if (${b[h - 1]} < ${Z[h - 1]}) {\n          result.g = getValue(${b});\n        }\n\n        ${b[h - 2]} = ${b[h - 2]} + 1;\n        if (${b[h - 2]} < ${Z[h - 2]}) {\n          result.a = getValue(${b});\n        }\n\n        ${b[h - 1]} = ${b[h - 1]} - 1;\n        if (${b[h - 2]} < ${Z[h - 2]} &&\n            ${b[h - 1]} < ${Z[h - 1]}) {\n          result.b = getValue(${b});\n        }\n        setOutput(result);\n      }\n    `;\n  }\n}\nfunction pb(I, l, G) {\n  const Z = I.indexOf(l);\n  return I.map((g, b) => b === Z ? `${g} - ${G}` : g).join();\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ed(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l, h = G.texData.get(Z.dataId);\n  return OG({ inputs: { x: h.complexTensorInfos.imag }, backend: G });\n}\nconst xk = {\n  kernelName: nY,\n  backendName: \"webgl\",\n  kernelFunc: Ed\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction F0(I, l, G) {\n  const Z = I[0].dtype;\n  if (Z === \"complex64\") {\n    const i = I.map((B) => Wb({ inputs: { input: B }, backend: G })), m = I.map((B) => Ed({ inputs: { input: B }, backend: G })), T = F0(i, l, G), s = F0(m, l, G), o = zZ({ inputs: { real: T, imag: s }, backend: G });\n    return i.forEach((B) => G.disposeIntermediateTensorInfo(B)), m.forEach((B) => G.disposeIntermediateTensorInfo(B)), G.disposeIntermediateTensorInfo(T), G.disposeIntermediateTensorInfo(s), o;\n  }\n  let h = G.shouldExecuteOnCPU(I);\n  if (Z === \"string\" && (h = !0), h) {\n    const i = I.map((n) => {\n      const t = [-1, Q(n.shape.slice(l))];\n      return ll({ inputs: { x: n }, backend: G, attrs: { shape: t } });\n    }), m = i.map((n) => ({ vals: G.readSync(n.dataId), shape: n.shape })), T = MI(\n      i.map((n) => n.shape),\n      1\n      /* axis */\n    ), s = i[0].shape[0] === 1, o = eK(m, T, Z, s), B = MI(I.map((n) => n.shape), l), C = G.makeTensorInfo(B, Z, o);\n    return i.forEach((n) => G.disposeIntermediateTensorInfo(n)), C;\n  }\n  const g = I.filter((i) => Q(i.shape) > 0), b = A().getBool(\"WEBGL_PACK_ARRAY_OPERATIONS\") && g[0].shape.length > 1;\n  if (g.length === 1) {\n    const i = b ? new kI(I[0].shape, sZ) : new nZ(I[0].shape, sZ);\n    return G.runWebGLProgram(i, I, Z);\n  }\n  const c = A().getNumber(\"WEBGL_MAX_TEXTURES_IN_SHADER\");\n  if (g.length > c) {\n    const i = [];\n    for (let T = 0; T < g.length; T += c) {\n      const s = g.slice(T, T + c);\n      i.push(F0(s, l, G));\n    }\n    const m = F0(i, l, G);\n    for (const T of i)\n      G.disposeIntermediateTensorInfo(T);\n    return m;\n  }\n  if (b) {\n    const i = new Ek(g.map((m) => m.shape), l);\n    return G.runWebGLProgram(i, g, Z);\n  }\n  const { tensors2D: d, outShape: W } = Uk(g, l, G), Y = new Jk(d.map((i) => i.shape)), V = G.runWebGLProgram(Y, d, Z);\n  d.forEach((i) => G.disposeIntermediateTensorInfo(i));\n  const a = ll({ inputs: { x: V }, attrs: { shape: W }, backend: G });\n  return G.disposeIntermediateTensorInfo(V), a;\n}\nfunction Uk(I, l, G) {\n  const Z = MI(I.map((g) => g.shape), l);\n  return { tensors2D: I.map((g) => ll({\n    inputs: { x: g },\n    attrs: { shape: [-1, Q(g.shape.slice(l))] },\n    backend: G\n  })), outShape: Z };\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction wB(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { axis: h } = Z, g = tl(h, l[0].shape)[0], b = l.map((W) => W.shape);\n  yV(b, g);\n  const c = MI(l.map((W) => W.shape), g);\n  if (Q(c) === 0)\n    return G.makeTensorInfo(c, l[0].dtype, []);\n  const d = l.filter((W) => Q(W.shape) > 0);\n  return d.length === 1 ? OG({ inputs: { x: d[0] }, backend: G }) : F0(d, g, G);\n}\nconst Hk = {\n  kernelName: mc,\n  backendName: \"webgl\",\n  kernelFunc: wB\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass QB {\n  constructor(l, G = !1, Z = null, h = !1, g = !1) {\n    this.variableNames = [\"x\", \"W\"], this.outputShape = l.outShape;\n    const b = l.padInfo.top, c = l.padInfo.left, d = l.strideHeight, W = l.strideWidth, Y = l.dilationHeight, V = l.dilationWidth, a = l.filterHeight, i = l.filterWidth, m = Math.floor(l.inChannels / 4) * 4, T = l.inChannels % 4, s = l.dataFormat === \"channelsLast\", o = s ? 1 : 2, B = s ? 2 : 3, C = s ? 3 : 1;\n    let n = \"\", X = \"\";\n    Z && (h ? n = `float activation(float a) {\n          float b = getPreluActivationWeightsAtOutCoords();\n          ${Z}\n        }` : g ? n = `float activation(float a) {\n          float b = getLeakyreluAlphaAtOutCoords();\n          ${Z}\n        }` : n = `\n          float activation(float x) {\n            ${Z}\n          }\n        `, X = \"result = activation(result);\");\n    const t = G ? \"result += getBiasAtOutCoords();\" : \"\";\n    G && this.variableNames.push(\"bias\"), h && this.variableNames.push(\"preluActivationWeights\"), g && this.variableNames.push(\"leakyreluAlpha\"), this.userCode = `\n      ${n}\n\n      const ivec2 strides = ivec2(${d}, ${W});\n      const ivec2 pads = ivec2(${b}, ${c});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d2 = coords[${C}];\n\n        ivec2 xRCCorner =\n            ivec2(coords[${o}], coords[${B}]) * strides - pads;\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${a}; wR++) {\n          int xR = xRCorner + wR * ${Y};\n\n          if (xR < 0 || xR >= ${l.inHeight}) {\n            continue;\n          }\n\n          for (int wC = 0; wC < ${i}; wC++) {\n            int xC = xCCorner + wC * ${V};\n\n            if (xC < 0 || xC >= ${l.inWidth}) {\n              continue;\n            }\n\n            for (int d1 = 0; d1 < ${m}; d1 += 4) {\n              vec4 wValues = vec4(\n                getW(wR, wC, d1, d2),\n                getW(wR, wC, d1 + 1, d2),\n                getW(wR, wC, d1 + 2, d2),\n                getW(wR, wC, d1 + 3, d2)\n              );\n\n              if (${s}) {\n                vec4 xValues = vec4(\n                  getX(batch, xR, xC, d1),\n                  getX(batch, xR, xC, d1 + 1),\n                  getX(batch, xR, xC, d1 + 2),\n                  getX(batch, xR, xC, d1 + 3)\n                );\n                dotProd += dot(xValues, wValues);\n              } else {\n                vec4 xValues = vec4(\n                  getX(batch, d1, xR, xC),\n                  getX(batch, d1 + 1, xR, xC),\n                  getX(batch, d1 + 2, xR, xC),\n                  getX(batch, d1 + 3, xR, xC)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n            }\n\n            if (${T === 1}) {\n\n              if (${s}) {\n                dotProd +=\n                    getX(batch, xR, xC, ${m}) *\n                    getW(wR, wC, ${m}, d2);\n              } else {\n                dotProd +=\n                    getX(batch, ${m}, xR, xC) *\n                    getW(wR, wC, ${m}, d2);\n              }\n\n            } else if (${T === 2}) {\n              vec2 wValues = vec2(\n                getW(wR, wC, ${m}, d2),\n                getW(wR, wC, ${m} + 1, d2)\n              );\n\n              if (${s}) {\n                vec2 xValues = vec2(\n                  getX(batch, xR, xC, ${m}),\n                  getX(batch, xR, xC, ${m} + 1)\n                );\n                dotProd += dot(xValues, wValues);\n              } else {\n                vec2 xValues = vec2(\n                  getX(batch, ${m}, xR, xC),\n                  getX(batch, ${m} + 1, xR, xC)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n\n            } else if (${T === 3}) {\n              vec3 wValues = vec3(\n                getW(wR, wC, ${m}, d2),\n                getW(wR, wC, ${m} + 1, d2),\n                getW(wR, wC, ${m} + 2, d2)\n              );\n\n              if (${s}) {\n                vec3 xValues = vec3(\n                  getX(batch, xR, xC, ${m}),\n                  getX(batch, xR, xC, ${m} + 1),\n                  getX(batch, xR, xC, ${m} + 2)\n                );\n                dotProd += dot(xValues, wValues);\n              } else {\n                vec3 xValues = vec3(\n                  getX(batch, ${m}, xR, xC),\n                  getX(batch, ${m} + 1, xR, xC),\n                  getX(batch, ${m} + 2, xR, xC)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n\n            }\n          }\n        }\n\n        float result = dotProd;\n        ${t}\n        ${X}\n        setOutput(result);\n      }\n    `;\n  }\n}\nclass Kk {\n  constructor(l) {\n    this.variableNames = [\"x\", \"W\"], this.outputShape = l.outShape;\n    const G = l.padInfo.front, Z = l.padInfo.top, h = l.padInfo.left, g = l.strideDepth, b = l.strideHeight, c = l.strideWidth, d = l.dilationDepth, W = l.dilationHeight, Y = l.dilationWidth, V = l.filterDepth, a = l.filterHeight, i = l.filterWidth, m = Math.floor(l.inChannels / 4) * 4, T = l.inChannels % 4;\n    this.userCode = `\n      const ivec3 strides = ivec3(${g}, ${b}, ${c});\n      const ivec3 pads = ivec3(${G}, ${Z}, ${h});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int d2 = coords.u;\n\n        ivec3 xFRCCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n        int xFCorner = xFRCCorner.x;\n        int xRCorner = xFRCCorner.y;\n        int xCCorner = xFRCCorner.z;\n\n        // Convolve x(?, ?, ?, d1) with w(:, :, :, d1, d2) to get\n        // y(yF, yR, yC, d2). ? = to be determined. : = across all\n        // values in that axis.\n        float dotProd = 0.0;\n        for (int wF = 0; wF < ${V}; wF++) {\n          int xF = xFCorner + wF * ${d};\n\n          if (xF < 0 || xF >= ${l.inDepth}) {\n            continue;\n          }\n\n          for (int wR = 0; wR < ${a}; wR++) {\n            int xR = xRCorner + wR * ${W};\n\n            if (xR < 0 || xR >= ${l.inHeight}) {\n              continue;\n            }\n\n            for (int wC = 0; wC < ${i}; wC++) {\n              int xC = xCCorner + wC * ${Y};\n\n              if (xC < 0 || xC >= ${l.inWidth}) {\n                continue;\n              }\n\n              for (int d1 = 0; d1 < ${m}; d1 += 4) {\n                vec4 xValues = vec4(\n                  getX(batch, xF, xR, xC, d1),\n                  getX(batch, xF, xR, xC, d1 + 1),\n                  getX(batch, xF, xR, xC, d1 + 2),\n                  getX(batch, xF, xR, xC, d1 + 3)\n                );\n                vec4 wValues = vec4(\n                  getW(wF, wR, wC, d1, d2),\n                  getW(wF, wR, wC, d1 + 1, d2),\n                  getW(wF, wR, wC, d1 + 2, d2),\n                  getW(wF, wR, wC, d1 + 3, d2)\n                );\n\n                dotProd += dot(xValues, wValues);\n              }\n\n              if (${T === 1}) {\n                dotProd +=\n                  getX(batch, xF, xR, xC, ${m}) *\n                  getW(wF, wR, wC, ${m}, d2);\n              } else if (${T === 2}) {\n                vec2 xValues = vec2(\n                  getX(batch, xF, xR, xC, ${m}),\n                  getX(batch, xF, xR, xC, ${m} + 1)\n                );\n                vec2 wValues = vec2(\n                  getW(wF, wR, wC, ${m}, d2),\n                  getW(wF, wR, wC, ${m} + 1, d2)\n                );\n                dotProd += dot(xValues, wValues);\n              } else if (${T === 3}) {\n                vec3 xValues = vec3(\n                  getX(batch, xF, xR, xC, ${m}),\n                  getX(batch, xF, xR, xC, ${m} + 1),\n                  getX(batch, xF, xR, xC, ${m} + 2)\n                );\n                vec3 wValues = vec3(\n                  getW(wF, wR, wC, ${m}, d2),\n                  getW(wF, wR, wC, ${m} + 1, d2),\n                  getW(wF, wR, wC, ${m} + 2, d2)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass vB {\n  constructor(l, G = !1, Z = null, h = !1, g = !1) {\n    this.variableNames = [\"x\", \"W\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [\n      { name: \"pads\", type: \"ivec2\" },\n      { name: \"strides\", type: \"ivec2\" },\n      { name: \"dilations\", type: \"ivec2\" },\n      { name: \"inDims\", type: \"ivec2\" }\n    ], this.outputShape = l.outShape, this.enableShapeUniforms = yG(this.outputShape.length);\n    const b = l.padInfo.left, c = l.strideWidth, d = l.dilationWidth, W = l.filterHeight, Y = l.filterWidth, V = Y;\n    let a = `\n       int xR; int xC; int xCOffset;\n       vec4 wTexel; vec4 previous; vec4 final;`;\n    for (let s = 0; s < Y; s++)\n      a += `\n           vec4 xTexelC${s * 2};\n           int xTexelC${s * 2}Ready;\n           vec4 xTexelC${s * 2 + 1};\n           int xTexelC${s * 2 + 1}Ready;\n           vec4 xC${s};`;\n    a += `\n     for (int r = 0; r < ${W}; r++) {\n      for (int d1 = 0; d1 < ${l.inChannels}; d1 += 2) {\n       `;\n    for (let s = 0; s < Y; s++)\n      a += `\n           xTexelC${s * 2} = vec4(0.0);\n           xTexelC${s * 2}Ready = 0;\n           xTexelC${s * 2 + 1} = vec4(0.0);\n           xTexelC${s * 2 + 1}Ready = 0;\n           xC${s} = vec4(0.0);`;\n    a += `\n         xR = xRCorner + r * dilations[0];\n         if (xR >=0 && xR < inDims[0]) {\n       `;\n    for (let s = 0; s < (V + 1) / 2; s++) {\n      const o = s * 2;\n      if (a += `\n           xC = xCCorner + ${o * d};\n           `, c === 1) {\n        if (o < Y && (b % 2 === 1 ? (a += `\n                 xCOffset = xC + 1;\n                 if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${o}Ready == 0) {\n                   xTexelC${o} = getX(batch, xR, xCOffset, d1);\n\n                   // Need to manually clear unused channels in case\n                   // we're reading from recycled texture.\n                   if (xCOffset + 1 >= inDims[1]) {\n                     xTexelC${o}.zw = vec2(0.0);\n                   }\n                   xTexelC${o}Ready = 1;\n                 }\n               `, d === 1 && o > 0 ? a += `\n                 xC${o} = vec4(xTexelC${o - 2}.zw, xTexelC${o}.xy);\n                 ` : a += `\n                   xCOffset = xC + 1 - 2;\n\n                   if (xCOffset >= 0 && xCOffset < inDims[1]) {\n                     previous = getX(batch, xR, xCOffset, d1);\n\n                     // Need to manually clear unused channels in case\n                     // we're reading from recycled texture.\n                     if (xCOffset + 1 >= inDims[1]) {\n                       previous.zw = vec2(0.0);\n                     }\n\n                     xC${o} = vec4(previous.zw, xTexelC${o}.xy);\n                   } else {\n                     xC${o} = vec4(0.0, 0.0, xTexelC${o}.xy);\n                   }\n                   `) : a += `\n                 if (xC >= 0 && xC < inDims[1] && xTexelC${o}Ready == 0) {\n                   xTexelC${o} = getX(batch, xR, xC, d1);\n                   if (xC + 1 >= inDims[1]) {\n                     xTexelC${o}.zw = vec2(0.0);\n                   }\n                   xTexelC${o}Ready = 1;\n                 }\n\n                 xC${o} = xTexelC${o};\n                 `, o + 1 < Y)) {\n          const B = b % 2 === 0 ? QW(d) : d;\n          d % 2 === 0 && b % 2 === 1 || d % 2 !== 0 && b % 2 !== 1 ? (a += `\n                   xCOffset = xC + imod(pads[1], 2) + ${B};\n\n                   if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${o + 1}Ready == 0) {\n                     xTexelC${o + 1} = getX(batch, xR, xCOffset, d1);\n\n                     // Need to manually clear unused channels in case\n                     // we're reading from recycled texture.\n                     if (xCOffset + 1 >= inDims[1]) {\n                       xTexelC${o + 1}.zw = vec2(0.0);\n                     }\n                     xTexelC${o + 1}Ready = 1;\n                   }\n                   `, d > 1 ? a += `\n                     xCOffset -= 2;\n                     if (xCOffset >= 0 && xCOffset < inDims[1]) {\n                      previous = getX(batch, xR, xCOffset, d1);\n                      xC${o + 1} = vec4(previous.zw, xTexelC${o + 1}.xy);\n                     } else {\n                      xC${o + 1} = vec4(0.0, 0.0, xTexelC${o + 1}.xy);\n                     }\n                     ` : a += `\n                     xC${o + 1} = vec4(xTexelC${o}.zw, xTexelC${o + 1}.xy);\n                     `) : B === 1 ? a += `\n                     xC${o + 1} = xTexelC${o};\n                     ` : a += `\n                     xCOffset = xC + ${B};\n\n                     if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${o + 1}Ready == 0) {\n                       xTexelC${o + 1} = getX(batch, xR, xCOffset, d1);\n                       if (xCOffset + 1 >= inDims[1]) {\n                         xTexelC${o + 1}.zw = vec2(0.0);\n                       }\n                       xTexelC${o + 1}Ready = 1;\n                     }\n\n                     xC${o + 1} = xTexelC${o + 1};\n                     `;\n        }\n      } else\n        o < Y && (b % 2 === 1 ? (a += `\n                 xCOffset = xC + 1 - strides[1];\n                 if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${o}Ready == 0) {\n                   xTexelC${o} = getX(batch, xR, xCOffset, d1);\n                   // Need to manually clear unused channels in case\n                   // we're reading from recycled texture.\n                   if (xCOffset + 1 >= inDims[1]) {\n                     xTexelC${o}.zw = vec2(0.0);\n                   }\n                   xTexelC${o}Ready = 1;\n                 }\n\n                 if(xC + 1 >= 0 && xC + 1 < inDims[1] && xTexelC${o + 1}Ready == 0) {\n                   xTexelC${o + 1} = getX(batch, xR, xC + 1, d1);\n                   // Need to manually clear unused channels in case\n                   // we're reading from recycled texture.\n                   if (xC + 2 >= inDims[1]) {\n                     xTexelC${o + 1}.zw = vec2(0.0);\n                   }\n                   xTexelC${o + 1}Ready = 1;\n                 }\n\n                 xC${o} = vec4(xTexelC${o}.zw, xTexelC${o + 1}.zw);\n               `, o + 1 < Y && (a += `\n                   final = vec4(0.0);\n                   xCOffset = xC + 1 + strides[1];\n                   if(xCOffset >= 0 && xCOffset < inDims[1]) {\n                     final = getX(batch, xR, xCOffset, d1);\n                   }\n                   xC${o + 1} = vec4(xTexelC${o + 1}.xy, final.xy);\n                 `)) : (a += `\n                 if(xC >= 0 && xC < inDims[1] && xTexelC${o}Ready == 0) {\n                   xTexelC${o} = getX(batch, xR, xC, d1);\n                   if (xC + 1 >= inDims[1]) {\n                     xTexelC${o}.zw = vec2(0.0);\n                   }\n                   xTexelC${o}Ready = 1;\n                 }\n\n                 xCOffset = xC + strides[1];\n                 if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${o + 1}Ready == 0) {\n                   xTexelC${o + 1} = getX(batch, xR, xCOffset, d1);\n                   if (xCOffset + 1 >= inDims[1]) {\n                     xTexelC${o + 1}.zw = vec2(0.);\n                   }\n                   xTexelC${o + 1}Ready = 1;\n                 }\n\n                 xC${o} = vec4(\n                   xTexelC${o}.xy, xTexelC${o + 1}.xy);\n               `, o + 1 < Y && (a += `\n                   xC${o + 1} = vec4(xTexelC${o}.zw, xTexelC${o + 1}.zw);\n                 `)));\n      o < Y && (a += `\n             wTexel = getW(r, ${o}, d1, d2);\n             dotProd += xC${o}.xxzz * vec4(wTexel.xy, wTexel.xy);\n             if(d1 + 1 < ${l.inChannels}) {\n               dotProd += xC${o}.yyww * vec4(wTexel.zw, wTexel.zw);\n             }\n           `, o + 1 < Y && (a += `\n               wTexel = getW(r, ${o + 1}, d1, d2);\n               dotProd += xC${o + 1}.xxzz * vec4(wTexel.xy, wTexel.xy);\n               if(d1 + 1 < ${l.inChannels}) {\n                 dotProd += xC${o + 1}.yyww * vec4(wTexel.zw, wTexel.zw);\n               }\n             `));\n    }\n    a += `\n     }\n   `, a += `\n     }\n   `, a += `\n     }\n   `;\n    let i = \"\", m = \"\";\n    Z && (h ? i = `vec4 activation(vec4 a) {\n           vec4 b = getPreluActivationWeightsAtOutCoords();\n           ${Z}\n         }` : g ? i = `vec4 activation(vec4 a) {\n           vec4 b = getLeakyreluAlphaAtOutCoords();\n           ${Z}\n         }` : i = `vec4 activation(vec4 x) {\n           ${Z}\n         }`, m = \"result = activation(result);\");\n    const T = G ? \"result += getBiasAtOutCoords();\" : \"\";\n    G && this.variableNames.push(\"bias\"), h && this.variableNames.push(\"preluActivationWeights\"), g && this.variableNames.push(\"leakyreluAlpha\"), this.userCode = `\n       ${i}\n\n       void main() {\n         ivec4 coords = getOutputCoords();\n         int batch = coords.x;\n         ivec2 xRCCorner = coords.yz * strides - pads;\n         int d2 = coords.w;\n         int xRCorner = xRCCorner.x;\n         int xCCorner = xRCCorner.y;\n\n         //intialize dotProd with a small epsilon seems to reduce GPU accuracy loss.\n         vec4 dotProd = vec4(0.000000000000001);\n\n         ${a}\n\n         vec4 result = dotProd - vec4(0.000000000000001);\n         ${T}\n         ${m}\n         setOutput(result);\n       }\n     `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Ak {\n  constructor(l, G) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [\n      { name: \"inputShape\", type: \"ivec4\" },\n      { name: \"pad\", type: \"ivec2\" },\n      { name: \"stride\", type: \"ivec2\" },\n      { name: \"dilation\", type: \"ivec2\" },\n      { name: \"inChannels\", type: \"int\" },\n      { name: \"itemsPerBlockRow\", type: \"int\" },\n      { name: \"outWidth\", type: \"int\" }\n    ], this.outputShape = l, this.enableShapeUniforms = yG(this.outputShape.length);\n    const { dataFormat: Z } = G, h = KG(), g = Z === \"channelsLast\", b = g ? 1 : 2, c = g ? 2 : 3, d = this.enableShapeUniforms ? \"if(blockIndex < outShape[2] && pos < outShape[1]) {\" : `if(blockIndex < ${l[2]} && pos < ${l[1]}) {`;\n    let W = \"\";\n    for (let Y = 0; Y <= 1; Y++)\n      for (let V = 0; V <= 1; V++)\n        W += `\n          blockIndex = rc.z + ${V};\n          pos = rc.y + ${Y};\n\n          ${d}\n            offsetY = int(blockIndex / outWidth) * stride[0] - pad[0];\n            d0 = offsetY + dilation[0] * (pos / itemsPerBlockRow);\n\n            if(d0 < inputShape[${b}] && d0 >= 0) {\n              // Use custom imod instead mod. On Intel GPU, mod may generate\n              // unexpected value.\n              // https://github.com/tensorflow/tfjs/issues/5447\n              offsetX = imod(blockIndex, outWidth) * stride[1] - pad[1];\n              d1 = offsetX + dilation[1] * (imod(pos, itemsPerBlockRow) /\n                  inChannels);\n\n              if(d1 < inputShape[${c}] && d1 >= 0) {\n\n                ch = imod(pos, inChannels);\n\n                if (${g}) {\n                  innerDims = vec2(d1, ch);\n                  result[${Y * 2 + V}] = getChannel(\n                    getA(rc.x, d0, int(innerDims.x),\n                    int(innerDims.y)), innerDims);\n                } else {\n                  innerDims = vec2(d0, d1);\n                  result[${Y * 2 + V}] = getChannel(\n                    getA(rc.x, ch, int(innerDims.x),\n                    int(innerDims.y)), innerDims);\n                }\n              }\n            }\n          }\n        `;\n    this.userCode = `\n      void main() {\n        ivec3 rc = getOutputCoords();\n\n        vec4 result = vec4(0);\n\n        int blockIndex, pos, offsetY, d0, offsetX, d1, ch;\n        vec2 innerDims;\n\n        ${W}\n\n        ${h.output} = result;\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Zc(I, l) {\n  const G = I.length;\n  return G >= 3 ? l ? [\n    ...I.slice(0, -3),\n    I[G - 3] * I[G - 2],\n    I[G - 1]\n    /* channel */\n  ] : [\n    ...I.slice(0, -3),\n    I[G - 3],\n    I[G - 2] * I[G - 1]\n    /* height * width */\n  ] : !l && G === 1 && I[0] > 1 ? [I[0], 1] : null;\n}\nfunction rB({ x: I, filter: l, convInfo: G, backend: Z, bias: h = null, preluActivationWeights: g = null, leakyreluAlpha: b = 0, activation: c = null }) {\n  const d = I.shape, W = Z.texData.get(I.dataId), Y = G.inChannels, V = d[0] * d[1] * d[2], a = G.outChannels, i = G.dataFormat === \"channelsLast\", m = !1, T = !1;\n  let s;\n  const o = [];\n  if (g != null) {\n    const n = Zc(g.shape, i);\n    n != null && (g = ll({\n      inputs: { x: g },\n      backend: Z,\n      attrs: { shape: n }\n    }), o.push(g));\n  }\n  if (h != null) {\n    const n = Zc(h.shape, i);\n    n != null && (h = ll({ inputs: { x: h }, backend: Z, attrs: { shape: n } }), o.push(h));\n  }\n  if (!((V === 1 || a === 1) && Y > AB) && W.isPacked && i && W.texture != null && d[2] % 2 !== 0 && Nl(W.shape.slice(-3), d.slice(-3))) {\n    const n = d[0] * d[1] * (d[2] + 1), X = {\n      dataId: I.dataId,\n      shape: [1, n, G.inChannels],\n      dtype: I.dtype\n    }, t = W.shape;\n    W.shape = W.shape.slice(), W.shape[W.shape.length - 2]++, u(Gc(W.shape, X.shape), () => `packed reshape ${W.shape} to ${X.shape} isn't free`);\n    const e = ll({\n      inputs: { x: l },\n      backend: Z,\n      attrs: { shape: [1, G.inChannels, G.outChannels] }\n    });\n    o.push(e);\n    const S = Ic({\n      a: X,\n      b: e,\n      backend: Z,\n      transposeA: m,\n      transposeB: T,\n      bias: h,\n      activation: c,\n      preluActivationWeights: g,\n      leakyreluAlpha: b\n    }), p = Z.texData.get(S.dataId);\n    u(p.isPacked, () => \"batchMatMul result is expected to be packed\"), W.shape = t, p.shape = G.outShape, s = OG({ inputs: { x: S }, backend: Z }), s.shape = G.outShape, o.push(S);\n  } else {\n    const n = G.outHeight * G.outWidth, X = ll({\n      inputs: { x: I },\n      backend: Z,\n      attrs: {\n        shape: i ? [G.batchSize, n, G.inChannels] : [G.batchSize, G.inChannels, n]\n      }\n    }), t = ll({\n      inputs: { x: l },\n      backend: Z,\n      attrs: { shape: [1, G.inChannels, G.outChannels] }\n    }), e = Ic({\n      a: i ? X : t,\n      b: i ? t : X,\n      transposeA: !i,\n      transposeB: T,\n      backend: Z,\n      bias: h,\n      activation: c,\n      preluActivationWeights: g,\n      leakyreluAlpha: b\n    });\n    s = ll({ inputs: { x: e }, backend: Z, attrs: { shape: G.outShape } }), o.push(X), o.push(t), o.push(e);\n  }\n  for (const n of o)\n    Z.disposeIntermediateTensorInfo(n);\n  return s;\n}\nfunction jB({ x: I, filter: l, convInfo: G, backend: Z, bias: h = null, preluActivationWeights: g = null, leakyreluAlpha: b = 0, activation: c = null }) {\n  const { filterWidth: d, filterHeight: W, inChannels: Y, outWidth: V, outHeight: a, dataFormat: i } = G, m = i === \"channelsLast\", T = d * W * Y, s = a * V, o = [G.batchSize, T, s], B = !0, C = !1, n = [];\n  if (g != null) {\n    const w = Zc(g.shape, m);\n    w != null && (g = ll({\n      inputs: { x: g },\n      backend: Z,\n      attrs: { shape: w }\n    }), n.push(g));\n  }\n  if (h != null) {\n    const w = Zc(h.shape, m);\n    w != null && (h = ll({ inputs: { x: h }, backend: Z, attrs: { shape: w } }), n.push(h));\n  }\n  const X = ll({\n    inputs: { x: l },\n    backend: Z,\n    attrs: { shape: [1, T, Q(l.shape) / T] }\n  });\n  n.push(X);\n  const t = new Ak(o, G), e = [\n    I.shape,\n    [G.padInfo.top, G.padInfo.left],\n    [G.strideHeight, G.strideWidth],\n    [G.dilationHeight, G.dilationWidth],\n    [G.inChannels],\n    [G.filterWidth * G.inChannels],\n    [G.outWidth]\n  ], S = Z.runWebGLProgram(t, [I], \"float32\", e), p = ll({ inputs: { x: S }, backend: Z, attrs: { shape: o } });\n  n.push(S), n.push(p);\n  const F = h != null, x = g != null, H = c === \"leakyrelu\", K = c ? L0(c, !0) : null, z = new KB(m ? p.shape : X.shape, m ? X.shape : p.shape, m ? [G.batchSize, s, G.outChannels] : [G.batchSize, G.outChannels, s], B, C, F, K, x, H), k = m ? [p, X] : [X, p];\n  if (h && k.push(h), x && k.push(g), H) {\n    const w = Z.makeTensorInfo([], \"float32\", JZ(b, \"float32\"));\n    k.push(w), n.push(w);\n  }\n  const L = Z.runWebGLProgram(z, k, \"float32\"), v = ll({ inputs: { x: L }, backend: Z, attrs: { shape: G.outShape } });\n  n.push(L);\n  for (const w of n)\n    Z.disposeIntermediateTensorInfo(w);\n  return v;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction kk(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dataFormat: d, dilations: W, dimRoundingMode: Y } = Z, V = YZ(d), a = CG(h.shape, g.shape, b, W, c, Y, !1, V);\n  let i;\n  if (a.filterHeight === 1 && a.filterWidth === 1 && a.dilationHeight === 1 && a.dilationWidth === 1 && a.strideHeight === 1 && a.strideWidth === 1 && (a.padInfo.type === \"SAME\" || a.padInfo.type === \"VALID\"))\n    i = rB({ x: h, filter: g, convInfo: a, backend: G });\n  else if (a.strideWidth <= 2 && V === \"channelsLast\" && A().getBool(\"WEBGL_EXP_CONV\")) {\n    const T = new vB(a), s = [\n      [a.padInfo.top, a.padInfo.left],\n      [a.strideHeight, a.strideWidth],\n      [a.dilationHeight, a.dilationWidth],\n      [a.inHeight, a.inWidth]\n    ];\n    i = G.runWebGLProgram(T, [h, g], \"float32\", s);\n  } else if (A().getBool(\"WEBGL_CONV_IM2COL\"))\n    i = jB({ x: h, filter: g, convInfo: a, backend: G });\n  else {\n    const T = new QB(a);\n    i = G.runWebGLProgram(T, [h, g], \"float32\");\n  }\n  const m = ll({ inputs: { x: i }, backend: G, attrs: { shape: a.outShape } });\n  return G.disposeIntermediateTensorInfo(i), m;\n}\nconst zk = {\n  kernelName: Tc,\n  backendName: \"webgl\",\n  kernelFunc: kk\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Lk {\n  constructor(l) {\n    this.variableNames = [\"x\", \"dy\"], this.outputShape = l.filterShape;\n    const G = l.strideHeight, Z = l.strideWidth, h = l.padInfo.top, g = l.padInfo.left, b = l.dataFormat === \"channelsLast\";\n    this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int wR = coords.x;\n        int wC = coords.y;\n        int d1 = coords.z;\n        int d2 = coords.w;\n\n        // Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n\n        for (int b = 0; b < ${l.batchSize}; b++) {\n          for (int yR = 0; yR < ${l.outHeight}; yR++) {\n            int xR = wR + yR * ${G} - ${h};\n\n            if (xR < 0 || xR >= ${l.inHeight}) {\n              continue;\n            }\n\n            for (int yC = 0; yC < ${l.outWidth}; yC++) {\n              int xC = wC + yC * ${Z} - ${g};\n\n              if (xC < 0 || xC >= ${l.inWidth}) {\n                continue;\n              }\n\n              ${b ? `float dyValue = getDy(b, yR, yC, d2);\n              float xValue = getX(b, xR, xC, d1);\n              dotProd += (xValue * dyValue);` : `float dyValue = getDy(b, d2, yR, yC);\n              float xValue = getX(b, d1, xR, xC);\n              dotProd += (xValue * dyValue);`}\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\nclass Mk {\n  constructor(l) {\n    this.variableNames = [\"dy\", \"W\"], this.outputShape = l.inShape;\n    const G = l.filterHeight, Z = l.filterWidth, h = l.strideHeight, g = l.strideWidth, b = l.dataFormat === \"channelsLast\", c = G - 1 - l.padInfo.top, d = Z - 1 - l.padInfo.left, W = b ? 1 : 2, Y = b ? 2 : 3, V = b ? 3 : 1;\n    this.userCode = `\n      const ivec2 pads = ivec2(${c}, ${d});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d1 = coords[${V}];\n\n        ivec2 dyCorner = ivec2(coords[${W}], coords[${Y}]) - pads;\n        int dyRCorner = dyCorner.x;\n        int dyCCorner = dyCorner.y;\n\n        // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${G}; wR++) {\n          float dyR = float(dyRCorner + wR) / ${h}.0;\n\n          if (dyR < 0.0 || dyR >= ${l.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          int wRPerm = ${G} - 1 - wR;\n\n          for (int wC = 0; wC < ${Z}; wC++) {\n            float dyC = float(dyCCorner + wC) / ${g}.0;\n\n            if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            int wCPerm = ${Z} - 1 - wC;\n\n            for (int d2 = 0; d2 < ${l.outChannels}; d2++) {\n\n              if (${b}) {\n                float xValue = getDy(batch, idyR, idyC, d2);\n                float wValue = getW(wRPerm, wCPerm, d1, d2);\n                dotProd += xValue * wValue;\n              } else {\n                float xValue = getDy(batch, d2, idyR, idyC);\n                float wValue = getW(wRPerm, wCPerm, d1, d2);\n                dotProd += xValue * wValue;\n              }\n\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\nclass wk {\n  constructor(l) {\n    this.variableNames = [\"x\", \"dy\"], this.outputShape = l.filterShape;\n    const G = l.strideDepth, Z = l.strideHeight, h = l.strideWidth, g = l.padInfo.front, b = l.padInfo.top, c = l.padInfo.left;\n    this.userCode = `\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int wF = coords.x;\n        int wR = coords.y;\n        int wC = coords.z;\n        int d1 = coords.w;\n        int d2 = coords.u;\n\n        float dotProd = 0.0;\n\n        for (int b = 0; b < ${l.batchSize}; b++) {\n          for (int yF = 0; yF < ${l.outDepth}; yF++) {\n            int xF = wF + yF * ${G} - ${g};\n\n            if (xF < 0 || xF >= ${l.inDepth}) {\n              continue;\n            }\n\n            for (int yR = 0; yR < ${l.outHeight}; yR++) {\n              int xR = wR + yR * ${Z} - ${b};\n\n              if (xR < 0 || xR >= ${l.inHeight}) {\n                continue;\n              }\n\n              for (int yC = 0; yC < ${l.outWidth}; yC++) {\n                int xC = wC + yC * ${h} - ${c};\n\n                if (xC < 0 || xC >= ${l.inWidth}) {\n                  continue;\n                }\n\n                float dyValue = getDy(b, yF, yR, yC, d2);\n                float xValue = getX(b, xF, xR, xC, d1);\n                dotProd += (xValue * dyValue);\n              }\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\nclass Qk {\n  constructor(l) {\n    this.variableNames = [\"dy\", \"W\"], this.outputShape = l.inShape;\n    const G = l.filterDepth, Z = l.filterHeight, h = l.filterWidth, g = l.strideDepth, b = l.strideHeight, c = l.strideWidth, d = G - 1 - l.padInfo.front, W = Z - 1 - l.padInfo.top, Y = h - 1 - l.padInfo.left;\n    this.userCode = `\n      const ivec3 pads = ivec3(${d}, ${W}, ${Y});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int d1 = coords.u;\n\n\n        ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n        int dyFCorner = dyCorner.x;\n        int dyRCorner = dyCorner.y;\n        int dyCCorner = dyCorner.z;\n\n        float dotProd = 0.0;\n        for (int wF = 0; wF < ${G}; wF++) {\n          float dyF = float(dyFCorner + wF) / ${g}.0;\n\n          if (dyF < 0.0 || dyF >= ${l.outDepth}.0 || fract(dyF) > 0.0) {\n            continue;\n          }\n          int idyF = int(dyF);\n\n          int wFPerm = ${G} - 1 - wF;\n\n          for (int wR = 0; wR < ${Z}; wR++) {\n            float dyR = float(dyRCorner + wR) / ${b}.0;\n\n            if (dyR < 0.0 || dyR >= ${l.outHeight}.0 ||\n              fract(dyR) > 0.0) {\n              continue;\n            }\n            int idyR = int(dyR);\n\n            int wRPerm = ${Z} - 1 - wR;\n\n            for (int wC = 0; wC < ${h}; wC++) {\n              float dyC = float(dyCCorner + wC) / ${c}.0;\n\n              if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                  fract(dyC) > 0.0) {\n                continue;\n              }\n              int idyC = int(dyC);\n\n              int wCPerm = ${h} - 1 - wC;\n\n              for (int d2 = 0; d2 < ${l.outChannels}; d2++) {\n                float xValue = getDy(batch, idyF, idyR, idyC, d2);\n                float wValue = getW(wFPerm, wRPerm, wCPerm, d1, d2);\n                dotProd += xValue * wValue;\n              }\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vk(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, dy: g } = l, { strides: b, pad: c, dataFormat: d, dimRoundingMode: W, filterShape: Y } = Z, V = YZ(d), a = CG(h.shape, Y, b, 1, c, W, !1, V), i = new Lk(a);\n  return G.runWebGLProgram(i, [h, g], \"float32\");\n}\nconst rk = {\n  kernelName: hY,\n  backendName: \"webgl\",\n  kernelFunc: vk\n};\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass jk {\n  constructor(l) {\n    this.variableNames = [\"dy\", \"W\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [\n      { name: \"strides\", type: \"vec2\" }\n    ], this.outputShape = l.inShape, this.enableShapeUniforms = yG(this.outputShape.length);\n    const G = l.filterHeight, Z = l.filterWidth, h = G - 1 - l.padInfo.top, g = Z - 1 - l.padInfo.left;\n    this.userCode = `\n      const ivec2 pads = ivec2(${h}, ${g});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d1 = coords[3];\n\n        ivec2 dyCorner = ivec2(coords[1], coords[2]) - pads;\n        int dyRCorner = dyCorner.x;\n        int dyCCorner = dyCorner.y;\n\n        vec4 result = vec4(0.);\n        for (int wR = 0; wR < ${G}; wR++) {\n          float dyR = float(dyRCorner + wR) / strides[0];\n          if (dyR < 0.0 || dyR >= ${l.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n          int wRPerm = ${G} - 1 - wR;\n\n          for (int wC = 0; wC < ${Z}; wC++) {\n            int wCPerm = ${Z} - 1 - wC;\n\n            float dyC = float(dyCCorner + wC) / strides[1];\n            bool idyCVal = (dyC >= 0.0) && (dyC < ${l.outWidth}.0)\n              && (fract(dyC) == 0.0);\n            int idyC = int(dyC);\n\n            float dyC2 = float(dyCCorner + wC + 1) / strides[1];\n            bool idyCVal2 = (dyC2 >= 0.0) && (dyC2 < ${l.outWidth}.0)\n              && (fract(dyC2) == 0.0);\n            int idyC2 = int(dyC2);\n\n            if (idyCVal && idyCVal2) {\n              for (int d2 = 0; d2 < ${l.outChannels}; d2 += 2) {\n                vec4 wValue = getW(wRPerm, wCPerm, d1, d2);\n                vec4 dySample = getDy(batch, idyR, idyC, d2);\n                vec4 dySample2 = (idyC / 2 == idyC2 / 2) ?\n                  dySample : getDy(batch, idyR, idyC2, d2);\n\n                vec2 dyValue = mod(float(idyC), 2.) == 0. ?\n                  dySample.xy : dySample.zw;\n                result.xy += vec2(dot(dyValue, wValue.xy),\n                  dot(dyValue, wValue.zw));\n\n                dyValue = mod(float(idyC2), 2.) == 0. ?\n                  dySample2.xy : dySample2.zw;\n                result.zw += vec2(dot(dyValue, wValue.xy),\n                  dot(dyValue, wValue.zw));\n              }\n            } else if (idyCVal) {\n              for (int d2 = 0; d2 < ${l.outChannels}; d2 += 2) {\n                vec4 wValue = getW(wRPerm, wCPerm, d1, d2);\n                vec4 dySample = getDy(batch, idyR, idyC, d2);\n                vec2 dyValue = mod(float(idyC), 2.) == 0. ?\n                  dySample.xy : dySample.zw;\n                result.xy += vec2(dot(dyValue, wValue.xy),\n                  dot(dyValue, wValue.zw));\n              }\n            } else if (idyCVal2) {\n              for (int d2 = 0; d2 < ${l.outChannels}; d2 += 2) {\n                vec4 wValue = getW(wRPerm, wCPerm, d1, d2);\n                vec4 dySample = getDy(batch, idyR, idyC2, d2);\n                vec2 dyValue = mod(float(idyC2), 2.) == 0. ?\n                  dySample.xy : dySample.zw;\n                result.zw += vec2(dot(dyValue, wValue.xy),\n                  dot(dyValue, wValue.zw));\n              }\n            }\n          }\n        }\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Dk(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, filter: g } = l, { inputShape: b, strides: c, pad: d, dataFormat: W, dimRoundingMode: Y } = Z, V = YZ(W), a = CG(b, g.shape, c, 1, d, Y, !1, V);\n  if (A().getBool(\"WEBGL_PACK_CONV2DTRANSPOSE\") && V === \"channelsLast\") {\n    const i = [\n      [a.strideHeight, a.strideWidth]\n    ], m = new jk(a);\n    return G.runWebGLProgram(m, [h, g], \"float32\", i);\n  } else {\n    const i = new Mk(a);\n    return G.runWebGLProgram(i, [h, g], \"float32\");\n  }\n}\nconst fk = {\n  kernelName: sc,\n  backendName: \"webgl\",\n  kernelFunc: Dk\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ok(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dilations: d } = Z, W = EZ(h.shape, g.shape, b, d, c), Y = new Kk(W);\n  return G.runWebGLProgram(Y, [h, g], \"float32\");\n}\nconst qk = {\n  kernelName: oc,\n  backendName: \"webgl\",\n  kernelFunc: Ok\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $k(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, dy: g } = l, { strides: b, pad: c, filterShape: d } = Z, W = EZ(h.shape, d, b, 1, c), Y = new wk(W);\n  return G.runWebGLProgram(Y, [h, g], \"float32\");\n}\nconst _k = {\n  kernelName: gY,\n  backendName: \"webgl\",\n  kernelFunc: $k\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction lz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, filter: g } = l, { pad: b, strides: c, inputShape: d } = Z, W = EZ(d, g.shape, c, 1, b), Y = new Qk(W);\n  return G.runWebGLProgram(Y, [h, g], \"float32\");\n}\nconst Gz = {\n  kernelName: bY,\n  backendName: \"webgl\",\n  kernelFunc: lz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Iz = T0 + `\n  return cos(x);\n`, Zz = `\n  vec4 result = cos(x);\n  bvec4 isNaN = isnan(x);\n  ${Fh}\n  return result;\n`, hz = Rl({ opSnippet: Iz, packedOpSnippet: Zz }), gz = {\n  kernelName: Ig,\n  backendName: \"webgl\",\n  kernelFunc: hz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bz = `\n  float e2x = exp(-x);\n  return (e2x + 1.0 / e2x) / 2.0;\n`, cz = Rl({ opSnippet: bz }), dz = {\n  kernelName: Zg,\n  backendName: \"webgl\",\n  kernelFunc: cz\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Wz {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"Image\", \"Boxes\", \"BoxInd\"], this.outputShape = [];\n    const [b, c, d, W] = l, [Y] = G, [V, a] = Z;\n    this.outputShape = [Y, V, a, W];\n    const i = h === \"bilinear\" ? 1 : 0, [m, T] = [`${c - 1}.0`, `${d - 1}.0`], [s, o, B] = V > 1 ? [\n      `${(c - 1) / (V - 1)}`,\n      \"(y2-y1) * height_ratio\",\n      `y1*${m} + float(y)*(height_scale)`\n    ] : [\n      \"0.0\",\n      \"0.0\",\n      `0.5 * (y1+y2) * ${m}`\n    ], [C, n, X] = a > 1 ? [\n      `${(d - 1) / (a - 1)}`,\n      \"(x2-x1) * width_ratio\",\n      `x1*${T} + float(x)*(width_scale)`\n    ] : [\n      \"0.0\",\n      \"0.0\",\n      `0.5 * (x1+x2) * ${T}`\n    ];\n    this.userCode = `\n      const float height_ratio = float(${s});\n      const float width_ratio = float(${C});\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int y = coords[1];\n        int x = coords[2];\n        int d = coords[3];\n\n        // get box vals\n        float y1 = getBoxes(b,0);\n        float x1 = getBoxes(b,1);\n        float y2 = getBoxes(b,2);\n        float x2 = getBoxes(b,3);\n\n        // get image in batch index\n        int bInd = round(getBoxInd(b));\n        if(bInd < 0 || bInd >= ${b}) {\n          return;\n        }\n\n        float height_scale = ${o};\n        float width_scale = ${n};\n\n        float in_y = ${B};\n        if( in_y < 0.0 || in_y > ${m} ) {\n          setOutput(float(${g}));\n          return;\n        }\n        float in_x = ${X};\n        if( in_x < 0.0 || in_x > ${T} ) {\n          setOutput(float(${g}));\n          return;\n        }\n\n        vec2 sourceFracIndexCR = vec2(in_x,in_y);\n        if(${i} == 1) {\n          // Compute the four integer indices.\n          ivec2 sourceFloorCR = ivec2(sourceFracIndexCR);\n          ivec2 sourceCeilCR = ivec2(ceil(sourceFracIndexCR));\n\n          float topLeft = getImage(b, sourceFloorCR.y, sourceFloorCR.x, d);\n          float bottomLeft = getImage(b, sourceCeilCR.y, sourceFloorCR.x, d);\n          float topRight = getImage(b, sourceFloorCR.y, sourceCeilCR.x, d);\n          float bottomRight = getImage(b, sourceCeilCR.y, sourceCeilCR.x, d);\n\n          vec2 fracCR = sourceFracIndexCR - vec2(sourceFloorCR);\n\n          float top = topLeft + (topRight - topLeft) * fracCR.x;\n          float bottom = bottomLeft + (bottomRight - bottomLeft) * fracCR.x;\n          float newValue = top + (bottom - top) * fracCR.y;\n          setOutput(newValue);\n        } else {\n          // Compute the coordinators of nearest neighbor point.\n          ivec2 sourceNearestCR = ivec2(floor(\n            sourceFracIndexCR + vec2(0.5,0.5)));\n          float newValue = getImage(b, sourceNearestCR.y, sourceNearestCR.x, d);\n          setOutput(newValue);\n        }\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Yz = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { image: h, boxes: g, boxInd: b } = l, { cropSize: c, method: d, extrapolationValue: W } = Z, Y = new Wz(h.shape, g.shape, c, d, W);\n  return G.runWebGLProgram(Y, [h, g, b], \"float32\");\n}, Vz = {\n  kernelName: dY,\n  backendName: \"webgl\",\n  kernelFunc: Yz\n};\nvar w0;\n(function(I) {\n  I.Prod = \"*\", I.Sum = \"+\";\n})(w0 || (w0 = {}));\nclass di {\n  constructor(l, G, Z, h) {\n    this.op = l, this.outputShape = G, this.variableNames = [\"x\"], this.customUniforms = [{ name: \"index\", type: \"float\" }];\n    const g = this.outputShape.length, b = this.op === w0.Prod ? \"1.0\" : \"0.0\", c = Z ? b : `getX(${Wi(g, \"coords\", this.op)})`, d = this.outputShape[this.outputShape.length - 1];\n    let W = \"\", Y = \"\";\n    Z ? (W = h ? `end != ${d - 1}` : \"end != 0\", Y = h ? \"end + 1\" : \"end - 1\") : (W = h ? `end + pow2 < ${d}` : \"end >= pow2\", Y = h ? \"end + pow2\" : \"end - pow2\"), this.userCode = `\n      void main() {\n        ${Ul(g)} coords = getOutputCoords();\n        int end = ${Yi(g, \"coords\", this.op)};\n        float val = ${c};\n        int pow2 = int(pow(2.0, index));\n        if (${W}) {\n          int idx = ${Y};\n          ${Yi(g, \"coords\", this.op)} = idx;\n          val ${this.op}= getX(${Wi(g, \"coords\", this.op)});\n        }\n        setOutput(val);\n      }\n    `;\n  }\n}\nfunction Wi(I, l, G) {\n  if (I === 1)\n    return `${l}`;\n  if (I === 2)\n    return `${l}.x, ${l}.y`;\n  if (I === 3)\n    return `${l}.x, ${l}.y, ${l}.z`;\n  if (I === 4)\n    return `${l}.x, ${l}.y, ${l}.z, ${l}.w`;\n  throw new Error(`Cumulative ${G} for rank ${I} is not yet supported`);\n}\nfunction Yi(I, l, G) {\n  if (I === 1)\n    return `${l}`;\n  if (I === 2)\n    return `${l}.y`;\n  if (I === 3)\n    return `${l}.z`;\n  if (I === 4)\n    return `${l}.w`;\n  throw new Error(`Cumulative ${G} for rank ${I} is not yet supported`);\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction DB(I, l, G, Z, h, g) {\n  const b = l.shape.length, c = Ol([Z], b);\n  let d = l;\n  c != null && (d = HG({ inputs: { x: l }, backend: G, attrs: { perm: c } }));\n  const W = GG(1, b)[0];\n  if (W !== b - 1)\n    throw new Error(`WebGL cumprod shader expects an inner-most axis=${l.shape.length - 1} but got axis=${Z}`);\n  const Y = d.shape[W];\n  let V = OG({ inputs: { x: d }, backend: G });\n  for (let a = 0; a <= Math.ceil(Math.log2(Y)) - 1; a++) {\n    const i = new di(I, d.shape, !1, g), m = [[a]], T = V;\n    V = G.runWebGLProgram(i, [V], V.dtype, m), G.disposeIntermediateTensorInfo(T);\n  }\n  if (h) {\n    const a = new di(I, d.shape, h, g), i = V;\n    V = G.runWebGLProgram(a, [V], V.dtype), G.disposeIntermediateTensorInfo(i);\n  }\n  if (c != null) {\n    const a = xZ(c), i = HG({ inputs: { x: V }, backend: G, attrs: { perm: a } });\n    return G.disposeIntermediateTensorInfo(V), G.disposeIntermediateTensorInfo(d), i;\n  }\n  return V;\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction az(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, exclusive: b, reverse: c } = Z;\n  return DB(w0.Prod, h, G, g, b, c);\n}\nconst iz = {\n  kernelName: cY,\n  backendName: \"webgl\",\n  kernelFunc: az\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, exclusive: b, reverse: c } = Z;\n  return DB(w0.Sum, h, G, g, b, c);\n}\nconst Tz = {\n  kernelName: Bc,\n  backendName: \"webgl\",\n  kernelFunc: mz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, weights: g } = l, { size: b, binaryOutput: c } = Z;\n  if (h.shape.length === 1) {\n    const d = G.readSync(h.dataId), W = G.readSync(g.dataId), Y = FB(d, W, g.dtype, g.shape, b);\n    return G.makeTensorInfo([b], g.dtype, Y);\n  } else if (h.shape.length === 2) {\n    const d = G.bufferSync(h), W = G.bufferSync(g), Y = CK(d, W, b, c);\n    return G.makeTensorInfo(Y.shape, g.dtype, Y.values);\n  }\n  throw new Error(`Error in denseBincount: input must be at most rank 2, but got rank${h.shape.length}.`);\n}\nconst oz = {\n  kernelName: WY,\n  backendName: \"webgl\",\n  kernelFunc: sz\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Bz {\n  constructor(l, G, Z) {\n    this.variableNames = [\"x\"], this.outputShape = [], this.outputShape = l, this.blockSize = G, this.dataFormat = Z, this.userCode = `\n    void main() {\n      ivec4 coords = getOutputCoords();\n      int b = coords[0];\n      int h = ${this.getHeightCoordString()};\n      int w = ${this.getWidthCoordString()};\n      int d = ${this.getDepthCoordString()};\n\n      int in_h = h / ${G};\n      int offset_h = imod(h, ${G});\n      int in_w = w / ${G};\n      int offset_w = imod(w, ${G});\n      int offset_d = (offset_h * ${G} + offset_w) *\n        ${this.getOutputDepthSize()};\n      int in_d = d + offset_d;\n\n      float result = ${this.getInputSamplingString()};\n      setOutput(result);\n    }\n  `;\n  }\n  getHeightCoordString() {\n    return this.dataFormat === \"NHWC\" ? \"coords[1]\" : \"coords[2]\";\n  }\n  getWidthCoordString() {\n    return this.dataFormat === \"NHWC\" ? \"coords[2]\" : \"coords[3]\";\n  }\n  getDepthCoordString() {\n    return this.dataFormat === \"NHWC\" ? \"coords[3]\" : \"coords[1]\";\n  }\n  getOutputDepthSize() {\n    return this.dataFormat === \"NHWC\" ? this.outputShape[3] : this.outputShape[1];\n  }\n  getInputSamplingString() {\n    return this.dataFormat === \"NHWC\" ? \"getX(b, in_h, in_w, in_d)\" : \"getX(b, in_d, in_h, in_w)\";\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction nz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { blockSize: g, dataFormat: b } = Z, c = h.shape[0], d = b === \"NHWC\" ? h.shape[1] : h.shape[2], W = b === \"NHWC\" ? h.shape[2] : h.shape[3], Y = b === \"NHWC\" ? h.shape[3] : h.shape[1], V = d * g, a = W * g, i = Y / (g * g), m = b === \"NHWC\" ? [c, V, a, i] : [c, i, V, a], T = new Bz(m, g, b);\n  return G.runWebGLProgram(T, [h], h.dtype);\n}\nconst Cz = {\n  kernelName: YY,\n  backendName: \"webgl\",\n  kernelFunc: nz\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass fB {\n  constructor(l, G = !1, Z = null, h = !1, g = !1) {\n    this.variableNames = [\"x\", \"W\"], this.customUniforms = [\n      { name: \"pads\", type: \"ivec2\" },\n      { name: \"strides\", type: \"ivec2\" },\n      { name: \"dilations\", type: \"ivec2\" },\n      { name: \"inDims\", type: \"ivec2\" }\n    ], this.outputShape = l.outShape, this.enableShapeUniforms = yG(this.outputShape.length);\n    const b = l.filterHeight, c = l.filterWidth, d = l.outChannels / l.inChannels;\n    let W = \"\", Y = \"\";\n    Z && (h ? W = `float activation(float a) {\n          float b = getPreluActivationWeightsAtOutCoords();\n          ${Z}\n        }` : g ? W = `float activation(float a) {\n          float b = getLeakyreluAlphaAtOutCoords();\n          ${Z}\n        }` : W = `\n          float activation(float x) {\n            ${Z}\n          }\n        `, Y = \"result = activation(result);\");\n    const V = G ? \"result += getBiasAtOutCoords();\" : \"\";\n    G && this.variableNames.push(\"bias\"), h && this.variableNames.push(\"preluActivationWeights\"), g && this.variableNames.push(\"leakyreluAlpha\"), this.userCode = `\n      ${W}\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords.x;\n        ivec2 xRCCorner = coords.yz * strides - pads;\n        int d2 = coords.w;\n        int d1 = d2 / ${d};\n        int q = d2 - d1 * ${d};\n\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        // TO DO(dsmilkov): Flatten the two for loops and vec4 the operations.\n        for (int wR = 0; wR < ${b}; wR++) {\n          int xR = xRCorner + wR * dilations[0];\n\n          if (xR < 0 || xR >= inDims[0]) {\n            continue;\n          }\n\n          for (int wC = 0; wC < ${c}; wC++) {\n            int xC = xCCorner + wC * dilations[1];\n\n            if (xC < 0 || xC >= inDims[1]) {\n              continue;\n            }\n\n            float xVal = getX(batch, xR, xC, d1);\n            float wVal = getW(wR, wC, d1, q);\n            dotProd += xVal * wVal;\n          }\n        }\n\n        float result = dotProd;\n        ${V}\n        ${Y}\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass OB {\n  constructor(l, G = !1, Z = null, h = !1, g = !1) {\n    this.variableNames = [\"x\", \"W\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [\n      { name: \"pads\", type: \"ivec2\" },\n      { name: \"strides\", type: \"ivec2\" },\n      { name: \"dilations\", type: \"ivec2\" },\n      { name: \"inDims\", type: \"ivec2\" }\n    ], this.outputShape = l.outShape, this.enableShapeUniforms = yG(this.outputShape.length);\n    const b = l.outChannels / l.inChannels, c = l.padInfo.left, d = l.strideWidth, W = l.dilationWidth, Y = l.filterHeight, V = l.filterWidth, a = V;\n    let i = `\n      int xR; int xC; int xCOffset;\n      vec4 wTexel; vec4 previous; vec4 final;`;\n    for (let o = 0; o < V; o++)\n      i += `\n          vec4 xTexelC${o * 2};\n          int xTexelC${o * 2}Ready;\n          vec4 xTexelC${o * 2 + 1};\n          int xTexelC${o * 2 + 1}Ready;\n          vec4 xC${o};`;\n    i += `\n    for (int r = 0; r < ${Y}; r++) {\n      `;\n    for (let o = 0; o < V; o++)\n      i += `\n          xTexelC${o * 2} = vec4(0.0);\n          xTexelC${o * 2}Ready = 0;\n          xTexelC${o * 2 + 1} = vec4(0.0);\n          xTexelC${o * 2 + 1}Ready = 0;\n          xC${o} = vec4(0.0);`;\n    i += `\n        xR = xRCorner + r * dilations[0];\n        if (xR >=0 && xR < inDims[0]) {\n      `;\n    for (let o = 0; o < (a + 1) / 2; o++) {\n      const B = o * 2;\n      if (i += `\n          xC = xCCorner + ${B * W};\n          `, d === 1) {\n        if (B < V && (c % 2 === 1 ? (i += `\n                xCOffset = xC + 1;\n                if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${B}Ready == 0) {\n                  xTexelC${B} = getX(batch, xR, xCOffset, d1);\n\n                  // Need to manually clear unused channels in case\n                  // we're reading from recycled texture.\n                  if (xCOffset + 1 >= inDims[1]) {\n                    xTexelC${B}.zw = vec2(0.0);\n                  }\n                  xTexelC${B}Ready = 1;\n                }\n              `, W === 1 && B > 0 ? i += `\n                xC${B} = vec4(xTexelC${B - 2}.zw, xTexelC${B}.xy);\n                ` : i += `\n                  xCOffset = xC + 1 - 2;\n\n                  if (xCOffset >= 0 && xCOffset < inDims[1]) {\n                    previous = getX(batch, xR, xCOffset, d1);\n\n                    // Need to manually clear unused channels in case\n                    // we're reading from recycled texture.\n                    if (xCOffset + 1 >= inDims[1]) {\n                      previous.zw = vec2(0.0);\n                    }\n\n                    xC${B} = vec4(previous.zw, xTexelC${B}.xy);\n                  } else {\n                    xC${B} = vec4(0.0, 0.0, xTexelC${B}.xy);\n                  }\n                  `) : i += `\n                if (xC >= 0 && xC < inDims[1] && xTexelC${B}Ready == 0) {\n                  xTexelC${B} = getX(batch, xR, xC, d1);\n                  if (xC + 1 >= inDims[1]) {\n                    xTexelC${B}.zw = vec2(0.0);\n                  }\n                  xTexelC${B}Ready = 1;\n                }\n\n                xC${B} = xTexelC${B};\n                `, B + 1 < V)) {\n          const C = c % 2 === 0 ? QW(W) : W;\n          W % 2 === 0 && c % 2 === 1 || W % 2 !== 0 && c % 2 !== 1 ? (i += `\n                  xCOffset = xC + imod(pads[1], 2) + ${C};\n\n                  if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${B + 1}Ready == 0) {\n                    xTexelC${B + 1} = getX(batch, xR, xCOffset, d1);\n\n                    // Need to manually clear unused channels in case\n                    // we're reading from recycled texture.\n                    if (xCOffset + 1 >= inDims[1]) {\n                      xTexelC${B + 1}.zw = vec2(0.0);\n                    }\n                    xTexelC${B + 1}Ready = 1;\n                  }\n                  `, W > 1 ? i += `\n                    xCOffset -= 2;\n                    if (xCOffset >= 0 && xCOffset < inDims[1]) {\n                     previous = getX(batch, xR, xCOffset, d1);\n                     xC${B + 1} = vec4(previous.zw, xTexelC${B + 1}.xy);\n                    } else {\n                     xC${B + 1} = vec4(0.0, 0.0, xTexelC${B + 1}.xy);\n                    }\n                    ` : i += `\n                    xC${B + 1} = vec4(xTexelC${B}.zw, xTexelC${B + 1}.xy);\n                    `) : C === 1 ? i += `\n                    xC${B + 1} = xTexelC${B};\n                    ` : i += `\n                    xCOffset = xC + ${C};\n\n                    if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${B + 1}Ready == 0) {\n                      xTexelC${B + 1} = getX(batch, xR, xCOffset, d1);\n                      if (xCOffset + 1 >= inDims[1]) {\n                        xTexelC${B + 1}.zw = vec2(0.0);\n                      }\n                      xTexelC${B + 1}Ready = 1;\n                    }\n\n                    xC${B + 1} = xTexelC${B + 1};\n                    `;\n        }\n      } else\n        B < V && (c % 2 === 1 ? (i += `\n                xCOffset = xC + 1 - strides[1];\n                if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${B}Ready == 0) {\n                  xTexelC${B} = getX(batch, xR, xCOffset, d1);\n                  // Need to manually clear unused channels in case\n                  // we're reading from recycled texture.\n                  if (xCOffset + 1 >= inDims[1]) {\n                    xTexelC${B}.zw = vec2(0.0);\n                  }\n                  xTexelC${B}Ready = 1;\n                }\n\n                if(xC + 1 >= 0 && xC + 1 < inDims[1] && xTexelC${B + 1}Ready == 0) {\n                  xTexelC${B + 1} = getX(batch, xR, xC + 1, d1);\n                  // Need to manually clear unused channels in case\n                  // we're reading from recycled texture.\n                  if (xC + 2 >= inDims[1]) {\n                    xTexelC${B + 1}.zw = vec2(0.0);\n                  }\n                  xTexelC${B + 1}Ready = 1;\n                }\n\n                xC${B} = vec4(xTexelC${B}.zw, xTexelC${B + 1}.zw);\n              `, B + 1 < V && (i += `\n                  final = vec4(0.0);\n                  xCOffset = xC + 1 + strides[1];\n                  if(xCOffset >= 0 && xCOffset < inDims[1]) {\n                    final = getX(batch, xR, xCOffset, d1);\n                  }\n                  xC${B + 1} = vec4(xTexelC${B + 1}.xy, final.xy);\n                `)) : (i += `\n                if(xC >= 0 && xC < inDims[1] && xTexelC${B}Ready == 0) {\n                  xTexelC${B} = getX(batch, xR, xC, d1);\n                  if (xC + 1 >= inDims[1]) {\n                    xTexelC${B}.zw = vec2(0.0);\n                  }\n                  xTexelC${B}Ready = 1;\n                }\n\n                xCOffset = xC + strides[1];\n                if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${B + 1}Ready == 0) {\n                  xTexelC${B + 1} = getX(batch, xR, xCOffset, d1);\n                  if (xCOffset + 1 >= inDims[1]) {\n                    xTexelC${B + 1}.zw = vec2(0.);\n                  }\n                  xTexelC${B + 1}Ready = 1;\n                }\n\n                xC${B} = vec4(\n                  xTexelC${B}.xy, xTexelC${B + 1}.xy);\n              `, B + 1 < V && (i += `\n                  xC${B + 1} = vec4(xTexelC${B}.zw, xTexelC${B + 1}.zw);\n                `)));\n      B < V && (i += `\n            wTexel = getW(r, ${B}, d1, q);\n            dotProd += xC${B} * vec4(wTexel.xz, wTexel.xz);\n          `, B + 1 < V && (i += `\n              wTexel = getW(r, ${B + 1}, d1, q);\n              dotProd += xC${B + 1} * vec4(wTexel.xz, wTexel.xz);\n            `));\n    }\n    i += `\n    }\n  `, i += `\n      }\n    `;\n    let m = \"\", T = \"\";\n    Z && (h ? m = `vec4 activation(vec4 a) {\n          vec4 b = getPreluActivationWeightsAtOutCoords();\n          ${Z}\n        }` : g ? m = `vec4 activation(vec4 a) {\n          vec4 b = getLeakyreluAlphaAtOutCoords();\n          ${Z}\n        }` : m = `vec4 activation(vec4 x) {\n          ${Z}\n        }`, T = \"result = activation(result);\");\n    const s = G ? \"result += getBiasAtOutCoords();\" : \"\";\n    G && this.variableNames.push(\"bias\"), h && this.variableNames.push(\"preluActivationWeights\"), g && this.variableNames.push(\"leakyreluAlpha\"), this.userCode = `\n      ${m}\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords.x;\n        ivec2 xRCCorner = coords.yz * strides - pads;\n        int d2 = coords.w;\n        int d1 = d2 / ${b};\n        int q = d2 - d1 * ${b};\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        //intialize dotProd with a small epsilon seems to reduce GPU accuracy loss.\n        vec4 dotProd = vec4(0.000000000000001);\n\n        ${i}\n\n        vec4 result = dotProd - vec4(0.000000000000001);\n        ${s}\n        ${T}\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Xz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dilations: d, dimRoundingMode: W } = Z;\n  let Y = d;\n  Y == null && (Y = [1, 1]), u(pG(b, Y), () => `Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${b} and dilations '${Y}'`);\n  const V = CG(\n    h.shape,\n    g.shape,\n    b,\n    Y,\n    c,\n    W,\n    !0\n    /* depthwise */\n  );\n  let a;\n  A().getBool(\"WEBGL_PACK_DEPTHWISECONV\") && V.strideWidth <= 2 && V.outChannels / V.inChannels === 1 ? a = new OB(V) : a = new fB(V);\n  const i = [\n    [V.padInfo.top, V.padInfo.left],\n    [V.strideHeight, V.strideWidth],\n    [V.dilationHeight, V.dilationWidth],\n    [V.inHeight, V.inWidth]\n  ];\n  return G.runWebGLProgram(a, [h, g], \"float32\", i);\n}\nconst tz = {\n  kernelName: nc,\n  backendName: \"webgl\",\n  kernelFunc: Xz\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass uz {\n  constructor(l) {\n    this.variableNames = [\"x\", \"dy\"], this.outputShape = l.filterShape;\n    const G = l.strideHeight, Z = l.strideWidth, h = l.padInfo.top, g = l.padInfo.left, b = l.outChannels / l.inChannels;\n    this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int wR = coords.x;\n        int wC = coords.y;\n        int d1 = coords.z;\n        int dm = coords.w;\n        int d2 = d1 * ${b} + dm;\n\n        float dotProd = 0.0;\n\n        // TO DO: Vec4 over the batch size\n        for (int b = 0; b < ${l.batchSize}; b++) {\n          for (int yR = 0; yR < ${l.outHeight}; yR++) {\n            int xR = wR + yR * ${G} - ${h};\n\n            if (xR < 0 || xR >= ${l.inHeight}) {\n              continue;\n            }\n\n            for (int yC = 0; yC < ${l.outWidth}; yC++) {\n              int xC = wC + yC * ${Z} - ${g};\n\n              if (xC < 0 || xC >= ${l.inWidth}) {\n                continue;\n              }\n\n              float dyValue = getDy(b, yR, yC, d2);\n              float xValue = getX(b, xR, xC, d1);\n              dotProd += (xValue * dyValue);\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\nclass ez {\n  constructor(l) {\n    this.variableNames = [\"dy\", \"W\"], this.outputShape = l.inShape;\n    const G = l.filterHeight, Z = l.filterWidth, h = l.strideHeight, g = l.strideWidth, b = G - 1 - l.padInfo.top, c = Z - 1 - l.padInfo.left, d = l.outChannels / l.inChannels;\n    this.userCode = `\n      const ivec2 pads = ivec2(${b}, ${c});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d1 = coords[3];\n        ivec2 dyCorner = coords.yz - pads;\n        int dyRCorner = dyCorner.x;\n        int dyCCorner = dyCorner.y;\n\n        float dotProd = 0.0;\n\n        for (int wR = 0; wR < ${G}; wR++) {\n          float dyR = float(dyRCorner + wR) / ${h}.0;\n\n          if (dyR < 0.0 || dyR >= ${l.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          int wRPerm = ${G} - 1 - wR;\n\n          for (int wC = 0; wC < ${Z}; wC++) {\n            float dyC = float(dyCCorner + wC) / ${g}.0;\n\n            if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            int wCPerm = ${Z} - 1 - wC;\n\n            // TO DO: Vec4 over the channelMul\n            for (int dm = 0; dm < ${d}; dm++) {\n              int d2 = d1 * ${d} + dm;\n              float xValue = getDy(batch, idyR, idyC, d2);\n              float wValue = getW(wRPerm, wCPerm, d1, dm);\n              dotProd += xValue * wValue;\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Sz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, dy: g } = l, { strides: b, dilations: c, pad: d, dimRoundingMode: W, filterShape: Y } = Z, V = CG(\n    h.shape,\n    Y,\n    b,\n    c,\n    d,\n    W,\n    !0\n    /* depthwise */\n  ), a = new uz(V);\n  return G.runWebGLProgram(a, [h, g], \"float32\");\n}\nconst Rz = {\n  kernelName: VY,\n  backendName: \"webgl\",\n  kernelFunc: Sz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, filter: g } = l, { strides: b, dilations: c, pad: d, dimRoundingMode: W, inputShape: Y } = Z, V = CG(\n    Y,\n    g.shape,\n    b,\n    c,\n    d,\n    W,\n    !0\n    /* depthwise */\n  ), a = new ez(V);\n  return G.runWebGLProgram(a, [h, g], \"float32\");\n}\nconst Fz = {\n  kernelName: aY,\n  backendName: \"webgl\",\n  kernelFunc: pz\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass yz {\n  constructor(l) {\n    this.variableNames = [\"X\"], this.outputShape = [l, l], this.userCode = `\n      void main() {\n          ivec2 coords = getOutputCoords();\n          float val = coords[0] == coords[1] ? getX(coords[0]) : 0.0;\n          setOutput(val);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Nz(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l, h = [...Z.shape, ...Z.shape], g = Q(Z.shape), b = ll({ inputs: { x: Z }, backend: G, attrs: { shape: [g] } }), c = new yz(g), d = G.runWebGLProgram(c, [b], b.dtype), W = ll({ inputs: { x: d }, backend: G, attrs: { shape: h } });\n  return G.disposeIntermediateTensorInfo(b), G.disposeIntermediateTensorInfo(d), W;\n}\nconst Pz = {\n  kernelName: Ni,\n  backendName: \"webgl\",\n  kernelFunc: Nz\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Jz {\n  constructor(l) {\n    this.variableNames = [\"x\", \"W\"], this.outputShape = l.outShape;\n    const { inHeight: G, inWidth: Z, padInfo: h, strideHeight: g, strideWidth: b, filterHeight: c, filterWidth: d, dilationHeight: W, dilationWidth: Y } = l, { top: V, left: a } = h;\n    this.userCode = `\n      const ivec2 strides = ivec2(${g}, ${b});\n      const ivec2 pads = ivec2(${V}, ${a});\n      const float neg_infinity = -3.4e38;\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords.x;\n        int d1 = coords.w;\n        ivec2 outTopLeftCorner =\n            coords.yz * strides - pads;\n        int hBeg = outTopLeftCorner.x;\n        int wBeg = outTopLeftCorner.y;\n\n        float curVal = neg_infinity;\n        for (int h = 0; h < ${c}; h++) {\n          int hIn = hBeg + h * ${W};\n\n          if (hIn >= 0 && hIn < ${G}) {\n            for (int w = 0; w < ${d}; w++) {\n              int wIn = wBeg + w * ${Y};\n\n              if (wIn >= 0 && wIn < ${Z}) {\n                float xVal = getX(batch, hIn, wIn, d1);\n                float wVal = getW(h, w, d1);\n\n                float val = xVal + wVal;\n                if (val > curVal) {\n                  curVal = val;\n                }\n              }\n            }\n          }\n        }\n\n        float result = curVal;\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Ez(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g } = l, { strides: b, pad: c, dilations: d } = Z, W = wg(h.shape, g.shape, b, c, \"NHWC\", d);\n  let Y;\n  const V = new Jz(W);\n  Y = G.runWebGLProgram(V, [h, g], \"float32\");\n  const a = ll({ inputs: { x: Y }, backend: G, attrs: { shape: W.outShape } });\n  return G.disposeIntermediateTensorInfo(Y), a;\n}\nconst xz = {\n  kernelName: Cc,\n  backendName: \"webgl\",\n  kernelFunc: Ez\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Uz(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { equation: h } = Z, g = l, { allDims: b, summedDims: c, idDims: d } = LV(h, g.length);\n  wV(b.length, d, g);\n  const { path: W, steps: Y } = QV(c, d), V = Y.length;\n  let a = null, i = b.length;\n  const m = [];\n  for (let T = 0; T < V; ++T) {\n    for (const s of Y[T]) {\n      const { permutationIndices: o, expandDims: B } = MV(i, d[s]);\n      let C;\n      vV(o) ? C = g[s] : (C = HG({ inputs: { x: g[s] }, backend: G, attrs: { perm: o } }), m.push(C));\n      const n = C.shape.slice();\n      for (let X = 0; X < B.length; ++X)\n        n.splice(B[X], 0, 1);\n      Nl(C.shape, n) || (C = ll({ inputs: { x: C }, backend: G, attrs: { shape: n } }), m.push(C)), a === null ? a = C : (a = P9({ inputs: { a: C, b: a }, backend: G }), m.push(a));\n    }\n    T < V - 1 && (W[T] >= 0 && (a = Jd({\n      inputs: { x: a },\n      backend: G,\n      attrs: {\n        axis: W[T] - (b.length - i),\n        keepDims: !1\n      }\n    }), m.push(a)), i--);\n  }\n  for (const T of m)\n    T !== a && G.disposeIntermediateTensorInfo(T);\n  return a;\n}\nconst Hz = {\n  kernelName: iY,\n  backendName: \"webgl\",\n  kernelFunc: Uz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Kz = \"return (x >= 0.0) ? x : (exp(x) - 1.0);\", Az = `\n  vec4 result;\n\n  result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n  result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n  result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n  result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n  return result;\n`, kz = Rl({ opSnippet: Kz, packedOpSnippet: Az }), zz = {\n  kernelName: gg,\n  backendName: \"webgl\",\n  kernelFunc: kz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Lz = \"return (b >= 0.0) ? a : a * (b + 1.0);\", Mz = `\n  vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.)));\n  return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0))));\n`, wz = (I) => {\n  const { inputs: l, backend: G } = I, { dy: Z, y: h } = l, g = A().getBool(\"WEBGL_PACK_BINARY_OPERATIONS\") ? new m0(Mz, Z.shape, h.shape) : new sh(Lz, Z.shape, h.shape);\n  return G.runWebGLProgram(g, [Z, h], Z.dtype);\n}, Qz = {\n  kernelName: mY,\n  backendName: \"webgl\",\n  kernelFunc: wz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst vz = `\n  return vec4(equal(a, b));\n`, rz = \"return float(a == b);\", jz = tG({\n  opSnippet: rz,\n  packedOpSnippet: vz,\n  dtype: \"bool\",\n  cpuKernelImpl: SK\n}), Dz = {\n  kernelName: Xc,\n  backendName: \"webgl\",\n  kernelFunc: jz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fz = `\n  // Error function is calculated approximately with elementary function.\n  // See \"Handbook of Mathematical Functions with Formulas,\n  // Graphs, and Mathematical Tables\", Abramowitz and Stegun.\n  float p = ${xV};\n  float a1 = ${UV};\n  float a2 = ${HV};\n  float a3 = ${KV};\n  float a4 = ${AV};\n  float a5 = ${kV};\n\n  float sign = sign(x);\n  x = abs(x);\n  float t = 1.0 / (1.0 + p * x);\n  return sign * (1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x));\n`, Oz = Rl({ opSnippet: fz }), qz = {\n  kernelName: bg,\n  backendName: \"webgl\",\n  kernelFunc: Oz\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst $z = T0 + `\n  return exp(x);\n`, _z = `\n  vec4 result = exp(x);\n  bvec4 isNaN = isnan(x);\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`, qB = Rl({\n  opSnippet: $z,\n  packedOpSnippet: _z,\n  cpuKernelImpl: RK,\n  dtype: \"float32\"\n}), l3 = {\n  kernelName: cg,\n  backendName: \"webgl\",\n  kernelFunc: qB\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zW(I) {\n  const { inputs: l, attrs: G, backend: Z } = I, { dim: h } = G, { input: g } = l, b = g.shape.length, c = g.shape.slice();\n  let d = h;\n  return h < 0 && (u(-(b + 1) <= h, () => `Axis must be in the interval [${-(b + 1)}, ${b}]`), d = b + h + 1), c.splice(d, 0, 1), ll({ inputs: { x: g }, backend: Z, attrs: { shape: c } });\n}\nconst G3 = {\n  kernelName: tc,\n  backendName: \"webgl\",\n  kernelFunc: zW\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Vi = \"return exp(x) - 1.0;\", I3 = Rl({ opSnippet: Vi, packedOpSnippet: Vi, cpuKernelImpl: pK }), Z3 = {\n  kernelName: dg,\n  backendName: \"webgl\",\n  kernelFunc: I3\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass ai {\n  constructor(l, G, Z) {\n    this.variableNames = [\"real\", \"imag\"];\n    const h = G[1];\n    this.outputShape = G;\n    const g = Z ? `2.0 * ${Math.PI}` : `-2.0 * ${Math.PI}`, b = Z ? `${h}.0` : \"1.0\";\n    let c;\n    if (l === \"real\")\n      c = \"return real * expR - imag * expI;\";\n    else if (l === \"imag\")\n      c = \"return real * expI + imag * expR;\";\n    else\n      throw new Error(`FFT component must be either \"real\" or \"imag\", got ${l}.`);\n    this.userCode = `\n      const float exponentMultiplier = ${g};\n\n      float unaryOpComplex(float real, float expR, float imag, float expI) {\n        ${c}\n      }\n\n      float mulMatDFT(int batch, int index) {\n        float indexRatio = float(index) / float(${h});\n        float exponentMultiplierTimesIndexRatio =\n            exponentMultiplier * indexRatio;\n\n        float result = 0.0;\n\n        for (int i = 0; i < ${h}; i++) {\n          // x = (-2|2 * PI / N) * index * i;\n          float x = exponentMultiplierTimesIndexRatio * float(i);\n          float expR = cos(x);\n          float expI = sin(x);\n          float real = getReal(batch, i);\n          float imag = getImag(batch, i);\n\n          result +=\n              unaryOpComplex(real, expR, imag, expI) / ${b};\n        }\n\n        return result;\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        setOutput(mulMatDFT(coords[0], coords[1]));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $B(I, l, G) {\n  const Z = G.texData.get(I.dataId), h = Q(I.shape), g = I.shape[I.shape.length - 1], b = h / g, c = ll({ inputs: { x: I }, backend: G, attrs: { shape: [b, g] } }), d = c.shape, W = new ai(\"real\", d, l), Y = new ai(\"imag\", d, l), V = [\n    {\n      dataId: Z.complexTensorInfos.real.dataId,\n      dtype: Z.complexTensorInfos.real.dtype,\n      shape: d\n    },\n    {\n      dataId: Z.complexTensorInfos.imag.dataId,\n      dtype: Z.complexTensorInfos.imag.dtype,\n      shape: d\n    }\n  ], a = G.runWebGLProgram(W, V, \"float32\"), i = G.runWebGLProgram(Y, V, \"float32\"), m = zZ({ inputs: { real: a, imag: i }, backend: G });\n  G.disposeIntermediateTensorInfo(a), G.disposeIntermediateTensorInfo(i);\n  const T = ll({ inputs: { x: m }, backend: G, attrs: { shape: I.shape } });\n  return G.disposeIntermediateTensorInfo(c), G.disposeIntermediateTensorInfo(m), T;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction h3(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l;\n  return $B(Z, !1, G);\n}\nconst g3 = {\n  kernelName: TY,\n  backendName: \"webgl\",\n  kernelFunc: h3\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass b3 {\n  constructor(l, G) {\n    this.outputShape = [], this.customUniforms = [{ name: \"value\", type: \"float\" }], this.variableNames = [\"x\"], this.outputShape = l, this.userCode = `\n      void main() {\n        // Input can be obtained from uniform value.\n        setOutput(value);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Yb(I) {\n  const { backend: l, attrs: G } = I, { shape: Z, value: h } = G;\n  let { dtype: g } = G;\n  if (g = g || l0(h), g === \"string\") {\n    const b = $l(g, Q(Z));\n    return b.fill(h), l.makeTensorInfo(Z, g, b);\n  } else {\n    const b = new b3(Z, h), c = [[h]];\n    return l.runWebGLProgram(b, [], g, c);\n  }\n}\nconst c3 = {\n  kernelName: sY,\n  backendName: \"webgl\",\n  kernelFunc: Yb\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass d3 {\n  constructor(l) {\n    this.variableNames = [\"Image\"], this.outputShape = [];\n    const G = l[2];\n    this.outputShape = l, this.userCode = `\n        void main() {\n          ivec4 coords = getOutputCoords();\n          int x = coords[2];\n\n          int coordX = ${G} - x - 1;\n          float outputValue;\n          if(coordX >= 0 && coordX < ${G}) {\n            outputValue = getImage(coords[0], coords[1], coordX, coords[3]);\n          } else {\n            outputValue = getImage(coords[0], coords[1], coords[2], coords[3]);\n          }\n          setOutput(outputValue);\n        }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst W3 = {\n  kernelName: oY,\n  backendName: \"webgl\",\n  kernelFunc: ({ inputs: I, backend: l }) => {\n    const { image: G } = I, Z = l, h = new d3(G.shape);\n    return Z.runWebGLProgram(h, [G], G.dtype);\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ii = \"return floor(x);\", Y3 = Rl({ opSnippet: ii, packedOpSnippet: ii, cpuKernelImpl: FK }), V3 = {\n  kernelName: Wg,\n  backendName: \"webgl\",\n  kernelFunc: Y3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst a3 = `\n  float s = sign(a) * sign(b);\n  int ia = round(a);\n  int ib = round(b);\n  if (ib != 0) {\n    // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n    return float(idiv(ia, ib, s));\n  } else {\n    return NAN;\n  }\n`, i3 = `\n  ivec4 ia = round(a);\n  ivec4 ib = round(b);\n  bvec4 cond = notEqual(ib, ivec4(0));\n  ivec4 result = ivec4(0);\n  vec4 s = sign(a) * sign(b);\n\n  // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n  if (cond[0]) {\n    result[0] = idiv(ia[0], ib[0], s[0]);\n  }\n  if (cond[1]) {\n    result[1] = idiv(ia[1], ib[1], s[1]);\n  }\n  if (cond[2]) {\n    result[2] = idiv(ia[2], ib[2], s[2]);\n  }\n  if (cond[3]) {\n    result[3] = idiv(ia[3], ib[3], s[3]);\n  }\n  return vec4(result);\n`, m3 = tG({ opSnippet: a3, packedOpSnippet: i3, dtype: \"int32\" }), T3 = {\n  kernelName: Yg,\n  backendName: \"webgl\",\n  kernelFunc: m3\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass s3 {\n  constructor(l) {\n    this.variableNames = [\"A\"];\n    const G = KG(), [Z, h] = l;\n    this.outputShape = l, this.userCode = `\n      void main() {\n        ivec3 coords = getOutputCoords();\n        int texR = coords[0];\n        int texC = coords[1];\n        int depth = coords[2];\n        vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${h}.0, ${Z}.0);\n\n        vec4 values = ${G.texture2D}(A, uv);\n        float value;\n        if (depth == 0) {\n          value = values.r;\n        } else if (depth == 1) {\n          value = values.g;\n        } else if (depth == 2) {\n          value = values.b;\n        } else if (depth == 3) {\n          value = values.a;\n        }\n\n        setOutput(floor(value * 255.0 + 0.5));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass o3 {\n  constructor(l) {\n    this.variableNames = [\"A\"], this.packedInputs = !1, this.packedOutput = !0;\n    const G = KG(), [Z, h] = l;\n    this.outputShape = l, this.userCode = `\n      void main() {\n        ivec3 coords = getOutputCoords();\n        int texR = coords[0];\n        int texC = coords[1];\n        int depth = coords[2];\n\n        vec4 result = vec4(0.);\n\n        for(int row=0; row<=1; row++) {\n          for(int col=0; col<=1; col++) {\n            texC = coords[1] + row;\n            depth = coords[2] + col;\n\n            vec2 uv = (vec2(texC, texR) + halfCR) /\n                       vec2(${h}.0, ${Z}.0);\n            vec4 values = ${G.texture2D}(A, uv);\n            float value;\n            if (depth == 0) {\n              value = values.r;\n            } else if (depth == 1) {\n              value = values.g;\n            } else if (depth == 2) {\n              value = values.b;\n            } else if (depth == 3) {\n              value = values.a;\n            }\n\n            result[row * 2 + col] = floor(value * 255.0 + 0.5);\n          }\n        }\n\n        ${G.output} = result;\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst B3 = {\n  kernelName: cW,\n  backendName: \"webgl\",\n  kernelFunc: n3\n};\nlet Jh, lW = A().getBool(\"CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU\");\nfunction n3(I) {\n  const { inputs: l, backend: G, attrs: Z } = I;\n  let { pixels: h } = l;\n  const { numChannels: g } = Z, b = typeof HTMLVideoElement < \"u\" && h instanceof HTMLVideoElement, c = typeof HTMLImageElement < \"u\" && h instanceof HTMLImageElement, [d, W] = b ? [\n    h.videoWidth,\n    h.videoHeight\n  ] : [h.width, h.height], Y = [W, d], V = [W, d, g];\n  if (c || b) {\n    const T = A().getBool(\"CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU\");\n    (Jh == null || T !== lW) && (lW = T, Jh = document.createElement(\"canvas\").getContext(\"2d\", { willReadFrequently: lW })), Jh.canvas.width = d, Jh.canvas.height = W, Jh.drawImage(h, 0, 0, d, W), h = Jh.canvas;\n  }\n  const a = G.makeTensorInfo(Y, \"int32\");\n  G.texData.get(a.dataId).usage = lI.PIXELS, G.gpgpu.uploadPixelDataToTexture(G.getTexture(a.dataId), h);\n  const i = A().getBool(\"WEBGL_PACK\") ? new o3(V) : new s3(V), m = G.runWebGLProgram(i, [a], \"int32\");\n  return G.disposeData(a.dataId), m;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction C3(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g, bias: b, preluActivationWeights: c } = l, { strides: d, pad: W, dataFormat: Y, dilations: V, dimRoundingMode: a, activation: i, leakyreluAlpha: m } = Z, T = YZ(Y), s = CG(h.shape, g.shape, d, V, W, a, !1, T);\n  let o;\n  const B = [], C = b != null, n = c != null, X = i === \"leakyrelu\", t = () => {\n    const S = [h, g], p = (F, x) => {\n      if (x === \"NCHW\" && F.shape.length === 1 && F.shape[0] !== 1) {\n        const H = ll({\n          inputs: { x: F },\n          backend: G,\n          attrs: { shape: [F.shape[0], 1, 1] }\n        });\n        return B.push(H), H;\n      }\n      return F;\n    };\n    if (C && S.push(p(b, Y)), n && S.push(p(c, Y)), X) {\n      const F = G.makeTensorInfo([], \"float32\", JZ(m, \"float32\"));\n      S.push(F), B.push(F);\n    }\n    return S;\n  };\n  if (s.filterHeight === 1 && s.filterWidth === 1 && s.dilationHeight === 1 && s.dilationWidth === 1 && s.strideHeight === 1 && s.strideWidth === 1 && (s.padInfo.type === \"SAME\" || s.padInfo.type === \"VALID\"))\n    o = rB({\n      x: h,\n      filter: g,\n      convInfo: s,\n      backend: G,\n      bias: b,\n      activation: i,\n      preluActivationWeights: c,\n      leakyreluAlpha: m\n    });\n  else if (s.strideWidth <= 2 && T === \"channelsLast\" && A().getBool(\"WEBGL_EXP_CONV\")) {\n    const S = i ? L0(i, !0) : null, p = new vB(s, C, S, n, X), F = [\n      [s.padInfo.top, s.padInfo.left],\n      [s.strideHeight, s.strideWidth],\n      [s.dilationHeight, s.dilationWidth],\n      [s.inHeight, s.inWidth]\n    ], x = t();\n    o = G.runWebGLProgram(p, x, \"float32\", F);\n  } else if (A().getBool(\"WEBGL_CONV_IM2COL\"))\n    o = jB({\n      x: h,\n      filter: g,\n      convInfo: s,\n      backend: G,\n      bias: b,\n      activation: i,\n      preluActivationWeights: c,\n      leakyreluAlpha: m\n    });\n  else {\n    const S = i ? L0(i, !1) : null, p = new QB(s, C, S, n, X), F = t();\n    o = G.runWebGLProgram(p, F, \"float32\");\n  }\n  const e = ll({ inputs: { x: o }, backend: G, attrs: { shape: s.outShape } });\n  return B.push(o), B.forEach((S) => G.disposeIntermediateTensorInfo(S)), e;\n}\nconst X3 = {\n  kernelName: Jb,\n  backendName: \"webgl\",\n  kernelFunc: C3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction t3(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, filter: g, bias: b, preluActivationWeights: c } = l, { strides: d, pad: W, dilations: Y, dimRoundingMode: V, activation: a, leakyreluAlpha: i } = Z, m = [];\n  let T = Y;\n  T == null && (T = [1, 1]), u(pG(d, T), () => `Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${d} and dilations '${T}'`);\n  const s = CG(\n    h.shape,\n    g.shape,\n    d,\n    T,\n    W,\n    V,\n    !0\n    /* depthwise */\n  ), o = A().getBool(\"WEBGL_PACK_DEPTHWISECONV\") && s.strideWidth <= 2 && s.outChannels / s.inChannels === 1, B = a ? L0(a, o) : null, C = [h, g], n = b != null, X = c != null, t = a === \"leakyrelu\";\n  if (n && C.push(b), X && C.push(c), t) {\n    const F = G.makeTensorInfo([], \"float32\", JZ(i, \"float32\"));\n    C.push(F), m.push(F);\n  }\n  let e;\n  o ? e = new OB(s, n, B, X, t) : e = new fB(s, n, B, X, t);\n  const S = [\n    [s.padInfo.top, s.padInfo.left],\n    [s.strideHeight, s.strideWidth],\n    [s.dilationHeight, s.dilationWidth],\n    [s.inHeight, s.inWidth]\n  ], p = G.runWebGLProgram(e, C, \"float32\", S);\n  return m.forEach((F) => G.disposeIntermediateTensorInfo(F)), p;\n}\nconst u3 = {\n  kernelName: fi,\n  backendName: \"webgl\",\n  kernelFunc: t3\n};\nclass e3 {\n  constructor(l, G, Z, h) {\n    this.sliceDim = l, this.strides = G, this.paramsShape = h, this.variableNames = [\"x\", \"indices\"], this.outputShape = Z;\n    const g = Ul(Z.length);\n    let b = `\n    int index;`;\n    for (let c = 0; c < this.sliceDim; c++)\n      b += `\n          index = round(getIndices(coords[0], ${c}));\n          out_of_bounds = out_of_bounds || index < 0;\n          out_of_bounds = out_of_bounds || index >= ${this.paramsShape[c]};\n          flattenIndex += index * ${this.strides[c]};`;\n    this.userCode = `\n         void main() {\n          ${g} coords = getOutputCoords();\n          int flattenIndex = 0;\n          bool out_of_bounds = false;\n\n          ${b}\n\n          setOutput(out_of_bounds ? 0.0 : getX(flattenIndex, coords[1]));\n        }\n      `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction S3(I) {\n  const { inputs: l, backend: G } = I, { params: Z, indices: h } = l, g = h.shape, b = g[g.length - 1], c = Q(Z.shape), [d, W, Y, V] = uV(Z, h), a = ll({ inputs: { x: h }, backend: G, attrs: { shape: [W, b] } }), i = ll({\n    inputs: { x: Z },\n    backend: G,\n    attrs: { shape: [Q(Z.shape) / Y, Y] }\n  });\n  if (G.shouldExecuteOnCPU([Z, h]) || Z.dtype === \"string\") {\n    const o = G.readSync(h.dataId), B = G.bufferSync(Z), C = yK(o, B, Z.dtype, W, b, Y, V, Z.shape, c);\n    return G.makeTensorInfo(d, Z.dtype, C.values);\n  }\n  const m = new e3(b, V, [W, Y], Z.shape), T = G.runWebGLProgram(m, [i, a], i.dtype), s = ll({ inputs: { x: T }, backend: G, attrs: { shape: d } });\n  return G.disposeIntermediateTensorInfo(a), G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(T), s;\n}\nconst R3 = {\n  kernelName: Pi,\n  backendName: \"webgl\",\n  kernelFunc: S3\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass p3 {\n  constructor(l, G) {\n    this.variableNames = [\"A\", \"indices\"], this.outputShape = G, this.rank = G.length;\n    const Z = Ul(this.rank), h = F3(l);\n    this.userCode = `\n      void main() {\n        ${Z} resRC = getOutputCoords();\n        int index = int(getIndices(resRC.x, resRC.z));\n        float inBounds = (index >= 0) && (index < ${l[2]}) ? 1.0 : 0.0;\n        setOutput(inBounds * getA(${h}));\n      }\n    `;\n  }\n}\nfunction F3(I, l) {\n  const G = [\"resRC.x\", \"resRC.y\", \"resRC.z\", \"resRC.w\"], Z = [];\n  for (let h = 0; h < I.length; h++)\n    h === 2 ? Z.push(\"index\") : Z.push(`${G[h]}`);\n  return Z.join();\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction _B(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, indices: g } = l, { axis: b, batchDims: c } = Z, d = tl(b, h.shape)[0];\n  if (A().get(\"DEBUG\")) {\n    const B = G.readSync(g.dataId), C = h.shape[d];\n    for (let n = 0; n < B.length; ++n) {\n      const X = B[n];\n      u(X <= C - 1 && X >= 0, () => `GatherV2: the index value ${X} is not in [0, ${C - 1}]`);\n    }\n  }\n  const W = jV(h, g, d, c), Y = Q(g.shape), V = [], a = ll({\n    inputs: { x: h },\n    backend: G,\n    attrs: {\n      shape: [\n        W.batchSize,\n        W.outerSize,\n        W.dimSize,\n        W.sliceSize\n      ]\n    }\n  }), i = ll({\n    inputs: { x: g },\n    backend: G,\n    attrs: { shape: [W.batchSize, Y / W.batchSize] }\n  });\n  V.push(a), V.push(i);\n  const m = [\n    W.batchSize,\n    W.outerSize,\n    Y / W.batchSize,\n    W.sliceSize\n  ];\n  if (G.shouldExecuteOnCPU([h, g]) || h.dtype === \"string\") {\n    const B = G.bufferSync(i), C = G.bufferSync(a), n = NK(C, B, m);\n    return V.forEach((X) => G.disposeIntermediateTensorInfo(X)), G.makeTensorInfo(W.outputShape, n.dtype, n.values);\n  }\n  const T = new p3(a.shape, m), s = G.runWebGLProgram(T, [a, i], a.dtype);\n  V.push(s);\n  const o = ll({ inputs: { x: s }, backend: G, attrs: { shape: W.outputShape } });\n  return V.forEach((B) => G.disposeIntermediateTensorInfo(B)), o;\n}\nconst y3 = {\n  kernelName: ec,\n  backendName: \"webgl\",\n  kernelFunc: _B\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst N3 = \"return float(a > b);\", P3 = `\n  return vec4(greaterThan(a, b));\n`, J3 = tG({\n  opSnippet: N3,\n  packedOpSnippet: P3,\n  cpuKernelImpl: PK,\n  dtype: \"bool\"\n}), E3 = {\n  kernelName: Sc,\n  backendName: \"webgl\",\n  kernelFunc: J3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst x3 = \"return float(a >= b);\", U3 = `\n  return vec4(greaterThanEqual(a, b));\n`, H3 = tG({\n  opSnippet: x3,\n  packedOpSnippet: U3,\n  dtype: \"bool\",\n  cpuKernelImpl: JK\n}), K3 = {\n  kernelName: Vg,\n  backendName: \"webgl\",\n  kernelFunc: H3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction A3(I) {\n  const { inputs: l, backend: G } = I, { input: Z } = l;\n  return $B(Z, !0, G);\n}\nconst k3 = {\n  kernelName: BY,\n  backendName: \"webgl\",\n  kernelFunc: A3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst z3 = \"return float(!isnan(x) && !isinf(x));\", L3 = Rl({ opSnippet: z3, dtype: \"bool\" }), M3 = {\n  kernelName: ig,\n  backendName: \"webgl\",\n  kernelFunc: L3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst w3 = \"return float(isinf(x));\", Q3 = Rl({ opSnippet: w3, dtype: \"bool\" }), v3 = {\n  kernelName: mg,\n  backendName: \"webgl\",\n  kernelFunc: Q3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst r3 = \"return float(isnan(x));\", j3 = Rl({ opSnippet: r3, dtype: \"bool\" }), D3 = {\n  kernelName: Tg,\n  backendName: \"webgl\",\n  kernelFunc: j3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst f3 = \"return float(a < b);\", O3 = `\n  return vec4(lessThan(a, b));\n`, q3 = tG({\n  opSnippet: f3,\n  packedOpSnippet: O3,\n  cpuKernelImpl: EK,\n  dtype: \"bool\"\n}), $3 = {\n  kernelName: pc,\n  backendName: \"webgl\",\n  kernelFunc: q3\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst _3 = \"return float(a <= b);\", lL = `\n  return vec4(lessThanEqual(a, b));\n`, GL = tG({\n  opSnippet: _3,\n  packedOpSnippet: lL,\n  cpuKernelImpl: xK,\n  dtype: \"bool\"\n}), IL = {\n  kernelName: Fc,\n  backendName: \"webgl\",\n  kernelFunc: GL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ZL(I) {\n  const { backend: l, attrs: G } = I, { start: Z, stop: h, num: g } = G, b = UK(Z, h, g);\n  return l.makeTensorInfo([b.length], \"float32\", b);\n}\nconst hL = {\n  kernelName: Ji,\n  backendName: \"webgl\",\n  kernelFunc: ZL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst gL = T0 + `\n  return x < 0.0 ? 0./0. : log(x);\n`, bL = `\n  vec4 result = log(x);\n  bvec4 isNaN = isnan(x);\n  result.r = isNaN.r ? x.r : (x.r < 0.0 ? 0./0. : result.r);\n  result.g = isNaN.g ? x.g : (x.g < 0.0 ? 0./0. : result.g);\n  result.b = isNaN.b ? x.b : (x.b < 0.0 ? 0./0. : result.b);\n  result.a = isNaN.a ? x.a : (x.a < 0.0 ? 0./0. : result.a);\n  return result;\n`, cL = Rl({ opSnippet: gL, packedOpSnippet: bL, cpuKernelImpl: HK }), dL = {\n  kernelName: sg,\n  backendName: \"webgl\",\n  kernelFunc: cL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst WL = T0 + `\n  return log(1.0 + x);\n`, YL = Rl({ opSnippet: WL }), VL = {\n  kernelName: og,\n  backendName: \"webgl\",\n  kernelFunc: YL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst aL = \"return float(a >= 1.0 && b >= 1.0);\", iL = `\n  return vec4(\n    vec4(greaterThanEqual(a, vec4(1.0))) *\n    vec4(greaterThanEqual(b, vec4(1.0))));\n`, mL = tG({\n  opSnippet: aL,\n  packedOpSnippet: iL,\n  dtype: \"bool\"\n}), TL = {\n  kernelName: yc,\n  backendName: \"webgl\",\n  kernelFunc: mL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst sL = \"return float(!(x >= 1.0));\", oL = Rl({ opSnippet: sL }), BL = {\n  kernelName: Nc,\n  backendName: \"webgl\",\n  kernelFunc: oL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst nL = \"return float(a >= 1.0 || b >= 1.0);\", CL = `\n  return min(\n    vec4(greaterThanEqual(a, vec4(1.0))) +\n    vec4(greaterThanEqual(b, vec4(1.0))),\n    vec4(1.0));\n`, XL = tG({ opSnippet: nL, packedOpSnippet: CL, dtype: \"bool\" }), tL = {\n  kernelName: Pc,\n  backendName: \"webgl\",\n  kernelFunc: XL\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass uL {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"x\"], this.outputShape = [];\n    const b = G, c = l[3] - 1;\n    this.outputShape = l;\n    let d;\n    const W = `float(${Z}) + float(${h}) * sum`;\n    g === 0.5 ? d = `inversesqrt(${W})` : g === 1 ? d = `1.0/(${W})` : d = `exp(log(${W}) * float(-${g}));`, this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int r = coords[1];\n        int c = coords[2];\n        int d = coords[3];\n        float x = getX(b, r, c, d);\n        float sum = 0.0;\n        for (int j = -${b}; j <= ${b}; j++) {\n          int idx = d + j;\n          if (idx >= 0 && idx <=  ${c}) {\n            float z = getX(b, r, c, idx);\n            sum += z * z;\n          }\n        }\n        float val = x * ${d};\n        setOutput(val);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass eL {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"x\"], this.outputShape = [], this.packedInputs = !0, this.packedOutput = !0;\n    const b = G, c = l[3] - 1;\n    this.outputShape = l;\n    let d;\n    const W = `float(${Z}) + float(${h}) * sum`;\n    g === 0.5 ? d = `inversesqrt(${W})` : g === 1 ? d = `1.0/(${W})` : d = `exp(log(${W}) * float(-${g}));`, this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords.x;\n        int r = coords.y;\n        int c = coords.z;\n        int d = coords.w;\n\n        bool hasNextCol = d < ${this.outputShape[3]};\n        bool hasNextRow = c < ${this.outputShape[2]};\n\n        vec4 sum = vec4(0.);\n        vec4 xFragAtOutputCoords = getX(b, r, c, d);\n\n        vec4 xAtOutputCoords = vec4(\n          getChannel(xFragAtOutputCoords, vec2(c, d)),\n          hasNextCol ?\n            getChannel(xFragAtOutputCoords, vec2(c, d + 1)) : 0.0,\n          hasNextRow ?\n            getChannel(xFragAtOutputCoords , vec2(c + 1, d)) : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getChannel(xFragAtOutputCoords, vec2(c + 1, d + 1)) : 0.0\n        );\n\n        int firstChannel = d - ${b};\n        vec2 cache = vec2(0.);\n        if(firstChannel >= 0){\n          vec4 firstChannelFrag = getX(b, r, c, firstChannel);\n          cache.x = getChannel(firstChannelFrag, vec2(c, firstChannel));\n            if(hasNextRow){\n              cache.y = getChannel(firstChannelFrag, vec2(c + 1, firstChannel));\n            }\n        }\n\n        ivec2 depth = ivec2(d, d + 1);\n        for (int j = - ${b}; j <= ${b}; j++) {\n          ivec2 idx = depth + j;\n          bvec2 aboveLowerBound = greaterThanEqual(idx, ivec2(0));\n          bvec2 belowUpperBound = lessThanEqual(idx, ivec2(${c}));\n\n          bool depthInRange = aboveLowerBound.x && belowUpperBound.x;\n          bool depthPlusOneInRange = aboveLowerBound.y && belowUpperBound.y;\n\n          if(depthInRange || depthPlusOneInRange){\n            vec4 z = vec4(0.);\n            vec4 xFragAtCurrentDepth;\n            z.xz = cache.xy;\n            if(depthPlusOneInRange && hasNextCol){\n              xFragAtCurrentDepth = idx.y != d ?\n                getX(b, r, c, idx.y) : xFragAtOutputCoords;\n              z.y = getChannel(xFragAtCurrentDepth, vec2(c, idx.y));\n              if(hasNextRow){\n                z.w = getChannel(xFragAtCurrentDepth, vec2(c + 1, idx.y));\n              }\n            }\n            cache.xy = z.yw;\n            sum += z * z;\n          }\n        }\n        vec4 result = xAtOutputCoords * ${d};\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst SL = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { depthRadius: g, bias: b, alpha: c, beta: d } = Z, W = A().getBool(\"WEBGL_PACK_NORMALIZATION\") ? new eL(h.shape, g, b, c, d) : new uL(h.shape, g, b, c, d);\n  return G.runWebGLProgram(W, [h], h.dtype);\n}, RL = {\n  kernelName: Jc,\n  backendName: \"webgl\",\n  kernelFunc: SL\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass pL {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"inputImage\", \"outputImage\", \"dy\"], this.outputShape = [], this.outputShape = l, this.depth = l[3], this.depthRadius = G, this.bias = Z, this.alpha = h, this.beta = g, this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int r = coords[1];\n        int c = coords[2];\n\n        float result = 0.0;\n        for (int d = 0; d < ${this.depth}; ++d) {\n          int depthBegin = int(max(0.0, float(d - ${G})));\n          int depthEnd = int(min(float(${this.depth}),\n              float(d + ${G} + 1)));\n\n          const int MIN_DEPTH_BEGIN = 0;\n          const int MAX_DEPTH_END = ${this.depth};\n\n          float norm = 0.0;\n          for (int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k) {\n            if (k < depthBegin){\n              continue;\n            }\n            else if (k >= depthBegin && k < depthEnd) {\n              norm += getInputImage(b, r, c, k) * getInputImage(b, r, c, k);\n            }\n            else {\n              break;\n            }\n          }\n\n          norm = float(${h}) * norm + float(${Z});\n\n          for(int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k){\n            if (k < depthBegin){\n              continue;\n            }\n            else if (k >= depthBegin && k < depthEnd){\n              float dyi = -2.0 * float(${h})\n                * float(${g})\n                * getInputImage(b, r, c, k) * getOutputImage(b, r, c, d)\n                / norm;\n              if (k == d) {\n                dyi += pow(norm, -1.0 * ${g});\n              }\n              if (k == coords[3]) {\n                dyi *= getDy(b, r, c, d);\n                result += dyi;\n              }\n            }\n            else {\n              break;\n            }\n          }\n      }\n      setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst FL = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, y: g, dy: b } = l, { depthRadius: c, bias: d, alpha: W, beta: Y } = Z, V = new pL(h.shape, c, d, W, Y);\n  return G.runWebGLProgram(V, [h, g, b], h.dtype);\n}, yL = {\n  kernelName: CY,\n  backendName: \"webgl\",\n  kernelFunc: FL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction NL(I, l, G, Z) {\n  const h = Q(l), b = Q(I.shape) / h, c = ll({ inputs: { x: I }, attrs: { shape: [b, h] }, backend: Z }), d = yh(c, I.dtype, \"max\", Z), W = ll({ inputs: { x: d }, attrs: { shape: G }, backend: Z });\n  return Z.disposeIntermediateTensorInfo(c), Z.disposeIntermediateTensorInfo(d), W;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ln(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { reductionIndices: g, keepDims: b } = Z, c = h.shape.length, d = tl(g, h.shape);\n  let W = d;\n  const Y = Ol(W, c), V = Y != null, a = G.shouldExecuteOnCPU([h]);\n  let i = h;\n  if (V) {\n    if (a) {\n      const C = G.texData.get(i.dataId).values, n = new Array(c);\n      for (let e = 0; e < n.length; e++)\n        n[e] = h.shape[Y[e]];\n      const X = y9(C, h.shape, h.dtype, Y, n);\n      i = G.makeTensorInfo(n, h.dtype);\n      const t = G.texData.get(i.dataId);\n      t.values = X;\n    } else\n      i = Pd(h, Y, G);\n    W = GG(W.length, c);\n  }\n  XG(\"max\", W, c);\n  const [m, T] = sG(i.shape, W);\n  let s = m;\n  b && (s = bG(m, d));\n  let o;\n  if (a) {\n    const C = G.texData.get(i.dataId).values, n = KK(C, Q(T), s, h.dtype);\n    o = G.makeTensorInfo(s, h.dtype);\n    const X = G.texData.get(o.dataId);\n    X.values = n;\n  } else\n    o = NL(i, T, s, G);\n  return V && G.disposeIntermediateTensorInfo(i), o;\n}\nconst PL = {\n  kernelName: Ec,\n  backendName: \"webgl\",\n  kernelFunc: ln\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst JL = N9 + `\n  return max(a, b);\n`, EL = `\n  vec4 result = vec4(max(a, b));\n  bvec4 isNaNA = isnan(a);\n  bvec4 isNaNB = isnan(b);\n  bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w);\n  ` + Fh + `\n  return result;\n`, xL = tG({\n  opSnippet: JL,\n  packedOpSnippet: EL,\n  cpuKernelImpl: AK\n}), UL = {\n  kernelName: Bg,\n  backendName: \"webgl\",\n  kernelFunc: xL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction HL(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l;\n  cb(h, \"maxPool\");\n  const { filterSize: g, strides: b, pad: c, dimRoundingMode: d } = Z, W = 1;\n  u(pG(b, W), () => `Error in maxPool: Either strides or dilations must be 1. Got strides ${b} and dilations '${W}'`);\n  const Y = sI(h.shape, g, b, W, c, d);\n  if (Y.filterWidth === 1 && Y.filterHeight === 1 && Nl(Y.inShape, Y.outShape))\n    return OG({ inputs: { x: h }, backend: G });\n  const V = new M0(Y, \"max\", !1);\n  return G.runWebGLProgram(V, [h], h.dtype);\n}\nconst KL = {\n  kernelName: xc,\n  backendName: \"webgl\",\n  kernelFunc: HL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction AL(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { filterSize: g, strides: b, pad: c, dataFormat: d, dimRoundingMode: W } = Z, Y = [1, 1, 1], V = WZ(h.shape, g, b, Y, c, W, d), a = new J9(V, \"max\", !1);\n  return G.runWebGLProgram(a, [h], h.dtype);\n}\nconst kL = {\n  kernelName: Uc,\n  backendName: \"webgl\",\n  kernelFunc: AL\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass zL {\n  constructor(l) {\n    this.variableNames = [\"dy\", \"maxPos\"], this.outputShape = l.inShape;\n    const G = l.strideHeight, Z = l.strideWidth, h = l.dilationHeight, g = l.effectiveFilterHeight, b = l.effectiveFilterWidth, c = g - 1 - l.padInfo.top, d = b - 1 - l.padInfo.left, W = g * b - 1;\n    this.userCode = `\n      const ivec2 pads = ivec2(${c}, ${d});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n\n        ivec2 dyRCCorner = coords.yz - pads;\n        int dyRCorner = dyRCCorner.x;\n        int dyCCorner = dyRCCorner.y;\n\n        // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${g};\n          wR += ${h}) {\n          float dyR = float(dyRCorner + wR) / ${G}.0;\n\n          if (dyR < 0.0 || dyR >= ${l.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          for (int wC = 0; wC < ${b}; wC++) {\n            float dyC = float(dyCCorner + wC) / ${Z}.0;\n\n            if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            float dyValue = getDy(b, idyR, idyC, d);\n            int maxPosValue = ${W} - int(getMaxPos(b, idyR, idyC, d));\n\n            // Get the current value, check it against the value from the\n            // position matrix.\n            int curPosValue = wR * ${b} + wC;\n            float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n            dotProd += dyValue * mask;\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\nclass LL {\n  constructor(l) {\n    this.variableNames = [\"dy\", \"maxPos\"], this.outputShape = l.inShape;\n    const G = l.strideDepth, Z = l.strideHeight, h = l.strideWidth, g = l.dilationDepth, b = l.dilationHeight, c = l.dilationWidth, d = l.effectiveFilterDepth, W = l.effectiveFilterHeight, Y = l.effectiveFilterWidth, V = d - 1 - l.padInfo.front, a = W - 1 - l.padInfo.top, i = Y - 1 - l.padInfo.left, m = d * W * Y - 1;\n    this.userCode = `\n      const ivec3 pads = ivec3(${V}, ${a}, ${i});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int ch = coords.u;\n\n        ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n        int dyDCorner = dyCorner.x;\n        int dyRCorner = dyCorner.y;\n        int dyCCorner = dyCorner.z;\n\n        // Convolve dy(?, ?, ?, ch) with pos mask(:, :, :, d) to get\n        // dx(xD, xR, xC, ch).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n\n        for (int wD = 0; wD < ${d};\n           wD += ${g}) {\n          float dyD = float(dyDCorner + wD) / ${G}.0;\n\n          if (dyD < 0.0 || dyD >= ${l.outDepth}.0 || fract(dyD) > 0.0) {\n            continue;\n          }\n          int idyD = int(dyD);\n\n          for (int wR = 0; wR < ${W};\n              wR += ${b}) {\n            float dyR = float(dyRCorner + wR) / ${Z}.0;\n\n            if (dyR < 0.0 || dyR >= ${l.outHeight}.0 ||\n                fract(dyR) > 0.0) {\n              continue;\n            }\n            int idyR = int(dyR);\n\n            for (int wC = 0; wC < ${Y};\n                wC += ${c}) {\n              float dyC = float(dyCCorner + wC) / ${h}.0;\n\n              if (dyC < 0.0 || dyC >= ${l.outWidth}.0 ||\n                  fract(dyC) > 0.0) {\n                continue;\n              }\n              int idyC = int(dyC);\n\n              float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n              int maxPosValue = ${m} -\n                  int(getMaxPos(batch, idyD, idyR, idyC, ch));\n\n              // Get the current value, check it against the value from the\n              // position matrix.\n              int curPosValue =\n                  wD * ${W} * ${Y} +\n                  wR * ${Y} + wC;\n              float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n              dotProd += dyValue * mask;\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction ML(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g } = l, b = g, { filterSize: c, strides: d, pad: W, dimRoundingMode: Y } = Z, V = [1, 1, 1], a = WZ(b.shape, c, d, V, W, Y), i = new J9(\n    a,\n    \"max\",\n    !0\n    /* get positions */\n  ), m = G.runWebGLProgram(i, [b], b.dtype), T = new LL(a), s = G.runWebGLProgram(T, [h, m], b.dtype);\n  return G.disposeIntermediateTensorInfo(m), s;\n}\nconst wL = {\n  kernelName: tY,\n  backendName: \"webgl\",\n  kernelFunc: ML\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction QL(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { dy: h, input: g, output: b } = l, c = g;\n  cb([g, b], \"maxPoolGrad\");\n  const { filterSize: d, strides: W, pad: Y, dimRoundingMode: V } = Z, a = sI(c.shape, d, W, 1, Y, V), i = !0, m = new M0(a, \"max\", i), T = G.runWebGLProgram(m, [c], c.dtype), s = new zL(a), o = G.runWebGLProgram(s, [h, T], c.dtype);\n  return G.disposeIntermediateTensorInfo(T), o;\n}\nconst vL = {\n  kernelName: XY,\n  backendName: \"webgl\",\n  kernelFunc: QL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction rL(I, l, G, Z) {\n  let h = new M0(G, \"max\", !1);\n  const g = Z.runWebGLProgram(h, [I], \"float32\");\n  h = new M0(G, \"max\", !0, !0, l);\n  const b = Z.runWebGLProgram(h, [I], \"float32\");\n  return [g, b];\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst jL = {\n  kernelName: Ei,\n  backendName: \"webgl\",\n  kernelFunc: ({ inputs: I, attrs: l, backend: G }) => {\n    const { x: Z } = I, { filterSize: h, strides: g, pad: b, includeBatchInIndex: c } = l, d = G;\n    u(Z.shape.length === 4, () => `Error in maxPool: input must be rank 4 but got rank ${Z.shape.length}.`);\n    const W = [1, 1];\n    u(pG(g, W), () => `Error in maxPool: Either strides or dilations must be 1. Got strides ${g} and dilations '${W}'`);\n    const Y = sI(Z.shape, h, g, W, b), [V, a] = rL(Z, c, Y, d);\n    return [V, a];\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction DL(I, l, G, Z) {\n  const h = Q(l), b = Q(I.shape) / h, c = ll({ inputs: { x: I }, attrs: { shape: [b, h] }, backend: Z }), d = yh(c, \"float32\", \"mean\", Z), W = ll({ inputs: { x: d }, attrs: { shape: G }, backend: Z });\n  return Z.disposeIntermediateTensorInfo(c), Z.disposeIntermediateTensorInfo(d), W;\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fL = {\n  kernelName: Hc,\n  backendName: \"webgl\",\n  kernelFunc: ({ inputs: I, attrs: l, backend: G }) => {\n    const { x: Z } = I, { keepDims: h, axis: g } = l, b = G, c = Z.shape.length, d = tl(g, Z.shape);\n    let W = d;\n    const Y = Ol(W, c), V = Y != null, a = b.shouldExecuteOnCPU([Z]), i = [];\n    let m = Z;\n    if (V) {\n      if (a) {\n        const n = b.texData.get(m.dataId).values, X = new Array(c);\n        for (let S = 0; S < X.length; S++)\n          X[S] = Z.shape[Y[S]];\n        const t = y9(n, Z.shape, Z.dtype, Y, X);\n        m = b.makeTensorInfo(X, Z.dtype);\n        const e = b.texData.get(m.dataId);\n        e.values = t;\n      } else\n        m = Pd(Z, Y, b);\n      i.push(m), W = GG(W.length, c);\n    }\n    XG(\"sum\", W, c);\n    const [T, s] = sG(m.shape, W);\n    let o = T;\n    h && (o = bG(T, d));\n    const B = DL(m, s, o, b);\n    for (const C of i)\n      b.disposeIntermediateTensorInfo(C);\n    return B;\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction OL(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z, c = h.shape.length, d = tl(g, h.shape);\n  let W = d;\n  const Y = Ol(W, c);\n  let V = h;\n  Y != null && (V = HG({ inputs: { x: h }, backend: G, attrs: { perm: Y } }), W = GG(W.length, h.shape.length)), XG(\"min\", W, c);\n  const [a, i] = sG(V.shape, W), m = Q(i), T = ll({ inputs: { x: V }, backend: G, attrs: { shape: [-1, m] } }), s = yh(T, T.dtype, \"min\", G);\n  let o;\n  if (b) {\n    const B = bG(a, d);\n    o = ll({ inputs: { x: s }, backend: G, attrs: { shape: B } });\n  } else\n    o = ll({ inputs: { x: s }, backend: G, attrs: { shape: a } });\n  return G.disposeIntermediateTensorInfo(T), G.disposeIntermediateTensorInfo(s), Y != null && G.disposeIntermediateTensorInfo(V), o;\n}\nconst qL = {\n  kernelName: Kc,\n  backendName: \"webgl\",\n  kernelFunc: OL\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst $L = N9 + `\n  return min(a, b);\n`, _L = `\n  vec4 result = vec4(min(a, b));\n  bvec4 isNaNA = isnan(a);\n  bvec4 isNaNB = isnan(b);\n  bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w);\n  ` + Fh + `\n  return result;\n`, lM = tG({\n  opSnippet: $L,\n  packedOpSnippet: _L,\n  cpuKernelImpl: kK\n}), GM = {\n  kernelName: ng,\n  backendName: \"webgl\",\n  kernelFunc: lM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass IM {\n  constructor(l, G, Z) {\n    this.variableNames = [\"x\"], this.outputShape = G.map(\n      (Y, V) => Y[0] + l[V] + Y[1]\n      /* afterPad */\n    );\n    const h = l.length, g = Ul(h), b = G.map((Y) => Y[0]).join(\",\"), c = G.map((Y, V) => Y[0] + l[V]).join(\",\"), d = [\"coords[0]\", \"coords[1]\", \"coords[2]\", \"coords[3]\"].slice(0, h), W = Z === \"reflect\" ? 0 : 1;\n    if (h === 1) {\n      this.userCode = `\n        int start = ${b};\n        int end = ${c};\n\n        void main() {\n          int outC = getOutputCoords();\n          if (outC < start) {\n            outC = start * 2 - outC - ${W};\n          } else if(outC >= end) {\n            outC = (end - 1) * 2 - outC + ${W};\n          }\n          setOutput(getX(outC - start));\n        }\n      `;\n      return;\n    }\n    this.userCode = `\n      ${g} start = ${g}(${b});\n      ${g} end = ${g}(${c});\n\n      void main() {\n        ${g} outC = getOutputCoords();\n        for (int i = 0; i < ${h}; i++) {\n          if (outC[i] < start[i]) {\n            outC[i] = start[i] * 2 - outC[i] - ${W};\n          } else if(outC[i] >= end[i]) {\n            outC[i] = (end[i] - 1) * 2 - outC[i] + ${W};\n          }\n        }\n        ${g} coords = outC - start;\n        setOutput(getX(${d}));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass ZM {\n  constructor(l, G, Z) {\n    this.variableNames = [\"x\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = G.map(\n      (m, T) => m[0] + l[T] + m[1]\n      /* afterPad */\n    );\n    const h = l.length, g = Ul(h), b = G.map((m) => m[0]).join(\",\"), c = G.map((m, T) => m[0] + l[T]).join(\",\"), d = xG(\"rc\", h), W = xG(\"source\", h), Y = `${d[h - 1]} < ${this.outputShape[h - 1]}`, V = h === 1 ? \"source\" : `vec2(${W.slice(-2).join()})`, a = Z === \"reflect\" ? 0 : 1;\n    let i = \"\";\n    if (h === 1) {\n      const m = `\n        ${g} source = rc;\n        if (source < start) {\n          source = start * 2 - source - ${a};\n        } else if (source >= end) {\n          source = (end - 1) * 2 - source + ${a};\n        }\n        source -= start;\n      `;\n      i = `\n        ${g} rc = outputLoc;\n        ${m}\n        result[0] = getChannel(getX(${W.join()}), ${V});\n        ${d[h - 1]} += 1;\n        if(${Y}) {\n          ${m}\n          result[1] = getChannel(getX(${W.join()}), ${V});\n        }\n      `;\n    } else {\n      const m = `\n        ${g} source = rc;\n        ${g} lt = ${g}(lessThan(source, start));\n        ${g} gte = ${g}(greaterThanEqual(source, end));\n        ${g} orig = 1 - (lt + gte);\n        source = orig * source +\n                lt * (start * 2 - source - ${a}) +\n                gte * ((end - 1) * 2 - source + ${a});\n        source -= start;\n      `;\n      i = `\n        ${g} rc = outputLoc;\n        ${m}\n        result[0] = getChannel(getX(${W.join()}), ${V});\n        ${d[h - 1]} += 1;\n        if(${Y}) {\n          ${m}\n          result[1] = getChannel(getX(${W.join()}), ${V});\n        }\n        rc = outputLoc;\n        ${d[h - 2]} += 1;\n        if(${d[h - 2]} < ${this.outputShape[h - 2]}) {\n          ${m}\n          result[2] = getChannel(getX(${W.join()}), ${V});\n          ${d[h - 1]} += 1;\n          if(${Y}) {\n            ${m}\n            result[3] = getChannel(getX(${W.join()}), ${V});\n          }\n        }\n      `;\n    }\n    this.userCode = `\n      const ${g} start = ${g}(${b});\n      const ${g} end = ${g}(${c});\n\n      void main() {\n        ${g} outputLoc = getOutputCoords();\n        vec4 result = vec4(0.);\n        ${i}\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst hM = ({ inputs: I, backend: l, attrs: G }) => {\n  const { x: Z } = I, { paddings: h, mode: g } = G, b = A().getBool(\"WEBGL_PACK_ARRAY_OPERATIONS\") ? new ZM(Z.shape, h, g) : new IM(Z.shape, h, g);\n  return l.runWebGLProgram(b, [Z], Z.dtype);\n}, gM = {\n  kernelName: Ac,\n  backendName: \"webgl\",\n  kernelFunc: hM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bM = `if (b == 0.0) return NAN;\n  return mod(a, b);`, cM = `\n  vec4 result = mod(a, b);\n  bvec4 isNaN = equal(b, vec4(0.0));\n  ` + Fh + `\n  return result;\n`, dM = tG({\n  opSnippet: bM,\n  packedOpSnippet: cM\n}), WM = {\n  kernelName: Cg,\n  backendName: \"webgl\",\n  kernelFunc: dM\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass YM {\n  constructor(l, G, Z) {\n    this.variableNames = [\"probs\"], this.customUniforms = [{ name: \"seed\", type: \"float\" }], this.outputShape = [l, Z], this.userCode = `\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n\n        float r = random(seed);\n        float cdf = 0.0;\n\n        for (int i = 0; i < ${G - 1}; i++) {\n          cdf += getProbs(batch, i);\n\n          if (r < cdf) {\n            setOutput(float(i));\n            return;\n          }\n        }\n\n        // If no other event happened, last event happened.\n        setOutput(float(${G - 1}));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst VM = `\nif (a == b) {\n  return 1.0;\n};\nreturn a / b;`, aM = `\n  // vec4 one = vec4(equal(a, b));\n  // return one + (vec4(1.0) - one) * a / b;\n  vec4 result = a / b;\n  if(a.x == b.x) {\n    result.x = 1.;\n  }\n  if(a.y == b.y) {\n    result.y = 1.;\n  }\n  if(a.z == b.z) {\n    result.z = 1.;\n  }\n  if(a.w == b.w) {\n    result.w = 1.;\n  }\n\n  return result;\n`, Gn = tG({ opSnippet: VM, packedOpSnippet: aM, checkOutOfBounds: !0 }), iM = {\n  kernelName: hg,\n  backendName: \"webgl\",\n  kernelFunc: Gn\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst mi = \"return a - b;\", In = tG({\n  opSnippet: mi,\n  packedOpSnippet: mi,\n  supportsComplex: !0,\n  cpuKernelImpl: b1\n}), mM = {\n  kernelName: Hg,\n  backendName: \"webgl\",\n  kernelFunc: In\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Zn(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { logits: h } = l, { dim: g } = Z, b = tl([g], h.shape), c = ln({\n    inputs: { x: h },\n    backend: G,\n    attrs: { reductionIndices: b, keepDims: !1 }\n  }), d = bG(c.shape, b), W = ll({ inputs: { x: c }, backend: G, attrs: { shape: d } }), Y = In({ inputs: { a: h, b: W }, backend: G }), V = qB({ inputs: { x: Y }, backend: G }), a = Jd({ inputs: { x: V }, backend: G, attrs: { axis: b, keepDims: !1 } }), i = ll({ inputs: { x: a }, backend: G, attrs: { shape: d } }), m = Gn({ inputs: { a: V, b: i }, backend: G });\n  return G.disposeIntermediateTensorInfo(c), G.disposeIntermediateTensorInfo(W), G.disposeIntermediateTensorInfo(Y), G.disposeIntermediateTensorInfo(V), G.disposeIntermediateTensorInfo(a), G.disposeIntermediateTensorInfo(i), m;\n}\nconst TM = {\n  kernelName: Id,\n  backendName: \"webgl\",\n  kernelFunc: Zn\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sM(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { logits: h } = l, { numSamples: g, seed: b, normalized: c } = Z, d = c ? h : Zn({ inputs: { logits: h }, backend: G, attrs: { dim: h.shape.length - 1 } }), W = d.shape[0], Y = d.shape[1], V = new YM(W, Y, g), a = [[b]], i = G.runWebGLProgram(V, [d], \"int32\", a);\n  return c || G.disposeIntermediateTensorInfo(d), i;\n}\nconst oM = {\n  kernelName: xi,\n  backendName: \"webgl\",\n  kernelFunc: sM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst BM = BI + `\n  return -x;\n`, nM = `\n  vec4 result = -x;\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`;\nfunction CM(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  if (G.shouldExecuteOnCPU([Z])) {\n    const g = G.texData.get(Z.dataId), [b, c] = LK(g.values, Z.shape, Z.dtype);\n    return G.makeTensorInfo(c, Z.dtype, b);\n  }\n  let h;\n  return A().getBool(\"WEBGL_PACK_UNARY_OPERATIONS\") ? h = new nZ(Z.shape, nM) : h = new kI(Z.shape, BM), G.runWebGLProgram(h, [Z], Z.dtype);\n}\nconst XM = {\n  kernelName: kc,\n  backendName: \"webgl\",\n  kernelFunc: CM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst tM = BV;\nfunction uM(I) {\n  _G(\"tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead\");\n  const { inputs: l, backend: G, attrs: Z } = I, { boxes: h, scores: g } = l, { maxOutputSize: b, iouThreshold: c, scoreThreshold: d } = Z, W = G.readSync(h.dataId), Y = G.readSync(g.dataId), { selectedIndices: V } = tM(W, Y, b, c, d);\n  return G.makeTensorInfo([V.length], \"int32\", new Int32Array(V));\n}\nconst eM = {\n  kernelName: uY,\n  backendName: \"webgl\",\n  kernelFunc: uM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst SM = nV;\nfunction RM(I) {\n  _G(\"tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead\");\n  const { inputs: l, backend: G, attrs: Z } = I, { boxes: h, scores: g } = l, { maxOutputSize: b, iouThreshold: c, scoreThreshold: d, padToMaxOutputSize: W } = Z, Y = G.readSync(h.dataId), V = G.readSync(g.dataId), { selectedIndices: a, validOutputs: i } = SM(Y, V, b, c, d, W);\n  return [\n    G.makeTensorInfo([a.length], \"int32\", new Int32Array(a)),\n    G.makeTensorInfo([], \"int32\", new Int32Array([i]))\n  ];\n}\nconst pM = {\n  kernelName: eY,\n  backendName: \"webgl\",\n  kernelFunc: RM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst FM = CV;\nfunction yM(I) {\n  _G(\"tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead\");\n  const { inputs: l, backend: G, attrs: Z } = I, { boxes: h, scores: g } = l, { maxOutputSize: b, iouThreshold: c, scoreThreshold: d, softNmsSigma: W } = Z, Y = G.readSync(h.dataId), V = G.readSync(g.dataId), a = b, i = c, m = d, T = W, { selectedIndices: s, selectedScores: o } = FM(Y, V, a, i, m, T);\n  return [\n    G.makeTensorInfo([s.length], \"int32\", new Int32Array(s)),\n    G.makeTensorInfo([o.length], \"float32\", new Float32Array(o))\n  ];\n}\nconst NM = {\n  kernelName: SY,\n  backendName: \"webgl\",\n  kernelFunc: yM\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass PM {\n  constructor(l, G, Z, h) {\n    this.variableNames = [\"indices\"], this.outputShape = [l, G], this.userCode = `\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int index = round(getIndices(coords.x));\n        setOutput(mix(float(${h}), float(${Z}),\n                      float(index == coords.y)));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst JM = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { indices: h } = l, { dtype: g, depth: b, onValue: c, offValue: d } = Z, W = Q(h.shape), Y = new PM(W, b, c, d), V = ll({ inputs: { x: h }, backend: G, attrs: { shape: [W] } }), a = G.runWebGLProgram(Y, [V], g);\n  G.disposeIntermediateTensorInfo(V);\n  const i = [...h.shape, b], m = ll({ inputs: { x: a }, backend: G, attrs: { shape: i } });\n  return G.disposeIntermediateTensorInfo(a), m;\n}, EM = {\n  kernelName: Mc,\n  backendName: \"webgl\",\n  kernelFunc: JM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction hc(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  if (Z.dtype === \"complex64\") {\n    const h = Wb({ inputs: { input: Z }, backend: G }), g = hc({ inputs: { x: h }, backend: G }), b = Ed({ inputs: { input: Z }, backend: G }), c = hc({ inputs: { x: b }, backend: G }), d = zZ({ inputs: { real: g, imag: c }, backend: G });\n    return G.disposeIntermediateTensorInfo(h), G.disposeIntermediateTensorInfo(g), G.disposeIntermediateTensorInfo(b), G.disposeIntermediateTensorInfo(c), d;\n  } else\n    return Yb({\n      attrs: {\n        shape: Z.shape,\n        dtype: Z.dtype,\n        value: Z.dtype === \"string\" ? \"\" : 0\n      },\n      backend: G\n    });\n}\nconst xM = {\n  kernelName: gd,\n  backendName: \"webgl\",\n  kernelFunc: hc\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction hn(I) {\n  const { inputs: l, backend: G } = I, { x: Z } = l;\n  if (Z.dtype === \"string\")\n    throw new Error(\"onesLike is not supported under string dtype\");\n  if (Z.dtype === \"complex64\") {\n    const h = Wb({ inputs: { input: Z }, backend: G }), g = hn({ inputs: { x: h }, backend: G }), b = Ed({ inputs: { input: Z }, backend: G }), c = hc({ inputs: { x: b }, backend: G }), d = zZ({ inputs: { real: g, imag: c }, backend: G });\n    return G.disposeIntermediateTensorInfo(h), G.disposeIntermediateTensorInfo(g), G.disposeIntermediateTensorInfo(b), G.disposeIntermediateTensorInfo(c), d;\n  } else\n    return Yb({ attrs: { shape: Z.shape, dtype: Z.dtype, value: 1 }, backend: G });\n}\nconst UM = {\n  kernelName: Lc,\n  backendName: \"webgl\",\n  kernelFunc: hn\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction HM(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { axis: h } = Z;\n  if (l.length === 1)\n    return zW({ inputs: { input: l[0] }, backend: G, attrs: { dim: h } });\n  const g = l[0].shape, b = l[0].dtype;\n  l.forEach((Y) => {\n    vW(g, Y.shape, \"All tensors passed to stack must have matching shapes\"), u(b === Y.dtype, () => \"All tensors passed to stack must have matching dtypes\");\n  });\n  const c = [], d = l.map((Y) => {\n    const V = zW({ inputs: { input: Y }, backend: G, attrs: { dim: h } });\n    return c.push(V), V;\n  }), W = wB({ inputs: d, backend: G, attrs: { axis: h } });\n  return c.forEach((Y) => G.disposeIntermediateTensorInfo(Y)), W;\n}\nconst KM = {\n  kernelName: wc,\n  backendName: \"webgl\",\n  kernelFunc: HM\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass AM {\n  constructor(l, G, Z) {\n    this.variableNames = [\"x\"], this.customUniforms = [{ name: \"value\", type: \"float\" }], this.outputShape = G.map(\n      (W, Y) => W[0] + l[Y] + W[1]\n      /* afterPad */\n    );\n    const h = l.length, g = Ul(h), b = G.map((W) => W[0]).join(\",\"), c = G.map((W, Y) => W[0] + l[Y]).join(\",\"), d = [\"coords[0]\", \"coords[1]\", \"coords[2]\", \"coords[3]\"].slice(0, h);\n    if (h === 1) {\n      this.userCode = `\n        int start = ${b};\n        int end = ${c};\n\n        void main() {\n          int outC = getOutputCoords();\n          if (outC < start || outC >= end) {\n            setOutput(value);\n          } else {\n            setOutput(getX(outC - start));\n          }\n        }\n      `;\n      return;\n    }\n    this.userCode = `\n      ${g} start = ${g}(${b});\n      ${g} end = ${g}(${c});\n\n      void main() {\n        ${g} outC = getOutputCoords();\n        if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) {\n          setOutput(value);\n        } else {\n          ${g} coords = outC - start;\n          setOutput(getX(${d}));\n        }\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass kM {\n  constructor(l, G, Z) {\n    this.variableNames = [\"x\"], this.packedInputs = !0, this.packedOutput = !0, this.customUniforms = [{ name: \"value\", type: \"float\" }], this.outputShape = G.map(\n      (T, s) => T[0] + l[s] + T[1]\n      /* afterPad */\n    );\n    const h = l.length, g = Ul(h), b = G.map((T) => T[0]).join(\",\"), c = G.map((T, s) => T[0] + l[s]).join(\",\"), d = xG(\"rc\", h), W = xG(\"source\", h), Y = `${d[h - 1]} < ${this.outputShape[h - 1]}`, V = h === 1 ? \"source\" : `vec2(${W.slice(-2).join()})`, a = [\n      `${g} rc = outputLoc;`,\n      `${d[h - 1]} += 1;\n       if(${Y}) {\n      `,\n      h === 1 ? \"\" : `}\n       rc = outputLoc;\n       ${d[h - 2]} += 1;\n       if(${d[h - 2]} < ${this.outputShape[h - 2]}) {`,\n      h === 1 ? \"\" : `  ${d[h - 1]} += 1;\n         if(${Y}) {`\n    ], i = h === 1 ? \"rc < start || rc >= end\" : \"any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))\";\n    let m = \"\";\n    for (let T = 0, s = h === 1 ? 2 : 4; T < s; T++)\n      m += `\n        ${a[T]}\n        if (${i}) {\n          result[${T}] = float(value);\n        } else {\n          ${g} source = rc - start;\n          result[${T}] = getChannel(getX(${W.join()}), ${V});\n        }\n      `;\n    m += h === 1 ? \"} \" : \"}}\", this.userCode = `\n      const ${g} start = ${g}(${b});\n      const ${g} end = ${g}(${c});\n\n      void main() {\n        ${g} outputLoc = getOutputCoords();\n        vec4 result = vec4(0.);\n        ${m}\n        setOutput(result);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst gn = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { paddings: g, constantValue: b } = Z;\n  if (Q(h.shape) === 0) {\n    const W = g.map(\n      (Y, V) => Y[0] + h.shape[V] + Y[1]\n      /* afterPad */\n    );\n    return Yb({\n      backend: G,\n      attrs: { shape: W, value: b, dtype: h.dtype }\n    });\n  }\n  const c = A().getBool(\"WEBGL_PACK_ARRAY_OPERATIONS\") ? new kM(h.shape, g, b) : new AM(h.shape, g, b), d = [[b]];\n  return G.runWebGLProgram(c, [h], h.dtype, d);\n}, zM = {\n  kernelName: Qc,\n  backendName: \"webgl\",\n  kernelFunc: gn\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst LM = `\n  if(a < 0.0 && floor(b) < b){\n    return NAN;\n  }\n  if (b == 0.0) {\n    return 1.0;\n  }\n  return (round(mod(b, 2.0)) != 1) ?\n      pow(abs(a), b) : sign(a) * pow(abs(a), b);\n`, MM = `\n  // isModRound1 has 1 for components with round(mod(b, 2.0)) == 1, 0 otherwise.\n  vec4 isModRound1 = vec4(equal(round(mod(b, 2.0)), ivec4(1)));\n  vec4 multiplier = sign(a) * isModRound1 + (vec4(1.0) - isModRound1);\n  vec4 result = multiplier * pow(abs(a), b);\n\n  // Ensure that a^0 = 1, including 0^0 = 1 as this correspond to TF and JS\n  bvec4 isExpZero = equal(b, vec4(0.0));\n  result.r = isExpZero.r ? 1.0 : result.r;\n  result.g = isExpZero.g ? 1.0 : result.g;\n  result.b = isExpZero.b ? 1.0 : result.b;\n  result.a = isExpZero.a ? 1.0 : result.a;\n\n  bvec4 isNaN1 = lessThan(a, vec4(0.0));\n  bvec4 isNaN2 = lessThan(floor(b), b);\n  bvec4 isNaN = bvec4(isNaN1.x && isNaN2.x, isNaN1.y && isNaN2.y, isNaN1.z && isNaN2.z, isNaN1.w && isNaN2.w);\n  ` + Fh + `\n  return result;\n`, wM = tG({ opSnippet: LM, packedOpSnippet: MM }), QM = {\n  kernelName: tg,\n  backendName: \"webgl\",\n  kernelFunc: wM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vM(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { axis: g, keepDims: b } = Z, c = h.shape.length, d = [], W = tl(g, h.shape);\n  let Y = W;\n  const V = Ol(Y, c);\n  let a = h;\n  V != null && (a = HG({ inputs: { x: h }, backend: G, attrs: { perm: V } }), Y = GG(Y.length, c), d.push(a)), XG(\"prod\", Y, c);\n  let i;\n  if (G.shouldExecuteOnCPU([a])) {\n    const m = G.texData.get(a.dataId).values, { outVals: T, outShape: s, outDtype: o } = wK(a.shape, a.dtype, m, Y);\n    i = G.makeTensorInfo(s, o, T);\n  } else {\n    const [m, T] = sG(a.shape, Y), s = Q(T), o = ll({ inputs: { x: a }, backend: G, attrs: { shape: [-1, s] } }), B = AY(h.dtype), C = yh(o, B, \"prod\", G);\n    i = ll({ inputs: { x: C }, backend: G, attrs: { shape: m } }), d.push(o), d.push(C);\n  }\n  if (b) {\n    d.push(i);\n    const m = bG(i.shape, W);\n    i = ll({ inputs: { x: i }, backend: G, attrs: { shape: m } });\n  }\n  return d.forEach((m) => G.disposeIntermediateTensorInfo(m)), i;\n}\nconst rM = {\n  kernelName: rc,\n  backendName: \"webgl\",\n  kernelFunc: vM\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction jM(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { paramsNestedSplits: h, paramsDenseValues: g, indices: b } = l, { outputRaggedRank: c } = Z, d = h.map((o) => G.readSync(o.dataId)), W = h.map((o) => o.shape), Y = G.readSync(g.dataId), V = G.readSync(b.dataId), [a, i, m] = QK(d, W, Y, g.shape, g.dtype, V, b.shape, c), T = a.map((o) => G.makeTensorInfo([o.length], \"int32\", o)), s = G.makeTensorInfo(m, g.dtype, i);\n  return T.concat([s]);\n}\nconst DM = {\n  kernelName: Ui,\n  backendName: \"webgl\",\n  kernelFunc: jM\n};\n/**\n * @license\n * Copyright 2022 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction fM(I) {\n  const { inputs: l, backend: G } = I, { starts: Z, limits: h, deltas: g } = l, b = G.readSync(Z.dataId), c = G.readSync(h.dataId), d = G.readSync(g.dataId), [W, Y] = vK(b, Z.shape, Z.dtype, c, h.shape, d, g.shape), V = G.makeTensorInfo([W.length], \"int32\", W), a = G.makeTensorInfo([Y.length], Z.dtype, Y);\n  return [V, a];\n}\nconst OM = {\n  kernelName: Hi,\n  backendName: \"webgl\",\n  kernelFunc: fM\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction qM(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { shape: h, values: g, defaultValue: b, rowPartitionTensors: c } = l, { rowPartitionTypes: d } = Z, W = G.readSync(h.dataId), Y = G.readSync(g.dataId), V = G.readSync(b.dataId), a = c.map((s) => G.readSync(s.dataId)), i = c.map((s) => s.shape), [m, T] = rK(W, h.shape, Y, g.shape, g.dtype, V, b.shape, a, i, d);\n  return G.makeTensorInfo(m, g.dtype, T);\n}\nconst $M = {\n  kernelName: Ki,\n  backendName: \"webgl\",\n  kernelFunc: qM\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bn = (I) => {\n  const { backend: l, attrs: G } = I, { start: Z, stop: h, step: g, dtype: b } = G, c = jK(Z, h, g, b);\n  return l.makeTensorInfo([c.length], b, c);\n}, _M = {\n  kernelName: RY,\n  backendName: \"webgl\",\n  kernelFunc: bn\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst lw = \"return 1.0 / x;\", Gw = Rl({ opSnippet: lw }), Iw = {\n  kernelName: ug,\n  backendName: \"webgl\",\n  kernelFunc: Gw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Zw = BI + `\n  return (x < 0.0) ? 0.0 : x;\n`, hw = `\n  vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`, gw = Rl({ opSnippet: Zw, packedOpSnippet: hw }), bw = {\n  kernelName: eg,\n  backendName: \"webgl\",\n  kernelFunc: gw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst cw = BI + `\n  return (x < 0.0) ? 0.0 : min(6.0, x);\n`, dw = `\n  vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`, Ww = Rl({ opSnippet: cw, packedOpSnippet: dw }), Yw = {\n  kernelName: Sg,\n  backendName: \"webgl\",\n  kernelFunc: Ww\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Vw {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"A\"], this.outputShape = [];\n    const [b, c, d, W] = l;\n    this.outputShape = [b, G, Z, W];\n    const Y = [\n      h && G > 1 ? c - 1 : c,\n      h && Z > 1 ? d - 1 : d\n    ], V = [\n      h && G > 1 ? G - 1 : G,\n      h && Z > 1 ? Z - 1 : Z\n    ];\n    let a;\n    g ? a = \"(vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC - vec2(0.5)\" : a = \"vec2(yRC) * effectiveInputOverOutputRatioRC\", this.userCode = `\n      const vec2 effectiveInputOverOutputRatioRC = vec2(\n          ${Y[0] / V[0]},\n          ${Y[1] / V[1]});\n      const vec2 inputShapeRC = vec2(${c}.0, ${d}.0);\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        ivec2 yRC = coords.yz;\n\n        // Fractional source index.\n        vec2 sourceFracIndexRC = ${a};\n\n        // Compute the four integer indices.\n        ivec2 sourceFloorRC = ivec2(max(sourceFracIndexRC, vec2(0.0)));\n        ivec2 sourceCeilRC = ivec2(\n          min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n        float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d);\n        float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d);\n        float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d);\n        float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d);\n\n        vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);\n\n        float top = topLeft + (topRight - topLeft) * fracRC.y;\n        float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;\n        float newValue = top + (bottom - top) * fracRC.x;\n\n        setOutput(newValue);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass aw {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = [];\n    const [b, c, d, W] = l;\n    this.outputShape = [b, G, Z, W];\n    const Y = [\n      h && G > 1 ? c - 1 : c,\n      h && Z > 1 ? d - 1 : d\n    ], V = [\n      h && G > 1 ? G - 1 : G,\n      h && Z > 1 ? Z - 1 : Z\n    ];\n    let a;\n    g ? a = \"(vec3(yRC) + vec3(0.5)) * effectiveInputOverOutputRatioRC - vec3(0.5)\" : a = \"vec3(yRC) * effectiveInputOverOutputRatioRC\", this.userCode = `\n      const vec3 effectiveInputOverOutputRatioRC = vec3(\n          ${Y[0] / V[0]},\n          ${Y[1] / V[1]},\n          ${Y[1] / V[1]});\n      const vec3 inputShapeRC = vec3(${c}.0, ${d}.0,\n                                     ${d}.0);\n\n      float getAValue(int b, int r, int c, int d) {\n        return getChannel(getA(b, r, c, d), vec2(c, d));\n      }\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        // Calculate values for next column in yRC.z.\n        ivec3 yRC = coords.yzz + ivec3(0, 0, 1);\n\n        // Fractional source index.\n        vec3 sourceFracIndexRC = ${a};\n\n        // Compute the four integer indices.\n        ivec3 sourceFloorRC = ivec3(max(sourceFracIndexRC, vec3(0.0)));\n        ivec3 sourceCeilRC = ivec3(\n          min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n        // Should we calculate next column and row elements in 2x2 packed cell.\n        bool hasNextCol = d < ${W - 1};\n        bool hasNextRow = coords.z < ${Z - 1};\n\n        // In parallel, construct four corners for all four components in\n        // packed 2x2 cell.\n        vec4 topLeft = vec4(\n          getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d),\n          hasNextCol ? getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n        vec4 bottomLeft = vec4(\n          getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d),\n          hasNextCol ? getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n        vec4 topRight = vec4(\n          getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d),\n          hasNextCol ? getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n        vec4 bottomRight = vec4(\n          getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d),\n          hasNextCol ? getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n        vec3 fracRC = sourceFracIndexRC - vec3(sourceFloorRC);\n\n        vec4 top = mix(topLeft, topRight, fracRC.yyzz);\n        vec4 bottom = mix(bottomLeft, bottomRight, fracRC.yyzz);\n        vec4 newValue = mix(top, bottom, fracRC.x);\n\n        setOutput(newValue);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction iw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h } = l, { alignCorners: g, halfPixelCenters: b, size: c } = Z, [d, W] = c, Y = A().getBool(\"WEBGL_PACK_IMAGE_OPERATIONS\") ? new aw(h.shape, d, W, g, b) : new Vw(h.shape, d, W, g, b);\n  return G.runWebGLProgram(Y, [h], \"float32\");\n}\nconst mw = {\n  kernelName: fc,\n  backendName: \"webgl\",\n  kernelFunc: iw\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Tw {\n  constructor(l, G, Z) {\n    this.variableNames = [\"dy\"], this.outputShape = [], this.outputShape = G;\n    const [, h, g] = G, [, b, c] = l, d = [\n      Z && b > 1 ? h - 1 : h,\n      Z && c > 1 ? g - 1 : g\n    ], W = [\n      Z && b > 1 ? b - 1 : b,\n      Z && c > 1 ? c - 1 : c\n    ], Y = d[0] / W[0], V = d[1] / W[1], a = 1 / Y, i = 1 / V, m = Math.ceil(a) * 2 + 2, T = Math.ceil(i) * 2 + 2;\n    this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        int r = coords[1];\n        int c = coords[2];\n\n        float accumulator = 0.0;\n\n        const float heightScale = float(${Y});\n        const float widthScale = float(${V});\n\n        const float invHeightScale = float(${a});\n        const float invWidthScale = float(${i});\n\n        const int winHeight = int(${m});\n        const int winWidth = int(${T});\n\n        // Compute bounds for where in dy we will look\n        float startRLerp = floor(float(r) * invHeightScale);\n        int startDyR = int(startRLerp - float(winHeight / 2));\n\n        float startCLerp = floor(float(c) * invWidthScale);\n        int startDyC = int(startCLerp - float(winWidth / 2));\n\n        // Loop over dy\n        for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n          int dyR = dyROffset + startDyR;\n\n          // Guard against the window exceeding the bounds of dy\n          if (dyR < 0 || dyR >= ${b}) {\n            continue;\n          }\n\n          for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n            int dyC = dyCOffset + startDyC;\n\n            // Guard against the window exceeding the bounds of dy\n            if (dyC < 0 || dyC >= ${c}) {\n              continue;\n            }\n\n            float dxR = float(dyR) * heightScale;\n            int topDxRIndex = int(floor(dxR));\n            int bottomDxRIndex = int(min(ceil(dxR), ${h - 1}.0));\n            float dxRLerp = dxR - float(topDxRIndex);\n            float inverseDxRLerp = 1.0 - dxRLerp;\n\n            float dxC = float(dyC) * widthScale;\n            int leftDxCIndex = int(floor(dxC));\n            int rightDxCIndex = int(min(ceil(dxC), ${g - 1}.0));\n            float dxCLerp = dxC - float(leftDxCIndex);\n            float inverseDxCLerp = 1.0 - dxCLerp;\n\n            if (r == topDxRIndex && c == leftDxCIndex) {\n              // topLeft\n              accumulator +=\n                getDy(b, dyR, dyC, d) * inverseDxRLerp * inverseDxCLerp;\n            }\n\n            if (r == topDxRIndex && c == rightDxCIndex) {\n              // topRight\n              accumulator += getDy(b, dyR, dyC, d) * inverseDxRLerp * dxCLerp;\n            }\n\n            if (r == bottomDxRIndex && c == leftDxCIndex) {\n              // bottomLeft\n              accumulator += getDy(b, dyR, dyC, d) * dxRLerp * inverseDxCLerp;\n            }\n\n            if (r == bottomDxRIndex && c == rightDxCIndex) {\n              // bottomRight\n              accumulator += getDy(b, dyR, dyC, d) * dxRLerp * dxCLerp;\n            }\n          }\n        }\n        // End loop over dy\n\n        setOutput(accumulator);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h, dy: g } = l, { alignCorners: b } = Z, c = new Tw(g.shape, h.shape, b);\n  return G.runWebGLProgram(c, [g], g.dtype);\n}\nconst ow = {\n  kernelName: yY,\n  backendName: \"webgl\",\n  kernelFunc: sw\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Bw {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"A\"], this.outputShape = [];\n    const [b, c, d, W] = l;\n    this.outputShape = [b, G, Z, W];\n    const Y = [\n      h && G > 1 ? c - 1 : c,\n      h && Z > 1 ? d - 1 : d\n    ], V = [\n      h && G > 1 ? G - 1 : G,\n      h && Z > 1 ? Z - 1 : Z\n    ], a = h ? \"0.5\" : \"0.0\";\n    let i;\n    g ? i = \"max((vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC, vec2(0.0))\" : i = \"vec2(yRC) * effectiveInputOverOutputRatioRC\", this.userCode = `\n      const vec2 effectiveInputOverOutputRatioRC = vec2(\n          ${Y[0] / V[0]},\n          ${Y[1] / V[1]});\n      const vec2 inputShapeRC = vec2(${c}.0, ${d}.0);\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        ivec2 yRC = coords.yz;\n\n        // Fractional source index.\n        vec2 sourceFracIndexRC = ${i};\n\n        // Compute the coordinators of nearest neighbor point.\n        ivec2 sourceNearestRC = ivec2(\n          min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${a})));\n        float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d);\n\n        setOutput(newValue);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass nw {\n  constructor(l, G, Z, h, g) {\n    this.variableNames = [\"A\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = [];\n    const [b, c, d, W] = l;\n    this.outputShape = [b, G, Z, W];\n    const Y = [\n      h && G > 1 ? c - 1 : c,\n      h && Z > 1 ? d - 1 : d\n    ], V = [\n      h && G > 1 ? G - 1 : G,\n      h && Z > 1 ? Z - 1 : Z\n    ], a = h ? \"0.5\" : \"0.0\";\n    let i;\n    g ? i = \"max((vec3(yRC) + vec3(0.5)) * effectiveInputOverOutputRatioRC, vec3(0.0))\" : i = \"vec3(yRC) * effectiveInputOverOutputRatioRC\", this.userCode = `\n      const vec3 effectiveInputOverOutputRatioRC = vec3(\n          ${Y[0] / V[0]},\n          ${Y[1] / V[1]},\n          ${Y[1] / V[1]});\n      const vec3 inputShapeRC = vec3(${c}.0, ${d}.0,\n                                     ${d}.0);\n\n      float getAValue(int b, int r, int c, int d) {\n        return getChannel(getA(b, r, c, d), vec2(c, d));\n      }\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        // Calculate values for next column in yRC.z.\n        ivec3 yRC = coords.yzz + ivec3(0, 0, 1);\n\n        // Fractional source index.\n        vec3 sourceFracIndexRC = ${i};\n\n        // Compute the coordinators of nearest neighbor point.\n        ivec3 sourceNearestRC = ivec3(\n          min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${a})));\n\n        // Should we calculate next column and row elements in 2x2 packed cell.\n        bool hasNextCol = d < ${W - 1};\n        bool hasNextRow = coords.z < ${Z - 1};\n\n        vec4 newValue = vec4(\n          getAValue(b, sourceNearestRC.x, sourceNearestRC.y, d),\n          hasNextCol ? getAValue(b, sourceNearestRC.x, sourceNearestRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceNearestRC.x, sourceNearestRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceNearestRC.x, sourceNearestRC.z, d + 1) : 0.0);\n\n        setOutput(newValue);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Cw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h } = l, { alignCorners: g, halfPixelCenters: b, size: c } = Z, [d, W] = c, Y = A().getBool(\"WEBGL_PACK_IMAGE_OPERATIONS\") ? new nw(h.shape, d, W, g, b) : new Bw(h.shape, d, W, g, b);\n  return G.runWebGLProgram(Y, [h], h.dtype);\n}\nconst Xw = {\n  kernelName: Dc,\n  backendName: \"webgl\",\n  kernelFunc: Cw\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass tw {\n  constructor(l, G, Z) {\n    this.variableNames = [\"dy\"], this.outputShape = [], this.outputShape = G;\n    const [, h, g] = G, [, b, c] = l, d = [\n      Z && b > 1 ? h - 1 : h,\n      Z && c > 1 ? g - 1 : g\n    ], W = [\n      Z && b > 1 ? b - 1 : b,\n      Z && c > 1 ? c - 1 : c\n    ], Y = d[0] / W[0], V = d[1] / W[1], a = 1 / Y, i = 1 / V, m = Math.ceil(a) * 2 + 2, T = Math.ceil(i) * 2 + 2;\n    this.userCode = `\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        int r = coords[1];\n        int c = coords[2];\n\n        float accumulator = 0.0;\n\n        const float heightScale = float(${Y});\n        const float widthScale = float(${V});\n\n        const float invHeightScale = float(${a});\n        const float invWidthScale = float(${i});\n\n        const int winHeight = int(${m});\n        const int winWidth = int(${T});\n\n        // Compute bounds for where in dy we will look\n        float startRLerp = floor(float(r) * invHeightScale);\n        int startDyR = int(floor(startRLerp - float(winHeight / 2)));\n\n        float startCLerp = floor(float(c) * invWidthScale);\n        int startDyC = int(floor(startCLerp - float(winWidth / 2)));\n\n        // Loop over dy\n        for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n          int dyR = dyROffset + startDyR;\n\n          // Guard against the window exceeding the bounds of dy\n          if (dyR < 0 || dyR >= ${b}) {\n            continue;\n          }\n\n          for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n            int dyC = dyCOffset + startDyC;\n\n            // Guard against the window exceeding the bounds of dy\n            if (dyC < 0 || dyC >= ${c}) {\n              continue;\n            }\n\n            float sourceFracRow =\n              float(${d[0]}) *\n                (float(dyR) / float(${W[0]}));\n\n            float sourceFracCol =\n                float(${d[1]}) *\n                  (float(dyC) / float(${W[1]}));\n\n            int sourceNearestRow = int(min(\n                float(int(${h}) - 1),\n                ${Z} ? float(round(sourceFracRow)) :\n                                  float(floor(sourceFracRow))));\n\n            int sourceNearestCol = int(min(\n                float(int(${g}) - 1),\n                ${Z} ? float(round(sourceFracCol)) :\n                                  float(floor(sourceFracCol))));\n\n            if (r == sourceNearestRow && c == sourceNearestCol) {\n              accumulator += getDy(b, dyR, dyC, d);\n            }\n          }\n        }\n        // End loop over dy\n\n        setOutput(accumulator);\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction uw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { images: h, dy: g } = l, { alignCorners: b } = Z, c = new tw(g.shape, h.shape, b);\n  return G.runWebGLProgram(c, [g], g.dtype);\n}\nconst ew = {\n  kernelName: FY,\n  backendName: \"webgl\",\n  kernelFunc: uw\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Sw {\n  constructor(l, G) {\n    this.variableNames = [\"x\"];\n    const Z = l.length;\n    if (Z > 4)\n      throw new Error(`WebGL backend: Reverse of rank-${Z} tensor is not yet supported`);\n    if (this.outputShape = l, Z === 1) {\n      this.userCode = `\n        void main() {\n          int coord = getOutputCoords();\n          setOutput(getX(${l[0]} - coord - 1));\n        }\n      `;\n      return;\n    }\n    const h = (c) => G.indexOf(c) !== -1 && l[c] !== 1 ? `${l[c]} - coords[${c}] - 1` : `coords[${c}]`, g = l.map((c, d) => h(d)).join(\",\"), b = Ul(Z);\n    this.userCode = `\n      void main() {\n        ${b} coords = getOutputCoords();\n        setOutput(getX(${g}));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Rw {\n  constructor(l, G) {\n    this.variableNames = [\"x\"], this.packedInputs = !0, this.packedOutput = !0;\n    const Z = l.length;\n    if (Z > 4)\n      throw new Error(`WebGL backend: Reverse of rank-${Z} tensor is not yet supported`);\n    this.outputShape = l;\n    const h = xG(\"rc\", Z), g = `${h[Z - 1]} + 1 < ${this.outputShape[Z - 1]}`, b = `${h[Z - 2]} + 1 < ${this.outputShape[Z - 2]}`, c = Ul(Z);\n    Z === 1 ? this.userCode = `\n        void main(){\n          int rc = getOutputCoords();\n          vec4 result = vec4(0.);\n          result.r = getChannel(getX(${l[0]} - rc - 1),\n            ${l[0]} - rc - 1);\n          if(${g}){\n              result.g = getChannel(getX(${l[0]} - (rc  + 1) - 1),\n                ${l[0]} - (rc  + 1) - 1);\n          }\n          setOutput(result);\n        }\n      ` : this.userCode = `\n        void main() {\n          ${c} rc = getOutputCoords();\n          vec4 result = vec4(0.);\n          result.r = ${d(h.slice())};\n          if(${g}){\n            result.g = ${W(h.slice())};\n          }\n          if(${b}) {\n            result.b = ${Y(h.slice())};\n            if(${g}) {\n              result.a = ${V(h.slice())};\n            }\n          }\n          setOutput(result);\n        }\n    `;\n    function d(m) {\n      return a(m);\n    }\n    function W(m) {\n      return m[Z - 1] = \"(\" + m[Z - 1] + \" + 1)\", a(m);\n    }\n    function Y(m) {\n      return m[Z - 2] = \"(\" + m[Z - 2] + \" + 1)\", a(m);\n    }\n    function V(m) {\n      return m[Z - 1] = \"(\" + m[Z - 1] + \" + 1)\", m[Z - 2] = \"(\" + m[Z - 2] + \" + 1)\", a(m);\n    }\n    function a(m) {\n      const T = l.map((B, C) => i(C, m)), s = T.join(\",\"), o = T.slice(-2).join(\",\");\n      return `getChannel(getX(${s}), vec2(${o}))`;\n    }\n    function i(m, T) {\n      return G.indexOf(m) !== -1 && l[m] !== 1 ? `${l[m]} - ${T[m]} - 1` : `${T[m]}`;\n    }\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction pw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { dims: g } = Z, b = h.shape.length, c = tl(g, h.shape);\n  if (b === 0)\n    return OG({ inputs: { x: h }, backend: G });\n  const d = A().getBool(\"WEBGL_PACK_ARRAY_OPERATIONS\") ? new Rw(h.shape, c) : new Sw(h.shape, c);\n  return G.runWebGLProgram(d, [h], h.dtype);\n}\nconst Fw = {\n  kernelName: Oc,\n  backendName: \"webgl\",\n  kernelFunc: pw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass yw {\n  constructor(l, G) {\n    this.variableNames = [\"Image\"], this.outputShape = [], this.customUniforms = [{ name: \"params\", type: \"vec4\" }];\n    const Z = l[1], h = l[2];\n    this.outputShape = l;\n    let g = \"\";\n    typeof G == \"number\" ? g = `float outputValue = ${G.toFixed(2)};` : g = `\n        vec3 fill = vec3(${G.join(\",\")});\n        float outputValue = fill[coords[3]];`, this.userCode = `\n        void main() {\n          ivec4 coords = getOutputCoords();\n          int x = coords[2];\n          int y = coords[1];\n          float coordXFloat = (float(x) - params[0]) * params[3] -\n            (float(y) - params[1]) * params[2];\n          float coordYFloat = (float(x) - params[0]) * params[2] +\n            (float(y) - params[1]) * params[3];\n          int coordX = int(round(coordXFloat + params[0]));\n          int coordY = int(round(coordYFloat + params[1]));\n          ${g}\n          if(coordX >= 0 && coordX < ${h} && coordY >= 0 && coordY < ${Z}) {\n            outputValue = getImage(coords[0], coordY, coordX, coords[3]);\n          }\n          setOutput(outputValue);\n        }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Nw = {\n  kernelName: HY,\n  backendName: \"webgl\",\n  kernelFunc: ({ inputs: I, attrs: l, backend: G }) => {\n    const { image: Z } = I, { radians: h, fillValue: g, center: b } = l, c = G, d = new yw(Z.shape, g), [W, Y] = PV(b, Z.shape[1], Z.shape[2]), V = [[W, Y, Math.sin(h), Math.cos(h)]];\n    return c.runWebGLProgram(d, [Z], Z.dtype, V);\n  }\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Pw = `\n  // OpenGL ES does not support round function.\n  // The algorithm is based on banker's rounding.\n  float base = floor(x);\n  if ((x - base) < 0.5) {\n    return floor(x);\n  } else if ((x - base) > 0.5) {\n    return ceil(x);\n  } else {\n    if (mod(base, 2.0) == 0.0) {\n      return base;\n    } else {\n      return base + 1.0;\n    }\n  }\n`, Jw = Rl({ opSnippet: Pw }), Ew = {\n  kernelName: Rg,\n  backendName: \"webgl\",\n  kernelFunc: Jw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst xw = \"return inversesqrt(x);\", Uw = Rl({ opSnippet: xw, cpuKernelImpl: DK }), Hw = {\n  kernelName: pg,\n  backendName: \"webgl\",\n  kernelFunc: Uw\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass E9 {\n  constructor(l, G, Z, h, g, b, c = !0, d = !1) {\n    this.variableNames = [\"updates\", \"indices\", \"defaultValue\"], this.outputShape = b;\n    const W = Ul(g.length), Y = Ul(b.length);\n    let V = \"\";\n    Z === 1 ? V = \"i\" : Z === 2 && (V = \"i, j\");\n    const a = `getIndices(${V})`;\n    let i = \"\";\n    h === 1 ? i = \"i\" : h === 2 && (i = \"i, coords[1]\");\n    const m = `getUpdates(${i})`;\n    let T = \"\";\n    d && (T = \"coords[0], coords[1]\");\n    const s = `getDefaultValue(${T})`, o = G > 1 ? \"strides[j]\" : \"strides\";\n    this.userCode = `\n        ${W} strides = ${W}(${g});\n\n        void main() {\n          ${Y} coords = getOutputCoords();\n          float sum = 0.0;\n          bool found = false;\n          for (int i = 0; i < ${l}; i++) {\n            int flattenedIndex = 0;\n            for (int j = 0; j < ${G}; j++) {\n              int index = round(${a});\n              flattenedIndex += index * ${o};\n            }\n            if (flattenedIndex == coords[0]) {\n              sum += ${m};\n              found = true;\n            }\n          }\n          setOutput(mix(${s}, sum, float(found)));\n        }\n      `;\n  }\n}\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass Kw {\n  constructor(l, G, Z, h, g, b, c = !0, d = !1) {\n    this.variableNames = [\"updates\", \"indices\", \"defaultValue\"], this.packedInputs = !0, this.packedOutput = !0, this.outputShape = b;\n    const W = Ul(g.length), Y = Ul(b.length);\n    let V = \"\";\n    Z === 1 ? V = \"i\" : Z === 2 && (V = \"i, j\");\n    const a = `getIndices(${V})`;\n    let i = \"\";\n    h === 1 ? i = \"i\" : h === 2 && (i = \"i, coords[1]\");\n    const m = `getUpdates(${i})`;\n    let T = \"\";\n    d && (T = \"coords[0], coords[1]\");\n    const s = `getDefaultValue(${T})`, o = G > 1 ? \"strides[j]\" : \"strides\", B = G > 1 ? \"strides[j + 1]\" : \"strides\";\n    this.userCode = `\n        ${W} strides = ${W}(${g});\n\n        void main() {\n          ${Y} coords = getOutputCoords();\n          vec4 sum = vec4(0.);\n          vec4 found = vec4(0.);\n          for (int i = 0; i < ${l}; i+=2) {\n            ivec2 flattenedIndex = ivec2(0);\n            for (int j = 0; j < ${G}; j+=2) {\n              ivec4 index = round(${a});\n              flattenedIndex += index.xz * ${o};\n              if (j + 1 < ${G}) {\n                flattenedIndex += index.yw * ${B};\n              }\n            }\n            if (flattenedIndex[0] == coords[0] || flattenedIndex[1] == coords[0] ||\n                flattenedIndex[0] == coords[0] + 1 || flattenedIndex[1] == coords[0] + 1) {\n              vec4 updVals = ${m};\n              if (flattenedIndex[0] == coords[0]) {\n                sum.xy += updVals.xy;\n                found.xy = vec2(1.);\n              } else if (flattenedIndex[0] == coords[0] + 1) {\n                sum.zw += updVals.xy;\n                found.zw = vec2(1.);\n              }\n              if (flattenedIndex[1] == coords[0]) {\n                sum.xy += updVals.zw;\n                found.xy = vec2(1.);\n              } else if (flattenedIndex[1] == coords[0] + 1) {\n                sum.zw += updVals.zw;\n                found.zw = vec2(1.);\n              }\n            }\n          }\n          setOutput(mix(${s}, sum, found));\n        }\n      `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Aw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { indices: h, updates: g } = l, { shape: b } = Z, { sliceRank: c, numUpdates: d, sliceSize: W, strides: Y, outputSize: V } = uh(g, h, b), a = [V / W, W];\n  if (V === 0)\n    return G.makeTensorInfo(b, h.dtype);\n  const i = ll({ inputs: { x: h }, backend: G, attrs: { shape: [d, c] } }), m = ll({ inputs: { x: g }, backend: G, attrs: { shape: [d, W] } }), T = G.makeTensorInfo([], \"float32\", new Float32Array([0]));\n  let s;\n  A().getBool(\"WEBGL_PACK\") ? s = new Kw(d, c, i.shape.length, m.shape.length, Y, a) : s = new E9(d, c, i.shape.length, m.shape.length, Y, a);\n  const o = G.runWebGLProgram(s, [m, i, T], m.dtype), B = ll({ inputs: { x: o }, backend: G, attrs: { shape: b } });\n  return G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(m), G.disposeIntermediateTensorInfo(o), G.disposeIntermediateTensorInfo(T), B;\n}\nconst kw = {\n  kernelName: Ai,\n  backendName: \"webgl\",\n  kernelFunc: Aw\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass zw {\n  constructor(l, G, Z, h) {\n    this.variableNames = [\"sortedSequence\", \"values\"], this.customUniforms = [{ name: \"numInputs\", type: \"int\" }], this.outputShape = [l, Z];\n    const g = \"while (left < right) {\", b = `for (int i = 0; i < ${Math.ceil(Math.log2(G + 1))}; ++i) { if (left >= right) break;`, c = A().getNumber(\"WEBGL_VERSION\") === 2 ? g : b, d = h === \"left\" ? \"<\" : \"<=\";\n    this.userCode = `\n       int findBound(int batch, float value) {\n         int left = 0;\n         int right = numInputs;\n         int mid;\n         ${c}\n           mid = (left + right) / 2;\n           if (getSortedSequence(batch, mid) ${d} value) {\n             left = mid + 1;\n           } else {\n             right = mid;\n           }\n         }\n         return right;\n       }\n\n       void main() {\n         ivec2 coords = getOutputCoords();\n         int batch = coords[0];\n         int valueIndex = coords[1];\n\n         float value = getValues(batch, valueIndex);\n\n         setOutput(float(findBound(batch, value)));\n       }\n     `;\n  }\n}\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Lw(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { sortedSequence: h, values: g } = l, { side: b } = Z, c = new zw(h.shape[0], h.shape[1], g.shape[1], b), d = [[h.shape[1]]];\n  return G.runWebGLProgram(c, [h, g], \"int32\", d);\n}\nconst Mw = {\n  kernelName: zi,\n  backendName: \"webgl\",\n  kernelFunc: Lw\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass ww {\n  constructor(l, G, Z) {\n    this.variableNames = [\"c\", \"a\", \"b\"], this.outputShape = G;\n    let h, g;\n    if (Z > 4)\n      throw Error(`Where for rank ${Z} is not yet supported`);\n    if (Z === 1)\n      g = \"resRC\", h = \"resRC\";\n    else {\n      const c = [\"resRC.x\", \"resRC.y\", \"resRC.z\", \"resRC.w\"], d = [], W = [];\n      for (let Y = 0; Y < G.length; Y++)\n        W.push(`${c[Y]}`), Y < l && d.push(`${c[Y]}`);\n      h = d.join(), g = W.join();\n    }\n    const b = Ul(Z);\n    this.userCode = `\n      void main() {\n        ${b} resRC = getOutputCoords();\n        float cVal = getC(${h});\n        if (cVal >= 1.0) {\n          setOutput(getA(${g}));\n        } else {\n          setOutput(getB(${g}));\n        }\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Qw(I) {\n  const { inputs: l, backend: G } = I, { condition: Z, t: h, e: g } = l, b = new ww(Z.shape.length, h.shape, h.shape.length);\n  return G.runWebGLProgram(b, [Z, h, g], DG(h.dtype, g.dtype));\n}\nconst vw = {\n  kernelName: qc,\n  backendName: \"webgl\",\n  kernelFunc: Qw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst rw = `\n  // Stable and Attracting Fixed Point (0, 1) for Normalized Weights.\n  // see: https://arxiv.org/abs/1706.02515\n  float scaleAlpha = ${Td};\n  float scale = ${sd};\n  return (x >= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);\n`, jw = Rl({ opSnippet: rw }), Dw = {\n  kernelName: Fg,\n  backendName: \"webgl\",\n  kernelFunc: jw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fw = T0 + `\n  return 1.0 / (1.0 + exp(-1.0 * x));\n`, Ow = `\n  vec4 result = 1.0 / (1.0 + exp(-1.0 * x));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n`, qw = Rl({\n  opSnippet: fw,\n  packedOpSnippet: Ow,\n  cpuKernelImpl: OK\n}), $w = {\n  kernelName: Jg,\n  backendName: \"webgl\",\n  kernelFunc: qw\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst _w = `\n  if (isnan(x)) { return 0.0; }\n  return sign(x);\n`, lQ = Rl({ opSnippet: _w }), GQ = {\n  kernelName: Pg,\n  backendName: \"webgl\",\n  kernelFunc: lQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst IQ = T0 + `\n  return sin(x);\n`, ZQ = `\n  vec4 result = sin(x);\n  bvec4 isNaN = isnan(x);\n  ${Fh}\n  return result;\n`, hQ = Rl({ opSnippet: IQ, packedOpSnippet: ZQ }), gQ = {\n  kernelName: yg,\n  backendName: \"webgl\",\n  kernelFunc: hQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst bQ = `\n  float e2x = exp(x);\n  return (e2x - 1.0 / e2x) / 2.0;\n`, cQ = Rl({ opSnippet: bQ }), dQ = {\n  kernelName: Ng,\n  backendName: \"webgl\",\n  kernelFunc: cQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst WQ = `\n  float epsilon = 1.1920928955078125e-7;\n  float threshold = log(epsilon) + 2.0;\n\n  bool too_large = x > -threshold;\n  bool too_small = x < threshold;\n\n  float result;\n  float exp_x = exp(x);\n\n  if (too_large){\n    result = x;\n  }\n  else if (too_small){\n    result = exp_x;\n  }\n  else{\n    result = log(exp_x + 1.0);\n  }\n  return result;\n`, YQ = Rl({ opSnippet: WQ }), VQ = {\n  kernelName: Eg,\n  backendName: \"webgl\",\n  kernelFunc: YQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst aQ = (I) => {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { blockShape: g, paddings: b } = Z;\n  u(h.shape.length <= 4, () => \"spaceToBatchND for rank > 4 with a WebGL backend not implemented yet\");\n  const c = g.reduce((o, B) => o * B), d = [[0, 0]];\n  d.push(...b);\n  for (let o = 1 + g.length; o < h.shape.length; ++o)\n    d.push([0, 0]);\n  const W = [], Y = gn({\n    inputs: { x: h },\n    backend: G,\n    attrs: { paddings: d, constantValue: 0 }\n  }), V = Dg(Y.shape, g, c, !1), a = fg(V.length, g.length, !1), i = Og(Y.shape, g, c, !1), m = ll({ inputs: { x: Y }, backend: G, attrs: { shape: V } }), T = HG({\n    inputs: { x: m },\n    backend: G,\n    attrs: { perm: a }\n  }), s = ll({ inputs: { x: T }, backend: G, attrs: { shape: i } });\n  return W.push(Y), W.push(m), W.push(T), W.forEach((o) => G.disposeIntermediateTensorInfo(o)), s;\n}, iQ = {\n  kernelName: ld,\n  backendName: \"webgl\",\n  kernelFunc: aQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction mQ(I) {\n  const { inputs: l, backend: G } = I, { indices: Z, values: h, denseShape: g, defaultValue: b } = l;\n  if (g.shape.length !== 1)\n    throw new Error(`Dense shape must be a vector, saw:\n         ${g.shape}`);\n  if (Z.shape.length !== 2)\n    throw new Error(`Indices must be a matrix, saw:\n         ${Z.shape}`);\n  if (h.shape.length !== 1)\n    throw new Error(`Values must be a vector, saw:\n         ${h.shape}`);\n  if (b.shape.length !== 0)\n    throw new Error(`Default value must be a scalar, saw:\n        ${b.shape}`);\n  const c = G.readSync(Z.dataId), d = G.readSync(h.dataId), W = G.readSync(g.dataId), Y = G.readSync(b.dataId)[0], [V, a, i, m, T] = $K(c, Z.shape, Z.dtype, d, h.dtype, W, Y);\n  return [\n    G.makeTensorInfo(a, Z.dtype, V),\n    G.makeTensorInfo([a[0]], h.dtype, i),\n    G.makeTensorInfo([m.length], \"bool\", new Uint8Array(m.map((s) => Number(s)))),\n    G.makeTensorInfo([T.length], Z.dtype, new Int32Array(T))\n  ];\n}\nconst TQ = {\n  kernelName: Li,\n  backendName: \"webgl\",\n  kernelFunc: mQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction sQ(I) {\n  const { inputs: l, backend: G } = I, { inputIndices: Z, inputShape: h, newShape: g } = l;\n  if (Z.shape.length !== 2)\n    throw new Error(`Input indices should be a matrix but received shape ${Z.shape}`);\n  if (h.shape.length !== 1)\n    throw new Error(`Input shape should be a vector but received shape ${h.shape}`);\n  if (g.shape.length !== 1)\n    throw new Error(`Target shape should be a vector but received shape ${g.shape}`);\n  const b = Array.from(G.readSync(h.dataId)), c = G.readSync(Z.dataId), d = Array.from(G.readSync(g.dataId)), [W, Y, V] = _K(c, Z.shape, Z.dtype, b, d);\n  return [\n    G.makeTensorInfo(Y, Z.dtype, W),\n    G.makeTensorInfo([V.length], g.dtype, new Int32Array(V))\n  ];\n}\nconst oQ = {\n  kernelName: Mi,\n  backendName: \"webgl\",\n  kernelFunc: sQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction BQ(I) {\n  const { inputs: l, backend: G } = I, { data: Z, indices: h, segmentIds: g } = l;\n  if (Z.shape.length < 1)\n    throw new Error(\"Data should be at least 1 dimensional but received scalar\");\n  if (h.shape.length !== 1)\n    throw new Error(`Indices should be a vector but received shape\n              ${h.shape}`);\n  if (g.shape.length !== 1)\n    throw new Error(`Segment ids should be a vector but received shape\n              ${g.shape}`);\n  const b = G.readSync(Z.dataId), c = G.readSync(h.dataId), d = G.readSync(g.dataId), [W, Y] = NB(b, Z.shape, Z.dtype, c, d, !0);\n  return G.makeTensorInfo(Y, Z.dtype, W);\n}\nconst nQ = {\n  kernelName: wi,\n  backendName: \"webgl\",\n  kernelFunc: BQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction CQ(I) {\n  const { inputs: l, backend: G } = I, { data: Z, indices: h, segmentIds: g } = l;\n  if (Z.shape.length < 1)\n    throw new Error(\"Data should be at least 1 dimensional but received scalar\");\n  if (h.shape.length !== 1)\n    throw new Error(`Indices should be a vector but received shape\n             ${h.shape}`);\n  if (g.shape.length !== 1)\n    throw new Error(`Segment ids should be a vector but received shape\n             ${g.shape}`);\n  const b = G.readSync(Z.dataId), c = G.readSync(h.dataId), d = G.readSync(g.dataId), [W, Y] = NB(b, Z.shape, Z.dtype, c, d);\n  return G.makeTensorInfo(Y, Z.dtype, W);\n}\nconst XQ = {\n  kernelName: Qi,\n  backendName: \"webgl\",\n  kernelFunc: CQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction tQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { sparseIndices: h, sparseValues: g, defaultValue: b } = l, { outputShape: c } = Z, { sliceRank: d, numUpdates: W, sliceSize: Y, strides: V, outputSize: a } = uh(g, h, c), i = !1;\n  if (g.dtype === \"string\") {\n    const o = G.bufferSync(h), B = G.bufferSync(g), C = eZ(G.readSync(b.dataId)[0]), n = fK(o, B, c, a, Y, W, d, V, C, i);\n    return G.makeTensorInfo(c, n.dtype, n.values);\n  }\n  const m = new E9(W, d, h.shape.length, g.shape.length, V, [a, 1], i), T = G.runWebGLProgram(m, [g, h, b], g.dtype), s = ll({ inputs: { x: T }, backend: G, attrs: { shape: c } });\n  return G.disposeIntermediateTensorInfo(T), s;\n}\nconst uQ = {\n  kernelName: vi,\n  backendName: \"webgl\",\n  kernelFunc: tQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction eQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { numOrSizeSplits: g, axis: b } = Z, c = tl(b, h.shape)[0], d = rV(h, g, c), W = h.shape.length, Y = new Array(W).fill(0), V = h.shape.slice();\n  return d.map((a) => {\n    const i = [...V];\n    i[c] = a;\n    const m = s0({ inputs: { x: h }, backend: G, attrs: { begin: Y, size: i } });\n    return Y[c] += a, m;\n  });\n}\nconst SQ = {\n  kernelName: Gd,\n  backendName: \"webgl\",\n  kernelFunc: eQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst Ti = \"return sqrt(x);\", RQ = Rl({ opSnippet: Ti, packedOpSnippet: Ti, cpuKernelImpl: l1 }), pQ = {\n  kernelName: xg,\n  backendName: \"webgl\",\n  kernelFunc: RQ\n};\n/**\n * @license\n * Copyright 2019 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst FQ = \"return x * x;\", yQ = Rl({ opSnippet: FQ }), NQ = {\n  kernelName: NY,\n  backendName: \"webgl\",\n  kernelFunc: yQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst si = \"return (a - b) * (a - b);\", PQ = tG({ opSnippet: si, packedOpSnippet: si }), JQ = {\n  kernelName: Ug,\n  backendName: \"webgl\",\n  kernelFunc: PQ\n};\n/**\n * @license\n * Copyright 2023 Google LLC.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction EQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l;\n  if (h.dtype !== \"string\")\n    throw new Error(\"Input must be of datatype string\");\n  const g = G.readSync(h.dataId), b = cZ(g), c = G1(b, \"string\", Z);\n  return G.makeTensorInfo(h.shape, \"string\", c);\n}\nconst xQ = {\n  kernelName: PY,\n  backendName: \"webgl\",\n  kernelFunc: EQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction UQ({ inputs: I, attrs: l, backend: G }) {\n  const { x: Z } = I, h = BI + `\n    return x > 0.0 ? 1.0 : float(${l.alpha});\n  `, g = new kI(Z.shape, h);\n  return G.runWebGLProgram(g, [Z], Z.dtype);\n}\nconst HQ = {\n  kernelName: zg,\n  backendName: \"webgl\",\n  kernelFunc: UQ\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass KQ {\n  constructor(l, G, Z) {\n    this.variableNames = [\"x\"], this.outputShape = Z;\n    const h = Z.length, g = Ul(Z.length), b = Ul(Z.length);\n    let c = \"\";\n    if (h === 1)\n      c = \"coords * strides + begin\";\n    else {\n      let d = 0;\n      c = Z.map((W, Y) => (d++, Z.length === 1 ? `coords * strides[${Y}] + begin[${Y}]` : `coords[${d - 1}] * strides[${Y}] + begin[${Y}]`)).join(\",\");\n    }\n    this.userCode = `\n      ${g} begin = ${g}(${l});\n      ${g} strides = ${g}(${G});\n\n      void main() {\n        ${b} coords = getOutputCoords();\n        setOutput(getX(${c}));\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction AQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { begin: g, end: b, strides: c, beginMask: d, endMask: W, ellipsisMask: Y, newAxisMask: V, shrinkAxisMask: a } = Z, { finalShapeSparse: i, finalShape: m, isIdentity: T, sliceDim0: s, isSimpleSlice: o, begin: B, end: C, strides: n } = FV(h.shape, g, b, c, d, W, Y, V, a);\n  let X;\n  if (T)\n    X = ll({ inputs: { x: h }, backend: G, attrs: { shape: m } });\n  else if (s || o) {\n    u(h.shape.length >= 1, () => `Input must have rank at least 1, got: ${h.shape.length}`);\n    const e = SV(B, C, n), S = s0({ inputs: { x: h }, backend: G, attrs: { begin: B, size: e } });\n    X = ll({ inputs: { x: S }, backend: G, attrs: { shape: m } }), G.disposeIntermediateTensorInfo(S);\n  } else if (G.shouldExecuteOnCPU([h])) {\n    const S = G.readSync(h.dataId), p = Xl(h.shape, h.dtype, S), F = I1(i, p, n, B);\n    X = G.makeTensorInfo(m, h.dtype, F.values);\n  } else {\n    const S = new KQ(B, n, i);\n    X = G.runWebGLProgram(S, [h], h.dtype);\n  }\n  const t = ll({ inputs: { x: X }, backend: G, attrs: { shape: m } });\n  return G.disposeIntermediateTensorInfo(X), t;\n}\nconst kQ = {\n  kernelName: JY,\n  backendName: \"webgl\",\n  kernelFunc: AQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction zQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { separator: h, nGramWidths: g, leftPad: b, rightPad: c, padWidth: d, preserveShortSequences: W } = Z, { data: Y, dataSplits: V } = l, a = G.readSync(Y.dataId), i = G.readSync(V.dataId), [m, T] = Z1(a, i, h, g, b, c, d, W);\n  return [\n    G.makeTensorInfo([m.length], \"string\", m),\n    G.makeTensorInfo(V.shape, \"int32\", T)\n  ];\n}\nconst LQ = {\n  kernelName: ri,\n  backendName: \"webgl\",\n  kernelFunc: zQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction MQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { skipEmpty: h } = Z, { input: g, delimiter: b } = l;\n  if (g.dtype !== \"string\")\n    throw new Error(\"Input must be of datatype string\");\n  if (g.shape.length !== 1)\n    throw new Error(`Input must be a vector, got shape: ${g.shape}`);\n  if (b.shape.length !== 0)\n    throw new Error(`Delimiter must be a scalar, got shape: ${b.shape}`);\n  const c = G.readSync(g.dataId), d = G.readSync(b.dataId)[0], [W, Y, V] = h1(c, d, h), a = Y.length;\n  return [\n    G.makeTensorInfo([a, 2], \"int32\", W),\n    G.makeTensorInfo([a], \"string\", Y),\n    G.makeTensorInfo([2], \"int32\", new Int32Array(V))\n  ];\n}\nconst wQ = {\n  kernelName: ji,\n  backendName: \"webgl\",\n  kernelFunc: MQ\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction QQ(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { numBuckets: h } = Z, { input: g } = l;\n  if (g.dtype !== \"string\")\n    throw new Error(\"Input must be of datatype string\");\n  if (h <= 0)\n    throw new Error(\"Number of buckets must be at least 1\");\n  const b = G.readSync(g.dataId), c = g1(b, h);\n  return G.makeTensorInfo(g.shape, \"int32\", c);\n}\nconst vQ = {\n  kernelName: Di,\n  backendName: \"webgl\",\n  kernelFunc: QQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst rQ = \"return tan(x);\", jQ = Rl({ opSnippet: rQ }), DQ = {\n  kernelName: Kg,\n  backendName: \"webgl\",\n  kernelFunc: jQ\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst fQ = `\n  float e2x = exp(-2.0 * abs(x));\n  return sign(x) * (1.0 - e2x) / (1.0 + e2x);\n`, OQ = Rl({ opSnippet: fQ }), qQ = {\n  kernelName: Ag,\n  backendName: \"webgl\",\n  kernelFunc: OQ\n};\n/**\n * @license\n * Copyright 2022 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction $Q(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { tensor: h, indices: g, updates: b } = l, { sliceRank: c, numUpdates: d, sliceSize: W, strides: Y, outputSize: V } = uh(b, g, h.shape), a = [V / W, W];\n  if (V === 0)\n    return G.makeTensorInfo(h.shape, g.dtype);\n  const i = ll({ inputs: { x: g }, backend: G, attrs: { shape: [d, c] } }), m = ll({ inputs: { x: b }, backend: G, attrs: { shape: [d, W] } }), T = ll({ inputs: { x: h }, backend: G, attrs: { shape: a } }), s = new E9(d, c, i.shape.length, m.shape.length, Y, a, !1, !0), o = G.runWebGLProgram(s, [m, i, T], T.dtype), B = ll({ inputs: { x: o }, backend: G, attrs: { shape: h.shape } });\n  return G.disposeIntermediateTensorInfo(i), G.disposeIntermediateTensorInfo(m), G.disposeIntermediateTensorInfo(T), G.disposeIntermediateTensorInfo(o), B;\n}\nconst _Q = {\n  kernelName: ki,\n  backendName: \"webgl\",\n  kernelFunc: $Q\n};\n/**\n * @license\n * Copyright 2017 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass lv {\n  constructor(l, G) {\n    this.variableNames = [\"A\"];\n    const Z = new Array(l.length);\n    for (let b = 0; b < Z.length; b++)\n      Z[b] = l[b] * G[b];\n    this.outputShape = Z, this.rank = Z.length;\n    const h = Ul(this.rank), g = Gv(l);\n    this.userCode = `\n      void main() {\n        ${h} resRC = getOutputCoords();\n        setOutput(getA(${g}));\n      }\n    `;\n  }\n}\nfunction Gv(I) {\n  const l = I.length;\n  if (l > 5)\n    throw Error(`Tile for rank ${l} is not yet supported`);\n  if (l === 1)\n    return `imod(resRC, ${I[0]})`;\n  const G = [\"resRC.x\", \"resRC.y\", \"resRC.z\", \"resRC.w\", \"resRC.u\"], Z = [];\n  for (let h = 0; h < I.length; h++)\n    Z.push(`imod(${G[h]}, ${I[h]})`);\n  return Z.join();\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction cn(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { reps: g } = Z;\n  if (h.dtype === \"string\" || h.shape.length > 5) {\n    const d = G.readSync(h.dataId), W = h.dtype === \"string\" ? d.map((a) => eZ(a)) : d, Y = Xl(h.shape, h.dtype, W), V = c1(Y, g);\n    return G.makeTensorInfo(V.shape, V.dtype, V.values);\n  }\n  const b = new lv(h.shape, g);\n  return G.runWebGLProgram(b, [h], h.dtype);\n}\nconst Iv = {\n  kernelName: kg,\n  backendName: \"webgl\",\n  kernelFunc: cn\n};\nclass Zv {\n  /**\n   * @param shape desired output shape (can be larger than input shape, output\n   *                                    will be padded with -Infinity)\n   */\n  constructor(l) {\n    this.variableNames = [\"x\", \"indices\"], this.customUniforms = [\n      { name: \"n\", type: \"int\" },\n      { name: \"firstPass\", type: \"int\" },\n      { name: \"negativeInf\", type: \"float\" },\n      { name: \"dir\", type: \"int\" },\n      { name: \"inc\", type: \"int\" }\n    ], this.outputShape = l, this.userCode = `\n       void main() {\n         ivec2 coords = getOutputCoords();\n         int batch = coords[0];\n         int elemIdx = coords[1];\n\n         // We compare elements pair-wise within a group of size 2 * inc.\n         // The comparing rule for each group alternates between ascending\n         // and descending. Within each group, we compare each pair at\n         // positions i and i+inc. To decide whether an element at position i\n         // is x0 or x1, we mod it by 2 * inc, if the result is smaller than\n         // inc, it is in the first half of the group, we denote it as x0,\n         // otherwise we denote it as x1.\n         // For example, as shown in the Bitonic top K paper referenced above,\n         // Figure5(a) shows that element[1] is in the\n         // second half of the group when group size is 2, but it is in the\n         // first half of the group when group size is 4.\n\n         bool isFirstInPair = imod(elemIdx, 2 * inc) < inc;\n         int i = isFirstInPair ? elemIdx : elemIdx - inc;\n\n         int i0 = firstPass == 1 ? i : int(getIndices(batch, i));\n         int i1 = firstPass == 1 ? i + inc : int(getIndices(batch, i + inc));\n         float x0 = i0 < n ? getX(batch, i0) : negativeInf;\n         float x1 = i1 < n ? getX(batch, i1) : negativeInf;\n\n         // Denotes which direction indices are in (ascending or descending).\n         bool reverse = imod(elemIdx, 2 * dir) >= dir;\n         bool isGreater = x0 > x1 || (x0 == x1 && i1 > i0);\n         if (reverse == isGreater) { // Elements in opposite order of direction\n           int iTemp = i0;\n           i0 = i1;\n           i1 = iTemp;\n         }\n         if (isFirstInPair) {\n            setOutput(float(i0));\n         } else {\n            setOutput(float(i1));\n         }\n       }\n     `;\n  }\n}\nclass hv {\n  /**\n   * @param shape desired output shape (must be half of the input size)\n   */\n  constructor(l) {\n    this.variableNames = [\"x\", \"indices\"], this.customUniforms = [\n      { name: \"n\", type: \"int\" },\n      { name: \"firstPass\", type: \"int\" },\n      { name: \"k\", type: \"int\" }\n    ], this.outputShape = l, this.userCode = `\n    void main() {\n         // Takes max of indices (0, k), (1, k + 1), (2, k + 2) ...\n         ivec2 coords = getOutputCoords();\n         int batch = coords[0];\n         int elemIdx = coords[1];\n\n         // The output size is half of the previous size.\n         // If the previous sequence is | | | | _ _ _ _  | | | |  _ _ _ _ (k=4),\n         // we only need to output the indices at positions |, the indices at\n         // positions _ can be thrown away, see Figure5(b) After Phase 2\n         // (Merge phase) in the Bitonic Top K paper referenced above.\n         // For example, the paper shows we only need to output the orange bars.\n         // The output sequence should look like this | | | | | | | |.\n         // Because the sequence is halved, to map the output index back\n         // to the previous sequence to find the corresponding value,\n         // we need to double the index. When we double the index,\n         // we basically interpolate a position, so 2i looks like\n         // | _ | _ | _ | _ | _ | _ | _. We move the | to the first k position\n         // of each 2k positions by - elemIdx % k. E.g. for output at\n         // index 4,5,6,7, we want to get the corresponding element at\n         // original index 8,9,10,11, for output at index 8,9,10,11,\n         // we want to get the corresponding element at original index\n         // 16,17,18,19, so on and so forth.\n\n         int i = elemIdx < k ? elemIdx : (elemIdx * 2 - imod(elemIdx, k));\n         int i0 = firstPass == 1 ? i : int(getIndices(batch, i));\n         int i1 = firstPass == 1 ? i + k : int(getIndices(batch, i + k));\n\n         float x0 = getX(batch, i0);\n         float x1 = i1 < n ? getX(batch, i1) : x0;\n\n         setOutput(x0 >= x1 ? float(i0) : float(i1));\n       }\n     `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction vZ(I, l) {\n  l !== null && I.disposeIntermediateTensorInfo(l);\n}\nfunction oi(I) {\n  let l = 1;\n  for (; l < I; )\n    l *= 2;\n  return l;\n}\nfunction gv(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h } = l, { k: g, sorted: b } = Z, c = A().getNumber(\"TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD\"), d = A().getNumber(\"TOPK_K_CPU_HANDOFF_THRESHOLD\"), W = h.shape, Y = W[W.length - 1];\n  if (G.shouldExecuteOnCPU([h]) || Y < c || g > d) {\n    const F = G.readSync(h.dataId), [x, H] = d1(F, W, h.dtype, g, b);\n    return [\n      G.makeTensorInfo(x.shape, x.dtype, x.values),\n      G.makeTensorInfo(H.shape, H.dtype, H.values)\n    ];\n  }\n  if (g === 0)\n    return W[W.length - 1] = 0, [\n      G.makeTensorInfo(W, h.dtype, []),\n      G.makeTensorInfo(W, \"int32\", [])\n    ];\n  if (Y === 1)\n    return [\n      h,\n      Yb({ attrs: { shape: W, dtype: \"int32\", value: 0 }, backend: G })\n    ];\n  const V = G.texData.get(h.dataId), a = V !== null && V.isPacked, i = a ? G.unpackTensor(h) : h, T = Q(W) / Y, s = ll({ inputs: { x: i }, attrs: { shape: [T, Y] }, backend: G });\n  a && vZ(G, i);\n  const o = oi(g), B = oi(Y);\n  let C = null;\n  const n = () => C === null ? [s, s] : [s, C], X = (F, x, H) => {\n    const K = n(), z = new Zv(H), L = [[Y], [C === null ? 1 : 0], [Number.NEGATIVE_INFINITY], [F], [x]], v = C;\n    C = G.runWebGLProgram(z, K, \"int32\", L), vZ(G, v);\n  };\n  for (let F = 1; F < o; F *= 2) {\n    const x = F * 2;\n    for (let H = F; H >= 1; H /= 2)\n      X(x, H, [T, B]);\n  }\n  for (let F = B; F > o; F /= 2) {\n    const x = n(), H = new hv([T, F / 2]), z = [[Y], [C === null ? 1 : 0], [o]], k = C;\n    C = G.runWebGLProgram(H, x, \"int32\", z), vZ(G, k);\n    const L = o / 2, v = L * 2;\n    for (let w = L; w >= 1; w /= 2)\n      X(v, w, C.shape);\n  }\n  let t = C;\n  C = s0({ inputs: { x: C }, backend: G, attrs: { begin: 0, size: [T, g] } }), vZ(G, t);\n  let e = _B({ inputs: { x: s, indices: C }, backend: G, attrs: { axis: 1, batchDims: 1 } });\n  vZ(G, s);\n  const S = W.slice(0, -1);\n  S.push(g), t = C, C = ll({ inputs: { x: C }, attrs: { shape: S }, backend: G }), vZ(G, t);\n  const p = e;\n  return e = ll({ inputs: { x: e }, attrs: { shape: S }, backend: G }), vZ(G, p), [e, C];\n}\nconst bv = {\n  kernelName: EY,\n  backendName: \"webgl\",\n  kernelFunc: gv\n};\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass cv {\n  constructor(l, G, Z, h, g, b) {\n    this.variableNames = [\"Image\", \"Transforms\"], this.outputShape = b;\n    const c = Z === \"nearest\" ? 1 : 2;\n    let d;\n    switch (h) {\n      case \"constant\":\n        d = 1;\n        break;\n      case \"reflect\":\n        d = 2;\n        break;\n      case \"wrap\":\n        d = 3;\n        break;\n      case \"nearest\":\n        d = 4;\n        break;\n      default:\n        d = 1;\n        break;\n    }\n    this.userCode = `\n            float mapCoord(float outCoord, float len) {\n              float inCoord = outCoord;\n              if(${d} == 2) {\n                if (inCoord < 0.0) {\n                  if (len <= 1.0) {\n                    inCoord = 0.0;\n                  } else {\n                    float sz2 = 2.0 * len;\n                    if (inCoord < sz2) {\n                      inCoord = sz2 * float(int(float(-inCoord / sz2))) +\n                      inCoord;\n                    }\n                    inCoord = inCoord < -len ? inCoord + sz2 : -inCoord - 1.0;\n                  }\n                } else if (inCoord > len - 1.0) {\n                  if (len <= 1.0) {\n                    inCoord = 0.0;\n                  } else {\n                    float sz2 = 2.0 * len;\n                    inCoord -= sz2 * float(int(float(inCoord / sz2)));\n                    if (inCoord >= len) {\n                      inCoord = sz2 - inCoord - 1.0;\n                    }\n                  }\n                }\n                return clamp(inCoord, 0.0, len - 1.0);\n              } else if (${d} == 3) {\n                if (inCoord < 0.0) {\n                  if (len <= 1.0) {\n                    inCoord = 0.0;\n                  } else {\n                    float sz = len - 1.0;\n                    inCoord += len * (float(int(float(-inCoord / sz))) + 1.0);\n                  }\n                } else if (inCoord > len - 1.0) {\n                  if (len <= 1.0) {\n                    inCoord = 0.0;\n                  } else {\n                    float sz = len - 1.0;\n                    inCoord -= len * float(int(float(inCoord / sz)));\n                  }\n                }\n                return clamp(inCoord, 0.0, len - 1.0);\n              } else if (${d} == 4) {\n                return clamp(outCoord, 0.0, len - 1.0);\n              } else {\n                return outCoord;\n              }\n            }\n\n            float readWithFillValue(int batch, int coordY, int coordX,\n              int channel) {\n              float outputValue;\n              if (0 <= coordY && coordY < ${l} && 0 <= coordX && coordX < ${G}) {\n                  outputValue = getImage(batch, coordY, coordX, channel);\n              } else {\n                outputValue = float(${g});\n              }\n              return outputValue;\n            }\n\n            void main() {\n              ivec4 coords = getOutputCoords();\n              float outputValue;\n              int batch = coords[0];\n              int x = coords[2];\n              int y = coords[1];\n              int channel = coords[3];\n              float xf = float(x);\n              float yf = float(y);\n              float a1 = getTransforms(batch, 0);\n              float a2 = getTransforms(batch, 1);\n              float a3 = getTransforms(batch, 2);\n              float b1 = getTransforms(batch, 3);\n              float b2 = getTransforms(batch, 4);\n              float b3 = getTransforms(batch, 5);\n              float c1 = getTransforms(batch, 6);\n              float c2 = getTransforms(batch, 7);\n              float projection = c1 * xf + c2 * yf + 1.0;\n              if (projection == 0.0) {\n                outputValue = float(${g});\n              } else {\n                float inX = (a1 * xf + a2 * yf + a3) / projection;\n                float inY = (b1 * xf + b2 * yf + b3) / projection;\n                float mapX = mapCoord(inX, float(${G}));\n                float mapY = mapCoord(inY, float(${l}));\n\n                if (${c} == 1) {\n                  int coordY = int(round(mapY));\n                  int coordX = int(round(mapX));\n                  outputValue = readWithFillValue(batch, coordY, coordX,\n                    channel);\n                } else {\n                  float yFloor = floor(mapY);\n                  float xFloor = floor(mapX);\n                  float yCeil = yFloor + 1.0;\n                  float xCeil = xFloor + 1.0;\n                  float valueYFloor = (xCeil - mapX) *\n                  readWithFillValue(batch, int(yFloor), int(xFloor), channel) +\n                  (mapX - xFloor) *\n                  readWithFillValue(batch, int(yFloor), int(xCeil), channel);\n                  float valueYCeil = (xCeil - mapX) *\n                  readWithFillValue(batch, int(yCeil), int(xFloor), channel) +\n                  (mapX - xFloor) *\n                  readWithFillValue(batch, int(yCeil), int(xCeil), channel);\n                  outputValue = (yCeil - mapY) * valueYFloor +\n                  (mapY - yFloor) * valueYCeil;\n                }\n              }\n              setOutput(outputValue);\n            }\n        `;\n  }\n}\n/**\n * @license\n * Copyright 2021 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction dv(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { image: h, transforms: g } = l, { interpolation: b, fillMode: c, fillValue: d, outputShape: W } = Z, [Y, V, a, i] = h.shape, [m, T] = W ?? [V, a], s = [\n    Y,\n    m,\n    T,\n    i\n  ], o = new cv(V, a, b, c, d, s);\n  return G.runWebGLProgram(o, [h, g], \"float32\");\n}\nconst Wv = {\n  kernelName: xY,\n  backendName: \"webgl\",\n  kernelFunc: dv\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Yv(I) {\n  const { inputs: l, attrs: G, backend: Z } = I, { axis: h } = G, { x: g } = l;\n  cb(g, \"unique\"), console.warn(\"WARNING: \", \"UI might be locked temporarily as data is being downloaded\");\n  const b = Z.readSync(g.dataId), { outputValues: c, outputShape: d, indices: W } = W1(b, h, g.shape, g.dtype);\n  return [\n    Z.makeTensorInfo(d, g.dtype, c),\n    Z.makeTensorInfo([W.length], \"int32\", W)\n  ];\n}\nconst Vv = {\n  kernelName: UY,\n  backendName: \"webgl\",\n  kernelFunc: Yv\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction av(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { value: h } = l;\n  let { axis: g } = Z;\n  g < 0 && (g += h.shape.length);\n  const b = h, c = b.shape.length, d = h.shape[g], W = new Array(c - 1);\n  let Y = 0;\n  for (let T = 0; T < c; T++)\n    T !== g && (W[Y++] = b.shape[T]);\n  const V = [], a = new Array(c).fill(0), i = b.shape.slice();\n  i[g] = 1;\n  const m = new Array(d);\n  for (let T = 0; T < m.length; T++) {\n    a[g] = T;\n    const s = s0({ inputs: { x: b }, backend: G, attrs: { begin: a, size: i } }), o = ll({ inputs: { x: s }, backend: G, attrs: { shape: W } });\n    m[T] = o, V.push(s);\n  }\n  return V.forEach((T) => G.disposeIntermediateTensorInfo(T)), m;\n}\nconst iv = {\n  kernelName: Zd,\n  backendName: \"webgl\",\n  kernelFunc: av\n};\n/**\n * @license\n * Copyright 2018 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nclass mv {\n  constructor(l, G) {\n    this.variableNames = [\"x\", \"segmentIds\"];\n    const Z = l.windowSize, h = l.batchSize, g = l.inSize, b = l.numSegments, c = b * Math.ceil(g / Z);\n    this.outputShape = [h, c];\n    const d = \"0.0\", W = \"sumValue\", Y = Math.floor(Z / 4) * 4, V = Z % 4, a = `\n        sumValue += dot(values, segFilter);\n    `;\n    let i = \"\";\n    g % Z > 0 && (i = `\n        if (inIdx < 0 || inIdx >= ${g}) {\n          return initializationValue;\n        }\n      `);\n    let m = \"\";\n    g % Z > 0 && (m = `\n        if (inIdx < 0 || inIdx >= ${g}) {\n          return -1.0;\n        }\n      `), this.userCode = `\n      const float initializationValue = ${d};\n\n      float getValue(int batch, int inIdx) {\n        ${i}\n        return getX(batch, inIdx);\n      }\n\n      float getSegmentIdAtIndex(int inIdx) {\n        ${m}\n        return getSegmentIds(inIdx);\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = int(floor(float(outIdx) / float(\n          ${b})) * float(${Z}));\n        int currentSeg = int(mod(float(outIdx), float(${b})));\n\n        float sumValue = 0.0;\n\n        for (int i = 0; i < ${Y}; i += 4) {\n          int inIdx = inOffset + i;\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            getValue(batch, inIdx + 3)\n          );\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 3)) == currentSeg ? 1 : 0\n          );\n\n          ${a}\n        }\n\n        int inIdx = inOffset + ${Y};\n        if (${V === 1}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            initializationValue,\n            initializationValue,\n            initializationValue\n          );\n\n          int inIdxSeg = int(getSegmentIdAtIndex(inIdx));\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            0,\n            0,\n            0\n          );\n\n          ${a}\n        } else if (${V === 2}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            initializationValue,\n            initializationValue\n          );\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n              0,\n              0\n          );\n\n          ${a}\n        } else if (${V === 3}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            initializationValue\n          );\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n            0\n          );\n\n          ${a}\n        }\n        setOutput(${W});\n      }\n    `;\n  }\n}\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nfunction Tv(I) {\n  const { inputs: l, backend: G, attrs: Z } = I, { x: h, segmentIds: g } = l, { numSegments: b } = Z, c = h.shape.length, d = [];\n  let W = 0;\n  const Y = Ol([W], c);\n  let V = h;\n  Y != null && (V = HG({ inputs: { x: h }, backend: G, attrs: { perm: Y } }), d.push(V), W = GG(1, c)[0]);\n  const a = LT(V.shape, W, b), i = Q([V.shape[W]]), m = ll({ inputs: { x: V }, backend: G, attrs: { shape: [-1, i] } });\n  d.push(m);\n  const T = AY(h.dtype), s = (n, X, t, e, S) => {\n    const p = n.shape[0], F = n.shape[1], x = zT(F, S), H = { windowSize: x, inSize: F, batchSize: p, numSegments: S }, K = new mv(H, X), z = G.compileAndRun(K, [n, t], e);\n    if (d.push(z), z.shape[1] === S)\n      return z;\n    const k = bn({\n      backend: G,\n      attrs: { start: 0, stop: S, step: 1, dtype: \"float32\" }\n    }), L = cn({\n      inputs: { x: k },\n      backend: G,\n      attrs: { reps: [F / x] }\n    });\n    return d.push(k), d.push(L), s(z, X, L, e, S);\n  }, o = s(m, \"unsortedSegmentSum\", g, T, b), B = ll({ inputs: { x: o }, backend: G, attrs: { shape: a } });\n  let C = B;\n  if (Y != null) {\n    d.push(B);\n    const n = xZ(Y);\n    C = HG({ inputs: { x: C }, backend: G, attrs: { perm: n } });\n  }\n  return d.forEach((n) => G.disposeIntermediateTensorInfo(n)), C;\n}\nconst sv = {\n  kernelName: hd,\n  backendName: \"webgl\",\n  kernelFunc: Tv\n};\n/**\n * @license\n * Copyright 2020 Google LLC. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =============================================================================\n */\nconst ov = [\n  lA,\n  IA,\n  gA,\n  dA,\n  YA,\n  iA,\n  TA,\n  oA,\n  XA,\n  uA,\n  RA,\n  yA,\n  JA,\n  HA,\n  kA,\n  LA,\n  wA,\n  jA,\n  fA,\n  qA,\n  Gk,\n  dk,\n  Yk,\n  mk,\n  sk,\n  tk,\n  ek,\n  Fk,\n  K1,\n  Pk,\n  Hk,\n  zk,\n  rk,\n  fk,\n  qk,\n  _k,\n  Gz,\n  gz,\n  dz,\n  Vz,\n  iz,\n  Tz,\n  oz,\n  Cz,\n  tz,\n  Rz,\n  Fz,\n  Pz,\n  xz,\n  Hz,\n  zz,\n  Qz,\n  Dz,\n  qz,\n  l3,\n  G3,\n  Z3,\n  g3,\n  c3,\n  W3,\n  V3,\n  T3,\n  B3,\n  X3,\n  u3,\n  R3,\n  y3,\n  E3,\n  K3,\n  H1,\n  k3,\n  xk,\n  M3,\n  v3,\n  D3,\n  k1,\n  $3,\n  IL,\n  hL,\n  dL,\n  VL,\n  TL,\n  BL,\n  tL,\n  RL,\n  yL,\n  PL,\n  UL,\n  KL,\n  kL,\n  wL,\n  vL,\n  jL,\n  fL,\n  qL,\n  GM,\n  gM,\n  WM,\n  oM,\n  M1,\n  XM,\n  eM,\n  pM,\n  NM,\n  Bk,\n  EM,\n  UM,\n  KM,\n  zM,\n  QM,\n  L1,\n  rM,\n  DM,\n  OM,\n  $M,\n  _M,\n  nk,\n  iM,\n  Iw,\n  bw,\n  Yw,\n  Q1,\n  mw,\n  ow,\n  Xw,\n  ew,\n  Fw,\n  Nw,\n  Ew,\n  Hw,\n  kw,\n  Mw,\n  vw,\n  Dw,\n  $w,\n  GQ,\n  gQ,\n  dQ,\n  bk,\n  TM,\n  VQ,\n  iQ,\n  TQ,\n  oQ,\n  nQ,\n  XQ,\n  uQ,\n  SQ,\n  pQ,\n  NQ,\n  JQ,\n  xQ,\n  HQ,\n  kQ,\n  LQ,\n  wQ,\n  vQ,\n  mM,\n  q1,\n  DQ,\n  qQ,\n  _Q,\n  Iv,\n  bv,\n  Wv,\n  $1,\n  Vv,\n  iv,\n  sv,\n  xM\n];\nfor (const I of ov)\n  Oi(I);\nclass x9 {\n  constructor(l) {\n    l instanceof hG ? (l.shape.length == 4 && (l = J(l, l.shape.slice(1))), this.tensorImage = l) : l instanceof ImageBitmap ? this.bitmapImage = l : (l instanceof HTMLImageElement || l instanceof HTMLVideoElement) && (this.htmlImage = l);\n  }\n  async bitmap() {\n    if (this.bitmapImage) return this.bitmapImage;\n    if (this.htmlImage)\n      this.bitmapImage = await createImageBitmap(this.htmlImage);\n    else if (this.tensorImage)\n      throw new Error(\"Not implemented\");\n    return this.bitmapImage;\n  }\n  tensor() {\n    const l = this.bitmapImage || this.htmlImage;\n    if (!l)\n      throw new Error(\"No image\");\n    return this.tensorImage || (this.tensorImage = wS(l)), this.tensorImage;\n  }\n  async tensor4D() {\n    if (!this.tensor4DImage) {\n      let l = await this.tensor();\n      this.tensor4DImage = EG(l);\n    }\n    return this.tensor4DImage;\n  }\n  async array() {\n    return this.tensorImage ? this.tensorImage.array() : (await this.tensor()).array();\n  }\n  dims() {\n    return this.bitmapImage ? [this.bitmapImage.width, this.bitmapImage.height] : this.tensorImage ? [this.tensorImage.shape[0], this.tensorImage.shape[1]] : this.htmlImage instanceof HTMLImageElement ? [this.htmlImage.width, this.htmlImage.height] : [0, 0];\n  }\n  dispose() {\n    this.tensorImage && Cl(this.tensorImage), this.tensor4DImage && Cl(this.tensor4DImage);\n  }\n  static fromArray(l) {\n    let G = kY(l);\n    return new x9(G);\n  }\n}\nconst Bi = 2, ni = 10;\nclass Vb extends Error {\n  constructor(l, G) {\n    super(l instanceof Error ? l.message : typeof l == \"string\" ? l : JSON.stringify(l)), this.code = G;\n  }\n}\nclass Ci extends Vb {\n  constructor(l) {\n    super(l, 404);\n  }\n}\nclass Bv extends Vb {\n  constructor(l) {\n    super(l, 429);\n  }\n}\nclass nv extends Vb {\n  constructor(l) {\n    super(l, 429);\n  }\n}\nclass Cv extends Vb {\n  constructor(l) {\n    super(l, 404);\n  }\n}\nclass Xv extends Vb {\n  constructor(l) {\n    super(l, 404);\n  }\n}\nconst dn = \"KGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIF9tZXJnZU5hbWVzcGFjZXMoaGEsYWEpe3JldHVybiBhYS5mb3JFYWNoKGZ1bmN0aW9uKHhhKXt4YSYmdHlwZW9mIHhhIT0ic3RyaW5nIiYmIUFycmF5LmlzQXJyYXkoeGEpJiZPYmplY3Qua2V5cyh4YSkuZm9yRWFjaChmdW5jdGlvbihiYSl7aWYoYmEhPT0iZGVmYXVsdCImJiEoYmEgaW4gaGEpKXt2YXIgU2E9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih4YSxiYSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KGhhLGJhLFNhLmdldD9TYTp7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4geGFbYmFdfX0pfX0pfSksT2JqZWN0LmZyZWV6ZShoYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRVBTSUxPTl9GTE9BVDMyJDM9MWUtNyxFUFNJTE9OX0ZMT0FUMTYkMz0xZS00O2xldCBEYXRhU3RvcmFnZSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLmJhY2tlbmQ9YWEsdGhpcy5kYXRhTW92ZXI9eGEsdGhpcy5kYXRhPW5ldyBXZWFrTWFwLHRoaXMuZGF0YUlkc0NvdW50PTB9Z2V0KGFhKXtyZXR1cm4gdGhpcy5kYXRhLmhhcyhhYSl8fHRoaXMuZGF0YU1vdmVyLm1vdmVEYXRhKHRoaXMuYmFja2VuZCxhYSksdGhpcy5kYXRhLmdldChhYSl9c2V0KGFhLHhhKXt0aGlzLmRhdGFJZHNDb3VudCsrLHRoaXMuZGF0YS5zZXQoYWEseGEpfWhhcyhhYSl7cmV0dXJuIHRoaXMuZGF0YS5oYXMoYWEpfWRlbGV0ZShhYSl7cmV0dXJuIHRoaXMuZGF0YUlkc0NvdW50LS0sdGhpcy5kYXRhLmRlbGV0ZShhYSl9bnVtRGF0YUlkcygpe3JldHVybiB0aGlzLmRhdGFJZHNDb3VudH19LEtlcm5lbEJhY2tlbmQkMT1jbGFzc3tyZWZDb3VudChhYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoInJlZkNvdW50Iil9aW5jUmVmKGFhKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQkMSgiaW5jUmVmIil9dGltZXJBdmFpbGFibGUoKXtyZXR1cm4hMH10aW1lKGFhKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQkMSgidGltZSIpfXJlYWQoYWEpe3JldHVybiBub3RZZXRJbXBsZW1lbnRlZCQxKCJyZWFkIil9cmVhZFN5bmMoYWEpe3JldHVybiBub3RZZXRJbXBsZW1lbnRlZCQxKCJyZWFkU3luYyIpfXJlYWRUb0dQVShhYSx4YSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoInJlYWRUb0dQVSIpfW51bURhdGFJZHMoKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQkMSgibnVtRGF0YUlkcyIpfWRpc3Bvc2VEYXRhKGFhLHhhKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQkMSgiZGlzcG9zZURhdGEiKX13cml0ZShhYSx4YSxiYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoIndyaXRlIil9bW92ZShhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoIm1vdmUiKX1jcmVhdGVUZW5zb3JGcm9tR1BVRGF0YShhYSx4YSxiYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoImNyZWF0ZVRlbnNvckZyb21HUFVEYXRhIil9bWVtb3J5KCl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoIm1lbW9yeSIpfWZsb2F0UHJlY2lzaW9uKCl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoImZsb2F0UHJlY2lzaW9uIil9ZXBzaWxvbigpe3JldHVybiB0aGlzLmZsb2F0UHJlY2lzaW9uKCk9PT0zMj9FUFNJTE9OX0ZMT0FUMzIkMzpFUFNJTE9OX0ZMT0FUMTYkM31kaXNwb3NlKCl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkJDEoImRpc3Bvc2UiKX19O2Z1bmN0aW9uIG5vdFlldEltcGxlbWVudGVkJDEoaGEpe3Rocm93IG5ldyBFcnJvcihgJyR7aGF9JyBub3QgeWV0IGltcGxlbWVudGVkIG9yIG5vdCBmb3VuZCBpbiB0aGUgcmVnaXN0cnkuIFRoaXMga2VybmVsIG1heSBub3QgYmUgc3VwcG9ydGVkIGJ5IHRoZSB0ZmpzIGJhY2tlbmQgeW91IGhhdmUgY2hvc2VuYCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2h1ZmZsZShoYSl7bGV0IGFhPWhhLmxlbmd0aCx4YT0wO2Zvcig7YWE+MDspeGE9TWF0aC5yYW5kb20oKSphYXwwLGFhLS0sc3dhcCQxKGhhLGFhLHhhKX1mdW5jdGlvbiBjbGFtcCQxKGhhLGFhLHhhKXtyZXR1cm4gTWF0aC5tYXgoaGEsTWF0aC5taW4oYWEseGEpKX1mdW5jdGlvbiBuZWFyZXN0TGFyZ2VyRXZlbiQxKGhhKXtyZXR1cm4gaGElMj09PTA/aGE6aGErMX1mdW5jdGlvbiBzd2FwJDEoaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtoYVthYV09aGFbeGFdLGhhW3hhXT1iYX1mdW5jdGlvbiBzdW0kNihoYSl7bGV0IGFhPTA7Zm9yKGxldCB4YT0wO3hhPGhhLmxlbmd0aDt4YSsrKWFhKz1oYVt4YV07cmV0dXJuIGFhfWZ1bmN0aW9uIGFzc2VydCQyKGhhLGFhKXtpZighaGEpdGhyb3cgbmV3IEVycm9yKHR5cGVvZiBhYT09InN0cmluZyI/YWE6YWEoKSl9ZnVuY3Rpb24gYXNzZXJ0U2hhcGVzTWF0Y2gkMShoYSxhYSx4YT0iIil7YXNzZXJ0JDIoYXJyYXlzRXF1YWwkMShoYSxhYSksKCk9PnhhK2AgU2hhcGVzICR7aGF9IGFuZCAke2FhfSBtdXN0IG1hdGNoYCl9ZnVuY3Rpb24gYXNzZXJ0Tm9uTnVsbChoYSl7YXNzZXJ0JDIoaGEhPW51bGwsKCk9PiJUaGUgaW5wdXQgdG8gdGhlIHRlbnNvciBjb25zdHJ1Y3RvciBtdXN0IGJlIGEgbm9uLW51bGwgdmFsdWUuIil9ZnVuY3Rpb24gc2l6ZUZyb21TaGFwZSQxKGhhKXtpZihoYS5sZW5ndGg9PT0wKXJldHVybiAxO2xldCBhYT1oYVswXTtmb3IobGV0IHhhPTE7eGE8aGEubGVuZ3RoO3hhKyspYWEqPWhhW3hhXTtyZXR1cm4gYWF9ZnVuY3Rpb24gYXJyYXlzRXF1YWxXaXRoTnVsbChoYSxhYSl7aWYoaGE9PT1hYSlyZXR1cm4hMDtpZihoYT09bnVsbHx8YWE9PW51bGx8fGhhLmxlbmd0aCE9PWFhLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoO3hhKyspaWYoaGFbeGFdIT09bnVsbCYmYWFbeGFdIT09bnVsbCYmaGFbeGFdIT09YWFbeGFdKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIGFycmF5c0VxdWFsJDEoaGEsYWEpe2lmKGhhPT09YWEpcmV0dXJuITA7aWYoaGE9PW51bGx8fGFhPT1udWxsfHxoYS5sZW5ndGghPT1hYS5sZW5ndGgpcmV0dXJuITE7Zm9yKGxldCB4YT0wO3hhPGhhLmxlbmd0aDt4YSsrKWlmKGhhW3hhXSE9PWFhW3hhXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBpc0ludCQxKGhhKXtyZXR1cm4gaGElMT09PTB9ZnVuY3Rpb24gc2l6ZVRvU3F1YXJpc2hTaGFwZSQxKGhhKXtjb25zdCBhYT1NYXRoLmNlaWwoTWF0aC5zcXJ0KGhhKSk7cmV0dXJuW2FhLE1hdGguY2VpbChoYS9hYSldfWZ1bmN0aW9uIHJpZ2h0UGFkJDEoaGEsYWEpe3JldHVybiBhYTw9aGEubGVuZ3RoP2hhOmhhKyIgIi5yZXBlYXQoYWEtaGEubGVuZ3RoKX1mdW5jdGlvbiByZXBlYXRlZFRyeSQxKGhhLGFhPVNhPT4wLHhhLGJhKXtyZXR1cm4gbmV3IFByb21pc2UoKFNhLFRhKT0+e2xldCB3YT0wO2NvbnN0IEVhPSgpPT57aWYoaGEoKSl7U2EoKTtyZXR1cm59d2ErKztjb25zdCBrYT1hYSh3YSk7aWYoeGEhPW51bGwmJndhPj14YSl7VGEoKTtyZXR1cm59YmEhPW51bGw/YmEoRWEsa2EpOnNldFRpbWVvdXQoRWEsa2EpfTtFYSgpfSl9ZnVuY3Rpb24gaW5mZXJGcm9tSW1wbGljaXRTaGFwZSQxKGhhLGFhKXtsZXQgeGE9MSxiYT0tMTtmb3IobGV0IFRhPTA7VGE8aGEubGVuZ3RoOysrVGEpaWYoaGFbVGFdPj0wKXhhKj1oYVtUYV07ZWxzZSBpZihoYVtUYV09PT0tMSl7aWYoYmEhPT0tMSl0aHJvdyBFcnJvcihgU2hhcGVzIGNhbiBvbmx5IGhhdmUgMSBpbXBsaWNpdCBzaXplLiBGb3VuZCAtMSBhdCBkaW0gJHtiYX0gYW5kIGRpbSAke1RhfWApO2JhPVRhfWVsc2UgaWYoaGFbVGFdPDApdGhyb3cgRXJyb3IoYFNoYXBlcyBjYW4gbm90IGJlIDwgMC4gRm91bmQgJHtoYVtUYV19IGF0IGRpbSAke1RhfWApO2lmKGJhPT09LTEpe2lmKGFhPjAmJmFhIT09eGEpdGhyb3cgRXJyb3IoYFNpemUoJHthYX0pIG11c3QgbWF0Y2ggdGhlIHByb2R1Y3Qgb2Ygc2hhcGUgJHtoYX1gKTtyZXR1cm4gaGF9aWYoeGE9PT0wKXRocm93IEVycm9yKGBDYW5ub3QgaW5mZXIgdGhlIG1pc3Npbmcgc2l6ZSBpbiBbJHtoYX1dIHdoZW4gdGhlcmUgYXJlIDAgZWxlbWVudHNgKTtpZihhYSV4YSE9PTApdGhyb3cgRXJyb3IoYFRoZSBpbXBsaWNpdCBzaGFwZSBjYW4ndCBiZSBhIGZyYWN0aW9uYWwgbnVtYmVyLiBHb3QgJHthYX0gLyAke3hhfWApO2NvbnN0IFNhPWhhLnNsaWNlKCk7cmV0dXJuIFNhW2JhXT1hYS94YSxTYX1mdW5jdGlvbiBwYXJzZUF4aXNQYXJhbSQxKGhhLGFhKXtjb25zdCB4YT1hYS5sZW5ndGg7cmV0dXJuIGhhPWhhPT1udWxsP2FhLm1hcCgoYmEsU2EpPT5TYSk6W10uY29uY2F0KGhhKSxhc3NlcnQkMihoYS5ldmVyeShiYT0+YmE+PS14YSYmYmE8eGEpLCgpPT5gQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW4gcmFuZ2UgWy0ke3hhfSwgJHt4YX0pIGJ1dCBnb3QgYXhpcyAke2hhfWApLGFzc2VydCQyKGhhLmV2ZXJ5KGJhPT5pc0ludCQxKGJhKSksKCk9PmBBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbnRlZ2VycyBidXQgZ290IGF4aXMgJHtoYX1gKSxoYS5tYXAoYmE9PmJhPDA/eGErYmE6YmEpfWZ1bmN0aW9uIHNxdWVlemVTaGFwZSQxKGhhLGFhKXtjb25zdCB4YT1bXSxiYT1bXSxTYT1hYSE9bnVsbCYmQXJyYXkuaXNBcnJheShhYSkmJmFhLmxlbmd0aD09PTAsVGE9YWE9PW51bGx8fFNhP251bGw6cGFyc2VBeGlzUGFyYW0kMShhYSxoYSkuc29ydCgpO2xldCB3YT0wO2ZvcihsZXQgRWE9MDtFYTxoYS5sZW5ndGg7KytFYSl7aWYoVGEhPW51bGwpe2lmKFRhW3dhXT09PUVhJiZoYVtFYV0hPT0xKXRocm93IG5ldyBFcnJvcihgQ2FuJ3Qgc3F1ZWV6ZSBheGlzICR7RWF9IHNpbmNlIGl0cyBkaW0gJyR7aGFbRWFdfScgaXMgbm90IDFgKTsoVGFbd2FdPT1udWxsfHxUYVt3YV0+RWEpJiZoYVtFYV09PT0xJiYoeGEucHVzaChoYVtFYV0pLGJhLnB1c2goRWEpKSxUYVt3YV08PUVhJiZ3YSsrfWhhW0VhXSE9PTEmJih4YS5wdXNoKGhhW0VhXSksYmEucHVzaChFYSkpfXJldHVybntuZXdTaGFwZTp4YSxrZXB0RGltczpiYX19ZnVuY3Rpb24gZ2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKGhhLGFhKXtyZXR1cm4gZ2V0QXJyYXlGcm9tRFR5cGUkMShoYSxhYSl9ZnVuY3Rpb24gZ2V0QXJyYXlGcm9tRFR5cGUkMShoYSxhYSl7bGV0IHhhPW51bGw7aWYoaGE9PW51bGx8fGhhPT09ImZsb2F0MzIiKXhhPW5ldyBGbG9hdDMyQXJyYXkoYWEpO2Vsc2UgaWYoaGE9PT0iaW50MzIiKXhhPW5ldyBJbnQzMkFycmF5KGFhKTtlbHNlIGlmKGhhPT09ImJvb2wiKXhhPW5ldyBVaW50OEFycmF5KGFhKTtlbHNlIGlmKGhhPT09InN0cmluZyIpeGE9bmV3IEFycmF5KGFhKTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhIHR5cGUgJHtoYX1gKTtyZXR1cm4geGF9ZnVuY3Rpb24gY2hlY2tDb252ZXJzaW9uRm9yRXJyb3JzJDEoaGEsYWEpe2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7eGErKyl7Y29uc3QgYmE9aGFbeGFdO2lmKGlzTmFOKGJhKXx8IWlzRmluaXRlKGJhKSl0aHJvdyBFcnJvcihgQSB0ZW5zb3Igb2YgdHlwZSAke2FhfSBiZWluZyB1cGxvYWRlZCBjb250YWlucyAke2JhfS5gKX19ZnVuY3Rpb24gaXNWYWxpZER0eXBlJDEoaGEpe3JldHVybiBoYT09PSJib29sInx8aGE9PT0iY29tcGxleDY0Inx8aGE9PT0iZmxvYXQzMiJ8fGhhPT09ImludDMyInx8aGE9PT0ic3RyaW5nIn1mdW5jdGlvbiBoYXNFbmNvZGluZ0xvc3MkMShoYSxhYSl7cmV0dXJuIShhYT09PSJjb21wbGV4NjQifHxhYT09PSJmbG9hdDMyIiYmaGEhPT0iY29tcGxleDY0Inx8YWE9PT0iaW50MzIiJiZoYSE9PSJmbG9hdDMyIiYmaGEhPT0iY29tcGxleDY0Inx8YWE9PT0iYm9vbCImJmhhPT09ImJvb2wiKX1mdW5jdGlvbiBieXRlc1BlckVsZW1lbnQkMShoYSl7aWYoaGE9PT0iZmxvYXQzMiJ8fGhhPT09ImludDMyIilyZXR1cm4gNDtpZihoYT09PSJjb21wbGV4NjQiKXJldHVybiA4O2lmKGhhPT09ImJvb2wiKXJldHVybiAxO3Rocm93IG5ldyBFcnJvcihgVW5rbm93biBkdHlwZSAke2hhfWApfWZ1bmN0aW9uIGJ5dGVzRnJvbVN0cmluZ0FycmF5JDEoaGEpe2lmKGhhPT1udWxsKXJldHVybiAwO2xldCBhYT0wO3JldHVybiBoYS5mb3JFYWNoKHhhPT5hYSs9eGEubGVuZ3RoKSxhYX1mdW5jdGlvbiBpc1N0cmluZyQxKGhhKXtyZXR1cm4gdHlwZW9mIGhhPT0ic3RyaW5nInx8aGEgaW5zdGFuY2VvZiBTdHJpbmd9ZnVuY3Rpb24gaXNCb29sZWFuJDEoaGEpe3JldHVybiB0eXBlb2YgaGE9PSJib29sZWFuIn1mdW5jdGlvbiBpc051bWJlciQxKGhhKXtyZXR1cm4gdHlwZW9mIGhhPT0ibnVtYmVyIn1mdW5jdGlvbiBpbmZlckR0eXBlJDEoaGEpe3JldHVybiBBcnJheS5pc0FycmF5KGhhKT9pbmZlckR0eXBlJDEoaGFbMF0pOmhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5PyJmbG9hdDMyIjpoYSBpbnN0YW5jZW9mIEludDMyQXJyYXl8fGhhIGluc3RhbmNlb2YgVWludDhBcnJheXx8aGEgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheT8iaW50MzIiOmlzTnVtYmVyJDEoaGEpPyJmbG9hdDMyIjppc1N0cmluZyQxKGhhKT8ic3RyaW5nIjppc0Jvb2xlYW4kMShoYSk/ImJvb2wiOiJmbG9hdDMyIn1mdW5jdGlvbiBpc0Z1bmN0aW9uJDEoaGEpe3JldHVybiEhKGhhJiZoYS5jb25zdHJ1Y3RvciYmaGEuY2FsbCYmaGEuYXBwbHkpfWZ1bmN0aW9uIG5lYXJlc3REaXZpc29yJDEoaGEsYWEpe2ZvcihsZXQgeGE9YWE7eGE8aGE7Kyt4YSlpZihoYSV4YT09PTApcmV0dXJuIHhhO3JldHVybiBoYX1mdW5jdGlvbiBjb21wdXRlU3RyaWRlcyQxKGhhKXtjb25zdCBhYT1oYS5sZW5ndGg7aWYoYWE8MilyZXR1cm5bXTtjb25zdCB4YT1uZXcgQXJyYXkoYWEtMSk7eGFbYWEtMl09aGFbYWEtMV07Zm9yKGxldCBiYT1hYS0zO2JhPj0wOy0tYmEpeGFbYmFdPXhhW2JhKzFdKmhhW2JhKzFdO3JldHVybiB4YX1mdW5jdGlvbiBjcmVhdGVOZXN0ZWRBcnJheSQxKGhhLGFhLHhhLGJhPSExKXtjb25zdCBTYT1uZXcgQXJyYXk7aWYoYWEubGVuZ3RoPT09MSl7Y29uc3QgVGE9YWFbMF0qKGJhPzI6MSk7Zm9yKGxldCB3YT0wO3dhPFRhO3dhKyspU2Fbd2FdPXhhW2hhK3dhXX1lbHNle2NvbnN0IFRhPWFhWzBdLHdhPWFhLnNsaWNlKDEpLEVhPXdhLnJlZHVjZSgoa2EsQWEpPT5rYSpBYSkqKGJhPzI6MSk7Zm9yKGxldCBrYT0wO2thPFRhO2thKyspU2Fba2FdPWNyZWF0ZU5lc3RlZEFycmF5JDEoaGEra2EqRWEsd2EseGEsYmEpfXJldHVybiBTYX1mdW5jdGlvbiB0b05lc3RlZEFycmF5JDEoaGEsYWEseGE9ITEpe2lmKGhhLmxlbmd0aD09PTApcmV0dXJuIGFhWzBdO2NvbnN0IGJhPWhhLnJlZHVjZSgoU2EsVGEpPT5TYSpUYSkqKHhhPzI6MSk7aWYoYmE9PT0wKXJldHVybltdO2lmKGJhIT09YWEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgWyR7aGF9XSBkb2VzIG5vdCBtYXRjaCB0aGUgaW5wdXQgc2l6ZSAke2FhLmxlbmd0aH0ke3hhPyIgZm9yIGEgY29tcGxleCB0ZW5zb3IiOiIifS5gKTtyZXR1cm4gY3JlYXRlTmVzdGVkQXJyYXkkMSgwLGhhLGFhLHhhKX1mdW5jdGlvbiBjb252ZXJ0QmFja2VuZFZhbHVlc0FuZEFycmF5QnVmZmVyKGhhLGFhKXtpZihBcnJheS5pc0FycmF5KGhhKSlyZXR1cm4gaGE7aWYoYWE9PT0iZmxvYXQzMiIpcmV0dXJuIGhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5P2hhOm5ldyBGbG9hdDMyQXJyYXkoaGEpO2lmKGFhPT09ImludDMyIilyZXR1cm4gaGEgaW5zdGFuY2VvZiBJbnQzMkFycmF5P2hhOm5ldyBJbnQzMkFycmF5KGhhKTtpZihhYT09PSJib29sInx8YWE9PT0ic3RyaW5nIilyZXR1cm4gVWludDhBcnJheS5mcm9tKG5ldyBJbnQzMkFycmF5KGhhKSk7dGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGR0eXBlICR7YWF9YCl9ZnVuY3Rpb24gbWFrZU9uZXNUeXBlZEFycmF5JDEoaGEsYWEpe2NvbnN0IHhhPW1ha2VaZXJvc1R5cGVkQXJyYXkkMShoYSxhYSk7Zm9yKGxldCBiYT0wO2JhPHhhLmxlbmd0aDtiYSsrKXhhW2JhXT0xO3JldHVybiB4YX1mdW5jdGlvbiBtYWtlWmVyb3NUeXBlZEFycmF5JDEoaGEsYWEpe2lmKGFhPT1udWxsfHxhYT09PSJmbG9hdDMyInx8YWE9PT0iY29tcGxleDY0IilyZXR1cm4gbmV3IEZsb2F0MzJBcnJheShoYSk7aWYoYWE9PT0iaW50MzIiKXJldHVybiBuZXcgSW50MzJBcnJheShoYSk7aWYoYWE9PT0iYm9vbCIpcmV0dXJuIG5ldyBVaW50OEFycmF5KGhhKTt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YSB0eXBlICR7YWF9YCl9ZnVuY3Rpb24gbWFrZVplcm9zTmVzdGVkVHlwZWRBcnJheShoYSxhYSl7Y29uc3QgeGE9aGEucmVkdWNlKChiYSxTYSk9PmJhKlNhLDEpO2lmKGFhPT1udWxsfHxhYT09PSJmbG9hdDMyIilyZXR1cm4gdG9OZXN0ZWRBcnJheSQxKGhhLG5ldyBGbG9hdDMyQXJyYXkoeGEpKTtpZihhYT09PSJpbnQzMiIpcmV0dXJuIHRvTmVzdGVkQXJyYXkkMShoYSxuZXcgSW50MzJBcnJheSh4YSkpO2lmKGFhPT09ImJvb2wiKXJldHVybiB0b05lc3RlZEFycmF5JDEoaGEsbmV3IFVpbnQ4QXJyYXkoeGEpKTt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YSB0eXBlICR7YWF9YCl9ZnVuY3Rpb24gYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKGhhKXtoYS5mb3JFYWNoKGFhPT57YXNzZXJ0JDIoTnVtYmVyLmlzSW50ZWdlcihhYSkmJmFhPj0wLCgpPT5gVGVuc29yIG11c3QgaGF2ZSBhIHNoYXBlIGNvbXByaXNlZCBvZiBwb3NpdGl2ZSBpbnRlZ2VycyBidXQgZ290IHNoYXBlIFske2hhfV0uYCl9KX1mdW5jdGlvbiBsb2NUb0luZGV4JDEoaGEsYWEseGEpe2lmKGFhPT09MClyZXR1cm4gMDtpZihhYT09PTEpcmV0dXJuIGhhWzBdO2xldCBiYT1oYVtoYS5sZW5ndGgtMV07Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aC0xOysrU2EpYmErPXhhW1NhXSpoYVtTYV07cmV0dXJuIGJhfWZ1bmN0aW9uIGluZGV4VG9Mb2MkMShoYSxhYSx4YSl7aWYoYWE9PT0wKXJldHVybltdO2lmKGFhPT09MSlyZXR1cm5baGFdO2NvbnN0IGJhPW5ldyBBcnJheShhYSk7Zm9yKGxldCBTYT0wO1NhPGJhLmxlbmd0aC0xOysrU2EpYmFbU2FdPU1hdGguZmxvb3IoaGEveGFbU2FdKSxoYS09YmFbU2FdKnhhW1NhXTtyZXR1cm4gYmFbYmEubGVuZ3RoLTFdPWhhLGJhfWZ1bmN0aW9uIGlzUHJvbWlzZSQxKGhhKXtyZXR1cm4gaGEmJmhhLnRoZW4mJnR5cGVvZiBoYS50aGVuPT0iZnVuY3Rpb24ifS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFRFTlNPUkZMT1dKU19GTEFHU19QUkVGSVgkMT0idGZqc2ZsYWdzIjtsZXQgRW52aXJvbm1lbnQkMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy5nbG9iYWw9YWEsdGhpcy5mbGFncz17fSx0aGlzLmZsYWdSZWdpc3RyeT17fSx0aGlzLnVybEZsYWdzPXt9LHRoaXMuZ2V0UXVlcnlQYXJhbXM9Z2V0UXVlcnlQYXJhbXMkMSx0aGlzLnBvcHVsYXRlVVJMRmxhZ3MoKX1zZXRQbGF0Zm9ybShhYSx4YSl7dGhpcy5wbGF0Zm9ybSE9bnVsbCYmKGVudiQxKCkuZ2V0Qm9vbCgiSVNfVEVTVCIpfHxlbnYkMSgpLmdldEJvb2woIlBST0QiKXx8Y29uc29sZS53YXJuKGBQbGF0Zm9ybSAke3RoaXMucGxhdGZvcm1OYW1lfSBoYXMgYWxyZWFkeSBiZWVuIHNldC4gT3ZlcndyaXRpbmcgdGhlIHBsYXRmb3JtIHdpdGggJHthYX0uYCkpLHRoaXMucGxhdGZvcm1OYW1lPWFhLHRoaXMucGxhdGZvcm09eGF9cmVnaXN0ZXJGbGFnKGFhLHhhLGJhKXtpZih0aGlzLmZsYWdSZWdpc3RyeVthYV09e2V2YWx1YXRpb25Gbjp4YSxzZXRIb29rOmJhfSx0aGlzLnVybEZsYWdzW2FhXSE9bnVsbCl7Y29uc3QgU2E9dGhpcy51cmxGbGFnc1thYV07ZW52JDEoKS5nZXRCb29sKCJJU19URVNUIil8fGVudiQxKCkuZ2V0Qm9vbCgiUFJPRCIpfHxjb25zb2xlLndhcm4oYFNldHRpbmcgZmVhdHVyZSBvdmVycmlkZSBmcm9tIFVSTCAke2FhfTogJHtTYX0uYCksdGhpcy5zZXQoYWEsU2EpfX1hc3luYyBnZXRBc3luYyhhYSl7cmV0dXJuIGFhIGluIHRoaXMuZmxhZ3M/dGhpcy5mbGFnc1thYV06KHRoaXMuZmxhZ3NbYWFdPWF3YWl0IHRoaXMuZXZhbHVhdGVGbGFnKGFhKSx0aGlzLmZsYWdzW2FhXSl9Z2V0KGFhKXtpZihhYSBpbiB0aGlzLmZsYWdzKXJldHVybiB0aGlzLmZsYWdzW2FhXTtjb25zdCB4YT10aGlzLmV2YWx1YXRlRmxhZyhhYSk7aWYoaXNQcm9taXNlJDEoeGEpKXRocm93IG5ldyBFcnJvcihgRmxhZyAke2FhfSBjYW5ub3QgYmUgc3luY2hyb25vdXNseSBldmFsdWF0ZWQuIFBsZWFzZSB1c2UgZ2V0QXN5bmMoKSBpbnN0ZWFkLmApO3JldHVybiB0aGlzLmZsYWdzW2FhXT14YSx0aGlzLmZsYWdzW2FhXX1nZXROdW1iZXIoYWEpe3JldHVybiB0aGlzLmdldChhYSl9Z2V0Qm9vbChhYSl7cmV0dXJuIHRoaXMuZ2V0KGFhKX1nZXRTdHJpbmcoYWEpe3JldHVybiB0aGlzLmdldChhYSl9Z2V0RmxhZ3MoKXtyZXR1cm4gdGhpcy5mbGFnc31nZXQgZmVhdHVyZXMoKXtyZXR1cm4gdGhpcy5mbGFnc31zZXQoYWEseGEpe2lmKHRoaXMuZmxhZ1JlZ2lzdHJ5W2FhXT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBzZXQgZmxhZyAke2FhfSBhcyBpdCBoYXMgbm90IGJlZW4gcmVnaXN0ZXJlZC5gKTt0aGlzLmZsYWdzW2FhXT14YSx0aGlzLmZsYWdSZWdpc3RyeVthYV0uc2V0SG9vayE9bnVsbCYmdGhpcy5mbGFnUmVnaXN0cnlbYWFdLnNldEhvb2soeGEpfWV2YWx1YXRlRmxhZyhhYSl7aWYodGhpcy5mbGFnUmVnaXN0cnlbYWFdPT1udWxsKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGV2YWx1YXRlIGZsYWcgJyR7YWF9Jzogbm8gZXZhbHVhdGlvbiBmdW5jdGlvbiBmb3VuZC5gKTtyZXR1cm4gdGhpcy5mbGFnUmVnaXN0cnlbYWFdLmV2YWx1YXRpb25GbigpfXNldEZsYWdzKGFhKXt0aGlzLmZsYWdzPU9iamVjdC5hc3NpZ24oe30sYWEpfXJlc2V0KCl7dGhpcy5mbGFncz17fSx0aGlzLnVybEZsYWdzPXt9LHRoaXMucG9wdWxhdGVVUkxGbGFncygpfXBvcHVsYXRlVVJMRmxhZ3MoKXtpZih0eXBlb2YgdGhpcy5nbG9iYWw+InUifHx0eXBlb2YgdGhpcy5nbG9iYWwubG9jYXRpb24+InUifHx0eXBlb2YgdGhpcy5nbG9iYWwubG9jYXRpb24uc2VhcmNoPiJ1IilyZXR1cm47Y29uc3QgYWE9dGhpcy5nZXRRdWVyeVBhcmFtcyh0aGlzLmdsb2JhbC5sb2NhdGlvbi5zZWFyY2gpO1RFTlNPUkZMT1dKU19GTEFHU19QUkVGSVgkMSBpbiBhYSYmYWFbVEVOU09SRkxPV0pTX0ZMQUdTX1BSRUZJWCQxXS5zcGxpdCgiLCIpLmZvckVhY2goYmE9Pntjb25zdFtTYSxUYV09YmEuc3BsaXQoIjoiKTt0aGlzLnVybEZsYWdzW1NhXT1wYXJzZVZhbHVlJDEoU2EsVGEpfSl9fTtmdW5jdGlvbiBnZXRRdWVyeVBhcmFtcyQxKGhhKXtjb25zdCBhYT17fTtyZXR1cm4gaGEucmVwbGFjZSgvWz8mXShbXj0/Jl0rKSg/Oj0oW14mXSopKT8vZywoeGEsLi4uYmEpPT4oZGVjb2RlUGFyYW0kMShhYSxiYVswXSxiYVsxXSksYmEuam9pbigiPSIpKSksYWF9ZnVuY3Rpb24gZGVjb2RlUGFyYW0kMShoYSxhYSx4YSl7aGFbZGVjb2RlVVJJQ29tcG9uZW50KGFhKV09ZGVjb2RlVVJJQ29tcG9uZW50KHhhfHwiIil9ZnVuY3Rpb24gcGFyc2VWYWx1ZSQxKGhhLGFhKXtjb25zdCB4YT1hYS50b0xvd2VyQ2FzZSgpO3JldHVybiB4YT09PSJ0cnVlInx8eGE9PT0iZmFsc2UiP3hhPT09InRydWUiOmAkeyt4YX1gPT09eGE/K3hhOmFhfWZ1bmN0aW9uIGVudiQxKCl7cmV0dXJuIEVOViQ3fWxldCBFTlYkNz1udWxsO2Z1bmN0aW9uIHNldEVudmlyb25tZW50R2xvYmFsJDEoaGEpe0VOViQ3PWhhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBnbG9iYWxOYW1lU3BhY2UkMTtmdW5jdGlvbiBnZXRHbG9iYWxOYW1lc3BhY2UkMSgpe2lmKGdsb2JhbE5hbWVTcGFjZSQxPT1udWxsKXtsZXQgaGE7aWYodHlwZW9mIHdpbmRvdzwidSIpaGE9d2luZG93O2Vsc2UgaWYodHlwZW9mIGdsb2JhbDwidSIpaGE9Z2xvYmFsO2Vsc2UgaWYodHlwZW9mIHByb2Nlc3M8InUiKWhhPXByb2Nlc3M7ZWxzZSBpZih0eXBlb2Ygc2VsZjwidSIpaGE9c2VsZjtlbHNlIHRocm93IG5ldyBFcnJvcigiQ291bGQgbm90IGZpbmQgYSBnbG9iYWwgb2JqZWN0Iik7Z2xvYmFsTmFtZVNwYWNlJDE9aGF9cmV0dXJuIGdsb2JhbE5hbWVTcGFjZSQxfWZ1bmN0aW9uIGdldEdsb2JhbE1hcCQxKCl7Y29uc3QgaGE9Z2V0R2xvYmFsTmFtZXNwYWNlJDEoKTtyZXR1cm4gaGEuX3RmR2xvYmFscz09bnVsbCYmKGhhLl90Zkdsb2JhbHM9bmV3IE1hcCksaGEuX3RmR2xvYmFsc31mdW5jdGlvbiBnZXRHbG9iYWwkMShoYSxhYSl7Y29uc3QgeGE9Z2V0R2xvYmFsTWFwJDEoKTtpZih4YS5oYXMoaGEpKXJldHVybiB4YS5nZXQoaGEpO3tjb25zdCBiYT1hYSgpO3JldHVybiB4YS5zZXQoaGEsYmEpLHhhLmdldChoYSl9fWNvbnN0IEFicyQxPSJBYnMiLEFjb3MkMT0iQWNvcyIsQWNvc2gkMT0iQWNvc2giLEFkZCQyPSJBZGQiLEFkZE4kMT0iQWRkTiIsQWxsJDE9IkFsbCIsQW55JDE9IkFueSIsQXJnTWF4JDE9IkFyZ01heCIsQXJnTWluJDE9IkFyZ01pbiIsQXNpbiQxPSJBc2luIixBc2luaCQxPSJBc2luaCIsQXRhbiQxPSJBdGFuIixBdGFuaCQxPSJBdGFuaCIsQXRhbjIkMT0iQXRhbjIiLEF2Z1Bvb2wkMT0iQXZnUG9vbCIsQXZnUG9vbEdyYWQkMT0iQXZnUG9vbEdyYWQiLEF2Z1Bvb2wzRCQxPSJBdmdQb29sM0QiLEF2Z1Bvb2wzREdyYWQkMT0iQXZnUG9vbDNER3JhZCIsQmF0Y2hNYXRNdWwkMT0iQmF0Y2hNYXRNdWwiLEJhdGNoVG9TcGFjZU5EJDE9IkJhdGNoVG9TcGFjZU5EIixCaW5jb3VudCQxPSJCaW5jb3VudCIsQml0d2lzZUFuZCQxPSJCaXR3aXNlQW5kIixCcm9hZGNhc3RUbz0iQnJvYWRjYXN0VG8iLEJyb2FkY2FzdEFyZ3MkMT0iQnJvYWRjYXN0QXJncyIsQ2FzdCQxPSJDYXN0IixDZWlsJDE9IkNlaWwiLENsaXBCeVZhbHVlJDE9IkNsaXBCeVZhbHVlIixDb21wbGV4JDE9IkNvbXBsZXgiLENvbXBsZXhBYnMkMT0iQ29tcGxleEFicyIsQ29uY2F0JDE9IkNvbmNhdCIsQ29udjJEJDI9IkNvbnYyRCIsQ29udjJEQmFja3Byb3BGaWx0ZXIkMT0iQ29udjJEQmFja3Byb3BGaWx0ZXIiLENvbnYyREJhY2twcm9wSW5wdXQkMT0iQ29udjJEQmFja3Byb3BJbnB1dCIsQ29udjNEJDI9IkNvbnYzRCIsQ29udjNEQmFja3Byb3BGaWx0ZXJWMiQxPSJDb252M0RCYWNrcHJvcEZpbHRlclYyIixDb252M0RCYWNrcHJvcElucHV0VjIkMT0iQ29udjNEQmFja3Byb3BJbnB1dFYyIixDb3MkMT0iQ29zIixDb3NoJDE9IkNvc2giLEN1bXByb2QkMT0iQ3VtcHJvZCIsQ3Vtc3VtJDE9IkN1bXN1bSIsQ3JvcEFuZFJlc2l6ZSQxPSJDcm9wQW5kUmVzaXplIixEZW5zZUJpbmNvdW50JDE9IkRlbnNlQmluY291bnQiLERlcHRoVG9TcGFjZSQxPSJEZXB0aFRvU3BhY2UiLERlcHRod2lzZUNvbnYyZE5hdGl2ZSQxPSJEZXB0aHdpc2VDb252MmROYXRpdmUiLERlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDE9IkRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyIixEZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcElucHV0JDE9IkRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQiLERpYWckMT0iRGlhZyIsRGlsYXRpb24yRCQxPSJEaWxhdGlvbjJEIixEaWxhdGlvbjJEQmFja3Byb3BJbnB1dD0iRGlsYXRpb24yREJhY2twcm9wSW5wdXQiLERpbGF0aW9uMkRCYWNrcHJvcEZpbHRlcj0iRGlsYXRpb24yREJhY2twcm9wRmlsdGVyIixEcmF3PSJEcmF3IixSZWFsRGl2JDE9IlJlYWxEaXYiLEVpbnN1bSQxPSJFaW5zdW0iLEVsdSQyPSJFbHUiLEVsdUdyYWQkMT0iRWx1R3JhZCIsRXJmJDE9IkVyZiIsRXF1YWwkMT0iRXF1YWwiLEV4cCQxPSJFeHAiLEV4cGFuZERpbXMkMT0iRXhwYW5kRGltcyIsRXhwbTEkMT0iRXhwbTEiLEZGVCQxPSJGRlQiLEZpbGwkMT0iRmlsbCIsRmxpcExlZnRSaWdodCQxPSJGbGlwTGVmdFJpZ2h0IixGbG9vciQxPSJGbG9vciIsRmxvb3JEaXYkMT0iRmxvb3JEaXYiLEZ1c2VkQmF0Y2hOb3JtJDE9IkZ1c2VkQmF0Y2hOb3JtIixHYXRoZXJWMiQxPSJHYXRoZXJWMiIsR2F0aGVyTmQkMT0iR2F0aGVyTmQiLEdyZWF0ZXIkMT0iR3JlYXRlciIsR3JlYXRlckVxdWFsJDE9IkdyZWF0ZXJFcXVhbCIsSWRlbnRpdHkkMj0iSWRlbnRpdHkiLElGRlQkMT0iSUZGVCIsSW1hZyQxPSJJbWFnIixJc0Zpbml0ZSQxPSJJc0Zpbml0ZSIsSXNJbmYkMT0iSXNJbmYiLElzTmFuJDE9IklzTmFuIixMZWFreVJlbHUkMT0iTGVha3lSZWx1IixMZXNzJDE9Ikxlc3MiLExlc3NFcXVhbCQxPSJMZXNzRXF1YWwiLExpblNwYWNlJDE9IkxpblNwYWNlIixMb2ckMT0iTG9nIixMb2cxcCQxPSJMb2cxcCIsTG9naWNhbEFuZCQxPSJMb2dpY2FsQW5kIixMb2dpY2FsTm90JDE9IkxvZ2ljYWxOb3QiLExvZ2ljYWxPciQxPSJMb2dpY2FsT3IiLExvZ1NvZnRtYXgkMT0iTG9nU29mdG1heCIsTFJOJDE9IkxSTiIsTFJOR3JhZCQxPSJMUk5HcmFkIixNYXgkMT0iTWF4IixNYXhpbXVtJDI9Ik1heGltdW0iLE1heFBvb2wkMT0iTWF4UG9vbCIsTWF4UG9vbEdyYWQkMT0iTWF4UG9vbEdyYWQiLE1heFBvb2wzRCQxPSJNYXhQb29sM0QiLE1heFBvb2wzREdyYWQkMT0iTWF4UG9vbDNER3JhZCIsTWF4UG9vbFdpdGhBcmdtYXgkMT0iTWF4UG9vbFdpdGhBcmdtYXgiLE1lYW4kMT0iTWVhbiIsTWluJDE9Ik1pbiIsTWluaW11bSQyPSJNaW5pbXVtIixNaXJyb3JQYWQkMT0iTWlycm9yUGFkIixNb2QkMT0iTW9kIixNdWx0aW5vbWlhbCQxPSJNdWx0aW5vbWlhbCIsTXVsdGlwbHkkMj0iTXVsdGlwbHkiLE5lZyQxPSJOZWciLE5vdEVxdWFsJDE9Ik5vdEVxdWFsIixOb25NYXhTdXBwcmVzc2lvblYzJDE9Ik5vbk1heFN1cHByZXNzaW9uVjMiLE5vbk1heFN1cHByZXNzaW9uVjQkMT0iTm9uTWF4U3VwcHJlc3Npb25WNCIsTm9uTWF4U3VwcHJlc3Npb25WNSQxPSJOb25NYXhTdXBwcmVzc2lvblY1IixPbmVzTGlrZSQxPSJPbmVzTGlrZSIsT25lSG90JDE9Ik9uZUhvdCIsUGFjayQxPSJQYWNrIixQYWRWMiQxPSJQYWRWMiIsUG93JDE9IlBvdyIsUHJlbHUkMT0iUHJlbHUiLFByb2QkMT0iUHJvZCIsUmFnZ2VkR2F0aGVyJDE9IlJhZ2dlZEdhdGhlciIsUmFnZ2VkUmFuZ2UkMT0iUmFnZ2VkUmFuZ2UiLFJhZ2dlZFRlbnNvclRvVGVuc29yJDE9IlJhZ2dlZFRlbnNvclRvVGVuc29yIixSYW5nZSQxPSJSYW5nZSIsUmVhbCQxPSJSZWFsIixSZWNpcHJvY2FsJDE9IlJlY2lwcm9jYWwiLFJlbHUkMj0iUmVsdSIsUmVzaGFwZSQyPSJSZXNoYXBlIixSZXNpemVOZWFyZXN0TmVpZ2hib3IkMT0iUmVzaXplTmVhcmVzdE5laWdoYm9yIixSZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkJDE9IlJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWQiLFJlc2l6ZUJpbGluZWFyJDE9IlJlc2l6ZUJpbGluZWFyIixSZXNpemVCaWxpbmVhckdyYWQkMT0iUmVzaXplQmlsaW5lYXJHcmFkIixSZWx1NiQyPSJSZWx1NiIsUmV2ZXJzZSQxPSJSZXZlcnNlIixSb3VuZCQxPSJSb3VuZCIsUnNxcnQkMT0iUnNxcnQiLFNjYXR0ZXJOZCQxPSJTY2F0dGVyTmQiLFRlbnNvclNjYXR0ZXJVcGRhdGUkMT0iVGVuc29yU2NhdHRlclVwZGF0ZSIsU2VhcmNoU29ydGVkJDE9IlNlYXJjaFNvcnRlZCIsU2VsZWN0JDE9IlNlbGVjdCIsU2VsdSQyPSJTZWx1IixTbGljZSQxPSJTbGljZSIsU2luJDE9IlNpbiIsU2luaCQxPSJTaW5oIixTaWduJDE9IlNpZ24iLFNpZ21vaWQkMj0iU2lnbW9pZCIsU29mdHBsdXMkMj0iU29mdHBsdXMiLFNxcnQkMT0iU3FydCIsU3VtJDE9IlN1bSIsU3BhY2VUb0JhdGNoTkQkMT0iU3BhY2VUb0JhdGNoTkQiLFNwbGl0ViQxPSJTcGxpdFYiLFNvZnRtYXgkMz0iU29mdG1heCIsU3BhcnNlRmlsbEVtcHR5Um93cyQxPSJTcGFyc2VGaWxsRW1wdHlSb3dzIixTcGFyc2VSZXNoYXBlJDE9IlNwYXJzZVJlc2hhcGUiLFNwYXJzZVNlZ21lbnRNZWFuJDE9IlNwYXJzZVNlZ21lbnRNZWFuIixTcGFyc2VTZWdtZW50U3VtJDE9IlNwYXJzZVNlZ21lbnRTdW0iLFNwYXJzZVRvRGVuc2UkMT0iU3BhcnNlVG9EZW5zZSIsU3F1YXJlZERpZmZlcmVuY2UkMT0iU3F1YXJlZERpZmZlcmVuY2UiLFNxdWFyZSQxPSJTcXVhcmUiLFN0YXRpY1JlZ2V4UmVwbGFjZSQxPSJTdGF0aWNSZWdleFJlcGxhY2UiLFN0cmlkZWRTbGljZSQxPSJTdHJpZGVkU2xpY2UiLFN0cmluZ05HcmFtcyQxPSJTdHJpbmdOR3JhbXMiLFN0cmluZ1NwbGl0JDE9IlN0cmluZ1NwbGl0IixTdHJpbmdUb0hhc2hCdWNrZXRGYXN0JDE9IlN0cmluZ1RvSGFzaEJ1Y2tldEZhc3QiLFN1YiQxPSJTdWIiLFRhbiQxPSJUYW4iLFRhbmgkMj0iVGFuaCIsVGlsZSQxPSJUaWxlIixUb3BLJDE9IlRvcEsiLFRyYW5zZm9ybSQxPSJUcmFuc2Zvcm0iLFRyYW5zcG9zZSQxPSJUcmFuc3Bvc2UiLFVuaXF1ZSQxPSJVbmlxdWUiLFVucGFjayQxPSJVbnBhY2siLFVuc29ydGVkU2VnbWVudFN1bSQxPSJVbnNvcnRlZFNlZ21lbnRTdW0iLFplcm9zTGlrZSQxPSJaZXJvc0xpa2UiLFN0ZXAkMT0iU3RlcCIsRnJvbVBpeGVscyQxPSJGcm9tUGl4ZWxzIixSb3RhdGVXaXRoT2Zmc2V0JDE9IlJvdGF0ZVdpdGhPZmZzZXQiLF9GdXNlZE1hdE11bCQxPSJfRnVzZWRNYXRNdWwiLEZ1c2VkQ29udjJEJDE9IkZ1c2VkQ29udjJEIixGdXNlZERlcHRod2lzZUNvbnYyRCQxPSJGdXNlZERlcHRod2lzZUNvbnYyRCI7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gd2FybiQxKC4uLmhhKXtlbnYkMSgpLmdldEJvb2woIklTX1RFU1QiKXx8ZW52JDEoKS5nZXRCb29sKCJQUk9EIil8fGNvbnNvbGUud2FybiguLi5oYSl9ZnVuY3Rpb24gbG9nJDUoLi4uaGEpe2VudiQxKCkuZ2V0Qm9vbCgiSVNfVEVTVCIpfHxlbnYkMSgpLmdldEJvb2woIlBST0QiKXx8Y29uc29sZS5sb2coLi4uaGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGtlcm5lbFJlZ2lzdHJ5JDE9Z2V0R2xvYmFsJDEoImtlcm5lbFJlZ2lzdHJ5IiwoKT0+bmV3IE1hcCksZ3JhZFJlZ2lzdHJ5JDE9Z2V0R2xvYmFsJDEoImdyYWRSZWdpc3RyeSIsKCk9Pm5ldyBNYXApO2Z1bmN0aW9uIGdldEtlcm5lbCQxKGhhLGFhKXtjb25zdCB4YT1tYWtlS2V5JDEoaGEsYWEpO3JldHVybiBrZXJuZWxSZWdpc3RyeSQxLmdldCh4YSl9ZnVuY3Rpb24gZ2V0R3JhZGllbnQkMShoYSl7cmV0dXJuIGdyYWRSZWdpc3RyeSQxLmdldChoYSl9ZnVuY3Rpb24gZ2V0S2VybmVsc0ZvckJhY2tlbmQkMShoYSl7Y29uc3QgYWE9a2VybmVsUmVnaXN0cnkkMS5lbnRyaWVzKCkseGE9W107Zm9yKDs7KXtjb25zdHtkb25lOmJhLHZhbHVlOlNhfT1hYS5uZXh0KCk7aWYoYmEpYnJlYWs7Y29uc3RbVGEsd2FdPVNhLFtFYV09VGEuc3BsaXQoIl8iKTtFYT09PWhhJiZ4YS5wdXNoKHdhKX1yZXR1cm4geGF9ZnVuY3Rpb24gcmVnaXN0ZXJLZXJuZWwkMShoYSl7Y29uc3R7a2VybmVsTmFtZTphYSxiYWNrZW5kTmFtZTp4YX09aGEsYmE9bWFrZUtleSQxKGFhLHhhKTtrZXJuZWxSZWdpc3RyeSQxLmhhcyhiYSkmJndhcm4kMShgVGhlIGtlcm5lbCAnJHthYX0nIGZvciBiYWNrZW5kICcke3hhfScgaXMgYWxyZWFkeSByZWdpc3RlcmVkYCksa2VybmVsUmVnaXN0cnkkMS5zZXQoYmEsaGEpfWZ1bmN0aW9uIHJlZ2lzdGVyR3JhZGllbnQoaGEpe2NvbnN0e2tlcm5lbE5hbWU6YWF9PWhhO2dyYWRSZWdpc3RyeSQxLmhhcyhhYSkmJmVudiQxKCkuZ2V0Qm9vbCgiREVCVUciKSYmd2FybiQxKGBPdmVycmlkaW5nIHRoZSBncmFkaWVudCBmb3IgJyR7YWF9J2ApLGdyYWRSZWdpc3RyeSQxLnNldChhYSxoYSl9ZnVuY3Rpb24gbWFrZUtleSQxKGhhLGFhKXtyZXR1cm5gJHthYX1fJHtoYX1gfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlzVHlwZWRBcnJheUJyb3dzZXIkMShoYSl7cmV0dXJuIGhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5fHxoYSBpbnN0YW5jZW9mIEludDMyQXJyYXl8fGhhIGluc3RhbmNlb2YgVWludDhBcnJheXx8aGEgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheX12YXIgY29tbW9uanNHbG9iYWw9dHlwZW9mIGdsb2JhbFRoaXM8InUiP2dsb2JhbFRoaXM6dHlwZW9mIHdpbmRvdzwidSI/d2luZG93OnR5cGVvZiBnbG9iYWw8InUiP2dsb2JhbDp0eXBlb2Ygc2VsZjwidSI/c2VsZjp7fTtmdW5jdGlvbiBnZXREZWZhdWx0RXhwb3J0RnJvbUNqcyhoYSl7cmV0dXJuIGhhJiZoYS5fX2VzTW9kdWxlJiZPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaGEsImRlZmF1bHQiKT9oYS5kZWZhdWx0OmhhfWZ1bmN0aW9uIGdldEF1Z21lbnRlZE5hbWVzcGFjZShoYSl7aWYoaGEuX19lc01vZHVsZSlyZXR1cm4gaGE7dmFyIGFhPWhhLmRlZmF1bHQ7aWYodHlwZW9mIGFhPT0iZnVuY3Rpb24iKXt2YXIgeGE9ZnVuY3Rpb24gYmEoKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIGJhP1JlZmxlY3QuY29uc3RydWN0KGFhLGFyZ3VtZW50cyx0aGlzLmNvbnN0cnVjdG9yKTphYS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9O3hhLnByb3RvdHlwZT1hYS5wcm90b3R5cGV9ZWxzZSB4YT17fTtyZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHhhLCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KSxPYmplY3Qua2V5cyhoYSkuZm9yRWFjaChmdW5jdGlvbihiYSl7dmFyIFNhPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaGEsYmEpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh4YSxiYSxTYS5nZXQ/U2E6e2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIGhhW2JhXX19KX0pLHhhfXZhciBsb25nPUxvbmckMix3YXNtPW51bGw7dHJ5e3dhc209bmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobmV3IFVpbnQ4QXJyYXkoWzAsOTcsMTE1LDEwOSwxLDAsMCwwLDEsMTMsMiw5NiwwLDEsMTI3LDk2LDQsMTI3LDEyNywxMjcsMTI3LDEsMTI3LDMsNyw2LDAsMSwxLDEsMSwxLDYsNiwxLDEyNywxLDY1LDAsMTEsNyw1MCw2LDMsMTA5LDExNywxMDgsMCwxLDUsMTAwLDEwNSwxMTgsOTUsMTE1LDAsMiw1LDEwMCwxMDUsMTE4LDk1LDExNywwLDMsNSwxMTQsMTAxLDEwOSw5NSwxMTUsMCw0LDUsMTE0LDEwMSwxMDksOTUsMTE3LDAsNSw4LDEwMywxMDEsMTE2LDk1LDEwNCwxMDUsMTAzLDEwNCwwLDAsMTAsMTkxLDEsNiw0LDAsMzUsMCwxMSwzNiwxLDEsMTI2LDMyLDAsMTczLDMyLDEsMTczLDY2LDMyLDEzNCwxMzIsMzIsMiwxNzMsMzIsMywxNzMsNjYsMzIsMTM0LDEzMiwxMjYsMzQsNCw2NiwzMiwxMzUsMTY3LDM2LDAsMzIsNCwxNjcsMTEsMzYsMSwxLDEyNiwzMiwwLDE3MywzMiwxLDE3Myw2NiwzMiwxMzQsMTMyLDMyLDIsMTczLDMyLDMsMTczLDY2LDMyLDEzNCwxMzIsMTI3LDM0LDQsNjYsMzIsMTM1LDE2NywzNiwwLDMyLDQsMTY3LDExLDM2LDEsMSwxMjYsMzIsMCwxNzMsMzIsMSwxNzMsNjYsMzIsMTM0LDEzMiwzMiwyLDE3MywzMiwzLDE3Myw2NiwzMiwxMzQsMTMyLDEyOCwzNCw0LDY2LDMyLDEzNSwxNjcsMzYsMCwzMiw0LDE2NywxMSwzNiwxLDEsMTI2LDMyLDAsMTczLDMyLDEsMTczLDY2LDMyLDEzNCwxMzIsMzIsMiwxNzMsMzIsMywxNzMsNjYsMzIsMTM0LDEzMiwxMjksMzQsNCw2NiwzMiwxMzUsMTY3LDM2LDAsMzIsNCwxNjcsMTEsMzYsMSwxLDEyNiwzMiwwLDE3MywzMiwxLDE3Myw2NiwzMiwxMzQsMTMyLDMyLDIsMTczLDMyLDMsMTczLDY2LDMyLDEzNCwxMzIsMTMwLDM0LDQsNjYsMzIsMTM1LDE2NywzNiwwLDMyLDQsMTY3LDExXSkpLHt9KS5leHBvcnRzfWNhdGNoKGhhKXt9ZnVuY3Rpb24gTG9uZyQyKGhhLGFhLHhhKXt0aGlzLmxvdz1oYXwwLHRoaXMuaGlnaD1hYXwwLHRoaXMudW5zaWduZWQ9ISF4YX1Mb25nJDIucHJvdG90eXBlLl9faXNMb25nX18sT2JqZWN0LmRlZmluZVByb3BlcnR5KExvbmckMi5wcm90b3R5cGUsIl9faXNMb25nX18iLHt2YWx1ZTohMH0pO2Z1bmN0aW9uIGlzTG9uZyhoYSl7cmV0dXJuKGhhJiZoYS5fX2lzTG9uZ19fKT09PSEwfUxvbmckMi5pc0xvbmc9aXNMb25nO3ZhciBJTlRfQ0FDSEU9e30sVUlOVF9DQUNIRT17fTtmdW5jdGlvbiBmcm9tSW50KGhhLGFhKXt2YXIgeGEsYmEsU2E7cmV0dXJuIGFhPyhoYT4+Pj0wLChTYT0wPD1oYSYmaGE8MjU2KSYmKGJhPVVJTlRfQ0FDSEVbaGFdLGJhKT9iYTooeGE9ZnJvbUJpdHMoaGEsKGhhfDApPDA/LTE6MCwhMCksU2EmJihVSU5UX0NBQ0hFW2hhXT14YSkseGEpKTooaGF8PTAsKFNhPS0xMjg8PWhhJiZoYTwxMjgpJiYoYmE9SU5UX0NBQ0hFW2hhXSxiYSk/YmE6KHhhPWZyb21CaXRzKGhhLGhhPDA/LTE6MCwhMSksU2EmJihJTlRfQ0FDSEVbaGFdPXhhKSx4YSkpfUxvbmckMi5mcm9tSW50PWZyb21JbnQ7ZnVuY3Rpb24gZnJvbU51bWJlcihoYSxhYSl7aWYoaXNOYU4oaGEpKXJldHVybiBhYT9VWkVSTzpaRVJPO2lmKGFhKXtpZihoYTwwKXJldHVybiBVWkVSTztpZihoYT49VFdPX1BXUl82NF9EQkwpcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRX1lbHNle2lmKGhhPD0tVFdPX1BXUl82M19EQkwpcmV0dXJuIE1JTl9WQUxVRTtpZihoYSsxPj1UV09fUFdSXzYzX0RCTClyZXR1cm4gTUFYX1ZBTFVFfXJldHVybiBoYTwwP2Zyb21OdW1iZXIoLWhhLGFhKS5uZWcoKTpmcm9tQml0cyhoYSVUV09fUFdSXzMyX0RCTHwwLGhhL1RXT19QV1JfMzJfREJMfDAsYWEpfUxvbmckMi5mcm9tTnVtYmVyPWZyb21OdW1iZXI7ZnVuY3Rpb24gZnJvbUJpdHMoaGEsYWEseGEpe3JldHVybiBuZXcgTG9uZyQyKGhhLGFhLHhhKX1Mb25nJDIuZnJvbUJpdHM9ZnJvbUJpdHM7dmFyIHBvd19kYmw9TWF0aC5wb3c7ZnVuY3Rpb24gZnJvbVN0cmluZyhoYSxhYSx4YSl7aWYoaGEubGVuZ3RoPT09MCl0aHJvdyBFcnJvcigiZW1wdHkgc3RyaW5nIik7aWYoaGE9PT0iTmFOInx8aGE9PT0iSW5maW5pdHkifHxoYT09PSIrSW5maW5pdHkifHxoYT09PSItSW5maW5pdHkiKXJldHVybiBaRVJPO2lmKHR5cGVvZiBhYT09Im51bWJlciI/KHhhPWFhLGFhPSExKTphYT0hIWFhLHhhPXhhfHwxMCx4YTwyfHwzNjx4YSl0aHJvdyBSYW5nZUVycm9yKCJyYWRpeCIpO3ZhciBiYTtpZigoYmE9aGEuaW5kZXhPZigiLSIpKT4wKXRocm93IEVycm9yKCJpbnRlcmlvciBoeXBoZW4iKTtpZihiYT09PTApcmV0dXJuIGZyb21TdHJpbmcoaGEuc3Vic3RyaW5nKDEpLGFhLHhhKS5uZWcoKTtmb3IodmFyIFNhPWZyb21OdW1iZXIocG93X2RibCh4YSw4KSksVGE9WkVSTyx3YT0wO3dhPGhhLmxlbmd0aDt3YSs9OCl7dmFyIEVhPU1hdGgubWluKDgsaGEubGVuZ3RoLXdhKSxrYT1wYXJzZUludChoYS5zdWJzdHJpbmcod2Esd2ErRWEpLHhhKTtpZihFYTw4KXt2YXIgQWE9ZnJvbU51bWJlcihwb3dfZGJsKHhhLEVhKSk7VGE9VGEubXVsKEFhKS5hZGQoZnJvbU51bWJlcihrYSkpfWVsc2UgVGE9VGEubXVsKFNhKSxUYT1UYS5hZGQoZnJvbU51bWJlcihrYSkpfXJldHVybiBUYS51bnNpZ25lZD1hYSxUYX1Mb25nJDIuZnJvbVN0cmluZz1mcm9tU3RyaW5nO2Z1bmN0aW9uIGZyb21WYWx1ZShoYSxhYSl7cmV0dXJuIHR5cGVvZiBoYT09Im51bWJlciI/ZnJvbU51bWJlcihoYSxhYSk6dHlwZW9mIGhhPT0ic3RyaW5nIj9mcm9tU3RyaW5nKGhhLGFhKTpmcm9tQml0cyhoYS5sb3csaGEuaGlnaCx0eXBlb2YgYWE9PSJib29sZWFuIj9hYTpoYS51bnNpZ25lZCl9TG9uZyQyLmZyb21WYWx1ZT1mcm9tVmFsdWU7dmFyIFRXT19QV1JfMTZfREJMPTY1NTM2LFRXT19QV1JfMjRfREJMPTE8PDI0LFRXT19QV1JfMzJfREJMPVRXT19QV1JfMTZfREJMKlRXT19QV1JfMTZfREJMLFRXT19QV1JfNjRfREJMPVRXT19QV1JfMzJfREJMKlRXT19QV1JfMzJfREJMLFRXT19QV1JfNjNfREJMPVRXT19QV1JfNjRfREJMLzIsVFdPX1BXUl8yND1mcm9tSW50KFRXT19QV1JfMjRfREJMKSxaRVJPPWZyb21JbnQoMCk7TG9uZyQyLlpFUk89WkVSTzt2YXIgVVpFUk89ZnJvbUludCgwLCEwKTtMb25nJDIuVVpFUk89VVpFUk87dmFyIE9ORT1mcm9tSW50KDEpO0xvbmckMi5PTkU9T05FO3ZhciBVT05FPWZyb21JbnQoMSwhMCk7TG9uZyQyLlVPTkU9VU9ORTt2YXIgTkVHX09ORT1mcm9tSW50KC0xKTtMb25nJDIuTkVHX09ORT1ORUdfT05FO3ZhciBNQVhfVkFMVUU9ZnJvbUJpdHMoLTEsMjE0NzQ4MzY0NywhMSk7TG9uZyQyLk1BWF9WQUxVRT1NQVhfVkFMVUU7dmFyIE1BWF9VTlNJR05FRF9WQUxVRT1mcm9tQml0cygtMSwtMSwhMCk7TG9uZyQyLk1BWF9VTlNJR05FRF9WQUxVRT1NQVhfVU5TSUdORURfVkFMVUU7dmFyIE1JTl9WQUxVRT1mcm9tQml0cygwLC0yMTQ3NDgzNjQ4LCExKTtMb25nJDIuTUlOX1ZBTFVFPU1JTl9WQUxVRTt2YXIgTG9uZ1Byb3RvdHlwZT1Mb25nJDIucHJvdG90eXBlO0xvbmdQcm90b3R5cGUudG9JbnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51bnNpZ25lZD90aGlzLmxvdz4+PjA6dGhpcy5sb3d9LExvbmdQcm90b3R5cGUudG9OdW1iZXI9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51bnNpZ25lZD8odGhpcy5oaWdoPj4+MCkqVFdPX1BXUl8zMl9EQkwrKHRoaXMubG93Pj4+MCk6dGhpcy5oaWdoKlRXT19QV1JfMzJfREJMKyh0aGlzLmxvdz4+PjApfSxMb25nUHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKGFhKXtpZihhYT1hYXx8MTAsYWE8Mnx8MzY8YWEpdGhyb3cgUmFuZ2VFcnJvcigicmFkaXgiKTtpZih0aGlzLmlzWmVybygpKXJldHVybiIwIjtpZih0aGlzLmlzTmVnYXRpdmUoKSlpZih0aGlzLmVxKE1JTl9WQUxVRSkpe3ZhciB4YT1mcm9tTnVtYmVyKGFhKSxiYT10aGlzLmRpdih4YSksU2E9YmEubXVsKHhhKS5zdWIodGhpcyk7cmV0dXJuIGJhLnRvU3RyaW5nKGFhKStTYS50b0ludCgpLnRvU3RyaW5nKGFhKX1lbHNlIHJldHVybiItIit0aGlzLm5lZygpLnRvU3RyaW5nKGFhKTtmb3IodmFyIFRhPWZyb21OdW1iZXIocG93X2RibChhYSw2KSx0aGlzLnVuc2lnbmVkKSx3YT10aGlzLEVhPSIiOzspe3ZhciBrYT13YS5kaXYoVGEpLEFhPXdhLnN1YihrYS5tdWwoVGEpKS50b0ludCgpPj4+MCxGYT1BYS50b1N0cmluZyhhYSk7aWYod2E9a2Esd2EuaXNaZXJvKCkpcmV0dXJuIEZhK0VhO2Zvcig7RmEubGVuZ3RoPDY7KUZhPSIwIitGYTtFYT0iIitGYStFYX19LExvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oaWdofSxMb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzVW5zaWduZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oaWdoPj4+MH0sTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubG93fSxMb25nUHJvdG90eXBlLmdldExvd0JpdHNVbnNpZ25lZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmxvdz4+PjB9LExvbmdQcm90b3R5cGUuZ2V0TnVtQml0c0Ficz1mdW5jdGlvbigpe2lmKHRoaXMuaXNOZWdhdGl2ZSgpKXJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSk/NjQ6dGhpcy5uZWcoKS5nZXROdW1CaXRzQWJzKCk7Zm9yKHZhciBhYT10aGlzLmhpZ2ghPTA/dGhpcy5oaWdoOnRoaXMubG93LHhhPTMxO3hhPjAmJiEoYWEmMTw8eGEpO3hhLS0pO3JldHVybiB0aGlzLmhpZ2ghPTA/eGErMzM6eGErMX0sTG9uZ1Byb3RvdHlwZS5pc1plcm89ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oaWdoPT09MCYmdGhpcy5sb3c9PT0wfSxMb25nUHJvdG90eXBlLmVxej1Mb25nUHJvdG90eXBlLmlzWmVybyxMb25nUHJvdG90eXBlLmlzTmVnYXRpdmU9ZnVuY3Rpb24oKXtyZXR1cm4hdGhpcy51bnNpZ25lZCYmdGhpcy5oaWdoPDB9LExvbmdQcm90b3R5cGUuaXNQb3NpdGl2ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnVuc2lnbmVkfHx0aGlzLmhpZ2g+PTB9LExvbmdQcm90b3R5cGUuaXNPZGQ9ZnVuY3Rpb24oKXtyZXR1cm4odGhpcy5sb3cmMSk9PT0xfSxMb25nUHJvdG90eXBlLmlzRXZlbj1mdW5jdGlvbigpe3JldHVybih0aGlzLmxvdyYxKT09PTB9LExvbmdQcm90b3R5cGUuZXF1YWxzPWZ1bmN0aW9uKGFhKXtyZXR1cm4gaXNMb25nKGFhKXx8KGFhPWZyb21WYWx1ZShhYSkpLHRoaXMudW5zaWduZWQhPT1hYS51bnNpZ25lZCYmdGhpcy5oaWdoPj4+MzE9PT0xJiZhYS5oaWdoPj4+MzE9PT0xPyExOnRoaXMuaGlnaD09PWFhLmhpZ2gmJnRoaXMubG93PT09YWEubG93fSxMb25nUHJvdG90eXBlLmVxPUxvbmdQcm90b3R5cGUuZXF1YWxzLExvbmdQcm90b3R5cGUubm90RXF1YWxzPWZ1bmN0aW9uKGFhKXtyZXR1cm4hdGhpcy5lcShhYSl9LExvbmdQcm90b3R5cGUubmVxPUxvbmdQcm90b3R5cGUubm90RXF1YWxzLExvbmdQcm90b3R5cGUubmU9TG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHMsTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbj1mdW5jdGlvbihhYSl7cmV0dXJuIHRoaXMuY29tcChhYSk8MH0sTG9uZ1Byb3RvdHlwZS5sdD1Mb25nUHJvdG90eXBlLmxlc3NUaGFuLExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsPWZ1bmN0aW9uKGFhKXtyZXR1cm4gdGhpcy5jb21wKGFhKTw9MH0sTG9uZ1Byb3RvdHlwZS5sdGU9TG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwsTG9uZ1Byb3RvdHlwZS5sZT1Mb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbCxMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuPWZ1bmN0aW9uKGFhKXtyZXR1cm4gdGhpcy5jb21wKGFhKT4wfSxMb25nUHJvdG90eXBlLmd0PUxvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW4sTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw9ZnVuY3Rpb24oYWEpe3JldHVybiB0aGlzLmNvbXAoYWEpPj0wfSxMb25nUHJvdG90eXBlLmd0ZT1Mb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbCxMb25nUHJvdG90eXBlLmdlPUxvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsLExvbmdQcm90b3R5cGUuY29tcGFyZT1mdW5jdGlvbihhYSl7aWYoaXNMb25nKGFhKXx8KGFhPWZyb21WYWx1ZShhYSkpLHRoaXMuZXEoYWEpKXJldHVybiAwO3ZhciB4YT10aGlzLmlzTmVnYXRpdmUoKSxiYT1hYS5pc05lZ2F0aXZlKCk7cmV0dXJuIHhhJiYhYmE/LTE6IXhhJiZiYT8xOnRoaXMudW5zaWduZWQ/YWEuaGlnaD4+PjA+dGhpcy5oaWdoPj4+MHx8YWEuaGlnaD09PXRoaXMuaGlnaCYmYWEubG93Pj4+MD50aGlzLmxvdz4+PjA/LTE6MTp0aGlzLnN1YihhYSkuaXNOZWdhdGl2ZSgpPy0xOjF9LExvbmdQcm90b3R5cGUuY29tcD1Mb25nUHJvdG90eXBlLmNvbXBhcmUsTG9uZ1Byb3RvdHlwZS5uZWdhdGU9ZnVuY3Rpb24oKXtyZXR1cm4hdGhpcy51bnNpZ25lZCYmdGhpcy5lcShNSU5fVkFMVUUpP01JTl9WQUxVRTp0aGlzLm5vdCgpLmFkZChPTkUpfSxMb25nUHJvdG90eXBlLm5lZz1Mb25nUHJvdG90eXBlLm5lZ2F0ZSxMb25nUHJvdG90eXBlLmFkZD1mdW5jdGlvbihhYSl7aXNMb25nKGFhKXx8KGFhPWZyb21WYWx1ZShhYSkpO3ZhciB4YT10aGlzLmhpZ2g+Pj4xNixiYT10aGlzLmhpZ2gmNjU1MzUsU2E9dGhpcy5sb3c+Pj4xNixUYT10aGlzLmxvdyY2NTUzNSx3YT1hYS5oaWdoPj4+MTYsRWE9YWEuaGlnaCY2NTUzNSxrYT1hYS5sb3c+Pj4xNixBYT1hYS5sb3cmNjU1MzUsRmE9MCxMYT0wLGVsPTAsdGw9MDtyZXR1cm4gdGwrPVRhK0FhLGVsKz10bD4+PjE2LHRsJj02NTUzNSxlbCs9U2Era2EsTGErPWVsPj4+MTYsZWwmPTY1NTM1LExhKz1iYStFYSxGYSs9TGE+Pj4xNixMYSY9NjU1MzUsRmErPXhhK3dhLEZhJj02NTUzNSxmcm9tQml0cyhlbDw8MTZ8dGwsRmE8PDE2fExhLHRoaXMudW5zaWduZWQpfSxMb25nUHJvdG90eXBlLnN1YnRyYWN0PWZ1bmN0aW9uKGFhKXtyZXR1cm4gaXNMb25nKGFhKXx8KGFhPWZyb21WYWx1ZShhYSkpLHRoaXMuYWRkKGFhLm5lZygpKX0sTG9uZ1Byb3RvdHlwZS5zdWI9TG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdCxMb25nUHJvdG90eXBlLm11bHRpcGx5PWZ1bmN0aW9uKGFhKXtpZih0aGlzLmlzWmVybygpKXJldHVybiBaRVJPO2lmKGlzTG9uZyhhYSl8fChhYT1mcm9tVmFsdWUoYWEpKSx3YXNtKXt2YXIgeGE9d2FzbS5tdWwodGhpcy5sb3csdGhpcy5oaWdoLGFhLmxvdyxhYS5oaWdoKTtyZXR1cm4gZnJvbUJpdHMoeGEsd2FzbS5nZXRfaGlnaCgpLHRoaXMudW5zaWduZWQpfWlmKGFhLmlzWmVybygpKXJldHVybiBaRVJPO2lmKHRoaXMuZXEoTUlOX1ZBTFVFKSlyZXR1cm4gYWEuaXNPZGQoKT9NSU5fVkFMVUU6WkVSTztpZihhYS5lcShNSU5fVkFMVUUpKXJldHVybiB0aGlzLmlzT2RkKCk/TUlOX1ZBTFVFOlpFUk87aWYodGhpcy5pc05lZ2F0aXZlKCkpcmV0dXJuIGFhLmlzTmVnYXRpdmUoKT90aGlzLm5lZygpLm11bChhYS5uZWcoKSk6dGhpcy5uZWcoKS5tdWwoYWEpLm5lZygpO2lmKGFhLmlzTmVnYXRpdmUoKSlyZXR1cm4gdGhpcy5tdWwoYWEubmVnKCkpLm5lZygpO2lmKHRoaXMubHQoVFdPX1BXUl8yNCkmJmFhLmx0KFRXT19QV1JfMjQpKXJldHVybiBmcm9tTnVtYmVyKHRoaXMudG9OdW1iZXIoKSphYS50b051bWJlcigpLHRoaXMudW5zaWduZWQpO3ZhciBiYT10aGlzLmhpZ2g+Pj4xNixTYT10aGlzLmhpZ2gmNjU1MzUsVGE9dGhpcy5sb3c+Pj4xNix3YT10aGlzLmxvdyY2NTUzNSxFYT1hYS5oaWdoPj4+MTYsa2E9YWEuaGlnaCY2NTUzNSxBYT1hYS5sb3c+Pj4xNixGYT1hYS5sb3cmNjU1MzUsTGE9MCxlbD0wLHRsPTAsbmw9MDtyZXR1cm4gbmwrPXdhKkZhLHRsKz1ubD4+PjE2LG5sJj02NTUzNSx0bCs9VGEqRmEsZWwrPXRsPj4+MTYsdGwmPTY1NTM1LHRsKz13YSpBYSxlbCs9dGw+Pj4xNix0bCY9NjU1MzUsZWwrPVNhKkZhLExhKz1lbD4+PjE2LGVsJj02NTUzNSxlbCs9VGEqQWEsTGErPWVsPj4+MTYsZWwmPTY1NTM1LGVsKz13YSprYSxMYSs9ZWw+Pj4xNixlbCY9NjU1MzUsTGErPWJhKkZhK1NhKkFhK1RhKmthK3dhKkVhLExhJj02NTUzNSxmcm9tQml0cyh0bDw8MTZ8bmwsTGE8PDE2fGVsLHRoaXMudW5zaWduZWQpfSxMb25nUHJvdG90eXBlLm11bD1Mb25nUHJvdG90eXBlLm11bHRpcGx5LExvbmdQcm90b3R5cGUuZGl2aWRlPWZ1bmN0aW9uKGFhKXtpZihpc0xvbmcoYWEpfHwoYWE9ZnJvbVZhbHVlKGFhKSksYWEuaXNaZXJvKCkpdGhyb3cgRXJyb3IoImRpdmlzaW9uIGJ5IHplcm8iKTtpZih3YXNtKXtpZighdGhpcy51bnNpZ25lZCYmdGhpcy5oaWdoPT09LTIxNDc0ODM2NDgmJmFhLmxvdz09PS0xJiZhYS5oaWdoPT09LTEpcmV0dXJuIHRoaXM7dmFyIHhhPSh0aGlzLnVuc2lnbmVkP3dhc20uZGl2X3U6d2FzbS5kaXZfcykodGhpcy5sb3csdGhpcy5oaWdoLGFhLmxvdyxhYS5oaWdoKTtyZXR1cm4gZnJvbUJpdHMoeGEsd2FzbS5nZXRfaGlnaCgpLHRoaXMudW5zaWduZWQpfWlmKHRoaXMuaXNaZXJvKCkpcmV0dXJuIHRoaXMudW5zaWduZWQ/VVpFUk86WkVSTzt2YXIgYmEsU2EsVGE7aWYodGhpcy51bnNpZ25lZCl7aWYoYWEudW5zaWduZWR8fChhYT1hYS50b1Vuc2lnbmVkKCkpLGFhLmd0KHRoaXMpKXJldHVybiBVWkVSTztpZihhYS5ndCh0aGlzLnNocnUoMSkpKXJldHVybiBVT05FO1RhPVVaRVJPfWVsc2V7aWYodGhpcy5lcShNSU5fVkFMVUUpKXtpZihhYS5lcShPTkUpfHxhYS5lcShORUdfT05FKSlyZXR1cm4gTUlOX1ZBTFVFO2lmKGFhLmVxKE1JTl9WQUxVRSkpcmV0dXJuIE9ORTt2YXIgd2E9dGhpcy5zaHIoMSk7cmV0dXJuIGJhPXdhLmRpdihhYSkuc2hsKDEpLGJhLmVxKFpFUk8pP2FhLmlzTmVnYXRpdmUoKT9PTkU6TkVHX09ORTooU2E9dGhpcy5zdWIoYWEubXVsKGJhKSksVGE9YmEuYWRkKFNhLmRpdihhYSkpLFRhKX1lbHNlIGlmKGFhLmVxKE1JTl9WQUxVRSkpcmV0dXJuIHRoaXMudW5zaWduZWQ/VVpFUk86WkVSTztpZih0aGlzLmlzTmVnYXRpdmUoKSlyZXR1cm4gYWEuaXNOZWdhdGl2ZSgpP3RoaXMubmVnKCkuZGl2KGFhLm5lZygpKTp0aGlzLm5lZygpLmRpdihhYSkubmVnKCk7aWYoYWEuaXNOZWdhdGl2ZSgpKXJldHVybiB0aGlzLmRpdihhYS5uZWcoKSkubmVnKCk7VGE9WkVST31mb3IoU2E9dGhpcztTYS5ndGUoYWEpOyl7YmE9TWF0aC5tYXgoMSxNYXRoLmZsb29yKFNhLnRvTnVtYmVyKCkvYWEudG9OdW1iZXIoKSkpO2Zvcih2YXIgRWE9TWF0aC5jZWlsKE1hdGgubG9nKGJhKS9NYXRoLkxOMiksa2E9RWE8PTQ4PzE6cG93X2RibCgyLEVhLTQ4KSxBYT1mcm9tTnVtYmVyKGJhKSxGYT1BYS5tdWwoYWEpO0ZhLmlzTmVnYXRpdmUoKXx8RmEuZ3QoU2EpOyliYS09a2EsQWE9ZnJvbU51bWJlcihiYSx0aGlzLnVuc2lnbmVkKSxGYT1BYS5tdWwoYWEpO0FhLmlzWmVybygpJiYoQWE9T05FKSxUYT1UYS5hZGQoQWEpLFNhPVNhLnN1YihGYSl9cmV0dXJuIFRhfSxMb25nUHJvdG90eXBlLmRpdj1Mb25nUHJvdG90eXBlLmRpdmlkZSxMb25nUHJvdG90eXBlLm1vZHVsbz1mdW5jdGlvbihhYSl7aWYoaXNMb25nKGFhKXx8KGFhPWZyb21WYWx1ZShhYSkpLHdhc20pe3ZhciB4YT0odGhpcy51bnNpZ25lZD93YXNtLnJlbV91Ondhc20ucmVtX3MpKHRoaXMubG93LHRoaXMuaGlnaCxhYS5sb3csYWEuaGlnaCk7cmV0dXJuIGZyb21CaXRzKHhhLHdhc20uZ2V0X2hpZ2goKSx0aGlzLnVuc2lnbmVkKX1yZXR1cm4gdGhpcy5zdWIodGhpcy5kaXYoYWEpLm11bChhYSkpfSxMb25nUHJvdG90eXBlLm1vZD1Mb25nUHJvdG90eXBlLm1vZHVsbyxMb25nUHJvdG90eXBlLnJlbT1Mb25nUHJvdG90eXBlLm1vZHVsbyxMb25nUHJvdG90eXBlLm5vdD1mdW5jdGlvbigpe3JldHVybiBmcm9tQml0cyh+dGhpcy5sb3csfnRoaXMuaGlnaCx0aGlzLnVuc2lnbmVkKX0sTG9uZ1Byb3RvdHlwZS5hbmQ9ZnVuY3Rpb24oYWEpe3JldHVybiBpc0xvbmcoYWEpfHwoYWE9ZnJvbVZhbHVlKGFhKSksZnJvbUJpdHModGhpcy5sb3cmYWEubG93LHRoaXMuaGlnaCZhYS5oaWdoLHRoaXMudW5zaWduZWQpfSxMb25nUHJvdG90eXBlLm9yPWZ1bmN0aW9uKGFhKXtyZXR1cm4gaXNMb25nKGFhKXx8KGFhPWZyb21WYWx1ZShhYSkpLGZyb21CaXRzKHRoaXMubG93fGFhLmxvdyx0aGlzLmhpZ2h8YWEuaGlnaCx0aGlzLnVuc2lnbmVkKX0sTG9uZ1Byb3RvdHlwZS54b3I9ZnVuY3Rpb24oYWEpe3JldHVybiBpc0xvbmcoYWEpfHwoYWE9ZnJvbVZhbHVlKGFhKSksZnJvbUJpdHModGhpcy5sb3deYWEubG93LHRoaXMuaGlnaF5hYS5oaWdoLHRoaXMudW5zaWduZWQpfSxMb25nUHJvdG90eXBlLnNoaWZ0TGVmdD1mdW5jdGlvbihhYSl7cmV0dXJuIGlzTG9uZyhhYSkmJihhYT1hYS50b0ludCgpKSwoYWEmPTYzKT09PTA/dGhpczphYTwzMj9mcm9tQml0cyh0aGlzLmxvdzw8YWEsdGhpcy5oaWdoPDxhYXx0aGlzLmxvdz4+PjMyLWFhLHRoaXMudW5zaWduZWQpOmZyb21CaXRzKDAsdGhpcy5sb3c8PGFhLTMyLHRoaXMudW5zaWduZWQpfSxMb25nUHJvdG90eXBlLnNobD1Mb25nUHJvdG90eXBlLnNoaWZ0TGVmdCxMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQ9ZnVuY3Rpb24oYWEpe3JldHVybiBpc0xvbmcoYWEpJiYoYWE9YWEudG9JbnQoKSksKGFhJj02Myk9PT0wP3RoaXM6YWE8MzI/ZnJvbUJpdHModGhpcy5sb3c+Pj5hYXx0aGlzLmhpZ2g8PDMyLWFhLHRoaXMuaGlnaD4+YWEsdGhpcy51bnNpZ25lZCk6ZnJvbUJpdHModGhpcy5oaWdoPj5hYS0zMix0aGlzLmhpZ2g+PTA/MDotMSx0aGlzLnVuc2lnbmVkKX0sTG9uZ1Byb3RvdHlwZS5zaHI9TG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0LExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkPWZ1bmN0aW9uKGFhKXtpZihpc0xvbmcoYWEpJiYoYWE9YWEudG9JbnQoKSksYWEmPTYzLGFhPT09MClyZXR1cm4gdGhpczt2YXIgeGE9dGhpcy5oaWdoO2lmKGFhPDMyKXt2YXIgYmE9dGhpcy5sb3c7cmV0dXJuIGZyb21CaXRzKGJhPj4+YWF8eGE8PDMyLWFhLHhhPj4+YWEsdGhpcy51bnNpZ25lZCl9ZWxzZSByZXR1cm4gYWE9PT0zMj9mcm9tQml0cyh4YSwwLHRoaXMudW5zaWduZWQpOmZyb21CaXRzKHhhPj4+YWEtMzIsMCx0aGlzLnVuc2lnbmVkKX0sTG9uZ1Byb3RvdHlwZS5zaHJ1PUxvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkLExvbmdQcm90b3R5cGUuc2hyX3U9TG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQsTG9uZ1Byb3RvdHlwZS50b1NpZ25lZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnVuc2lnbmVkP2Zyb21CaXRzKHRoaXMubG93LHRoaXMuaGlnaCwhMSk6dGhpc30sTG9uZ1Byb3RvdHlwZS50b1Vuc2lnbmVkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudW5zaWduZWQ/dGhpczpmcm9tQml0cyh0aGlzLmxvdyx0aGlzLmhpZ2gsITApfSxMb25nUHJvdG90eXBlLnRvQnl0ZXM9ZnVuY3Rpb24oYWEpe3JldHVybiBhYT90aGlzLnRvQnl0ZXNMRSgpOnRoaXMudG9CeXRlc0JFKCl9LExvbmdQcm90b3R5cGUudG9CeXRlc0xFPWZ1bmN0aW9uKCl7dmFyIGFhPXRoaXMuaGlnaCx4YT10aGlzLmxvdztyZXR1cm5beGEmMjU1LHhhPj4+OCYyNTUseGE+Pj4xNiYyNTUseGE+Pj4yNCxhYSYyNTUsYWE+Pj44JjI1NSxhYT4+PjE2JjI1NSxhYT4+PjI0XX0sTG9uZ1Byb3RvdHlwZS50b0J5dGVzQkU9ZnVuY3Rpb24oKXt2YXIgYWE9dGhpcy5oaWdoLHhhPXRoaXMubG93O3JldHVyblthYT4+PjI0LGFhPj4+MTYmMjU1LGFhPj4+OCYyNTUsYWEmMjU1LHhhPj4+MjQseGE+Pj4xNiYyNTUseGE+Pj44JjI1NSx4YSYyNTVdfSxMb25nJDIuZnJvbUJ5dGVzPWZ1bmN0aW9uKGFhLHhhLGJhKXtyZXR1cm4gYmE/TG9uZyQyLmZyb21CeXRlc0xFKGFhLHhhKTpMb25nJDIuZnJvbUJ5dGVzQkUoYWEseGEpfSxMb25nJDIuZnJvbUJ5dGVzTEU9ZnVuY3Rpb24oYWEseGEpe3JldHVybiBuZXcgTG9uZyQyKGFhWzBdfGFhWzFdPDw4fGFhWzJdPDwxNnxhYVszXTw8MjQsYWFbNF18YWFbNV08PDh8YWFbNl08PDE2fGFhWzddPDwyNCx4YSl9LExvbmckMi5mcm9tQnl0ZXNCRT1mdW5jdGlvbihhYSx4YSl7cmV0dXJuIG5ldyBMb25nJDIoYWFbNF08PDI0fGFhWzVdPDwxNnxhYVs2XTw8OHxhYVs3XSxhYVswXTw8MjR8YWFbMV08PDE2fGFhWzJdPDw4fGFhWzNdLHhhKX07dmFyIGxvbmckMT1nZXREZWZhdWx0RXhwb3J0RnJvbUNqcyhsb25nKSxMb25nRXhwb3J0cz1fbWVyZ2VOYW1lc3BhY2VzKHtfX3Byb3RvX186bnVsbCxkZWZhdWx0OmxvbmckMX0sW2xvbmddKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMb25nJDE9bG9uZyQxfHxMb25nRXhwb3J0cztmdW5jdGlvbiBoZXhUb0xvbmckMShoYSl7cmV0dXJuIExvbmckMS5mcm9tU3RyaW5nKGhhLCEwLDE2KX1jb25zdCBrMCQxPWhleFRvTG9uZyQxKCJjM2E1Yzg1Yzk3Y2IzMTI3IiksazEkMT1oZXhUb0xvbmckMSgiYjQ5MmI2NmZiZTk4ZjI3MyIpLGsyJDE9aGV4VG9Mb25nJDEoIjlhZTE2YTNiMmY5MDQwNGYiKTtmdW5jdGlvbiBzaGlmdE1peCQxKGhhKXtyZXR1cm4gaGEueG9yKGhhLnNocnUoNDcpKX1mdW5jdGlvbiBmZXRjaCQyKGhhLGFhLHhhKXtjb25zdCBiYT1oYS5zbGljZShhYSxhYSt4YSk7cmV0dXJuIExvbmckMS5mcm9tQnl0ZXMoQXJyYXkuZnJvbShiYSksITAsITApfWZ1bmN0aW9uIGZldGNoNjQkMShoYSxhYSl7cmV0dXJuIGZldGNoJDIoaGEsYWEsOCl9ZnVuY3Rpb24gZmV0Y2gzMiQxKGhhLGFhKXtyZXR1cm4gZmV0Y2gkMihoYSxhYSw0KX1mdW5jdGlvbiByb3RhdGU2NCQxKGhhLGFhKXtyZXR1cm4gYWE9PT0wP2hhOmhhLnNocnUoYWEpLm9yKGhhLnNobCg2NC1hYSkpfWZ1bmN0aW9uIGhhc2hMZW4xNiQxKGhhLGFhLHhhPWhleFRvTG9uZyQxKCI5ZGRmZWEwOGViMzgyZDY5Iikpe2xldCBiYT1oYS54b3IoYWEpLm11bCh4YSk7YmE9YmEueG9yKGJhLnNocnUoNDcpKTtsZXQgU2E9YWEueG9yKGJhKS5tdWwoeGEpO3JldHVybiBTYT1TYS54b3IoU2Euc2hydSg0NykpLFNhPVNhLm11bCh4YSksU2F9ZnVuY3Rpb24gd2Vha0hhc2hMZW4zMldpdGhTZWVkcyQxKGhhLGFhLHhhLGJhLFNhLFRhKXtTYT1TYS5hZGQoaGEpLFRhPXJvdGF0ZTY0JDEoVGEuYWRkKFNhKS5hZGQoYmEpLDIxKTtjb25zdCB3YT1TYTtyZXR1cm4gU2E9U2EuYWRkKGFhKSxTYT1TYS5hZGQoeGEpLFRhPVRhLmFkZChyb3RhdGU2NCQxKFNhLDQ0KSksW1NhLmFkZChiYSksVGEuYWRkKHdhKV19ZnVuY3Rpb24gd2Vha0hhc2hMZW4zMldpdGhTZWVkc1N0ciQxKGhhLGFhLHhhLGJhKXtyZXR1cm4gd2Vha0hhc2hMZW4zMldpdGhTZWVkcyQxKGZldGNoNjQkMShoYSxhYSksZmV0Y2g2NCQxKGhhLGFhKzgpLGZldGNoNjQkMShoYSxhYSsxNiksZmV0Y2g2NCQxKGhhLGFhKzI0KSx4YSxiYSl9ZnVuY3Rpb24gaGFzaExlbjB0bzE2JDEoaGEsYWE9aGEubGVuZ3RoKXtpZihhYT49OCl7Y29uc3QgeGE9azIkMS5hZGQoYWEqMiksYmE9ZmV0Y2g2NCQxKGhhLDApLmFkZChrMiQxKSxTYT1mZXRjaDY0JDEoaGEsYWEtOCksVGE9cm90YXRlNjQkMShTYSwzNykubXVsKHhhKS5hZGQoYmEpLHdhPXJvdGF0ZTY0JDEoYmEsMjUpLmFkZChTYSkubXVsKHhhKTtyZXR1cm4gaGFzaExlbjE2JDEoVGEsd2EseGEpfWlmKGFhPj00KXtjb25zdCB4YT1rMiQxLmFkZChhYSoyKSxiYT1mZXRjaDMyJDEoaGEsMCk7cmV0dXJuIGhhc2hMZW4xNiQxKGJhLnNobCgzKS5hZGQoYWEpLGZldGNoMzIkMShoYSxhYS00KSx4YSl9aWYoYWE+MCl7Y29uc3QgeGE9aGFbMF0sYmE9aGFbYWE+PjFdLFNhPWhhW2FhLTFdLFRhPXhhKyhiYTw8OCksd2E9YWErKFNhPDwyKTtyZXR1cm4gc2hpZnRNaXgkMShrMiQxLm11bChUYSkueG9yKGswJDEubXVsKHdhKSkpLm11bChrMiQxKX1yZXR1cm4gazIkMX1mdW5jdGlvbiBoYXNoTGVuMTd0bzMyJDEoaGEsYWE9aGEubGVuZ3RoKXtjb25zdCB4YT1rMiQxLmFkZChhYSoyKSxiYT1mZXRjaDY0JDEoaGEsMCkubXVsKGsxJDEpLFNhPWZldGNoNjQkMShoYSw4KSxUYT1mZXRjaDY0JDEoaGEsYWEtOCkubXVsKHhhKSx3YT1mZXRjaDY0JDEoaGEsYWEtMTYpLm11bChrMiQxKTtyZXR1cm4gaGFzaExlbjE2JDEocm90YXRlNjQkMShiYS5hZGQoU2EpLDQzKS5hZGQocm90YXRlNjQkMShUYSwzMCkpLmFkZCh3YSksYmEuYWRkKHJvdGF0ZTY0JDEoU2EuYWRkKGsyJDEpLDE4KSkuYWRkKFRhKSx4YSl9ZnVuY3Rpb24gaGFzaExlbjMzdG82NCQxKGhhLGFhPWhhLmxlbmd0aCl7Y29uc3QgeGE9azIkMS5hZGQoYWEqMiksYmE9ZmV0Y2g2NCQxKGhhLDApLm11bChrMiQxKSxTYT1mZXRjaDY0JDEoaGEsOCksVGE9ZmV0Y2g2NCQxKGhhLGFhLTgpLm11bCh4YSksd2E9ZmV0Y2g2NCQxKGhhLGFhLTE2KS5tdWwoazIkMSksRWE9cm90YXRlNjQkMShiYS5hZGQoU2EpLDQzKS5hZGQocm90YXRlNjQkMShUYSwzMCkpLmFkZCh3YSksa2E9aGFzaExlbjE2JDEoRWEsYmEuYWRkKHJvdGF0ZTY0JDEoU2EuYWRkKGsyJDEpLDE4KSkuYWRkKFRhKSx4YSksQWE9ZmV0Y2g2NCQxKGhhLDE2KS5tdWwoeGEpLEZhPWZldGNoNjQkMShoYSwyNCksTGE9RWEuYWRkKGZldGNoNjQkMShoYSxhYS0zMikpLm11bCh4YSksZWw9a2EuYWRkKGZldGNoNjQkMShoYSxhYS0yNCkpLm11bCh4YSk7cmV0dXJuIGhhc2hMZW4xNiQxKHJvdGF0ZTY0JDEoQWEuYWRkKEZhKSw0MykuYWRkKHJvdGF0ZTY0JDEoTGEsMzApKS5hZGQoZWwpLEFhLmFkZChyb3RhdGU2NCQxKEZhLmFkZChiYSksMTgpKS5hZGQoTGEpLHhhKX1mdW5jdGlvbiBmaW5nZXJQcmludDY0JDEoaGEsYWE9aGEubGVuZ3RoKXtjb25zdCB4YT1Mb25nJDEuZnJvbU51bWJlcig4MSwhMCk7aWYoYWE8PTMyKXJldHVybiBhYTw9MTY/aGFzaExlbjB0bzE2JDEoaGEsYWEpOmhhc2hMZW4xN3RvMzIkMShoYSxhYSk7aWYoYWE8PTY0KXJldHVybiBoYXNoTGVuMzN0bzY0JDEoaGEsYWEpO2xldCBiYT14YSxTYT14YS5tdWwoazEkMSkuYWRkKDExMyksVGE9c2hpZnRNaXgkMShTYS5tdWwoazIkMSkuYWRkKDExMykpLm11bChrMiQxKSx3YT1bTG9uZyQxLlVaRVJPLExvbmckMS5VWkVST10sRWE9W0xvbmckMS5VWkVSTyxMb25nJDEuVVpFUk9dO2JhPWJhLm11bChrMiQxKS5hZGQoZmV0Y2g2NCQxKGhhLDApKTtsZXQga2E9MDtjb25zdCBBYT0oYWEtMT4+NikqNjQsRmE9QWErKGFhLTEmNjMpLTYzO2RvIGJhPXJvdGF0ZTY0JDEoYmEuYWRkKFNhKS5hZGQod2FbMF0pLmFkZChmZXRjaDY0JDEoaGEsa2ErOCkpLDM3KS5tdWwoazEkMSksU2E9cm90YXRlNjQkMShTYS5hZGQod2FbMV0pLmFkZChmZXRjaDY0JDEoaGEsa2ErNDgpKSw0MikubXVsKGsxJDEpLGJhPWJhLnhvcihFYVsxXSksU2E9U2EuYWRkKHdhWzBdKS5hZGQoZmV0Y2g2NCQxKGhhLGthKzQwKSksVGE9cm90YXRlNjQkMShUYS5hZGQoRWFbMF0pLDMzKS5tdWwoazEkMSksd2E9d2Vha0hhc2hMZW4zMldpdGhTZWVkc1N0ciQxKGhhLGthLHdhWzFdLm11bChrMSQxKSxiYS5hZGQoRWFbMF0pKSxFYT13ZWFrSGFzaExlbjMyV2l0aFNlZWRzU3RyJDEoaGEsa2ErMzIsVGEuYWRkKEVhWzFdKSxTYS5hZGQoZmV0Y2g2NCQxKGhhLGthKzE2KSkpLFtUYSxiYV09W2JhLFRhXSxrYSs9NjQ7d2hpbGUoa2EhPT1BYSk7Y29uc3QgTGE9azEkMS5hZGQoVGEuYW5kKDI1NSkuc2hsKDEpKTtyZXR1cm4ga2E9RmEsRWFbMF09RWFbMF0uYWRkKGFhLTEmNjMpLHdhWzBdPXdhWzBdLmFkZChFYVswXSksRWFbMF09RWFbMF0uYWRkKHdhWzBdKSxiYT1yb3RhdGU2NCQxKGJhLmFkZChTYSkuYWRkKHdhWzBdKS5hZGQoZmV0Y2g2NCQxKGhhLGthKzgpKSwzNykubXVsKExhKSxTYT1yb3RhdGU2NCQxKFNhLmFkZCh3YVsxXSkuYWRkKGZldGNoNjQkMShoYSxrYSs0OCkpLDQyKS5tdWwoTGEpLGJhPWJhLnhvcihFYVsxXS5tdWwoOSkpLFNhPVNhLmFkZCh3YVswXS5tdWwoOSkuYWRkKGZldGNoNjQkMShoYSxrYSs0MCkpKSxUYT1yb3RhdGU2NCQxKFRhLmFkZChFYVswXSksMzMpLm11bChMYSksd2E9d2Vha0hhc2hMZW4zMldpdGhTZWVkc1N0ciQxKGhhLGthLHdhWzFdLm11bChMYSksYmEuYWRkKEVhWzBdKSksRWE9d2Vha0hhc2hMZW4zMldpdGhTZWVkc1N0ciQxKGhhLGthKzMyLFRhLmFkZChFYVsxXSksU2EuYWRkKGZldGNoNjQkMShoYSxrYSsxNikpKSxbVGEsYmFdPVtiYSxUYV0saGFzaExlbjE2JDEoaGFzaExlbjE2JDEod2FbMF0sRWFbMF0sTGEpLmFkZChzaGlmdE1peCQxKFNhKS5tdWwoazAkMSkpLmFkZChUYSksaGFzaExlbjE2JDEod2FbMV0sRWFbMV0sTGEpLmFkZChiYSksTGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNyZWF0ZVNjYWxhclZhbHVlJDEoaGEsYWEpe3JldHVybiBhYT09PSJzdHJpbmciP2VuY29kZVN0cmluZyQxKGhhKTp0b1R5cGVkQXJyYXkkMShbaGFdLGFhKX1mdW5jdGlvbiBub0NvbnZlcnNpb25OZWVkZWQkMShoYSxhYSl7cmV0dXJuIGhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5JiZhYT09PSJmbG9hdDMyInx8aGEgaW5zdGFuY2VvZiBJbnQzMkFycmF5JiZhYT09PSJpbnQzMiJ8fGhhIGluc3RhbmNlb2YgVWludDhBcnJheSYmYWE9PT0iYm9vbCJ9ZnVuY3Rpb24gdG9UeXBlZEFycmF5JDEoaGEsYWEpe2lmKGFhPT09InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgY29udmVydCBhIHN0cmluZ1tdIHRvIGEgVHlwZWRBcnJheSIpO2lmKEFycmF5LmlzQXJyYXkoaGEpJiYoaGE9ZmxhdHRlbiQyKGhhKSksZW52JDEoKS5nZXRCb29sKCJERUJVRyIpJiZjaGVja0NvbnZlcnNpb25Gb3JFcnJvcnMkMShoYSxhYSksbm9Db252ZXJzaW9uTmVlZGVkJDEoaGEsYWEpKXJldHVybiBoYTtpZihhYT09bnVsbHx8YWE9PT0iZmxvYXQzMiJ8fGFhPT09ImNvbXBsZXg2NCIpcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoaGEpO2lmKGFhPT09ImludDMyIilyZXR1cm4gbmV3IEludDMyQXJyYXkoaGEpO2lmKGFhPT09ImJvb2wiKXtjb25zdCB4YT1uZXcgVWludDhBcnJheShoYS5sZW5ndGgpO2ZvcihsZXQgYmE9MDtiYTx4YS5sZW5ndGg7KytiYSlNYXRoLnJvdW5kKGhhW2JhXSkhPT0wJiYoeGFbYmFdPTEpO3JldHVybiB4YX1lbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhIHR5cGUgJHthYX1gKX1mdW5jdGlvbiBub3ckMSgpe3JldHVybiBlbnYkMSgpLnBsYXRmb3JtLm5vdygpfWZ1bmN0aW9uIGVuY29kZVN0cmluZyQxKGhhLGFhPSJ1dGYtOCIpe3JldHVybiBhYT1hYXx8InV0Zi04IixlbnYkMSgpLnBsYXRmb3JtLmVuY29kZShoYSxhYSl9ZnVuY3Rpb24gZGVjb2RlU3RyaW5nJDEoaGEsYWE9InV0Zi04Iil7cmV0dXJuIGFhPWFhfHwidXRmLTgiLGVudiQxKCkucGxhdGZvcm0uZGVjb2RlKGhhLGFhKX1mdW5jdGlvbiBpc1R5cGVkQXJyYXkkMShoYSl7cmV0dXJuIGVudiQxKCkucGxhdGZvcm0uaXNUeXBlZEFycmF5IT1udWxsP2VudiQxKCkucGxhdGZvcm0uaXNUeXBlZEFycmF5KGhhKTppc1R5cGVkQXJyYXlCcm93c2VyJDEoaGEpfWZ1bmN0aW9uIGZsYXR0ZW4kMihoYSxhYT1bXSx4YT0hMSl7aWYoYWE9PW51bGwmJihhYT1bXSksdHlwZW9mIGhhPT0iYm9vbGVhbiJ8fHR5cGVvZiBoYT09Im51bWJlciJ8fHR5cGVvZiBoYT09InN0cmluZyJ8fGlzUHJvbWlzZSQxKGhhKXx8aGE9PW51bGx8fGlzVHlwZWRBcnJheSQxKGhhKSYmeGEpYWEucHVzaChoYSk7ZWxzZSBpZihBcnJheS5pc0FycmF5KGhhKXx8aXNUeXBlZEFycmF5JDEoaGEpKWZvcihsZXQgYmE9MDtiYTxoYS5sZW5ndGg7KytiYSlmbGF0dGVuJDIoaGFbYmFdLGFhLHhhKTtlbHNle2xldCBiYT0tMTtmb3IoY29uc3QgU2Egb2YgT2JqZWN0LmtleXMoaGEpKS9eKFsxLTldK1swLTldKnwwKSQvLnRlc3QoU2EpJiYoYmE9TWF0aC5tYXgoYmEsTnVtYmVyKFNhKSkpO2ZvcihsZXQgU2E9MDtTYTw9YmE7U2ErKylmbGF0dGVuJDIoaGFbU2FdLGFhLHhhKX1yZXR1cm4gYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFByb2ZpbGVyJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMuYmFja2VuZFRpbWVyPWFhLHRoaXMubG9nZ2VyPXhhLHhhPT1udWxsJiYodGhpcy5sb2dnZXI9bmV3IExvZ2dlciQxKX1wcm9maWxlS2VybmVsKGFhLHhhLGJhKXtsZXQgU2E7Y29uc3QgVGE9KCk9PntTYT1iYSgpfTtsZXQgd2E7Y29uc3QgRWE9bm93JDEoKTtpZih0aGlzLmJhY2tlbmRUaW1lci50aW1lckF2YWlsYWJsZSgpKXdhPXRoaXMuYmFja2VuZFRpbWVyLnRpbWUoVGEpO2Vsc2V7VGEoKTtmb3IoY29uc3QgQWEgb2YgU2EpQWEuZGF0YVN5bmMoKTt3YT1Qcm9taXNlLnJlc29sdmUoe2tlcm5lbE1zOm5vdyQxKCktRWF9KX1pZihlbnYkMSgpLmdldEJvb2woIkNIRUNLX0NPTVBVVEFUSU9OX0ZPUl9FUlJPUlMiKSlmb3IobGV0IEFhPTA7QWE8U2EubGVuZ3RoO0FhKyspe2NvbnN0IEZhPVNhW0FhXTtGYS5kYXRhKCkudGhlbihMYT0+e2NoZWNrQ29tcHV0YXRpb25Gb3JFcnJvcnMkMShMYSxGYS5kdHlwZSxhYSl9KX1yZXR1cm57a2VybmVsTmFtZTphYSxvdXRwdXRzOlNhLGlucHV0czp4YSx0aW1lTXM6d2EudGhlbihBYT0+QWEua2VybmVsTXMpLGV4dHJhSW5mbzp3YS50aGVuKEFhPT5BYS5nZXRFeHRyYVByb2ZpbGVJbmZvIT1udWxsP0FhLmdldEV4dHJhUHJvZmlsZUluZm8oKToiIil9fWxvZ0tlcm5lbFByb2ZpbGUoYWEpe2NvbnN0e2tlcm5lbE5hbWU6eGEsb3V0cHV0czpiYSx0aW1lTXM6U2EsaW5wdXRzOlRhLGV4dHJhSW5mbzp3YX09YWE7YmEuZm9yRWFjaChFYT0+e1Byb21pc2UuYWxsKFtFYS5kYXRhKCksU2Esd2FdKS50aGVuKGthPT57dGhpcy5sb2dnZXIubG9nS2VybmVsUHJvZmlsZSh4YSxFYSxrYVswXSxrYVsxXSxUYSxrYVsyXSl9KX0pfX07ZnVuY3Rpb24gY2hlY2tDb21wdXRhdGlvbkZvckVycm9ycyQxKGhhLGFhLHhhKXtpZihhYSE9PSJmbG9hdDMyIilyZXR1cm4hMTtmb3IobGV0IGJhPTA7YmE8aGEubGVuZ3RoO2JhKyspe2NvbnN0IFNhPWhhW2JhXTtpZihpc05hTihTYSl8fCFpc0Zpbml0ZShTYSkpcmV0dXJuIGNvbnNvbGUud2FybihgRm91bmQgJHtTYX0gaW4gdGhlIHJlc3VsdCBvZiAnJHt4YX0nYCksITB9cmV0dXJuITF9bGV0IExvZ2dlciQxPWNsYXNze2xvZ0tlcm5lbFByb2ZpbGUoYWEseGEsYmEsU2EsVGEsd2Epe2NvbnN0IEVhPXR5cGVvZiBTYT09Im51bWJlciI/cmlnaHRQYWQkMShgJHtTYX1tc2AsOSk6U2EuZXJyb3Isa2E9cmlnaHRQYWQkMShhYSwyNSksQWE9eGEucmFuayxGYT14YS5zaXplLExhPXJpZ2h0UGFkJDEoeGEuc2hhcGUudG9TdHJpbmcoKSwxNCk7bGV0IGVsPSIiO2Zvcihjb25zdCB0bCBpbiBUYSl7Y29uc3Qgbmw9VGFbdGxdO2lmKG5sIT1udWxsKXtjb25zdCBzbD1ubC5zaGFwZXx8eGEuc2hhcGUscmw9c2wubGVuZ3RoO2VsKz1gJHt0bH06ICR7cmx9RCAke3JsPjA/c2w6IiJ9IGB9fWNvbnNvbGUubG9nKGAlYyR7a2F9CSVjJHtFYX0JJWMke0FhfUQgJHtMYX0JJWMke0ZhfQklYyR7ZWx9CSVjJHt3YX1gLCJmb250LXdlaWdodDpib2xkIiwiY29sb3I6cmVkIiwiY29sb3I6Ymx1ZSIsImNvbG9yOiBvcmFuZ2UiLCJjb2xvcjogZ3JlZW4iLCJjb2xvcjogc3RlZWxibHVlIil9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRGaWx0ZXJlZE5vZGVzWFRvWSQxKGhhLGFhLHhhKXtjb25zdCBiYT17fSxTYT17fTtmb3IobGV0IGthPTA7a2E8YWEubGVuZ3RoO2thKyspYmFbYWFba2FdLmlkXT0hMDtmb3IobGV0IGthPTA7a2E8aGEubGVuZ3RoO2thKyspe2NvbnN0IEFhPWhhW2thXSxGYT1BYS5pbnB1dHM7Zm9yKGNvbnN0IExhIGluIEZhKXtjb25zdCBlbD1GYVtMYV07bGV0IHRsPSExO2ZvcihsZXQgbmw9MDtubDxhYS5sZW5ndGg7bmwrKylpZihiYVtlbC5pZF0pe0FhLm91dHB1dHMuZm9yRWFjaChzbD0+YmFbc2wuaWRdPSEwKSx0bD0hMCxTYVtBYS5pZF09ITA7YnJlYWt9aWYodGwpYnJlYWt9fWNvbnN0IFRhPXt9O1RhW3hhLmlkXT0hMDtjb25zdCB3YT17fTtmb3IobGV0IGthPWhhLmxlbmd0aC0xO2thPj0wO2thLS0pe2NvbnN0IEFhPWhhW2thXSxGYT1BYS5pbnB1dHM7Zm9yKGxldCBMYT0wO0xhPEFhLm91dHB1dHMubGVuZ3RoO0xhKyspaWYoVGFbQWEub3V0cHV0c1tMYV0uaWRdKXtmb3IoY29uc3QgZWwgaW4gRmEpVGFbRmFbZWxdLmlkXT0hMCx3YVtBYS5pZF09ITA7YnJlYWt9fWNvbnN0IEVhPVtdO2ZvcihsZXQga2E9MDtrYTxoYS5sZW5ndGg7a2ErKyl7Y29uc3QgQWE9aGFba2FdO2lmKFNhW0FhLmlkXSYmd2FbQWEuaWRdKXtjb25zdCBGYT17fTtmb3IoY29uc3QgZWwgaW4gQWEuaW5wdXRzKXtjb25zdCB0bD1BYS5pbnB1dHNbZWxdO2JhW3RsLmlkXSYmKEZhW2VsXT10bCl9Y29uc3QgTGE9T2JqZWN0LmFzc2lnbih7fSxBYSk7TGEuaW5wdXRzPUZhLExhLm91dHB1dHM9QWEub3V0cHV0cyxFYS5wdXNoKExhKX19cmV0dXJuIEVhfWZ1bmN0aW9uIGJhY2twcm9wYWdhdGVHcmFkaWVudHMkMShoYSxhYSx4YSxiYSl7Zm9yKGxldCBTYT1hYS5sZW5ndGgtMTtTYT49MDtTYS0tKXtjb25zdCBUYT1hYVtTYV0sd2E9W107aWYoVGEub3V0cHV0cy5mb3JFYWNoKGthPT57Y29uc3QgQWE9aGFba2EuaWRdO0FhIT1udWxsP3dhLnB1c2goQWEpOndhLnB1c2gobnVsbCl9KSxUYS5ncmFkaWVudD09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb21wdXRlIGdyYWRpZW50OiBncmFkaWVudCBmdW5jdGlvbiBub3QgZm91bmQgZm9yICR7VGEua2VybmVsTmFtZX0uYCk7Y29uc3QgRWE9VGEuZ3JhZGllbnQod2EpO2Zvcihjb25zdCBrYSBpbiBUYS5pbnB1dHMpe2lmKCEoa2EgaW4gRWEpKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGJhY2twcm9wIHRocm91Z2ggaW5wdXQgJHtrYX0uIEF2YWlsYWJsZSBncmFkaWVudHMgZm91bmQ6ICR7T2JqZWN0LmtleXMoRWEpfS5gKTtjb25zdCBBYT14YSgoKT0+RWFba2FdKCkpO2lmKEFhLmR0eXBlIT09ImZsb2F0MzIiKXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gZ3JhZGllbnQgZm9yIG9wICR7VGEua2VybmVsTmFtZX0uIFRoZSBncmFkaWVudCBvZiBpbnB1dCAke2thfSBtdXN0IGhhdmUgJ2Zsb2F0MzInIGR0eXBlLCBidXQgaGFzICcke0FhLmR0eXBlfSdgKTtjb25zdCBGYT1UYS5pbnB1dHNba2FdO2lmKCFhcnJheXNFcXVhbCQxKEFhLnNoYXBlLEZhLnNoYXBlKSl0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGluIGdyYWRpZW50IGZvciBvcCAke1RhLmtlcm5lbE5hbWV9LiBUaGUgZ3JhZGllbnQgb2YgaW5wdXQgJyR7a2F9JyBoYXMgc2hhcGUgJyR7QWEuc2hhcGV9Jywgd2hpY2ggZG9lcyBub3QgbWF0Y2ggdGhlIHNoYXBlIG9mIHRoZSBpbnB1dCAnJHtGYS5zaGFwZX0nYCk7aWYoaGFbRmEuaWRdPT1udWxsKWhhW0ZhLmlkXT1BYTtlbHNle2NvbnN0IExhPWhhW0ZhLmlkXTtoYVtGYS5pZF09YmEoTGEsQWEpLExhLmRpc3Bvc2UoKX19fX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBGT1JNQVRfTElNSVRfTlVNX1ZBTFMkMT0yMCxGT1JNQVRfTlVNX0ZJUlNUX0xBU1RfVkFMUyQxPTMsRk9STUFUX05VTV9TSUdfRElHSVRTJDE9NztmdW5jdGlvbiB0ZW5zb3JUb1N0cmluZyQxKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1jb21wdXRlU3RyaWRlcyQxKGFhKSxUYT1jb21wdXRlTWF4U2l6ZVBlckNvbHVtbiQxKGhhLGFhLHhhLFNhKSx3YT1hYS5sZW5ndGgsRWE9c3ViVGVuc29yVG9TdHJpbmckMShoYSxhYSx4YSxTYSxUYSksa2E9WyJUZW5zb3IiXTtyZXR1cm4gYmEmJihrYS5wdXNoKGAgIGR0eXBlOiAke3hhfWApLGthLnB1c2goYCAgcmFuazogJHt3YX1gKSxrYS5wdXNoKGAgIHNoYXBlOiBbJHthYX1dYCksa2EucHVzaCgiICB2YWx1ZXM6IikpLGthLnB1c2goRWEubWFwKEFhPT4iICAgICIrQWEpLmpvaW4oYApgKSksa2Euam9pbihgCmApfWZ1bmN0aW9uIGNvbXB1dGVNYXhTaXplUGVyQ29sdW1uJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPXNpemVGcm9tU2hhcGUkMShhYSksVGE9YmFbYmEubGVuZ3RoLTFdLHdhPW5ldyBBcnJheShUYSkuZmlsbCgwKSxFYT1hYS5sZW5ndGgsa2E9eGE9PT0iY29tcGxleDY0Ij9jcmVhdGVDb21wbGV4VHVwbGVzJDEoaGEpOmhhO2lmKEVhPjEpZm9yKGxldCBBYT0wO0FhPFNhL1RhO0FhKyspe2NvbnN0IEZhPUFhKlRhO2ZvcihsZXQgTGE9MDtMYTxUYTtMYSsrKXdhW0xhXT1NYXRoLm1heCh3YVtMYV0sdmFsVG9TdHJpbmckMShrYVtGYStMYV0sMCx4YSkubGVuZ3RoKX1yZXR1cm4gd2F9ZnVuY3Rpb24gdmFsVG9TdHJpbmckMShoYSxhYSx4YSl7bGV0IGJhO3JldHVybiBBcnJheS5pc0FycmF5KGhhKT9iYT1gJHtwYXJzZUZsb2F0KGhhWzBdLnRvRml4ZWQoRk9STUFUX05VTV9TSUdfRElHSVRTJDEpKX0gKyAke3BhcnNlRmxvYXQoaGFbMV0udG9GaXhlZChGT1JNQVRfTlVNX1NJR19ESUdJVFMkMSkpfWpgOmlzU3RyaW5nJDEoaGEpP2JhPWAnJHtoYX0nYDp4YT09PSJib29sIj9iYT1ib29sTnVtVG9TdHJpbmckMShoYSk6YmE9cGFyc2VGbG9hdChoYS50b0ZpeGVkKEZPUk1BVF9OVU1fU0lHX0RJR0lUUyQxKSkudG9TdHJpbmcoKSxyaWdodFBhZCQxKGJhLGFhKX1mdW5jdGlvbiBib29sTnVtVG9TdHJpbmckMShoYSl7cmV0dXJuIGhhPT09MD8iZmFsc2UiOiJ0cnVlIn1mdW5jdGlvbiBzdWJUZW5zb3JUb1N0cmluZyQxKGhhLGFhLHhhLGJhLFNhLFRhPSEwKXtjb25zdCB3YT14YT09PSJjb21wbGV4NjQiPzI6MSxFYT1hYVswXSxrYT1hYS5sZW5ndGg7aWYoa2E9PT0wKXtpZih4YT09PSJjb21wbGV4NjQiKXtjb25zdCBzbD1jcmVhdGVDb21wbGV4VHVwbGVzJDEoaGEpO3JldHVyblt2YWxUb1N0cmluZyQxKHNsWzBdLDAseGEpXX1yZXR1cm4geGE9PT0iYm9vbCI/W2Jvb2xOdW1Ub1N0cmluZyQxKGhhWzBdKV06W2hhWzBdLnRvU3RyaW5nKCldfWlmKGthPT09MSl7aWYoRWE+Rk9STUFUX0xJTUlUX05VTV9WQUxTJDEpe2NvbnN0IHJsPUZPUk1BVF9OVU1fRklSU1RfTEFTVF9WQUxTJDEqd2E7bGV0IG9sPUFycmF5LmZyb20oaGEuc2xpY2UoMCxybCkpLGFsPUFycmF5LmZyb20oaGEuc2xpY2UoKEVhLUZPUk1BVF9OVU1fRklSU1RfTEFTVF9WQUxTJDEpKndhLEVhKndhKSk7cmV0dXJuIHhhPT09ImNvbXBsZXg2NCImJihvbD1jcmVhdGVDb21wbGV4VHVwbGVzJDEob2wpLGFsPWNyZWF0ZUNvbXBsZXhUdXBsZXMkMShhbCkpLFsiWyIrb2wubWFwKChsbCxpbCk9PnZhbFRvU3RyaW5nJDEobGwsU2FbaWxdLHhhKSkuam9pbigiLCAiKSsiLCAuLi4sICIrYWwubWFwKChsbCxpbCk9PnZhbFRvU3RyaW5nJDEobGwsU2FbRWEtRk9STUFUX05VTV9GSVJTVF9MQVNUX1ZBTFMkMStpbF0seGEpKS5qb2luKCIsICIpKyJdIl19cmV0dXJuWyJbIisoeGE9PT0iY29tcGxleDY0Ij9jcmVhdGVDb21wbGV4VHVwbGVzJDEoaGEpOkFycmF5LmZyb20oaGEpKS5tYXAoKHJsLG9sKT0+dmFsVG9TdHJpbmckMShybCxTYVtvbF0seGEpKS5qb2luKCIsICIpKyJdIl19Y29uc3QgQWE9YWEuc2xpY2UoMSksRmE9YmEuc2xpY2UoMSksTGE9YmFbMF0qd2EsZWw9W107aWYoRWE+Rk9STUFUX0xJTUlUX05VTV9WQUxTJDEpe2ZvcihsZXQgc2w9MDtzbDxGT1JNQVRfTlVNX0ZJUlNUX0xBU1RfVkFMUyQxO3NsKyspe2NvbnN0IHJsPXNsKkxhLG9sPXJsK0xhO2VsLnB1c2goLi4uc3ViVGVuc29yVG9TdHJpbmckMShoYS5zbGljZShybCxvbCksQWEseGEsRmEsU2EsITEpKX1lbC5wdXNoKCIuLi4iKTtmb3IobGV0IHNsPUVhLUZPUk1BVF9OVU1fRklSU1RfTEFTVF9WQUxTJDE7c2w8RWE7c2wrKyl7Y29uc3Qgcmw9c2wqTGEsb2w9cmwrTGE7ZWwucHVzaCguLi5zdWJUZW5zb3JUb1N0cmluZyQxKGhhLnNsaWNlKHJsLG9sKSxBYSx4YSxGYSxTYSxzbD09PUVhLTEpKX19ZWxzZSBmb3IobGV0IHNsPTA7c2w8RWE7c2wrKyl7Y29uc3Qgcmw9c2wqTGEsb2w9cmwrTGE7ZWwucHVzaCguLi5zdWJUZW5zb3JUb1N0cmluZyQxKGhhLnNsaWNlKHJsLG9sKSxBYSx4YSxGYSxTYSxzbD09PUVhLTEpKX1jb25zdCB0bD1rYT09PTI/IiwiOiIiO2VsWzBdPSJbIisoRWE+MD9lbFswXSt0bDoiIik7Zm9yKGxldCBzbD0xO3NsPGVsLmxlbmd0aC0xO3NsKyspZWxbc2xdPSIgIitlbFtzbF0rdGw7bGV0IG5sPWAsCmA7Zm9yKGxldCBzbD0yO3NsPGthO3NsKyspbmwrPWAKYDtyZXR1cm4gZWxbZWwubGVuZ3RoLTFdPSIgIitlbFtlbC5sZW5ndGgtMV0rIl0iKyhUYT8iIjpubCksZWx9ZnVuY3Rpb24gY3JlYXRlQ29tcGxleFR1cGxlcyQxKGhhKXtjb25zdCBhYT1bXTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoO3hhKz0yKWFhLnB1c2goW2hhW3hhXSxoYVt4YSsxXV0pO3JldHVybiBhYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgVGVuc29yQnVmZmVyJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEpe2lmKHRoaXMuZHR5cGU9eGEsdGhpcy5zaGFwZT1hYS5zbGljZSgpLHRoaXMuc2l6ZT1zaXplRnJvbVNoYXBlJDEoYWEpLGJhIT1udWxsKXtjb25zdCBTYT1iYS5sZW5ndGg7YXNzZXJ0JDIoU2E9PT10aGlzLnNpemUsKCk9PmBMZW5ndGggb2YgdmFsdWVzICcke1NhfScgZG9lcyBub3QgbWF0Y2ggdGhlIHNpemUgaW5mZXJyZWQgYnkgdGhlIHNoYXBlICcke3RoaXMuc2l6ZX0nLmApfWlmKHhhPT09ImNvbXBsZXg2NCIpdGhyb3cgbmV3IEVycm9yKCJjb21wbGV4NjQgZHR5cGUgVGVuc29yQnVmZmVycyBhcmUgbm90IHN1cHBvcnRlZC4gUGxlYXNlIGNyZWF0ZSBhIFRlbnNvckJ1ZmZlciBmb3IgdGhlIHJlYWwgYW5kIGltYWdpbmFyeSBwYXJ0cyBzZXBhcmF0ZWx5IGFuZCBjYWxsIHRmLmNvbXBsZXgocmVhbCwgaW1hZykuIik7dGhpcy52YWx1ZXM9YmF8fGdldEFycmF5RnJvbURUeXBlJDEoeGEsdGhpcy5zaXplKSx0aGlzLnN0cmlkZXM9Y29tcHV0ZVN0cmlkZXMkMShhYSl9c2V0KGFhLC4uLnhhKXt4YS5sZW5ndGg9PT0wJiYoeGE9WzBdKSxhc3NlcnQkMih4YS5sZW5ndGg9PT10aGlzLnJhbmssKCk9PmBUaGUgbnVtYmVyIG9mIHByb3ZpZGVkIGNvb3JkaW5hdGVzICgke3hhLmxlbmd0aH0pIG11c3QgbWF0Y2ggdGhlIHJhbmsgKCR7dGhpcy5yYW5rfSlgKTtjb25zdCBiYT10aGlzLmxvY1RvSW5kZXgoeGEpO3RoaXMudmFsdWVzW2JhXT1hYX1nZXQoLi4uYWEpe2FhLmxlbmd0aD09PTAmJihhYT1bMF0pO2xldCB4YT0wO2Zvcihjb25zdCBTYSBvZiBhYSl7aWYoU2E8MHx8U2E+PXRoaXMuc2hhcGVbeGFdKXtjb25zdCBUYT1gUmVxdWVzdGVkIG91dCBvZiByYW5nZSBlbGVtZW50IGF0ICR7YWF9LiAgIEJ1ZmZlciBzaGFwZT0ke3RoaXMuc2hhcGV9YDt0aHJvdyBuZXcgRXJyb3IoVGEpfXhhKyt9bGV0IGJhPWFhW2FhLmxlbmd0aC0xXTtmb3IobGV0IFNhPTA7U2E8YWEubGVuZ3RoLTE7KytTYSliYSs9dGhpcy5zdHJpZGVzW1NhXSphYVtTYV07cmV0dXJuIHRoaXMudmFsdWVzW2JhXX1sb2NUb0luZGV4KGFhKXtpZih0aGlzLnJhbms9PT0wKXJldHVybiAwO2lmKHRoaXMucmFuaz09PTEpcmV0dXJuIGFhWzBdO2xldCB4YT1hYVthYS5sZW5ndGgtMV07Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aC0xOysrYmEpeGErPXRoaXMuc3RyaWRlc1tiYV0qYWFbYmFdO3JldHVybiB4YX1pbmRleFRvTG9jKGFhKXtpZih0aGlzLnJhbms9PT0wKXJldHVybltdO2lmKHRoaXMucmFuaz09PTEpcmV0dXJuW2FhXTtjb25zdCB4YT1uZXcgQXJyYXkodGhpcy5zaGFwZS5sZW5ndGgpO2ZvcihsZXQgYmE9MDtiYTx4YS5sZW5ndGgtMTsrK2JhKXhhW2JhXT1NYXRoLmZsb29yKGFhL3RoaXMuc3RyaWRlc1tiYV0pLGFhLT14YVtiYV0qdGhpcy5zdHJpZGVzW2JhXTtyZXR1cm4geGFbeGEubGVuZ3RoLTFdPWFhLHhhfWdldCByYW5rKCl7cmV0dXJuIHRoaXMuc2hhcGUubGVuZ3RofXRvVGVuc29yKCl7cmV0dXJuIHRyYWNrZXJGbiQxKCkubWFrZVRlbnNvcih0aGlzLnZhbHVlcyx0aGlzLnNoYXBlLHRoaXMuZHR5cGUpfX0sdHJhY2tlckZuJDE9bnVsbCxvcEhhbmRsZXIkMz1udWxsO2Z1bmN0aW9uIHNldFRlbnNvclRyYWNrZXIkMShoYSl7dHJhY2tlckZuJDE9aGF9ZnVuY3Rpb24gc2V0T3BIYW5kbGVyJDEoaGEpe29wSGFuZGxlciQzPWhhfWxldCBUZW5zb3IkMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy5rZXB0PSExLHRoaXMuaXNEaXNwb3NlZEludGVybmFsPSExLHRoaXMuc2hhcGU9YWEuc2xpY2UoKSx0aGlzLmR0eXBlPXhhfHwiZmxvYXQzMiIsdGhpcy5zaXplPXNpemVGcm9tU2hhcGUkMShhYSksdGhpcy5zdHJpZGVzPWNvbXB1dGVTdHJpZGVzJDEoYWEpLHRoaXMuZGF0YUlkPWJhLHRoaXMuaWQ9U2EsdGhpcy5yYW5rVHlwZT10aGlzLnJhbms8NT90aGlzLnJhbmsudG9TdHJpbmcoKToiaGlnaGVyIn1nZXQgcmFuaygpe3JldHVybiB0aGlzLnNoYXBlLmxlbmd0aH1hc3luYyBidWZmZXIoKXtjb25zdCBhYT1hd2FpdCB0aGlzLmRhdGEoKTtyZXR1cm4gb3BIYW5kbGVyJDMuYnVmZmVyKHRoaXMuc2hhcGUsdGhpcy5kdHlwZSxhYSl9YnVmZmVyU3luYygpe3JldHVybiBvcEhhbmRsZXIkMy5idWZmZXIodGhpcy5zaGFwZSx0aGlzLmR0eXBlLHRoaXMuZGF0YVN5bmMoKSl9YXN5bmMgYXJyYXkoKXtjb25zdCBhYT1hd2FpdCB0aGlzLmRhdGEoKTtyZXR1cm4gdG9OZXN0ZWRBcnJheSQxKHRoaXMuc2hhcGUsYWEsdGhpcy5kdHlwZT09PSJjb21wbGV4NjQiKX1hcnJheVN5bmMoKXtyZXR1cm4gdG9OZXN0ZWRBcnJheSQxKHRoaXMuc2hhcGUsdGhpcy5kYXRhU3luYygpLHRoaXMuZHR5cGU9PT0iY29tcGxleDY0Iil9YXN5bmMgZGF0YSgpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCk7Y29uc3QgYWE9dHJhY2tlckZuJDEoKS5yZWFkKHRoaXMuZGF0YUlkKTtpZih0aGlzLmR0eXBlPT09InN0cmluZyIpe2NvbnN0IHhhPWF3YWl0IGFhO3RyeXtyZXR1cm4geGEubWFwKGJhPT5kZWNvZGVTdHJpbmckMShiYSkpfWNhdGNoe3Rocm93IG5ldyBFcnJvcigiRmFpbGVkIHRvIGRlY29kZSB0aGUgc3RyaW5nIGJ5dGVzIGludG8gdXRmLTguIFRvIGdldCB0aGUgb3JpZ2luYWwgYnl0ZXMsIGNhbGwgdGVuc29yLmJ5dGVzKCkuIil9fXJldHVybiBhYX1kYXRhVG9HUFUoYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRyYWNrZXJGbiQxKCkucmVhZFRvR1BVKHRoaXMuZGF0YUlkLGFhKX1kYXRhU3luYygpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCk7Y29uc3QgYWE9dHJhY2tlckZuJDEoKS5yZWFkU3luYyh0aGlzLmRhdGFJZCk7aWYodGhpcy5kdHlwZT09PSJzdHJpbmciKXRyeXtyZXR1cm4gYWEubWFwKHhhPT5kZWNvZGVTdHJpbmckMSh4YSkpfWNhdGNoe3Rocm93IG5ldyBFcnJvcigiRmFpbGVkIHRvIGRlY29kZSB0aGUgc3RyaW5nIGJ5dGVzIGludG8gdXRmLTguIFRvIGdldCB0aGUgb3JpZ2luYWwgYnl0ZXMsIGNhbGwgdGVuc29yLmJ5dGVzKCkuIil9cmV0dXJuIGFhfWFzeW5jIGJ5dGVzKCl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKTtjb25zdCBhYT1hd2FpdCB0cmFja2VyRm4kMSgpLnJlYWQodGhpcy5kYXRhSWQpO3JldHVybiB0aGlzLmR0eXBlPT09InN0cmluZyI/YWE6bmV3IFVpbnQ4QXJyYXkoYWEuYnVmZmVyKX1kaXNwb3NlKCl7dGhpcy5pc0Rpc3Bvc2VkfHwodGhpcy5rZXJhc01hc2smJnRoaXMua2VyYXNNYXNrLmRpc3Bvc2UoKSx0cmFja2VyRm4kMSgpLmRpc3Bvc2VUZW5zb3IodGhpcyksdGhpcy5pc0Rpc3Bvc2VkSW50ZXJuYWw9ITApfWdldCBpc0Rpc3Bvc2VkKCl7cmV0dXJuIHRoaXMuaXNEaXNwb3NlZEludGVybmFsfXRocm93SWZEaXNwb3NlZCgpe2lmKHRoaXMuaXNEaXNwb3NlZCl0aHJvdyBuZXcgRXJyb3IoIlRlbnNvciBpcyBkaXNwb3NlZC4iKX1wcmludChhYT0hMSl7cmV0dXJuIG9wSGFuZGxlciQzLnByaW50KHRoaXMsYWEpfWNsb25lKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksb3BIYW5kbGVyJDMuY2xvbmUodGhpcyl9dG9TdHJpbmcoYWE9ITEpe2NvbnN0IHhhPXRoaXMuZGF0YVN5bmMoKTtyZXR1cm4gdGVuc29yVG9TdHJpbmckMSh4YSx0aGlzLnNoYXBlLHRoaXMuZHR5cGUsYWEpfWNhc3QoYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLG9wSGFuZGxlciQzLmNhc3QodGhpcyxhYSl9dmFyaWFibGUoYWE9ITAseGEsYmEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRyYWNrZXJGbiQxKCkubWFrZVZhcmlhYmxlKHRoaXMsYWEseGEsYmEpfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KFRlbnNvciQxLFN5bWJvbC5oYXNJbnN0YW5jZSx7dmFsdWU6aGE9PiEhaGEmJmhhLmRhdGEhPW51bGwmJmhhLmRhdGFTeW5jIT1udWxsJiZoYS50aHJvd0lmRGlzcG9zZWQhPW51bGx9KTtmdW5jdGlvbiBnZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCl7cmV0dXJuIGdldEdsb2JhbCQxKCJUZW5zb3IiLCgpPT5UZW5zb3IkMSl9Z2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpO2xldCBWYXJpYWJsZSQxPWNsYXNzIGV4dGVuZHMgVGVuc29yJDF7Y29uc3RydWN0b3IoYWEseGEsYmEsU2Epe3N1cGVyKGFhLnNoYXBlLGFhLmR0eXBlLGFhLmRhdGFJZCxTYSksdGhpcy50cmFpbmFibGU9eGEsdGhpcy5uYW1lPWJhfWFzc2lnbihhYSl7aWYoYWEuZHR5cGUhPT10aGlzLmR0eXBlKXRocm93IG5ldyBFcnJvcihgZHR5cGUgb2YgdGhlIG5ldyB2YWx1ZSAoJHthYS5kdHlwZX0pIGFuZCBwcmV2aW91cyB2YWx1ZSAoJHt0aGlzLmR0eXBlfSkgbXVzdCBtYXRjaGApO2lmKCFhcnJheXNFcXVhbCQxKGFhLnNoYXBlLHRoaXMuc2hhcGUpKXRocm93IG5ldyBFcnJvcihgc2hhcGUgb2YgdGhlIG5ldyB2YWx1ZSAoJHthYS5zaGFwZX0pIGFuZCBwcmV2aW91cyB2YWx1ZSAoJHt0aGlzLnNoYXBlfSkgbXVzdCBtYXRjaGApO3RyYWNrZXJGbiQxKCkuZGlzcG9zZVRlbnNvcih0aGlzKSx0aGlzLmRhdGFJZD1hYS5kYXRhSWQsdHJhY2tlckZuJDEoKS5pbmNSZWYodGhpcyxudWxsKX1kaXNwb3NlKCl7dHJhY2tlckZuJDEoKS5kaXNwb3NlVmFyaWFibGUodGhpcyksdGhpcy5pc0Rpc3Bvc2VkSW50ZXJuYWw9ITB9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkoVmFyaWFibGUkMSxTeW1ib2wuaGFzSW5zdGFuY2Use3ZhbHVlOmhhPT5oYSBpbnN0YW5jZW9mIFRlbnNvciQxJiZoYS5hc3NpZ24hPW51bGwmJmhhLmFzc2lnbiBpbnN0YW5jZW9mIEZ1bmN0aW9ufSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovdmFyIFJhbmskMTsoZnVuY3Rpb24oaGEpe2hhLlIwPSJSMCIsaGEuUjE9IlIxIixoYS5SMj0iUjIiLGhhLlIzPSJSMyIsaGEuUjQ9IlI0IixoYS5SNT0iUjUiLGhhLlI2PSJSNiJ9KShSYW5rJDF8fChSYW5rJDE9e30pKTt2YXIgVXBjYXN0SW50MzJBbmRNYXAkMTsoZnVuY3Rpb24oaGEpe2hhLmZsb2F0MzI9ImZsb2F0MzIiLGhhLmludDMyPSJpbnQzMiIsaGEuYm9vbD0iaW50MzIiLGhhLmNvbXBsZXg2ND0iY29tcGxleDY0In0pKFVwY2FzdEludDMyQW5kTWFwJDF8fChVcGNhc3RJbnQzMkFuZE1hcCQxPXt9KSk7dmFyIFVwY2FzdEJvb2xBbmRNYXAkMTsoZnVuY3Rpb24oaGEpe2hhLmZsb2F0MzI9ImZsb2F0MzIiLGhhLmludDMyPSJpbnQzMiIsaGEuYm9vbD0iYm9vbCIsaGEuY29tcGxleDY0PSJjb21wbGV4NjQifSkoVXBjYXN0Qm9vbEFuZE1hcCQxfHwoVXBjYXN0Qm9vbEFuZE1hcCQxPXt9KSk7dmFyIFVwY2FzdEZsb2F0MzJBbmRNYXAkMTsoZnVuY3Rpb24oaGEpe2hhLmZsb2F0MzI9ImZsb2F0MzIiLGhhLmludDMyPSJmbG9hdDMyIixoYS5ib29sPSJmbG9hdDMyIixoYS5jb21wbGV4NjQ9ImNvbXBsZXg2NCJ9KShVcGNhc3RGbG9hdDMyQW5kTWFwJDF8fChVcGNhc3RGbG9hdDMyQW5kTWFwJDE9e30pKTt2YXIgVXBjYXN0Q29tcGxleDY0QW5kTWFwJDE7KGZ1bmN0aW9uKGhhKXtoYS5mbG9hdDMyPSJjb21wbGV4NjQiLGhhLmludDMyPSJjb21wbGV4NjQiLGhhLmJvb2w9ImNvbXBsZXg2NCIsaGEuY29tcGxleDY0PSJjb21wbGV4NjQifSkoVXBjYXN0Q29tcGxleDY0QW5kTWFwJDF8fChVcGNhc3RDb21wbGV4NjRBbmRNYXAkMT17fSkpO2NvbnN0IHVwY2FzdFR5cGVNYXAkMT17ZmxvYXQzMjpVcGNhc3RGbG9hdDMyQW5kTWFwJDEsaW50MzI6VXBjYXN0SW50MzJBbmRNYXAkMSxib29sOlVwY2FzdEJvb2xBbmRNYXAkMSxjb21wbGV4NjQ6VXBjYXN0Q29tcGxleDY0QW5kTWFwJDF9O2Z1bmN0aW9uIHVwY2FzdFR5cGUkMShoYSxhYSl7aWYoaGE9PT0ic3RyaW5nInx8YWE9PT0ic3RyaW5nIil7aWYoaGE9PT0ic3RyaW5nIiYmYWE9PT0ic3RyaW5nIilyZXR1cm4ic3RyaW5nIjt0aHJvdyBuZXcgRXJyb3IoYENhbiBub3QgdXBjYXN0ICR7aGF9IHdpdGggJHthYX1gKX1yZXR1cm4gdXBjYXN0VHlwZU1hcCQxW2hhXVthYV19ZnVuY3Rpb24gc3VtT3V0VHlwZSQxKGhhKXtyZXR1cm4gdXBjYXN0VHlwZSQxKGhhLCJpbnQzMiIpfWZ1bmN0aW9uIGlzV2ViR0xEYXRhJDEoaGEpe3JldHVybiBoYSE9bnVsbCYmdHlwZW9mIGhhPT0ib2JqZWN0IiYmInRleHR1cmUiaW4gaGEmJmhhLnRleHR1cmUgaW5zdGFuY2VvZiBXZWJHTFRleHR1cmV9ZnVuY3Rpb24gaXNXZWJHUFVEYXRhJDEoaGEpe3JldHVybiB0eXBlb2YgR1BVQnVmZmVyPCJ1IiYmaGEhPW51bGwmJnR5cGVvZiBoYT09Im9iamVjdCImJiJidWZmZXIiaW4gaGEmJmhhLmJ1ZmZlciBpbnN0YW5jZW9mIEdQVUJ1ZmZlcn0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYWtlVHlwZXNNYXRjaCQxKGhhLGFhKXtpZihoYS5kdHlwZT09PWFhLmR0eXBlKXJldHVybltoYSxhYV07Y29uc3QgeGE9dXBjYXN0VHlwZSQxKGhhLmR0eXBlLGFhLmR0eXBlKTtyZXR1cm5baGEuY2FzdCh4YSksYWEuY2FzdCh4YSldfWZ1bmN0aW9uIGFzc2VydFR5cGVzTWF0Y2goaGEsYWEpe2Fzc2VydCQyKGhhLmR0eXBlPT09YWEuZHR5cGUsKCk9PmBUaGUgZHR5cGVzIG9mIHRoZSBmaXJzdCgke2hhLmR0eXBlfSkgYW5kIHNlY29uZCgke2FhLmR0eXBlfSkgaW5wdXQgbXVzdCBtYXRjaGApfWZ1bmN0aW9uIGdldFRlbnNvcnNJbkNvbnRhaW5lciQxKGhhKXtjb25zdCBhYT1bXTtyZXR1cm4gd2Fsa1RlbnNvckNvbnRhaW5lciQxKGhhLGFhLG5ldyBTZXQpLGFhfWZ1bmN0aW9uIHdhbGtUZW5zb3JDb250YWluZXIkMShoYSxhYSx4YSl7aWYoaGE9PW51bGwpcmV0dXJuO2lmKGhhIGluc3RhbmNlb2YgVGVuc29yJDEpe2FhLnB1c2goaGEpO3JldHVybn1pZighaXNJdGVyYWJsZSQxKGhhKSlyZXR1cm47Y29uc3QgYmE9aGE7Zm9yKGNvbnN0IFNhIGluIGJhKXtjb25zdCBUYT1iYVtTYV07eGEuaGFzKFRhKXx8KHhhLmFkZChUYSksd2Fsa1RlbnNvckNvbnRhaW5lciQxKFRhLGFhLHhhKSl9fWZ1bmN0aW9uIGlzSXRlcmFibGUkMShoYSl7cmV0dXJuIEFycmF5LmlzQXJyYXkoaGEpfHx0eXBlb2YgaGE9PSJvYmplY3QifS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlzUmVnaXN0ZXJlZEtlcm5lbEludm9jYXRpb24kMShoYSl7cmV0dXJuIGhhLmtlcm5lbE5hbWUhPW51bGx9bGV0IEVuZ2luZVN0YXRlJDE9Y2xhc3N7Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyZWRWYXJpYWJsZXM9e30sdGhpcy5uZXh0VGFwZU5vZGVJZD0wLHRoaXMubnVtQnl0ZXM9MCx0aGlzLm51bVRlbnNvcnM9MCx0aGlzLm51bVN0cmluZ1RlbnNvcnM9MCx0aGlzLm51bURhdGFCdWZmZXJzPTAsdGhpcy5ncmFkaWVudERlcHRoPTAsdGhpcy5rZXJuZWxEZXB0aD0wLHRoaXMuc2NvcGVTdGFjaz1bXSx0aGlzLm51bURhdGFNb3Zlc1N0YWNrPVtdLHRoaXMubmV4dFNjb3BlSWQ9MCx0aGlzLnRlbnNvckluZm89bmV3IFdlYWtNYXAsdGhpcy5wcm9maWxpbmc9ITEsdGhpcy5hY3RpdmVQcm9maWxlPXtuZXdCeXRlczowLG5ld1RlbnNvcnM6MCxwZWFrQnl0ZXM6MCxrZXJuZWxzOltdLHJlc3VsdDpudWxsLGdldCBrZXJuZWxOYW1lcygpe3JldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodGhpcy5rZXJuZWxzLm1hcChhYT0+YWEubmFtZSkpKX19fWRpc3Bvc2UoKXtmb3IoY29uc3QgYWEgaW4gdGhpcy5yZWdpc3RlcmVkVmFyaWFibGVzKXRoaXMucmVnaXN0ZXJlZFZhcmlhYmxlc1thYV0uZGlzcG9zZSgpfX0sRW5naW5lJDE9Y2xhc3MgYWN7Y29uc3RydWN0b3IoYWEpe3RoaXMuRU5WPWFhLHRoaXMucmVnaXN0cnk9e30sdGhpcy5yZWdpc3RyeUZhY3Rvcnk9e30sdGhpcy5wZW5kaW5nQmFja2VuZEluaXRJZD0wLHRoaXMuc3RhdGU9bmV3IEVuZ2luZVN0YXRlJDF9YXN5bmMgcmVhZHkoKXtpZih0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdCE9bnVsbClyZXR1cm4gdGhpcy5wZW5kaW5nQmFja2VuZEluaXQudGhlbigoKT0+e30pO2lmKHRoaXMuYmFja2VuZEluc3RhbmNlIT1udWxsKXJldHVybjtjb25zdCBhYT10aGlzLmdldFNvcnRlZEJhY2tlbmRzKCk7Zm9yKGxldCB4YT0wO3hhPGFhLmxlbmd0aDt4YSsrKXtjb25zdCBiYT1hYVt4YV07aWYoYXdhaXQgdGhpcy5pbml0aWFsaXplQmFja2VuZChiYSkuc3VjY2Vzcyl7YXdhaXQgdGhpcy5zZXRCYWNrZW5kKGJhKTtyZXR1cm59fXRocm93IG5ldyBFcnJvcigiQ291bGQgbm90IGluaXRpYWxpemUgYW55IGJhY2tlbmRzLCBhbGwgYmFja2VuZCBpbml0aWFsaXphdGlvbnMgZmFpbGVkLiIpfWdldCBiYWNrZW5kKCl7aWYodGhpcy5wZW5kaW5nQmFja2VuZEluaXQhPW51bGwpdGhyb3cgbmV3IEVycm9yKGBCYWNrZW5kICcke3RoaXMuYmFja2VuZE5hbWV9JyBoYXMgbm90IHlldCBiZWVuIGluaXRpYWxpemVkLiBNYWtlIHN1cmUgdG8gYXdhaXQgdGYucmVhZHkoKSBvciBhd2FpdCB0Zi5zZXRCYWNrZW5kKCkgYmVmb3JlIGNhbGxpbmcgb3RoZXIgbWV0aG9kc2ApO2lmKHRoaXMuYmFja2VuZEluc3RhbmNlPT1udWxsKXtjb25zdHtuYW1lOmFhLGFzeW5jSW5pdDp4YX09dGhpcy5pbml0aWFsaXplQmFja2VuZHNBbmRSZXR1cm5CZXN0KCk7aWYoeGEpdGhyb3cgbmV3IEVycm9yKGBUaGUgaGlnaGVzdCBwcmlvcml0eSBiYWNrZW5kICcke2FhfScgaGFzIG5vdCB5ZXQgYmVlbiBpbml0aWFsaXplZC4gTWFrZSBzdXJlIHRvIGF3YWl0IHRmLnJlYWR5KCkgb3IgYXdhaXQgdGYuc2V0QmFja2VuZCgpIGJlZm9yZSBjYWxsaW5nIG90aGVyIG1ldGhvZHNgKTt0aGlzLnNldEJhY2tlbmQoYWEpfXJldHVybiB0aGlzLmJhY2tlbmRJbnN0YW5jZX1iYWNrZW5kTmFtZXMoKXtyZXR1cm4gT2JqZWN0LmtleXModGhpcy5yZWdpc3RyeUZhY3RvcnkpfWZpbmRCYWNrZW5kKGFhKXtpZighKGFhIGluIHRoaXMucmVnaXN0cnkpKWlmKGFhIGluIHRoaXMucmVnaXN0cnlGYWN0b3J5KXtjb25zdHthc3luY0luaXQ6eGF9PXRoaXMuaW5pdGlhbGl6ZUJhY2tlbmQoYWEpO2lmKHhhKXJldHVybiBudWxsfWVsc2UgcmV0dXJuIG51bGw7cmV0dXJuIHRoaXMucmVnaXN0cnlbYWFdfWZpbmRCYWNrZW5kRmFjdG9yeShhYSl7cmV0dXJuIGFhIGluIHRoaXMucmVnaXN0cnlGYWN0b3J5P3RoaXMucmVnaXN0cnlGYWN0b3J5W2FhXS5mYWN0b3J5Om51bGx9cmVnaXN0ZXJCYWNrZW5kKGFhLHhhLGJhPTEpe3JldHVybiBhYSBpbiB0aGlzLnJlZ2lzdHJ5RmFjdG9yeT8od2FybiQxKGAke2FhfSBiYWNrZW5kIHdhcyBhbHJlYWR5IHJlZ2lzdGVyZWQuIFJldXNpbmcgZXhpc3RpbmcgYmFja2VuZCBmYWN0b3J5LmApLCExKToodGhpcy5yZWdpc3RyeUZhY3RvcnlbYWFdPXtmYWN0b3J5OnhhLHByaW9yaXR5OmJhfSwhMCl9YXN5bmMgc2V0QmFja2VuZChhYSl7aWYodGhpcy5yZWdpc3RyeUZhY3RvcnlbYWFdPT1udWxsKXRocm93IG5ldyBFcnJvcihgQmFja2VuZCBuYW1lICcke2FhfScgbm90IGZvdW5kIGluIHJlZ2lzdHJ5YCk7aWYodGhpcy5iYWNrZW5kTmFtZT1hYSx0aGlzLnJlZ2lzdHJ5W2FhXT09bnVsbCl7dGhpcy5iYWNrZW5kSW5zdGFuY2U9bnVsbDtjb25zdHtzdWNjZXNzOnhhLGFzeW5jSW5pdDpiYX09dGhpcy5pbml0aWFsaXplQmFja2VuZChhYSk7aWYoIShiYT9hd2FpdCB4YTp4YSkpcmV0dXJuITF9cmV0dXJuIHRoaXMuYmFja2VuZEluc3RhbmNlPXRoaXMucmVnaXN0cnlbYWFdLHRoaXMuc2V0dXBSZWdpc3RlcmVkS2VybmVscygpLHRoaXMucHJvZmlsZXI9bmV3IFByb2ZpbGVyJDEodGhpcy5iYWNrZW5kSW5zdGFuY2UpLCEwfXNldHVwUmVnaXN0ZXJlZEtlcm5lbHMoKXtnZXRLZXJuZWxzRm9yQmFja2VuZCQxKHRoaXMuYmFja2VuZE5hbWUpLmZvckVhY2goeGE9Pnt4YS5zZXR1cEZ1bmMhPW51bGwmJnhhLnNldHVwRnVuYyh0aGlzLmJhY2tlbmRJbnN0YW5jZSl9KX1kaXNwb3NlUmVnaXN0ZXJlZEtlcm5lbHMoYWEpe2dldEtlcm5lbHNGb3JCYWNrZW5kJDEoYWEpLmZvckVhY2goYmE9PntiYS5kaXNwb3NlRnVuYyE9bnVsbCYmYmEuZGlzcG9zZUZ1bmModGhpcy5yZWdpc3RyeVthYV0pfSl9aW5pdGlhbGl6ZUJhY2tlbmQoYWEpe2NvbnN0IHhhPXRoaXMucmVnaXN0cnlGYWN0b3J5W2FhXTtpZih4YT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBpbml0aWFsaXplIGJhY2tlbmQgJHthYX0sIG5vIHJlZ2lzdHJhdGlvbiBmb3VuZC5gKTt0cnl7Y29uc3QgYmE9eGEuZmFjdG9yeSgpO2lmKGJhJiYhKGJhIGluc3RhbmNlb2YgS2VybmVsQmFja2VuZCQxKSYmdHlwZW9mIGJhLnRoZW49PSJmdW5jdGlvbiIpe2NvbnN0IFNhPSsrdGhpcy5wZW5kaW5nQmFja2VuZEluaXRJZCxUYT1iYS50aGVuKHdhPT5TYTx0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdElkPyExOih0aGlzLnJlZ2lzdHJ5W2FhXT13YSx0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdD1udWxsLCEwKSkuY2F0Y2god2E9PihTYTx0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdElkfHwodGhpcy5wZW5kaW5nQmFja2VuZEluaXQ9bnVsbCx3YXJuJDEoYEluaXRpYWxpemF0aW9uIG9mIGJhY2tlbmQgJHthYX0gZmFpbGVkYCksd2FybiQxKHdhLnN0YWNrfHx3YS5tZXNzYWdlKSksITEpKTtyZXR1cm4gdGhpcy5wZW5kaW5nQmFja2VuZEluaXQ9VGEse3N1Y2Nlc3M6VGEsYXN5bmNJbml0OiEwfX1lbHNlIHJldHVybiB0aGlzLnJlZ2lzdHJ5W2FhXT1iYSx7c3VjY2VzczohMCxhc3luY0luaXQ6ITF9fWNhdGNoKGJhKXtyZXR1cm4gd2FybiQxKGBJbml0aWFsaXphdGlvbiBvZiBiYWNrZW5kICR7YWF9IGZhaWxlZGApLHdhcm4kMShiYS5zdGFja3x8YmEubWVzc2FnZSkse3N1Y2Nlc3M6ITEsYXN5bmNJbml0OiExfX19cmVtb3ZlQmFja2VuZChhYSl7aWYoIShhYSBpbiB0aGlzLnJlZ2lzdHJ5RmFjdG9yeSkpdGhyb3cgbmV3IEVycm9yKGAke2FhfSBiYWNrZW5kIG5vdCBmb3VuZCBpbiByZWdpc3RyeWApO3RoaXMuYmFja2VuZE5hbWU9PT1hYSYmdGhpcy5wZW5kaW5nQmFja2VuZEluaXQhPW51bGwmJnRoaXMucGVuZGluZ0JhY2tlbmRJbml0SWQrKyxhYSBpbiB0aGlzLnJlZ2lzdHJ5JiYodGhpcy5kaXNwb3NlUmVnaXN0ZXJlZEtlcm5lbHMoYWEpLHRoaXMucmVnaXN0cnlbYWFdLmRpc3Bvc2UoKSxkZWxldGUgdGhpcy5yZWdpc3RyeVthYV0pLGRlbGV0ZSB0aGlzLnJlZ2lzdHJ5RmFjdG9yeVthYV0sdGhpcy5iYWNrZW5kTmFtZT09PWFhJiYodGhpcy5wZW5kaW5nQmFja2VuZEluaXQ9bnVsbCx0aGlzLmJhY2tlbmROYW1lPW51bGwsdGhpcy5iYWNrZW5kSW5zdGFuY2U9bnVsbCl9Z2V0U29ydGVkQmFja2VuZHMoKXtpZihPYmplY3Qua2V5cyh0aGlzLnJlZ2lzdHJ5RmFjdG9yeSkubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoIk5vIGJhY2tlbmQgZm91bmQgaW4gcmVnaXN0cnkuIik7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMucmVnaXN0cnlGYWN0b3J5KS5zb3J0KChhYSx4YSk9PnRoaXMucmVnaXN0cnlGYWN0b3J5W3hhXS5wcmlvcml0eS10aGlzLnJlZ2lzdHJ5RmFjdG9yeVthYV0ucHJpb3JpdHkpfWluaXRpYWxpemVCYWNrZW5kc0FuZFJldHVybkJlc3QoKXtjb25zdCBhYT10aGlzLmdldFNvcnRlZEJhY2tlbmRzKCk7Zm9yKGxldCB4YT0wO3hhPGFhLmxlbmd0aDt4YSsrKXtjb25zdCBiYT1hYVt4YV0se3N1Y2Nlc3M6U2EsYXN5bmNJbml0OlRhfT10aGlzLmluaXRpYWxpemVCYWNrZW5kKGJhKTtpZihUYXx8U2EpcmV0dXJue25hbWU6YmEsYXN5bmNJbml0OlRhfX10aHJvdyBuZXcgRXJyb3IoIkNvdWxkIG5vdCBpbml0aWFsaXplIGFueSBiYWNrZW5kcywgYWxsIGJhY2tlbmQgaW5pdGlhbGl6YXRpb25zIGZhaWxlZC4iKX1tb3ZlRGF0YShhYSx4YSl7Y29uc3QgYmE9dGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmdldCh4YSksU2E9YmEuYmFja2VuZCxUYT10aGlzLnJlYWRTeW5jKHhhKSx3YT1TYS5yZWZDb3VudCh4YSk7U2EuZGlzcG9zZURhdGEoeGEsITApLGJhLmJhY2tlbmQ9YWEsYWEubW92ZSh4YSxUYSxiYS5zaGFwZSxiYS5kdHlwZSx3YSksdGhpcy5zaG91bGRDaGVja0Zvck1lbUxlYWtzKCkmJnRoaXMuc3RhdGUubnVtRGF0YU1vdmVzU3RhY2tbdGhpcy5zdGF0ZS5udW1EYXRhTW92ZXNTdGFjay5sZW5ndGgtMV0rK310aWR5KGFhLHhhKXtsZXQgYmE9bnVsbDtpZih4YT09bnVsbCl7aWYodHlwZW9mIGFhIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiUGxlYXNlIHByb3ZpZGUgYSBmdW5jdGlvbiB0byB0aWR5KCkiKTt4YT1hYX1lbHNle2lmKHR5cGVvZiBhYSE9InN0cmluZyImJiEoYWEgaW5zdGFuY2VvZiBTdHJpbmcpKXRocm93IG5ldyBFcnJvcigiV2hlbiBjYWxsaW5nIHdpdGggdHdvIGFyZ3VtZW50cywgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRpZHkoKSBtdXN0IGJlIGEgc3RyaW5nIik7aWYodHlwZW9mIHhhIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiV2hlbiBjYWxsaW5nIHdpdGggdHdvIGFyZ3VtZW50cywgdGhlIDJuZCBhcmd1bWVudCB0byB0aWR5KCkgbXVzdCBiZSBhIGZ1bmN0aW9uIik7YmE9YWF9bGV0IFNhO3JldHVybiB0aGlzLnNjb3BlZFJ1bigoKT0+dGhpcy5zdGFydFNjb3BlKGJhKSwoKT0+dGhpcy5lbmRTY29wZShTYSksKCk9PihTYT14YSgpLFNhIGluc3RhbmNlb2YgUHJvbWlzZSYmY29uc29sZS5lcnJvcigiQ2Fubm90IHJldHVybiBhIFByb21pc2UgaW5zaWRlIG9mIHRpZHkuIiksU2EpKX1zY29wZWRSdW4oYWEseGEsYmEpe2FhKCk7dHJ5e2NvbnN0IFNhPWJhKCk7cmV0dXJuIHhhKCksU2F9Y2F0Y2goU2Epe3Rocm93IHhhKCksU2F9fW5leHRUZW5zb3JJZCgpe3JldHVybiBhYy5uZXh0VGVuc29ySWQrK31uZXh0VmFyaWFibGVJZCgpe3JldHVybiBhYy5uZXh0VmFyaWFibGVJZCsrfWNsb25lKGFhKXtjb25zdCB4YT1FTkdJTkUkMS5ydW5LZXJuZWwoSWRlbnRpdHkkMix7eDphYX0pLGJhPXt4OmFhfSxTYT13YT0+KHt4OigpPT57Y29uc3QgRWE9ImZsb2F0MzIiLGthPXt4OndhfSxBYT17ZHR5cGU6RWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQ2FzdCQxLGthLEFhKX19KSxUYT1bXTtyZXR1cm4gdGhpcy5hZGRUYXBlTm9kZSh0aGlzLnN0YXRlLmFjdGl2ZVNjb3BlLm5hbWUsYmEsW3hhXSxTYSxUYSx7fSkseGF9cnVuS2VybmVsKGFhLHhhLGJhKXtpZih0aGlzLmJhY2tlbmROYW1lPT1udWxsJiZ0aGlzLmJhY2tlbmQsIShnZXRLZXJuZWwkMShhYSx0aGlzLmJhY2tlbmROYW1lKSE9bnVsbCkpdGhyb3cgbmV3IEVycm9yKGBLZXJuZWwgJyR7YWF9JyBub3QgcmVnaXN0ZXJlZCBmb3IgYmFja2VuZCAnJHt0aGlzLmJhY2tlbmROYW1lfSdgKTtyZXR1cm4gdGhpcy5ydW5LZXJuZWxGdW5jKHtrZXJuZWxOYW1lOmFhLGlucHV0czp4YSxhdHRyczpiYX0pfXNob3VsZENoZWNrRm9yTWVtTGVha3MoKXtyZXR1cm4gdGhpcy5FTlYuZ2V0Qm9vbCgiSVNfVEVTVCIpfWNoZWNrS2VybmVsRm9yTWVtTGVhayhhYSx4YSxiYSl7Y29uc3QgU2E9dGhpcy5iYWNrZW5kLm51bURhdGFJZHMoKTtsZXQgVGE9MDtiYS5mb3JFYWNoKGthPT57VGErPWthLmR0eXBlPT09ImNvbXBsZXg2NCI/MzoxfSk7Y29uc3Qgd2E9dGhpcy5zdGF0ZS5udW1EYXRhTW92ZXNTdGFja1t0aGlzLnN0YXRlLm51bURhdGFNb3Zlc1N0YWNrLmxlbmd0aC0xXSxFYT1TYS14YS1UYS13YTtpZihFYT4wKXRocm93IG5ldyBFcnJvcihgQmFja2VuZCAnJHt0aGlzLmJhY2tlbmROYW1lfScgaGFzIGFuIGludGVybmFsIG1lbW9yeSBsZWFrICgke0VhfSBkYXRhIGlkcykgYWZ0ZXIgcnVubmluZyAnJHthYX0nYCl9cnVuS2VybmVsRnVuYyhhYSl7bGV0IHhhLGJhPVtdO2NvbnN0IFNhPXRoaXMuaXNUYXBlT24oKSxUYT10aGlzLnN0YXRlLm51bUJ5dGVzLHdhPXRoaXMuc3RhdGUubnVtVGVuc29yczt0aGlzLnNob3VsZENoZWNrRm9yTWVtTGVha3MoKSYmdGhpcy5zdGF0ZS5udW1EYXRhTW92ZXNTdGFjay5wdXNoKDApO2xldCBFYTt0aGlzLmJhY2tlbmROYW1lPT1udWxsJiZ0aGlzLmJhY2tlbmQ7bGV0IGthO2NvbnN0IEFhPWlzUmVnaXN0ZXJlZEtlcm5lbEludm9jYXRpb24kMShhYSk/YWEua2VybmVsTmFtZTp0aGlzLnN0YXRlLmFjdGl2ZVNjb3BlIT1udWxsP3RoaXMuc3RhdGUuYWN0aXZlU2NvcGUubmFtZToiIjtpZihpc1JlZ2lzdGVyZWRLZXJuZWxJbnZvY2F0aW9uJDEoYWEpKXtjb25zdHtrZXJuZWxOYW1lOm5sLGlucHV0czpzbCxhdHRyczpybH09YWE7dGhpcy5iYWNrZW5kTmFtZT09bnVsbCYmdGhpcy5iYWNrZW5kO2NvbnN0IG9sPWdldEtlcm5lbCQxKG5sLHRoaXMuYmFja2VuZE5hbWUpO2Fzc2VydCQyKG9sIT1udWxsLCgpPT5gQ2Fubm90IGZpbmQgcmVnaXN0ZXJlZCBrZXJuZWwgJyR7bmx9JyBmb3IgYmFja2VuZCAnJHt0aGlzLmJhY2tlbmROYW1lfSdgKSxFYT0oKT0+e2NvbnN0IGFsPXRoaXMuYmFja2VuZC5udW1EYXRhSWRzKCk7a2E9b2wua2VybmVsRnVuYyh7aW5wdXRzOnNsLGF0dHJzOnJsLGJhY2tlbmQ6dGhpcy5iYWNrZW5kfSk7Y29uc3QgbGw9QXJyYXkuaXNBcnJheShrYSk/a2E6W2thXTt0aGlzLnNob3VsZENoZWNrRm9yTWVtTGVha3MoKSYmdGhpcy5jaGVja0tlcm5lbEZvck1lbUxlYWsobmwsYWwsbGwpO2NvbnN0IGlsPWxsLm1hcChjbD0+Y2wucmFuayE9bnVsbD9jbDp0aGlzLm1ha2VUZW5zb3JGcm9tVGVuc29ySW5mbyhjbCkpO2lmKFNhKXtjb25zdCBjbD10aGlzLmdldFRlbnNvcnNGb3JHcmFkaWVudChubCxzbCxpbCk7YmE9dGhpcy5zYXZlVGVuc29yc0ZvckJhY2t3YXJkTW9kZShjbCl9cmV0dXJuIGlsfX1lbHNle2NvbnN0e2ZvcndhcmRGdW5jOm5sfT1hYSxzbD1ybD0+e1NhJiYoYmE9cmwubWFwKG9sPT50aGlzLmtlZXAodGhpcy5jbG9uZShvbCkpKSl9O0VhPSgpPT57Y29uc3Qgcmw9dGhpcy5iYWNrZW5kLm51bURhdGFJZHMoKTtrYT10aGlzLnRpZHkoKCk9Pm5sKHRoaXMuYmFja2VuZCxzbCkpO2NvbnN0IG9sPUFycmF5LmlzQXJyYXkoa2EpP2thOltrYV07cmV0dXJuIHRoaXMuc2hvdWxkQ2hlY2tGb3JNZW1MZWFrcygpJiZ0aGlzLmNoZWNrS2VybmVsRm9yTWVtTGVhayhBYSxybCxvbCksb2x9fWNvbnN0e2lucHV0czpGYSxhdHRyczpMYX09YWEsZWw9aXNSZWdpc3RlcmVkS2VybmVsSW52b2NhdGlvbiQxKGFhKT9udWxsOmFhLmJhY2t3YXJkc0Z1bmM7bGV0IHRsO3JldHVybiB0aGlzLnNjb3BlZFJ1bigoKT0+dGhpcy5zdGF0ZS5rZXJuZWxEZXB0aCsrLCgpPT50aGlzLnN0YXRlLmtlcm5lbERlcHRoLS0sKCk9PnshdGhpcy5FTlYuZ2V0Qm9vbCgiREVCVUciKSYmIXRoaXMuc3RhdGUucHJvZmlsaW5nP3hhPUVhKCk6KHRsPXRoaXMucHJvZmlsZXIucHJvZmlsZUtlcm5lbChBYSxGYSwoKT0+RWEoKSksdGhpcy5FTlYuZ2V0Qm9vbCgiREVCVUciKSYmdGhpcy5wcm9maWxlci5sb2dLZXJuZWxQcm9maWxlKHRsKSx4YT10bC5vdXRwdXRzKX0pLFNhJiZ0aGlzLmFkZFRhcGVOb2RlKEFhLEZhLHhhLGVsLGJhLExhKSx0aGlzLnN0YXRlLnByb2ZpbGluZyYmdGhpcy5zdGF0ZS5hY3RpdmVQcm9maWxlLmtlcm5lbHMucHVzaCh7bmFtZTpBYSxieXRlc0FkZGVkOnRoaXMuc3RhdGUubnVtQnl0ZXMtVGEsdG90YWxCeXRlc1NuYXBzaG90OnRoaXMuc3RhdGUubnVtQnl0ZXMsdGVuc29yc0FkZGVkOnRoaXMuc3RhdGUubnVtVGVuc29ycy13YSx0b3RhbFRlbnNvcnNTbmFwc2hvdDp0aGlzLnN0YXRlLm51bVRlbnNvcnMsaW5wdXRTaGFwZXM6T2JqZWN0LmtleXMoRmEpLm1hcChubD0+RmFbbmxdIT1udWxsP0ZhW25sXS5zaGFwZTpudWxsKSxvdXRwdXRTaGFwZXM6eGEubWFwKG5sPT5ubC5zaGFwZSksa2VybmVsVGltZU1zOnRsLnRpbWVNcyxleHRyYUluZm86dGwuZXh0cmFJbmZvfSksQXJyYXkuaXNBcnJheShrYSk/eGE6eGFbMF19c2F2ZVRlbnNvcnNGb3JCYWNrd2FyZE1vZGUoYWEpe3JldHVybiBhYS5tYXAoYmE9PnRoaXMua2VlcCh0aGlzLmNsb25lKGJhKSkpfWdldFRlbnNvcnNGb3JHcmFkaWVudChhYSx4YSxiYSl7Y29uc3QgU2E9Z2V0R3JhZGllbnQkMShhYSk7aWYoU2EhPW51bGwpe2NvbnN0IFRhPVNhLmlucHV0c1RvU2F2ZXx8W10sd2E9U2Eub3V0cHV0c1RvU2F2ZXx8W107bGV0IEVhO1NhLnNhdmVBbGxJbnB1dHM/KGFzc2VydCQyKEFycmF5LmlzQXJyYXkoeGEpLCgpPT4ic2F2ZUFsbElucHV0cyBpcyB0cnVlLCBleHBlY3RlZCBpbnB1dHMgdG8gYmUgYW4gYXJyYXkuIiksRWE9T2JqZWN0LmtleXMoeGEpLm1hcChBYT0+eGFbQWFdKSk6RWE9VGEubWFwKEFhPT54YVtBYV0pO2NvbnN0IGthPWJhLmZpbHRlcigoQWEsRmEpPT53YVtGYV0pO3JldHVybiBFYS5jb25jYXQoa2EpfXJldHVybltdfW1ha2VUZW5zb3IoYWEseGEsYmEsU2Epe2lmKGFhPT1udWxsKXRocm93IG5ldyBFcnJvcigiVmFsdWVzIHBhc3NlZCB0byBlbmdpbmUubWFrZVRlbnNvcigpIGFyZSBudWxsIik7YmE9YmF8fCJmbG9hdDMyIixTYT1TYXx8dGhpcy5iYWNrZW5kO2xldCBUYT1hYTtiYT09PSJzdHJpbmciJiZpc1N0cmluZyQxKGFhWzBdKSYmKFRhPWFhLm1hcChrYT0+ZW5jb2RlU3RyaW5nJDEoa2EpKSk7Y29uc3Qgd2E9U2Eud3JpdGUoVGEseGEsYmEpLEVhPW5ldyBUZW5zb3IkMSh4YSxiYSx3YSx0aGlzLm5leHRUZW5zb3JJZCgpKTtpZih0aGlzLnRyYWNrVGVuc29yKEVhLFNhKSxiYT09PSJzdHJpbmciKXtjb25zdCBrYT10aGlzLnN0YXRlLnRlbnNvckluZm8uZ2V0KHdhKSxBYT1ieXRlc0Zyb21TdHJpbmdBcnJheSQxKFRhKTt0aGlzLnN0YXRlLm51bUJ5dGVzKz1BYS1rYS5ieXRlcyxrYS5ieXRlcz1BYX1yZXR1cm4gRWF9bWFrZVRlbnNvckZyb21EYXRhSWQoYWEseGEsYmEsU2Epe2JhPWJhfHwiZmxvYXQzMiI7Y29uc3QgVGE9e2RhdGFJZDphYSxzaGFwZTp4YSxkdHlwZTpiYX07cmV0dXJuIHRoaXMubWFrZVRlbnNvckZyb21UZW5zb3JJbmZvKFRhLFNhKX1tYWtlVGVuc29yRnJvbVRlbnNvckluZm8oYWEseGEpe2NvbnN0e2RhdGFJZDpiYSxzaGFwZTpTYSxkdHlwZTpUYX09YWEsd2E9bmV3IFRlbnNvciQxKFNhLFRhLGJhLHRoaXMubmV4dFRlbnNvcklkKCkpO3JldHVybiB0aGlzLnRyYWNrVGVuc29yKHdhLHhhKSx3YX1tYWtlVmFyaWFibGUoYWEseGE9ITAsYmEsU2Epe2JhPWJhfHx0aGlzLm5leHRWYXJpYWJsZUlkKCkudG9TdHJpbmcoKSxTYSE9bnVsbCYmU2EhPT1hYS5kdHlwZSYmKGFhPWFhLmNhc3QoU2EpKTtjb25zdCBUYT1uZXcgVmFyaWFibGUkMShhYSx4YSxiYSx0aGlzLm5leHRUZW5zb3JJZCgpKTtpZih0aGlzLnN0YXRlLnJlZ2lzdGVyZWRWYXJpYWJsZXNbVGEubmFtZV0hPW51bGwpdGhyb3cgbmV3IEVycm9yKGBWYXJpYWJsZSB3aXRoIG5hbWUgJHtUYS5uYW1lfSB3YXMgYWxyZWFkeSByZWdpc3RlcmVkYCk7cmV0dXJuIHRoaXMuc3RhdGUucmVnaXN0ZXJlZFZhcmlhYmxlc1tUYS5uYW1lXT1UYSx0aGlzLmluY1JlZihUYSx0aGlzLmJhY2tlbmQpLFRhfXRyYWNrVGVuc29yKGFhLHhhKXt0aGlzLnN0YXRlLm51bVRlbnNvcnMrKyxhYS5kdHlwZT09PSJzdHJpbmciJiZ0aGlzLnN0YXRlLm51bVN0cmluZ1RlbnNvcnMrKztsZXQgYmE9MDthYS5kdHlwZSE9PSJjb21wbGV4NjQiJiZhYS5kdHlwZSE9PSJzdHJpbmciJiYoYmE9YWEuc2l6ZSpieXRlc1BlckVsZW1lbnQkMShhYS5kdHlwZSkpLHRoaXMuc3RhdGUubnVtQnl0ZXMrPWJhLHRoaXMuc3RhdGUudGVuc29ySW5mby5oYXMoYWEuZGF0YUlkKXx8KHRoaXMuc3RhdGUubnVtRGF0YUJ1ZmZlcnMrKyx0aGlzLnN0YXRlLnRlbnNvckluZm8uc2V0KGFhLmRhdGFJZCx7YmFja2VuZDp4YXx8dGhpcy5iYWNrZW5kLGR0eXBlOmFhLmR0eXBlLHNoYXBlOmFhLnNoYXBlLGJ5dGVzOmJhfSkpLGFhIGluc3RhbmNlb2YgVmFyaWFibGUkMXx8dGhpcy50cmFjayhhYSl9aW5jUmVmKGFhLHhhKXt0aGlzLnRyYWNrVGVuc29yKGFhLHhhKSx0aGlzLmJhY2tlbmQuaW5jUmVmKGFhLmRhdGFJZCl9cmVtb3ZlRGF0YUlkKGFhLHhhKXt0aGlzLnN0YXRlLnRlbnNvckluZm8uaGFzKGFhKSYmdGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmdldChhYSkuYmFja2VuZD09PXhhJiYodGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmRlbGV0ZShhYSksdGhpcy5zdGF0ZS5udW1EYXRhQnVmZmVycy0tKX1kaXNwb3NlVGVuc29yKGFhKXtpZighdGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmhhcyhhYS5kYXRhSWQpKXJldHVybjtjb25zdCB4YT10aGlzLnN0YXRlLnRlbnNvckluZm8uZ2V0KGFhLmRhdGFJZCk7aWYodGhpcy5zdGF0ZS5udW1UZW5zb3JzLS0sYWEuZHR5cGU9PT0ic3RyaW5nIiYmKHRoaXMuc3RhdGUubnVtU3RyaW5nVGVuc29ycy0tLHRoaXMuc3RhdGUubnVtQnl0ZXMtPXhhLmJ5dGVzKSxhYS5kdHlwZSE9PSJjb21wbGV4NjQiJiZhYS5kdHlwZSE9PSJzdHJpbmciKXtjb25zdCBiYT1hYS5zaXplKmJ5dGVzUGVyRWxlbWVudCQxKGFhLmR0eXBlKTt0aGlzLnN0YXRlLm51bUJ5dGVzLT1iYX14YS5iYWNrZW5kLmRpc3Bvc2VEYXRhKGFhLmRhdGFJZCkmJnRoaXMucmVtb3ZlRGF0YUlkKGFhLmRhdGFJZCx4YS5iYWNrZW5kKX1kaXNwb3NlVmFyaWFibGVzKCl7Zm9yKGNvbnN0IGFhIGluIHRoaXMuc3RhdGUucmVnaXN0ZXJlZFZhcmlhYmxlcyl7Y29uc3QgeGE9dGhpcy5zdGF0ZS5yZWdpc3RlcmVkVmFyaWFibGVzW2FhXTt0aGlzLmRpc3Bvc2VWYXJpYWJsZSh4YSl9fWRpc3Bvc2VWYXJpYWJsZShhYSl7dGhpcy5kaXNwb3NlVGVuc29yKGFhKSx0aGlzLnN0YXRlLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYWEubmFtZV0hPW51bGwmJmRlbGV0ZSB0aGlzLnN0YXRlLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYWEubmFtZV19bWVtb3J5KCl7Y29uc3QgYWE9dGhpcy5iYWNrZW5kLm1lbW9yeSgpO3JldHVybiBhYS5udW1UZW5zb3JzPXRoaXMuc3RhdGUubnVtVGVuc29ycyxhYS5udW1EYXRhQnVmZmVycz10aGlzLnN0YXRlLm51bURhdGFCdWZmZXJzLGFhLm51bUJ5dGVzPXRoaXMuc3RhdGUubnVtQnl0ZXMsdGhpcy5zdGF0ZS5udW1TdHJpbmdUZW5zb3JzPjAmJihhYS51bnJlbGlhYmxlPSEwLGFhLnJlYXNvbnM9PW51bGwmJihhYS5yZWFzb25zPVtdKSxhYS5yZWFzb25zLnB1c2goIk1lbW9yeSB1c2FnZSBieSBzdHJpbmcgdGVuc29ycyBpcyBhcHByb3hpbWF0ZSAoMiBieXRlcyBwZXIgY2hhcmFjdGVyKSIpKSxhYX1hc3luYyBwcm9maWxlKGFhKXt0aGlzLnN0YXRlLnByb2ZpbGluZz0hMDtjb25zdCB4YT10aGlzLnN0YXRlLm51bUJ5dGVzLGJhPXRoaXMuc3RhdGUubnVtVGVuc29yczt0aGlzLnN0YXRlLmFjdGl2ZVByb2ZpbGUua2VybmVscz1bXSx0aGlzLnN0YXRlLmFjdGl2ZVByb2ZpbGUucmVzdWx0PWF3YWl0IGFhKCksdGhpcy5zdGF0ZS5wcm9maWxpbmc9ITEsdGhpcy5zdGF0ZS5hY3RpdmVQcm9maWxlLnBlYWtCeXRlcz1NYXRoLm1heCguLi50aGlzLnN0YXRlLmFjdGl2ZVByb2ZpbGUua2VybmVscy5tYXAoU2E9PlNhLnRvdGFsQnl0ZXNTbmFwc2hvdCkpLHRoaXMuc3RhdGUuYWN0aXZlUHJvZmlsZS5uZXdCeXRlcz10aGlzLnN0YXRlLm51bUJ5dGVzLXhhLHRoaXMuc3RhdGUuYWN0aXZlUHJvZmlsZS5uZXdUZW5zb3JzPXRoaXMuc3RhdGUubnVtVGVuc29ycy1iYTtmb3IoY29uc3QgU2Egb2YgdGhpcy5zdGF0ZS5hY3RpdmVQcm9maWxlLmtlcm5lbHMpU2Eua2VybmVsVGltZU1zPWF3YWl0IFNhLmtlcm5lbFRpbWVNcyxTYS5leHRyYUluZm89YXdhaXQgU2EuZXh0cmFJbmZvO3JldHVybiB0aGlzLnN0YXRlLmFjdGl2ZVByb2ZpbGV9aXNUYXBlT24oKXtyZXR1cm4gdGhpcy5zdGF0ZS5ncmFkaWVudERlcHRoPjAmJnRoaXMuc3RhdGUua2VybmVsRGVwdGg9PT0wfWFkZFRhcGVOb2RlKGFhLHhhLGJhLFNhLFRhLHdhKXtjb25zdCBFYT17aWQ6dGhpcy5zdGF0ZS5uZXh0VGFwZU5vZGVJZCsrLGtlcm5lbE5hbWU6YWEsaW5wdXRzOnhhLG91dHB1dHM6YmEsc2F2ZWQ6VGF9LGthPWdldEdyYWRpZW50JDEoYWEpO2thIT1udWxsJiYoU2E9a2EuZ3JhZEZ1bmMpLFNhIT1udWxsJiYoRWEuZ3JhZGllbnQ9QWE9PihBYT1BYS5tYXAoKEZhLExhKT0+e2lmKEZhPT1udWxsKXtjb25zdCBlbD1iYVtMYV0sdGw9bWFrZVplcm9zVHlwZWRBcnJheSQxKGVsLnNpemUsZWwuZHR5cGUpO3JldHVybiB0aGlzLm1ha2VUZW5zb3IodGwsZWwuc2hhcGUsZWwuZHR5cGUpfXJldHVybiBGYX0pLFNhKEFhLmxlbmd0aD4xP0FhOkFhWzBdLFRhLHdhKSkpLHRoaXMuc3RhdGUuYWN0aXZlVGFwZS5wdXNoKEVhKX1rZWVwKGFhKXtyZXR1cm4gYWEua2VwdD0hMCxhYX1zdGFydFRhcGUoKXt0aGlzLnN0YXRlLmdyYWRpZW50RGVwdGg9PT0wJiYodGhpcy5zdGF0ZS5hY3RpdmVUYXBlPVtdKSx0aGlzLnN0YXRlLmdyYWRpZW50RGVwdGgrK31lbmRUYXBlKCl7dGhpcy5zdGF0ZS5ncmFkaWVudERlcHRoLS19c3RhcnRTY29wZShhYSl7Y29uc3QgeGE9e3RyYWNrOltdLG5hbWU6InVubmFtZWQgc2NvcGUiLGlkOnRoaXMuc3RhdGUubmV4dFNjb3BlSWQrK307YWEmJih4YS5uYW1lPWFhKSx0aGlzLnN0YXRlLnNjb3BlU3RhY2sucHVzaCh4YSksdGhpcy5zdGF0ZS5hY3RpdmVTY29wZT14YX1lbmRTY29wZShhYSl7Y29uc3QgeGE9Z2V0VGVuc29yc0luQ29udGFpbmVyJDEoYWEpLGJhPW5ldyBTZXQoeGEubWFwKFRhPT5UYS5pZCkpO2ZvcihsZXQgVGE9MDtUYTx0aGlzLnN0YXRlLmFjdGl2ZVNjb3BlLnRyYWNrLmxlbmd0aDtUYSsrKXtjb25zdCB3YT10aGlzLnN0YXRlLmFjdGl2ZVNjb3BlLnRyYWNrW1RhXTshd2Eua2VwdCYmIWJhLmhhcyh3YS5pZCkmJndhLmRpc3Bvc2UoKX1jb25zdCBTYT10aGlzLnN0YXRlLnNjb3BlU3RhY2sucG9wKCk7dGhpcy5zdGF0ZS5hY3RpdmVTY29wZT10aGlzLnN0YXRlLnNjb3BlU3RhY2subGVuZ3RoPT09MD9udWxsOnRoaXMuc3RhdGUuc2NvcGVTdGFja1t0aGlzLnN0YXRlLnNjb3BlU3RhY2subGVuZ3RoLTFdLHhhLmZvckVhY2goVGE9PnshVGEua2VwdCYmVGEuc2NvcGVJZD09PVNhLmlkJiZ0aGlzLnRyYWNrKFRhKX0pfWdyYWRpZW50cyhhYSx4YSxiYSxTYT0hMSl7aWYoYXNzZXJ0JDIoeGEubGVuZ3RoPjAsKCk9PiJncmFkaWVudHMoKSByZWNlaXZlZCBhbiBlbXB0eSBsaXN0IG9mIHhzLiIpLGJhIT1udWxsJiZiYS5kdHlwZSE9PSJmbG9hdDMyIil0aHJvdyBuZXcgRXJyb3IoYGR5IG11c3QgaGF2ZSAnZmxvYXQzMicgZHR5cGUsIGJ1dCBoYXMgJyR7YmEuZHR5cGV9J2ApO2NvbnN0IFRhPXRoaXMuc2NvcGVkUnVuKCgpPT50aGlzLnN0YXJ0VGFwZSgpLCgpPT50aGlzLmVuZFRhcGUoKSwoKT0+dGhpcy50aWR5KCJmb3J3YXJkIixhYSkpO2Fzc2VydCQyKFRhIGluc3RhbmNlb2YgVGVuc29yJDEsKCk9PiJUaGUgcmVzdWx0IHkgcmV0dXJuZWQgYnkgZigpIG11c3QgYmUgYSB0ZW5zb3IuIik7Y29uc3Qgd2E9Z2V0RmlsdGVyZWROb2Rlc1hUb1kkMSh0aGlzLnN0YXRlLmFjdGl2ZVRhcGUseGEsVGEpO2lmKCFTYSYmd2EubGVuZ3RoPT09MCYmeGEubGVuZ3RoPjApdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgY29tcHV0ZSBncmFkaWVudCBvZiB5PWYoeCkgd2l0aCByZXNwZWN0IHRvIHguIE1ha2Ugc3VyZSB0aGF0IHRoZSBmIHlvdSBwYXNzZWQgZW5jbG9zZXMgYWxsIG9wZXJhdGlvbnMgdGhhdCBsZWFkIGZyb20geCB0byB5LiIpO3JldHVybiB0aGlzLnRpZHkoImJhY2t3YXJkIiwoKT0+e2NvbnN0IEVhPXt9O0VhW1RhLmlkXT1iYT8/b25lcyQyKFRhLnNoYXBlKSxiYWNrcHJvcGFnYXRlR3JhZGllbnRzJDEoRWEsd2EsQWE9PnRoaXMudGlkeShBYSksYWRkJDQpO2NvbnN0IGthPXhhLm1hcChBYT0+RWFbQWEuaWRdKTtyZXR1cm4gdGhpcy5zdGF0ZS5ncmFkaWVudERlcHRoPT09MCYmKHRoaXMuc3RhdGUuYWN0aXZlVGFwZS5mb3JFYWNoKEFhPT57Zm9yKGNvbnN0IEZhIG9mIEFhLnNhdmVkKUZhLmRpc3Bvc2UoKX0pLHRoaXMuc3RhdGUuYWN0aXZlVGFwZT1udWxsKSx7dmFsdWU6VGEsZ3JhZHM6a2F9fSl9Y3VzdG9tR3JhZChhYSl7cmV0dXJuIGFzc2VydCQyKGlzRnVuY3Rpb24kMShhYSksKCk9PiJUaGUgZiBwYXNzZWQgaW4gY3VzdG9tR3JhZChmKSBtdXN0IGJlIGEgZnVuY3Rpb24uIiksKC4uLnhhKT0+e2Fzc2VydCQyKHhhLmV2ZXJ5KEVhPT5FYSBpbnN0YW5jZW9mIFRlbnNvciQxKSwoKT0+IlRoZSBhcmdzIHBhc3NlZCBpbiBjdXN0b21HcmFkKGYpKHgxLCB4MiwuLi4pIG11c3QgYWxsIGJlIHRlbnNvcnMiKTtsZXQgYmE7Y29uc3QgU2E9e307eGEuZm9yRWFjaCgoRWEsa2EpPT57U2Fba2FdPUVhfSk7Y29uc3QgVGE9KEVhLGthKT0+KGJhPWFhKC4uLnhhLGthKSxhc3NlcnQkMihiYS52YWx1ZSBpbnN0YW5jZW9mIFRlbnNvciQxLCgpPT4iVGhlIGZ1bmN0aW9uIGYgcGFzc2VkIGluIGN1c3RvbUdyYWQoZikgbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdoZXJlIGBvYmoudmFsdWVgIGlzIGEgdGVuc29yIiksYXNzZXJ0JDIoaXNGdW5jdGlvbiQxKGJhLmdyYWRGdW5jKSwoKT0+IlRoZSBmdW5jdGlvbiBmIHBhc3NlZCBpbiBjdXN0b21HcmFkKGYpIG11c3QgcmV0dXJuIGFuIG9iamVjdCB3aGVyZSBgb2JqLmdyYWRGdW5jYCBpcyBhIGZ1bmN0aW9uLiIpLGJhLnZhbHVlKSx3YT0oRWEsa2EpPT57Y29uc3QgQWE9YmEuZ3JhZEZ1bmMoRWEsa2EpLEZhPUFycmF5LmlzQXJyYXkoQWEpP0FhOltBYV07YXNzZXJ0JDIoRmEubGVuZ3RoPT09eGEubGVuZ3RoLCgpPT4iVGhlIGZ1bmN0aW9uIGYgcGFzc2VkIGluIGN1c3RvbUdyYWQoZikgbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdoZXJlIGBvYmouZ3JhZEZ1bmNgIGlzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBzYW1lIG51bWJlciBvZiB0ZW5zb3JzIGFzIGlucHV0cyBwYXNzZWQgdG8gZiguLi4pLiIpLGFzc2VydCQyKEZhLmV2ZXJ5KGVsPT5lbCBpbnN0YW5jZW9mIFRlbnNvciQxKSwoKT0+IlRoZSBmdW5jdGlvbiBmIHBhc3NlZCBpbiBjdXN0b21HcmFkKGYpIG11c3QgcmV0dXJuIGFuIG9iamVjdCB3aGVyZSBgb2JqLmdyYWRGdW5jYCBpcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGxpc3Qgb2Ygb25seSB0ZW5zb3JzLiIpO2NvbnN0IExhPXt9O3JldHVybiBGYS5mb3JFYWNoKChlbCx0bCk9PntMYVt0bF09KCk9PmVsfSksTGF9O3JldHVybiB0aGlzLnJ1bktlcm5lbEZ1bmMoe2ZvcndhcmRGdW5jOlRhLGJhY2t3YXJkc0Z1bmM6d2EsaW5wdXRzOlNhfSl9fXJlYWRTeW5jKGFhKXtyZXR1cm4gdGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmdldChhYSkuYmFja2VuZC5yZWFkU3luYyhhYSl9cmVhZChhYSl7cmV0dXJuIHRoaXMuc3RhdGUudGVuc29ySW5mby5nZXQoYWEpLmJhY2tlbmQucmVhZChhYSl9cmVhZFRvR1BVKGFhLHhhKXtyZXR1cm4gdGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmdldChhYSkuYmFja2VuZC5yZWFkVG9HUFUoYWEseGEpfWFzeW5jIHRpbWUoYWEpe2NvbnN0IHhhPW5vdyQxKCksYmE9YXdhaXQgdGhpcy5iYWNrZW5kLnRpbWUoYWEpO3JldHVybiBiYS53YWxsTXM9bm93JDEoKS14YSxiYX10cmFjayhhYSl7cmV0dXJuIHRoaXMuc3RhdGUuYWN0aXZlU2NvcGUhPW51bGwmJihhYS5zY29wZUlkPXRoaXMuc3RhdGUuYWN0aXZlU2NvcGUuaWQsdGhpcy5zdGF0ZS5hY3RpdmVTY29wZS50cmFjay5wdXNoKGFhKSksYWF9Z2V0IHJlZ2lzdGVyZWRWYXJpYWJsZXMoKXtyZXR1cm4gdGhpcy5zdGF0ZS5yZWdpc3RlcmVkVmFyaWFibGVzfXJlc2V0KCl7dGhpcy5wZW5kaW5nQmFja2VuZEluaXRJZCsrLHRoaXMuc3RhdGUuZGlzcG9zZSgpLHRoaXMuRU5WLnJlc2V0KCksdGhpcy5zdGF0ZT1uZXcgRW5naW5lU3RhdGUkMTtmb3IoY29uc3QgYWEgaW4gdGhpcy5yZWdpc3RyeSl0aGlzLmRpc3Bvc2VSZWdpc3RlcmVkS2VybmVscyhhYSksdGhpcy5yZWdpc3RyeVthYV0uZGlzcG9zZSgpLGRlbGV0ZSB0aGlzLnJlZ2lzdHJ5W2FhXTt0aGlzLmJhY2tlbmROYW1lPW51bGwsdGhpcy5iYWNrZW5kSW5zdGFuY2U9bnVsbCx0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdD1udWxsfX07RW5naW5lJDEubmV4dFRlbnNvcklkPTAsRW5naW5lJDEubmV4dFZhcmlhYmxlSWQ9MDtmdW5jdGlvbiBvbmVzJDIoaGEpe2NvbnN0IGFhPW1ha2VPbmVzVHlwZWRBcnJheSQxKHNpemVGcm9tU2hhcGUkMShoYSksImZsb2F0MzIiKTtyZXR1cm4gRU5HSU5FJDEubWFrZVRlbnNvcihhYSxoYSwiZmxvYXQzMiIpfWZ1bmN0aW9uIGdldE9yTWFrZUVuZ2luZSQxKCl7Y29uc3QgaGE9Z2V0R2xvYmFsTmFtZXNwYWNlJDEoKTtpZihoYS5fdGZlbmdpbmU9PW51bGwpe2NvbnN0IGFhPW5ldyBFbnZpcm9ubWVudCQxKGhhKTtoYS5fdGZlbmdpbmU9bmV3IEVuZ2luZSQxKGFhKX1yZXR1cm4gc2V0RW52aXJvbm1lbnRHbG9iYWwkMShoYS5fdGZlbmdpbmUuRU5WKSxzZXRUZW5zb3JUcmFja2VyJDEoKCk9PmhhLl90ZmVuZ2luZSksaGEuX3RmZW5naW5lfWNvbnN0IEVOR0lORSQxPWdldE9yTWFrZUVuZ2luZSQxKCk7ZnVuY3Rpb24gYWRkJDQoaGEsYWEpe2NvbnN0IHhhPXthOmhhLGI6YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQWRkJDIseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIF9pc05hdmlnYXRvckRlZmluZWQkMSgpe3JldHVybiB0eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yIT1udWxsfWZ1bmN0aW9uIGlzTW9iaWxlJDEoaGEpe2lmKGhhfHxfaXNOYXZpZ2F0b3JEZWZpbmVkJDEoKSl7aWYoaGF8fChoYT1uYXZpZ2F0b3IpLGhhLnByb2R1Y3Q9PT0iUmVhY3ROYXRpdmUiKXJldHVybiEwO2NvbnN0IGFhPWhhLnVzZXJBZ2VudHx8aGEudmVuZG9yfHwodHlwZW9mIHdpbmRvdzwidSI/d2luZG93Lm9wZXJhOiIiKTtpZighYWEpe2NvbnN0IHhhPWhhO3JldHVybiB4YS51c2VyQWdlbnREYXRhJiZ4YS51c2VyQWdlbnREYXRhLm1vYmlsZX1yZXR1cm4vKGFuZHJvaWR8YmJcZCt8bWVlZ28pLittb2JpbGV8YXZhbnRnb3xiYWRhXC98YmxhY2tiZXJyeXxibGF6ZXJ8Y29tcGFsfGVsYWluZXxmZW5uZWN8aGlwdG9wfGllbW9iaWxlfGlwKGhvbmV8b2QpfGlyaXN8a2luZGxlfGxnZSB8bWFlbW98bWlkcHxtbXB8bW9iaWxlLitmaXJlZm94fG5ldGZyb250fG9wZXJhIG0ob2J8aW4paXxwYWxtKCBvcyk/fHBob25lfHAoaXhpfHJlKVwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXC4oYnJvd3NlcnxsaW5rKXx2b2RhZm9uZXx3YXB8d2luZG93cyBjZXx4ZGF8eGlpbm8vaS50ZXN0KGFhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcLSl8YWkoa298cm4pfGFsKGF2fGNhfGNvKXxhbW9pfGFuKGV4fG55fHl3KXxhcHR1fGFyKGNofGdvKXxhcyh0ZXx1cyl8YXR0d3xhdShkaXxcLW18ciB8cyApfGF2YW58YmUoY2t8bGx8bnEpfGJpKGxifHJkKXxibChhY3xheil8YnIoZXx2KXd8YnVtYnxid1wtKG58dSl8YzU1XC98Y2FwaXxjY3dhfGNkbVwtfGNlbGx8Y2h0bXxjbGRjfGNtZFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXC1zfGRldml8ZGljYXxkbW9ifGRvKGN8cClvfGRzKDEyfFwtZCl8ZWwoNDl8YWkpfGVtKGwyfHVsKXxlcihpY3xrMCl8ZXNsOHxleihbNC03XTB8b3N8d2F8emUpfGZldGN8Zmx5KFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXC01fGdcLW1vfGdvKFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFwtKG18cHx0KXxoZWlcLXxoaShwdHx0YSl8aHAoIGl8aXApfGhzXC1jfGh0KGMoXC18IHxffGF8Z3xwfHN8dCl8dHApfGh1KGF3fHRjKXxpXC0oMjB8Z298bWEpfGkyMzB8aWFjKCB8XC18XC8pfGlicm98aWRlYXxpZzAxfGlrb218aW0xa3xpbm5vfGlwYXF8aXJpc3xqYSh0fHYpYXxqYnJvfGplbXV8amlnc3xrZGRpfGtlaml8a2d0KCB8XC8pfGtsb258a3B0IHxrd2NcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XC8oa3xsfHUpfDUwfDU0fFwtW2Etd10pfGxpYnd8bHlueHxtMVwtd3xtM2dhfG01MFwvfG1hKHRlfHVpfHhvKXxtYygwMXwyMXxjYSl8bVwtY3J8bWUocmN8cmkpfG1pKG84fG9hfHRzKXxtbWVmfG1vKDAxfDAyfGJpfGRlfGRvfHQoXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVwtfG9ufHRmfHdmfHdnfHd0KXxub2soNnxpKXxuenBofG8yaW18b3AodGl8d3YpfG9yYW58b3dnMXxwODAwfHBhbihhfGR8dCl8cGR4Z3xwZygxM3xcLShbMS04XXxjKSl8cGhpbHxwaXJlfHBsKGF5fHVjKXxwblwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XC1nfHFhXC1hfHFjKDA3fDEyfDIxfDMyfDYwfFwtWzItN118aVwtKXxxdGVrfHIzODB8cjYwMHxyYWtzfHJpbTl8cm8odmV8em8pfHM1NVwvfHNhKGdlfG1hfG1tfG1zfG55fHZhKXxzYygwMXxoXC18b298cFwtKXxzZGtcL3xzZShjKFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFwtfHNoYXJ8c2llKFwtfG0pfHNrXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcLXx2XC18diApfHN5KDAxfG1iKXx0MigxOHw1MCl8dDYoMDB8MTB8MTgpfHRhKGd0fGxrKXx0Y2xcLXx0ZGdcLXx0ZWwoaXxtKXx0aW1cLXx0XC1tb3x0byhwbHxzaCl8dHMoNzB8bVwtfG0zfG01KXx0eFwtOXx1cChcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcLXYpfHZtNDB8dm9kYXx2dWxjfHZ4KDUyfDUzfDYwfDYxfDcwfDgwfDgxfDgzfDg1fDk4KXx3M2MoXC18ICl8d2ViY3x3aGl0fHdpKGcgfG5jfG53KXx3bWxifHdvbnV8eDcwMHx5YXNcLXx5b3VyfHpldG98enRlXC0vaS50ZXN0KGFhLnN1YnN0cigwLDQpKX1yZXR1cm4hMX1mdW5jdGlvbiBpc0Jyb3dzZXIkMSgpe3JldHVybiB0eXBlb2Ygd2luZG93PCJ1IiYmd2luZG93LmRvY3VtZW50IT1udWxsfHx0eXBlb2YgV29ya2VyR2xvYmFsU2NvcGU8InUifS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVOViQ2PWVudiQxKCk7RU5WJDYucmVnaXN0ZXJGbGFnKCJERUJVRyIsKCk9PiExLGhhPT57aGEmJmNvbnNvbGUud2FybigiRGVidWdnaW5nIG1vZGUgaXMgT04uIFRoZSBvdXRwdXQgb2YgZXZlcnkgbWF0aCBjYWxsIHdpbGwgYmUgZG93bmxvYWRlZCB0byBDUFUgYW5kIGNoZWNrZWQgZm9yIE5hTnMuIFRoaXMgc2lnbmlmaWNhbnRseSBpbXBhY3RzIHBlcmZvcm1hbmNlLiIpfSksRU5WJDYucmVnaXN0ZXJGbGFnKCJJU19CUk9XU0VSIiwoKT0+aXNCcm93c2VyJDEoKSksRU5WJDYucmVnaXN0ZXJGbGFnKCJJU19OT0RFIiwoKT0+dHlwZW9mIHByb2Nlc3M8InUiJiZ0eXBlb2YgcHJvY2Vzcy52ZXJzaW9uczwidSImJnR5cGVvZiBwcm9jZXNzLnZlcnNpb25zLm5vZGU8InUiKSxFTlYkNi5yZWdpc3RlckZsYWcoIklTX0NIUk9NRSIsKCk9PnR5cGVvZiBuYXZpZ2F0b3I8InUiJiZuYXZpZ2F0b3IhPW51bGwmJm5hdmlnYXRvci51c2VyQWdlbnQhPW51bGwmJi9DaHJvbWUvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkmJi9Hb29nbGUgSW5jLy50ZXN0KG5hdmlnYXRvci52ZW5kb3IpKSxFTlYkNi5yZWdpc3RlckZsYWcoIklTX1NBRkFSSSIsKCk9PnR5cGVvZiBuYXZpZ2F0b3I8InUiJiZuYXZpZ2F0b3IhPW51bGwmJm5hdmlnYXRvci51c2VyQWdlbnQhPW51bGwmJi9TYWZhcmkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkmJi9BcHBsZS8udGVzdChuYXZpZ2F0b3IudmVuZG9yKSksRU5WJDYucmVnaXN0ZXJGbGFnKCJQUk9EIiwoKT0+ITEpLEVOViQ2LnJlZ2lzdGVyRmxhZygiVEVOU09STElLRV9DSEVDS19TSEFQRV9DT05TSVNURU5DWSIsKCk9PkVOViQ2LmdldEJvb2woIkRFQlVHIikpLEVOViQ2LnJlZ2lzdGVyRmxhZygiREVQUkVDQVRJT05fV0FSTklOR1NfRU5BQkxFRCIsKCk9PiEwKSxFTlYkNi5yZWdpc3RlckZsYWcoIklTX1RFU1QiLCgpPT4hMSksRU5WJDYucmVnaXN0ZXJGbGFnKCJDSEVDS19DT01QVVRBVElPTl9GT1JfRVJST1JTIiwoKT0+RU5WJDYuZ2V0Qm9vbCgiREVCVUciKSksRU5WJDYucmVnaXN0ZXJGbGFnKCJXUkFQX1RPX0lNQUdFQklUTUFQIiwoKT0+ITEpLEVOViQ2LnJlZ2lzdGVyRmxhZygiQ0FOVkFTMkRfV0lMTF9SRUFEX0ZSRVFVRU5UTFlfRk9SX0dQVSIsKCk9PiExKSxFTlYkNi5yZWdpc3RlckZsYWcoIlVTRV9TRVRUSU1FT1VUQ1VTVE9NIiwoKT0+ITEpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGluZmVyU2hhcGUkMShoYSxhYSl7bGV0IHhhPWhhO2lmKGlzVHlwZWRBcnJheSQxKGhhKSlyZXR1cm4gYWE9PT0ic3RyaW5nIj9bXTpbaGEubGVuZ3RoXTtpZihpc1dlYkdMRGF0YSQxKGhhKSl7Y29uc3QgU2E9aGEuY2hhbm5lbHN8fCJSR0JBIjtyZXR1cm5baGEuaGVpZ2h0LGhhLndpZHRoKlNhLmxlbmd0aF19ZWxzZSBpZihpc1dlYkdQVURhdGEkMShoYSkpcmV0dXJuW2hhLmJ1ZmZlci5zaXplLyhhYT09bnVsbD80OmJ5dGVzUGVyRWxlbWVudCQxKGFhKSldO2lmKCFBcnJheS5pc0FycmF5KGhhKSlyZXR1cm5bXTtjb25zdCBiYT1bXTtmb3IoO0FycmF5LmlzQXJyYXkoeGEpfHxpc1R5cGVkQXJyYXkkMSh4YSkmJmFhIT09InN0cmluZyI7KWJhLnB1c2goeGEubGVuZ3RoKSx4YT14YVswXTtyZXR1cm4gQXJyYXkuaXNBcnJheShoYSkmJmVudiQxKCkuZ2V0Qm9vbCgiVEVOU09STElLRV9DSEVDS19TSEFQRV9DT05TSVNURU5DWSIpJiZkZWVwQXNzZXJ0U2hhcGVDb25zaXN0ZW5jeSQxKGhhLGJhLFtdKSxiYX1mdW5jdGlvbiBkZWVwQXNzZXJ0U2hhcGVDb25zaXN0ZW5jeSQxKGhhLGFhLHhhKXtpZih4YT14YXx8W10sIUFycmF5LmlzQXJyYXkoaGEpJiYhaXNUeXBlZEFycmF5JDEoaGEpKXthc3NlcnQkMihhYS5sZW5ndGg9PT0wLCgpPT5gRWxlbWVudCBhcnJbJHt4YS5qb2luKCJdWyIpfV0gaXMgYSBwcmltaXRpdmUsIGJ1dCBzaG91bGQgYmUgYW4gYXJyYXkvVHlwZWRBcnJheSBvZiAke2FhWzBdfSBlbGVtZW50c2ApO3JldHVybn1hc3NlcnQkMihhYS5sZW5ndGg+MCwoKT0+YEVsZW1lbnQgYXJyWyR7eGEuam9pbigiXVsiKX1dIHNob3VsZCBiZSBhIHByaW1pdGl2ZSwgYnV0IGlzIGFuIGFycmF5IG9mICR7aGEubGVuZ3RofSBlbGVtZW50c2ApLGFzc2VydCQyKGhhLmxlbmd0aD09PWFhWzBdLCgpPT5gRWxlbWVudCBhcnJbJHt4YS5qb2luKCJdWyIpfV0gc2hvdWxkIGhhdmUgJHthYVswXX0gZWxlbWVudHMsIGJ1dCBoYXMgJHtoYS5sZW5ndGh9IGVsZW1lbnRzYCk7Y29uc3QgYmE9YWEuc2xpY2UoMSk7Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aDsrK1NhKWRlZXBBc3NlcnRTaGFwZUNvbnNpc3RlbmN5JDEoaGFbU2FdLGJhLHhhLmNvbmNhdChTYSkpfWZ1bmN0aW9uIGFzc2VydER0eXBlJDEoaGEsYWEseGEsYmEpe2lmKGhhIT09InN0cmluZ19vcl9udW1lcmljIil7aWYoaGE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJFeHBlY3RlZCBkdHlwZSBjYW5ub3QgYmUgbnVsbC4iKTtpZihoYSE9PSJudW1lcmljIiYmaGEhPT1hYXx8aGE9PT0ibnVtZXJpYyImJmFhPT09InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKGBBcmd1bWVudCAnJHt4YX0nIHBhc3NlZCB0byAnJHtiYX0nIG11c3QgYmUgJHtoYX0gdGVuc29yLCBidXQgZ290ICR7YWF9IHRlbnNvcmApfX1mdW5jdGlvbiBjb252ZXJ0VG9UZW5zb3IkMShoYSxhYSx4YSxiYT0ibnVtZXJpYyIpe2lmKGhhIGluc3RhbmNlb2YgZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpKXJldHVybiBhc3NlcnREdHlwZSQxKGJhLGhhLmR0eXBlLGFhLHhhKSxoYTtsZXQgU2E9aW5mZXJEdHlwZSQxKGhhKTtpZihTYSE9PSJzdHJpbmciJiZbImJvb2wiLCJpbnQzMiIsImZsb2F0MzIiXS5pbmRleE9mKGJhKT49MCYmKFNhPWJhKSxhc3NlcnREdHlwZSQxKGJhLFNhLGFhLHhhKSxoYT09bnVsbHx8IWlzVHlwZWRBcnJheSQxKGhhKSYmIUFycmF5LmlzQXJyYXkoaGEpJiZ0eXBlb2YgaGEhPSJudW1iZXIiJiZ0eXBlb2YgaGEhPSJib29sZWFuIiYmdHlwZW9mIGhhIT0ic3RyaW5nIil7Y29uc3Qga2E9aGE9PW51bGw/Im51bGwiOmhhLmNvbnN0cnVjdG9yLm5hbWU7dGhyb3cgbmV3IEVycm9yKGBBcmd1bWVudCAnJHthYX0nIHBhc3NlZCB0byAnJHt4YX0nIG11c3QgYmUgYSBUZW5zb3Igb3IgVGVuc29yTGlrZSwgYnV0IGdvdCAnJHtrYX0nYCl9Y29uc3QgVGE9aW5mZXJTaGFwZSQxKGhhLFNhKTshaXNUeXBlZEFycmF5JDEoaGEpJiYhQXJyYXkuaXNBcnJheShoYSkmJihoYT1baGFdKTtjb25zdCBFYT1TYSE9PSJzdHJpbmciP3RvVHlwZWRBcnJheSQxKGhhLFNhKTpmbGF0dGVuJDIoaGEsW10sITApO3JldHVybiBFTkdJTkUkMS5tYWtlVGVuc29yKEVhLFRhLFNhKX1mdW5jdGlvbiBjb252ZXJ0VG9UZW5zb3JBcnJheShoYSxhYSx4YSxiYT0ibnVtZXJpYyIpe2lmKCFBcnJheS5pc0FycmF5KGhhKSl0aHJvdyBuZXcgRXJyb3IoYEFyZ3VtZW50ICR7YWF9IHBhc3NlZCB0byAke3hhfSBtdXN0IGJlIGEgXGBUZW5zb3JbXVxgIG9yIFxgVGVuc29yTGlrZVtdXGBgKTtyZXR1cm4gaGEubWFwKChUYSx3YSk9PmNvbnZlcnRUb1RlbnNvciQxKFRhLGAke2FhfVske3dhfV1gLHhhLGJhKSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgT1BfU0NPUEVfU1VGRklYJDE9Il9fb3AiO2Z1bmN0aW9uIG9wJDEoaGEpe2NvbnN0IGFhPU9iamVjdC5rZXlzKGhhKTtpZihhYS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgUGxlYXNlIHByb3ZpZGUgYW4gb2JqZWN0IHdpdGggYSBzaW5nbGUga2V5IChvcGVyYXRpb24gbmFtZSkgbWFwcGluZyB0byBhIGZ1bmN0aW9uLiBHb3QgYW4gb2JqZWN0IHdpdGggJHthYS5sZW5ndGh9IGtleXMuYCk7bGV0IHhhPWFhWzBdO2NvbnN0IGJhPWhhW3hhXTt4YS5lbmRzV2l0aCgiXyIpJiYoeGE9eGEuc3Vic3RyaW5nKDAseGEubGVuZ3RoLTEpKSx4YT14YStPUF9TQ09QRV9TVUZGSVgkMTtjb25zdCBTYT0oLi4uVGEpPT57RU5HSU5FJDEuc3RhcnRTY29wZSh4YSk7dHJ5e2NvbnN0IHdhPWJhKC4uLlRhKTtyZXR1cm4gaXNQcm9taXNlJDEod2EpJiZjb25zb2xlLmVycm9yKCJDYW5ub3QgcmV0dXJuIGEgUHJvbWlzZSBpbnNpZGUgb2YgdGlkeS4iKSxFTkdJTkUkMS5lbmRTY29wZSh3YSksd2F9Y2F0Y2god2Epe3Rocm93IEVOR0lORSQxLmVuZFNjb3BlKG51bGwpLHdhfX07cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTYSwibmFtZSIse3ZhbHVlOnhhLGNvbmZpZ3VyYWJsZTohMH0pLFNhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbXBsZXhfJDEoaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJyZWFsIiwiY29tcGxleCIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJpbWFnIiwiY29tcGxleCIpO2Fzc2VydFNoYXBlc01hdGNoJDEoeGEuc2hhcGUsYmEuc2hhcGUsYHJlYWwgYW5kIGltYWcgc2hhcGVzLCAke3hhLnNoYXBlfSBhbmQgJHtiYS5zaGFwZX0sIG11c3QgbWF0Y2ggaW4gY2FsbCB0byB0Zi5jb21wbGV4KCkuYCk7Y29uc3QgU2E9e3JlYWw6eGEsaW1hZzpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChDb21wbGV4JDEsU2EpfWNvbnN0IGNvbXBsZXgkND1vcCQxKHtjb21wbGV4Xzpjb21wbGV4XyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWFrZVRlbnNvciQxKGhhLGFhLHhhLGJhKXtpZihiYT09bnVsbCliYT1pbmZlckR0eXBlJDEoaGEpO2Vsc2UgaWYoYmE9PT0iY29tcGxleDY0Iil0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBjb25zdHJ1Y3QgYSBjb21wbGV4NjQgdGVuc29yIGRpcmVjdGx5LiBQbGVhc2UgdXNlIHRmLmNvbXBsZXgocmVhbCwgaW1hZykuIik7aWYoaXNXZWJHUFVEYXRhJDEoaGEpfHxpc1dlYkdMRGF0YSQxKGhhKSl7aWYoYmEhPT0iZmxvYXQzMiImJmJhIT09ImludDMyIil0aHJvdyBuZXcgRXJyb3IoYENyZWF0aW5nIHRlbnNvciBmcm9tIEdQVSBkYXRhIG9ubHkgc3VwcG9ydHMgJ2Zsb2F0MzInfCdpbnQzMicgZHR5cGUsIHdoaWxlIHRoZSBkdHlwZSBpcyAke2JhfS5gKTtyZXR1cm4gRU5HSU5FJDEuYmFja2VuZC5jcmVhdGVUZW5zb3JGcm9tR1BVRGF0YShoYSxhYXx8eGEsYmEpfWlmKCFpc1R5cGVkQXJyYXkkMShoYSkmJiFBcnJheS5pc0FycmF5KGhhKSYmdHlwZW9mIGhhIT0ibnVtYmVyIiYmdHlwZW9mIGhhIT0iYm9vbGVhbiImJnR5cGVvZiBoYSE9InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKCJ2YWx1ZXMgcGFzc2VkIHRvIHRlbnNvcih2YWx1ZXMpIG11c3QgYmUgYSBudW1iZXIvYm9vbGVhbi9zdHJpbmcgb3IgYW4gYXJyYXkgb2YgbnVtYmVycy9ib29sZWFucy9zdHJpbmdzLCBvciBhIFR5cGVkQXJyYXkiKTtpZihhYSE9bnVsbCl7YXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKGFhKTtjb25zdCBTYT1zaXplRnJvbVNoYXBlJDEoYWEpLFRhPXNpemVGcm9tU2hhcGUkMSh4YSk7YXNzZXJ0JDIoU2E9PT1UYSwoKT0+YEJhc2VkIG9uIHRoZSBwcm92aWRlZCBzaGFwZSwgWyR7YWF9XSwgdGhlIHRlbnNvciBzaG91bGQgaGF2ZSAke1NhfSB2YWx1ZXMgYnV0IGhhcyAke1RhfWApO2ZvcihsZXQgd2E9MDt3YTx4YS5sZW5ndGg7Kyt3YSl7Y29uc3QgRWE9eGFbd2FdLGthPXdhPT09eGEubGVuZ3RoLTE/RWEhPT1zaXplRnJvbVNoYXBlJDEoYWEuc2xpY2Uod2EpKTohMDthc3NlcnQkMih4YVt3YV09PT1hYVt3YV18fCFrYSwoKT0+YEVycm9yIGNyZWF0aW5nIGEgbmV3IFRlbnNvci4gSW5mZXJyZWQgc2hhcGUgKCR7eGF9KSBkb2VzIG5vdCBtYXRjaCB0aGUgcHJvdmlkZWQgc2hhcGUgKCR7YWF9KS4gYCl9fXJldHVybiFpc1R5cGVkQXJyYXkkMShoYSkmJiFBcnJheS5pc0FycmF5KGhhKSYmKGhhPVtoYV0pLGFhPWFhfHx4YSxoYT1iYSE9PSJzdHJpbmciP3RvVHlwZWRBcnJheSQxKGhhLGJhKTpmbGF0dGVuJDIoaGEsW10sITApLEVOR0lORSQxLm1ha2VUZW5zb3IoaGEsYWEsYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRlbnNvcihoYSxhYSx4YSl7Y29uc3QgYmE9aW5mZXJTaGFwZSQxKGhhLHhhKTtyZXR1cm4gbWFrZVRlbnNvciQxKGhhLGFhLGJhLHhhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBEVFlQRV9WQUxVRV9TSVpFX01BUD17ZmxvYXQzMjo0LGZsb2F0MTY6MixpbnQzMjo0LHVpbnQxNjoyLHVpbnQ4OjEsYm9vbDoxLGNvbXBsZXg2NDo4fTtsZXQgQ29tcG9zaXRlQXJyYXlCdWZmZXIkMT1jbGFzcyBjY3tzdGF0aWMgam9pbihhYSl7cmV0dXJuIG5ldyBjYyhhYSkuc2xpY2UoKX1jb25zdHJ1Y3RvcihhYSl7aWYodGhpcy5zaGFyZHM9W10sdGhpcy5wcmV2aW91c1NoYXJkSW5kZXg9MCxhYT09bnVsbHx8KGFhIGluc3RhbmNlb2YgQXJyYXl8fChhYT1bYWFdKSxhYT1hYS5tYXAoYmE9PmlzVHlwZWRBcnJheSQxKGJhKT9iYS5idWZmZXI6YmEpLGFhLmxlbmd0aD09PTApKXJldHVybjt0aGlzLmJ1ZmZlclVuaWZvcm1TaXplPWFhWzBdLmJ5dGVMZW5ndGg7bGV0IHhhPTA7Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aDtiYSsrKXtjb25zdCBTYT1hYVtiYV07YmEhPT1hYS5sZW5ndGgtMSYmU2EuYnl0ZUxlbmd0aCE9PXRoaXMuYnVmZmVyVW5pZm9ybVNpemUmJih0aGlzLmJ1ZmZlclVuaWZvcm1TaXplPXZvaWQgMCk7Y29uc3QgVGE9eGErU2EuYnl0ZUxlbmd0aDt0aGlzLnNoYXJkcy5wdXNoKHtidWZmZXI6U2Esc3RhcnQ6eGEsZW5kOlRhfSkseGE9VGF9dGhpcy5zaGFyZHMubGVuZ3RoPT09MCYmKHRoaXMuYnl0ZUxlbmd0aD0wKSx0aGlzLmJ5dGVMZW5ndGg9dGhpcy5zaGFyZHNbdGhpcy5zaGFyZHMubGVuZ3RoLTFdLmVuZH1zbGljZShhYT0wLHhhPXRoaXMuYnl0ZUxlbmd0aCl7aWYodGhpcy5zaGFyZHMubGVuZ3RoPT09MClyZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO2lmKGFhPWlzTmFOKE51bWJlcihhYSkpPzA6YWEseGE9aXNOYU4oTnVtYmVyKHhhKSk/MDp4YSxhYT1NYXRoLm1heCgwLGFhKSx4YT1NYXRoLm1pbih0aGlzLmJ5dGVMZW5ndGgseGEpLHhhPD1hYSlyZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO2NvbnN0IGJhPXRoaXMuZmluZFNoYXJkRm9yQnl0ZShhYSk7aWYoYmE9PT0tMSl0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBmaW5kIHN0YXJ0IHNoYXJkIGZvciBieXRlICR7YWF9YCk7Y29uc3QgU2E9eGEtYWEsVGE9bmV3IEFycmF5QnVmZmVyKFNhKSx3YT1uZXcgVWludDhBcnJheShUYSk7bGV0IEVhPTA7Zm9yKGxldCBrYT1iYTtrYTx0aGlzLnNoYXJkcy5sZW5ndGg7a2ErKyl7Y29uc3QgQWE9dGhpcy5zaGFyZHNba2FdLExhPWFhK0VhLUFhLnN0YXJ0LGVsPUVhLG5sPU1hdGgubWluKHhhLEFhLmVuZCktQWEuc3RhcnQsc2w9bmV3IFVpbnQ4QXJyYXkoQWEuYnVmZmVyLExhLG5sLUxhKTtpZih3YS5zZXQoc2wsZWwpLEVhKz1zbC5sZW5ndGgseGE8QWEuZW5kKWJyZWFrfXJldHVybiBUYX1maW5kU2hhcmRGb3JCeXRlKGFhKXtpZih0aGlzLnNoYXJkcy5sZW5ndGg9PT0wfHxhYTwwfHxhYT49dGhpcy5ieXRlTGVuZ3RoKXJldHVybi0xO2lmKHRoaXMuYnVmZmVyVW5pZm9ybVNpemUhPW51bGwpcmV0dXJuIHRoaXMucHJldmlvdXNTaGFyZEluZGV4PU1hdGguZmxvb3IoYWEvdGhpcy5idWZmZXJVbmlmb3JtU2l6ZSksdGhpcy5wcmV2aW91c1NoYXJkSW5kZXg7ZnVuY3Rpb24geGEoU2Epe3JldHVybiBhYTxTYS5zdGFydD8tMTphYT49U2EuZW5kPzE6MH1pZih4YSh0aGlzLnNoYXJkc1t0aGlzLnByZXZpb3VzU2hhcmRJbmRleF0pPT09MClyZXR1cm4gdGhpcy5wcmV2aW91c1NoYXJkSW5kZXg7Y29uc3QgYmE9c2VhcmNoJDEodGhpcy5zaGFyZHMseGEpO3JldHVybiBiYT09PS0xPy0xOih0aGlzLnByZXZpb3VzU2hhcmRJbmRleD1iYSx0aGlzLnByZXZpb3VzU2hhcmRJbmRleCl9fTtmdW5jdGlvbiBzZWFyY2gkMShoYSxhYSl7bGV0IHhhPTAsYmE9aGEubGVuZ3RoO2Zvcig7eGE8PWJhOyl7Y29uc3QgU2E9TWF0aC5mbG9vcigoYmEteGEpLzIpK3hhLFRhPWFhKGhhW1NhXSk7aWYoVGE9PT0wKXJldHVybiBTYTtUYTwwP2JhPVNhOnhhPVNhKzF9cmV0dXJuLTF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZW5naW5lJDEoKXtyZXR1cm4gRU5HSU5FJDF9ZnVuY3Rpb24gbWVtb3J5KCl7cmV0dXJuIEVOR0lORSQxLm1lbW9yeSgpfWZ1bmN0aW9uIHRpZHkkMShoYSxhYSl7cmV0dXJuIEVOR0lORSQxLnRpZHkoaGEsYWEpfWZ1bmN0aW9uIGRpc3Bvc2UkMShoYSl7Z2V0VGVuc29yc0luQ29udGFpbmVyJDEoaGEpLmZvckVhY2goeGE9PnhhLmRpc3Bvc2UoKSl9ZnVuY3Rpb24ga2VlcCQxKGhhKXtyZXR1cm4gRU5HSU5FJDEua2VlcChoYSl9ZnVuY3Rpb24gc2V0QmFja2VuZChoYSl7cmV0dXJuIEVOR0lORSQxLnNldEJhY2tlbmQoaGEpfWZ1bmN0aW9uIGdldEJhY2tlbmQoKXtyZXR1cm4gRU5HSU5FJDEuYmFja2VuZE5hbWV9ZnVuY3Rpb24gcmVnaXN0ZXJCYWNrZW5kJDEoaGEsYWEseGE9MSl7cmV0dXJuIEVOR0lORSQxLnJlZ2lzdGVyQmFja2VuZChoYSxhYSx4YSl9ZnVuY3Rpb24gYmFja2VuZCgpe3JldHVybiBFTkdJTkUkMS5iYWNrZW5kfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE5VTV9CWVRFU19TVFJJTkdfTEVOR1RIPTQ7YXN5bmMgZnVuY3Rpb24gZW5jb2RlV2VpZ2h0cyhoYSxhYSl7Y29uc3QgeGE9W10sYmE9W10sU2E9QXJyYXkuaXNBcnJheShoYSk/aGEubWFwKHdhPT53YS5uYW1lKTpPYmplY3Qua2V5cyhoYSk7Zm9yKGxldCB3YT0wO3dhPFNhLmxlbmd0aDsrK3dhKXtjb25zdCBFYT1TYVt3YV0sa2E9QXJyYXkuaXNBcnJheShoYSk/aGFbd2FdLnRlbnNvcjpoYVtFYV07aWYoa2EuZHR5cGUhPT0iZmxvYXQzMiImJmthLmR0eXBlIT09ImludDMyIiYma2EuZHR5cGUhPT0iYm9vbCImJmthLmR0eXBlIT09InN0cmluZyImJmthLmR0eXBlIT09ImNvbXBsZXg2NCIpdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkdHlwZSBpbiB3ZWlnaHQgJyR7RWF9JzogJHtrYS5kdHlwZX1gKTtjb25zdCBBYT17bmFtZTpFYSxzaGFwZTprYS5zaGFwZSxkdHlwZTprYS5kdHlwZX07aWYoa2EuZHR5cGU9PT0ic3RyaW5nIil7Y29uc3QgRmE9bmV3IFByb21pc2UoYXN5bmMgTGE9Pntjb25zdCBlbD1hd2FpdCBrYS5ieXRlcygpLHRsPWVsLnJlZHVjZSgocmwsb2wpPT5ybCtvbC5sZW5ndGgsMCkrTlVNX0JZVEVTX1NUUklOR19MRU5HVEgqZWwubGVuZ3RoLG5sPW5ldyBVaW50OEFycmF5KHRsKTtsZXQgc2w9MDtmb3IobGV0IHJsPTA7cmw8ZWwubGVuZ3RoO3JsKyspe2NvbnN0IG9sPWVsW3JsXSxhbD1uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoW29sLmxlbmd0aF0pLmJ1ZmZlcik7bmwuc2V0KGFsLHNsKSxzbCs9TlVNX0JZVEVTX1NUUklOR19MRU5HVEgsbmwuc2V0KG9sLHNsKSxzbCs9b2wubGVuZ3RofUxhKG5sKX0pO2JhLnB1c2goRmEpfWVsc2UgYmEucHVzaChrYS5kYXRhKCkpO2FhIT1udWxsJiYoQWEuZ3JvdXA9YWEpLHhhLnB1c2goQWEpfWNvbnN0IFRhPWF3YWl0IFByb21pc2UuYWxsKGJhKTtyZXR1cm57ZGF0YTpjb25jYXRlbmF0ZVR5cGVkQXJyYXlzKFRhKSxzcGVjczp4YX19ZnVuY3Rpb24gZGVjb2RlV2VpZ2h0cyhoYSxhYSl7Y29uc3QgeGE9bmV3IENvbXBvc2l0ZUFycmF5QnVmZmVyJDEoaGEpLGJhPXt9O2xldCBTYT0wO2Zvcihjb25zdCBUYSBvZiBhYSl7Y29uc3Qgd2E9Z2V0V2VpZ2h0Qnl0ZWxlbmd0aChUYSwoRWEsa2EpPT54YS5zbGljZShTYStFYSxTYStrYSkpO2JhW1RhLm5hbWVdPWRlY29kZVdlaWdodChUYSx4YS5zbGljZShTYSxTYSt3YSkpLFNhKz13YX1yZXR1cm4gYmF9ZnVuY3Rpb24gZ2V0V2VpZ2h0Qnl0ZWxlbmd0aChoYSxhYSl7Y29uc3QgeGE9c2l6ZUZyb21TaGFwZSQxKGhhLnNoYXBlKTtsZXQgYmE7aWYoInF1YW50aXphdGlvbiJpbiBoYSl7Y29uc3QgU2E9aGEucXVhbnRpemF0aW9uO2JhPURUWVBFX1ZBTFVFX1NJWkVfTUFQW1NhLmR0eXBlXX1lbHNlIGlmKGhhLmR0eXBlPT09InN0cmluZyIpe2xldCBTYT0wO2ZvcihsZXQgVGE9MDtUYTx4YTtUYSsrKVNhKz1OVU1fQllURVNfU1RSSU5HX0xFTkdUSCtuZXcgVWludDMyQXJyYXkoYWEoU2EsU2ErTlVNX0JZVEVTX1NUUklOR19MRU5HVEgpKVswXTtyZXR1cm4gU2F9ZWxzZSBiYT1EVFlQRV9WQUxVRV9TSVpFX01BUFtoYS5kdHlwZV07cmV0dXJuIHhhKmJhfWFzeW5jIGZ1bmN0aW9uIGdldFdlaWdodEJ5dGVsZW5ndGhBc3luYyhoYSxhYSl7Y29uc3QgeGE9c2l6ZUZyb21TaGFwZSQxKGhhLnNoYXBlKTtsZXQgYmE7aWYoInF1YW50aXphdGlvbiJpbiBoYSl7Y29uc3QgU2E9aGEucXVhbnRpemF0aW9uO2JhPURUWVBFX1ZBTFVFX1NJWkVfTUFQW1NhLmR0eXBlXX1lbHNlIGlmKGhhLmR0eXBlPT09InN0cmluZyIpe2xldCBTYT0wO2ZvcihsZXQgVGE9MDtUYTx4YTtUYSsrKVNhKz1OVU1fQllURVNfU1RSSU5HX0xFTkdUSCtuZXcgVWludDMyQXJyYXkoYXdhaXQgYWEoU2EsU2ErTlVNX0JZVEVTX1NUUklOR19MRU5HVEgpKVswXTtyZXR1cm4gU2F9ZWxzZSBiYT1EVFlQRV9WQUxVRV9TSVpFX01BUFtoYS5kdHlwZV07cmV0dXJuIHhhKmJhfWZ1bmN0aW9uIGRlY29kZVdlaWdodChoYSxhYSl7Y29uc3QgeGE9aGEubmFtZSxiYT1oYS5kdHlwZSxTYT1oYS5zaGFwZSxUYT1zaXplRnJvbVNoYXBlJDEoU2EpO2xldCB3YSxFYT0wO2lmKCJxdWFudGl6YXRpb24iaW4gaGEpe2NvbnN0IGthPWhhLnF1YW50aXphdGlvbjtpZihrYS5kdHlwZT09PSJ1aW50OCJ8fGthLmR0eXBlPT09InVpbnQxNiIpe2lmKCEoIm1pbiJpbiBrYSYmInNjYWxlImluIGthKSl0aHJvdyBuZXcgRXJyb3IoYFdlaWdodCAke2hhLm5hbWV9IHdpdGggcXVhbnRpemF0aW9uICR7a2EuZHR5cGV9IGRvZXNuJ3QgaGF2ZSBjb3JyZXNwb25kaW5nIG1ldGFkYXRhIG1pbiBhbmQgc2NhbGUuYCl9ZWxzZSBpZihrYS5kdHlwZT09PSJmbG9hdDE2Iil7aWYoYmEhPT0iZmxvYXQzMiIpdGhyb3cgbmV3IEVycm9yKGBXZWlnaHQgJHtoYS5uYW1lfSBpcyBxdWFudGl6ZWQgd2l0aCAke2thLmR0eXBlfSB3aGljaCBvbmx5IHN1cHBvcnRzIHdlaWdodHMgb2YgdHlwZSBmbG9hdDMyIG5vdCAke2JhfS5gKX1lbHNlIHRocm93IG5ldyBFcnJvcihgV2VpZ2h0ICR7aGEubmFtZX0gaGFzIHVua25vd24gcXVhbnRpemF0aW9uIGR0eXBlICR7a2EuZHR5cGV9LiBTdXBwb3J0ZWQgcXVhbnRpemF0aW9uIGR0eXBlcyBhcmU6ICd1aW50OCcsICd1aW50MTYnLCBhbmQgJ2Zsb2F0MTYnLmApO2NvbnN0IEFhPURUWVBFX1ZBTFVFX1NJWkVfTUFQW2thLmR0eXBlXSxGYT1rYS5kdHlwZT09PSJ1aW50OCI/bmV3IFVpbnQ4QXJyYXkoYWEpOm5ldyBVaW50MTZBcnJheShhYSk7aWYoYmE9PT0iZmxvYXQzMiIpaWYoa2EuZHR5cGU9PT0idWludDgifHxrYS5kdHlwZT09PSJ1aW50MTYiKXt3YT1uZXcgRmxvYXQzMkFycmF5KEZhLmxlbmd0aCk7Zm9yKGxldCBMYT0wO0xhPEZhLmxlbmd0aDtMYSsrKXtjb25zdCBlbD1GYVtMYV07d2FbTGFdPWVsKmthLnNjYWxlK2thLm1pbn19ZWxzZSBpZihrYS5kdHlwZT09PSJmbG9hdDE2Iil3YT1nZXRGbG9hdDE2RGVjb2RlcigpKEZhKTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcXVhbnRpemF0aW9uIHR5cGUgJHtrYS5kdHlwZX0gZm9yIHdlaWdodCB0eXBlIGZsb2F0MzIuYCk7ZWxzZSBpZihiYT09PSJpbnQzMiIpe2lmKGthLmR0eXBlIT09InVpbnQ4IiYma2EuZHR5cGUhPT0idWludDE2Iil0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHF1YW50aXphdGlvbiB0eXBlICR7a2EuZHR5cGV9IGZvciB3ZWlnaHQgdHlwZSBpbnQzMi5gKTt3YT1uZXcgSW50MzJBcnJheShGYS5sZW5ndGgpO2ZvcihsZXQgTGE9MDtMYTxGYS5sZW5ndGg7TGErKyl7Y29uc3QgZWw9RmFbTGFdO3dhW0xhXT1NYXRoLnJvdW5kKGVsKmthLnNjYWxlK2thLm1pbil9fWVsc2UgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkdHlwZSBpbiB3ZWlnaHQgJyR7eGF9JzogJHtiYX1gKTtFYSs9VGEqQWF9ZWxzZSBpZihiYT09PSJzdHJpbmciKXtjb25zdCBrYT1zaXplRnJvbVNoYXBlJDEoaGEuc2hhcGUpO3dhPVtdO2ZvcihsZXQgQWE9MDtBYTxrYTtBYSsrKXtjb25zdCBGYT1uZXcgVWludDMyQXJyYXkoYWEuc2xpY2UoRWEsRWErTlVNX0JZVEVTX1NUUklOR19MRU5HVEgpKVswXTtFYSs9TlVNX0JZVEVTX1NUUklOR19MRU5HVEg7Y29uc3QgTGE9bmV3IFVpbnQ4QXJyYXkoYWEuc2xpY2UoRWEsRWErRmEpKTt3YS5wdXNoKExhKSxFYSs9RmF9fWVsc2V7Y29uc3Qga2E9RFRZUEVfVkFMVUVfU0laRV9NQVBbYmFdO2lmKGJhPT09ImZsb2F0MzIiKXdhPW5ldyBGbG9hdDMyQXJyYXkoYWEpO2Vsc2UgaWYoYmE9PT0iaW50MzIiKXdhPW5ldyBJbnQzMkFycmF5KGFhKTtlbHNlIGlmKGJhPT09ImJvb2wiKXdhPW5ldyBVaW50OEFycmF5KGFhKTtlbHNlIGlmKGJhPT09ImNvbXBsZXg2NCIpe3dhPW5ldyBGbG9hdDMyQXJyYXkoYWEpO2NvbnN0IEFhPW5ldyBGbG9hdDMyQXJyYXkod2EubGVuZ3RoLzIpLEZhPW5ldyBGbG9hdDMyQXJyYXkod2EubGVuZ3RoLzIpO2ZvcihsZXQgbmw9MDtubDxBYS5sZW5ndGg7bmwrKylBYVtubF09d2FbbmwqMl0sRmFbbmxdPXdhW25sKjIrMV07Y29uc3QgTGE9dGVuc29yKEFhLFNhLCJmbG9hdDMyIiksZWw9dGVuc29yKEZhLFNhLCJmbG9hdDMyIiksdGw9Y29tcGxleCQ0KExhLGVsKTtyZXR1cm4gTGEuZGlzcG9zZSgpLGVsLmRpc3Bvc2UoKSx0bH1lbHNlIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZHR5cGUgaW4gd2VpZ2h0ICcke3hhfSc6ICR7YmF9YCk7RWErPVRhKmthfXJldHVybiB0ZW5zb3Iod2EsU2EsYmEpfWFzeW5jIGZ1bmN0aW9uIHJlYWRUb0xlbmd0aChoYSxhYSx4YSl7bGV0IGJhPW5ldyBVaW50OEFycmF5KGFhKTtmb3IoO2JhLmJ5dGVMZW5ndGg8eGE7KXtjb25zdHtkb25lOlNhLHZhbHVlOlRhfT1hd2FpdCBoYS5yZWFkKCk7aWYoU2EmJlRhPT1udWxsKXtjb25zdCBFYT14YS1iYS5ieXRlTGVuZ3RoO3Rocm93IG5ldyBFcnJvcihgUmVhZGVyIGlzIGRvbmUgYnV0ICR7RWF9IGJ5dGVzIGFyZSBzdGlsbCBleHBlY3RlZGApfWNvbnN0IHdhPW5ldyBVaW50OEFycmF5KGJhLmxlbmd0aCtUYS5ieXRlTGVuZ3RoKTt3YS5zZXQoYmEsMCksd2Euc2V0KG5ldyBVaW50OEFycmF5KFRhKSxiYS5sZW5ndGgpLGJhPXdhfXJldHVybiBiYS5idWZmZXJ9YXN5bmMgZnVuY3Rpb24gZGVjb2RlV2VpZ2h0c1N0cmVhbShoYSxhYSl7Y29uc3QgeGE9e30sYmE9aGEuZ2V0UmVhZGVyKCk7bGV0IFNhPW5ldyBBcnJheUJ1ZmZlcigwKTtmb3IoY29uc3QgVGEgb2YgYWEpe2NvbnN0IHdhPWF3YWl0IGdldFdlaWdodEJ5dGVsZW5ndGhBc3luYyhUYSxhc3luYyhBYSxGYSk9PihTYT1hd2FpdCByZWFkVG9MZW5ndGgoYmEsU2EsRmEpLFNhLnNsaWNlKEFhLEZhKSkpO1NhPWF3YWl0IHJlYWRUb0xlbmd0aChiYSxTYSx3YSk7Y29uc3QgRWE9U2Euc2xpY2UoMCx3YSk7U2E9U2Euc2xpY2Uod2EpO2NvbnN0IGthPWRlY29kZVdlaWdodChUYSxFYSk7aWYoeGFbVGEubmFtZV09a2EsZ2V0QmFja2VuZCgpPT09IndlYmdwdSIpe2NvbnN0IEFhPWJhY2tlbmQoKTsidXBsb2FkVG9HUFUiaW4gQWEmJnNpemVGcm9tU2hhcGUkMShrYS5zaGFwZSk+PWVudiQxKCkuZ2V0KCJXRUJHUFVfQ1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQiKSYmQWEudXBsb2FkVG9HUFUoa2EuZGF0YUlkKX19cmV0dXJuIHhhfWZ1bmN0aW9uIGNvbmNhdGVuYXRlVHlwZWRBcnJheXMoaGEpe2lmKGhhPT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaW5wdXQgdmFsdWU6ICR7SlNPTi5zdHJpbmdpZnkoaGEpfWApO2xldCBhYT0wO2NvbnN0IHhhPVtdO2hhLmZvckVhY2goVGE9PntpZihhYSs9VGEuYnl0ZUxlbmd0aCx4YS5wdXNoKFRhLmJ5dGVMZW5ndGg9PT1UYS5idWZmZXIuYnl0ZUxlbmd0aD9UYTpuZXcgVGEuY29uc3RydWN0b3IoVGEpKSwhKFRhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5fHxUYSBpbnN0YW5jZW9mIEludDMyQXJyYXl8fFRhIGluc3RhbmNlb2YgVWludDhBcnJheSkpdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBUeXBlZEFycmF5IHN1YnR5cGU6ICR7VGEuY29uc3RydWN0b3IubmFtZX1gKX0pO2NvbnN0IGJhPW5ldyBVaW50OEFycmF5KGFhKTtsZXQgU2E9MDtyZXR1cm4geGEuZm9yRWFjaChUYT0+e2JhLnNldChuZXcgVWludDhBcnJheShUYS5idWZmZXIpLFNhKSxTYSs9VGEuYnl0ZUxlbmd0aH0pLGJhLmJ1ZmZlcn1jb25zdCB1c2VOb2RlQnVmZmVyJDE9dHlwZW9mIEJ1ZmZlcjwidSImJih0eXBlb2YgQmxvYj4idSJ8fHR5cGVvZiBhdG9iPiJ1Inx8dHlwZW9mIGJ0b2E+InUiKTtmdW5jdGlvbiBzdHJpbmdCeXRlTGVuZ3RoJDEoaGEpe3JldHVybiB1c2VOb2RlQnVmZmVyJDE/QnVmZmVyLmJ5dGVMZW5ndGgoaGEsInV0ZjgiKTpuZXcgQmxvYihbaGFdKS5zaXplfWZ1bmN0aW9uIGFycmF5QnVmZmVyVG9CYXNlNjRTdHJpbmckMShoYSl7aWYodXNlTm9kZUJ1ZmZlciQxKXJldHVybiBCdWZmZXIuZnJvbShoYSkudG9TdHJpbmcoImJhc2U2NCIpO2NvbnN0IGFhPW5ldyBVaW50OEFycmF5KGhhKTtsZXQgeGE9IiI7Zm9yKGxldCBiYT0wLFNhPWFhLmxlbmd0aDtiYTxTYTtiYSsrKXhhKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGFhW2JhXSk7cmV0dXJuIGJ0b2EoeGEpfWZ1bmN0aW9uIGJhc2U2NFN0cmluZ1RvQXJyYXlCdWZmZXIkMShoYSl7aWYodXNlTm9kZUJ1ZmZlciQxKXtjb25zdCBiYT1CdWZmZXIuZnJvbShoYSwiYmFzZTY0Iik7cmV0dXJuIGJhLmJ1ZmZlci5zbGljZShiYS5ieXRlT2Zmc2V0LGJhLmJ5dGVPZmZzZXQrYmEuYnl0ZUxlbmd0aCl9Y29uc3QgYWE9YXRvYihoYSkseGE9bmV3IFVpbnQ4QXJyYXkoYWEubGVuZ3RoKTtmb3IobGV0IGJhPTA7YmE8YWEubGVuZ3RoOysrYmEpeGEuc2V0KFthYS5jaGFyQ29kZUF0KGJhKV0sYmEpO3JldHVybiB4YS5idWZmZXJ9ZnVuY3Rpb24gY29uY2F0ZW5hdGVBcnJheUJ1ZmZlcnMkMShoYSl7cmV0dXJuIENvbXBvc2l0ZUFycmF5QnVmZmVyJDEuam9pbihoYSl9ZnVuY3Rpb24gYmFzZW5hbWUoaGEpe2NvbnN0IGFhPSIvIjtmb3IoaGE9aGEudHJpbSgpO2hhLmVuZHNXaXRoKGFhKTspaGE9aGEuc2xpY2UoMCxoYS5sZW5ndGgtMSk7Y29uc3QgeGE9aGEuc3BsaXQoYWEpO3JldHVybiB4YVt4YS5sZW5ndGgtMV19ZnVuY3Rpb24gZ2V0TW9kZWxKU09ORm9yTW9kZWxBcnRpZmFjdHMkMShoYSxhYSl7Y29uc3QgeGE9e21vZGVsVG9wb2xvZ3k6aGEubW9kZWxUb3BvbG9neSxmb3JtYXQ6aGEuZm9ybWF0LGdlbmVyYXRlZEJ5OmhhLmdlbmVyYXRlZEJ5LGNvbnZlcnRlZEJ5OmhhLmNvbnZlcnRlZEJ5LHdlaWdodHNNYW5pZmVzdDphYX07cmV0dXJuIGhhLnNpZ25hdHVyZSE9bnVsbCYmKHhhLnNpZ25hdHVyZT1oYS5zaWduYXR1cmUpLGhhLnVzZXJEZWZpbmVkTWV0YWRhdGEhPW51bGwmJih4YS51c2VyRGVmaW5lZE1ldGFkYXRhPWhhLnVzZXJEZWZpbmVkTWV0YWRhdGEpLGhhLm1vZGVsSW5pdGlhbGl6ZXIhPW51bGwmJih4YS5tb2RlbEluaXRpYWxpemVyPWhhLm1vZGVsSW5pdGlhbGl6ZXIpLGhhLmluaXRpYWxpemVyU2lnbmF0dXJlIT1udWxsJiYoeGEuaW5pdGlhbGl6ZXJTaWduYXR1cmU9aGEuaW5pdGlhbGl6ZXJTaWduYXR1cmUpLGhhLnRyYWluaW5nQ29uZmlnIT1udWxsJiYoeGEudHJhaW5pbmdDb25maWc9aGEudHJhaW5pbmdDb25maWcpLHhhfWZ1bmN0aW9uIGdldE1vZGVsQXJ0aWZhY3RzRm9ySlNPTlN5bmMkMShoYSxhYSx4YSl7Y29uc3QgYmE9e21vZGVsVG9wb2xvZ3k6aGEubW9kZWxUb3BvbG9neSxmb3JtYXQ6aGEuZm9ybWF0LGdlbmVyYXRlZEJ5OmhhLmdlbmVyYXRlZEJ5LGNvbnZlcnRlZEJ5OmhhLmNvbnZlcnRlZEJ5fTtpZihoYS50cmFpbmluZ0NvbmZpZyE9bnVsbCYmKGJhLnRyYWluaW5nQ29uZmlnPWhhLnRyYWluaW5nQ29uZmlnKSxoYS53ZWlnaHRzTWFuaWZlc3QhPW51bGwpe2lmKCFhYSl0aHJvdyBuZXcgRXJyb3IoIm1vZGVsSlNPTiBoYXMgd2VpZ2h0c01hbmlmZXN0IGJ1dCB3ZWlnaHRTcGVjcyBpcyBudWxsIik7aWYoIXhhKXRocm93IG5ldyBFcnJvcigibW9kZWxKU09OIGhhcyB3ZWlnaHRzTWFuaWZlc3QgYnV0IHdlaWdodERhdGEgaXMgbnVsbCIpO2JhLndlaWdodFNwZWNzPWFhLGJhLndlaWdodERhdGE9eGF9cmV0dXJuIGhhLnNpZ25hdHVyZSE9bnVsbCYmKGJhLnNpZ25hdHVyZT1oYS5zaWduYXR1cmUpLGhhLnVzZXJEZWZpbmVkTWV0YWRhdGEhPW51bGwmJihiYS51c2VyRGVmaW5lZE1ldGFkYXRhPWhhLnVzZXJEZWZpbmVkTWV0YWRhdGEpLGhhLm1vZGVsSW5pdGlhbGl6ZXIhPW51bGwmJihiYS5tb2RlbEluaXRpYWxpemVyPWhhLm1vZGVsSW5pdGlhbGl6ZXIpLGhhLmluaXRpYWxpemVyU2lnbmF0dXJlIT1udWxsJiYoYmEuaW5pdGlhbGl6ZXJTaWduYXR1cmU9aGEuaW5pdGlhbGl6ZXJTaWduYXR1cmUpLGJhfWFzeW5jIGZ1bmN0aW9uIGdldE1vZGVsQXJ0aWZhY3RzRm9ySlNPTiQxKGhhLGFhKXtsZXQgeGEsYmE7cmV0dXJuIGhhLndlaWdodHNNYW5pZmVzdCE9bnVsbCYmKFt4YSxiYV09YXdhaXQgYWEoaGEud2VpZ2h0c01hbmlmZXN0KSksZ2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OU3luYyQxKGhhLHhhLGJhKX1mdW5jdGlvbiBnZXRNb2RlbEFydGlmYWN0c0luZm9Gb3JKU09OJDEoaGEpe2lmKGhhLm1vZGVsVG9wb2xvZ3kgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil0aHJvdyBuZXcgRXJyb3IoIkV4cGVjdGVkIEpTT04gbW9kZWwgdG9wb2xvZ3ksIHJlY2VpdmVkIEFycmF5QnVmZmVyLiIpO3JldHVybntkYXRlU2F2ZWQ6bmV3IERhdGUsbW9kZWxUb3BvbG9neVR5cGU6IkpTT04iLG1vZGVsVG9wb2xvZ3lCeXRlczpoYS5tb2RlbFRvcG9sb2d5PT1udWxsPzA6c3RyaW5nQnl0ZUxlbmd0aCQxKEpTT04uc3RyaW5naWZ5KGhhLm1vZGVsVG9wb2xvZ3kpKSx3ZWlnaHRTcGVjc0J5dGVzOmhhLndlaWdodFNwZWNzPT1udWxsPzA6c3RyaW5nQnl0ZUxlbmd0aCQxKEpTT04uc3RyaW5naWZ5KGhhLndlaWdodFNwZWNzKSksd2VpZ2h0RGF0YUJ5dGVzOmhhLndlaWdodERhdGE9PW51bGw/MDpuZXcgQ29tcG9zaXRlQXJyYXlCdWZmZXIkMShoYS53ZWlnaHREYXRhKS5ieXRlTGVuZ3RofX1mdW5jdGlvbiBnZXRXZWlnaHRTcGVjcyQxKGhhKXtjb25zdCBhYT1bXTtmb3IoY29uc3QgeGEgb2YgaGEpYWEucHVzaCguLi54YS53ZWlnaHRzKTtyZXR1cm4gYWF9ZnVuY3Rpb24gY29tcHV0ZUZsb2F0MTZNYW50aXNhVGFibGUoKXtjb25zdCBoYT14YT0+e2xldCBiYT14YTw8MTMsU2E9MDtmb3IoOyEoYmEmODM4ODYwOCk7KVNhLT04Mzg4NjA4LGJhPDw9MTtyZXR1cm4gYmEmPS04Mzg4NjA5LFNhKz05NDc5MTI3MDQsYmF8U2F9LGFhPW5ldyBVaW50MzJBcnJheSgyMDQ4KTthYVswXT0wO2ZvcihsZXQgeGE9MTt4YTwxMDI0O3hhKyspYWFbeGFdPWhhKHhhKTtmb3IobGV0IHhhPTEwMjQ7eGE8MjA0ODt4YSsrKWFhW3hhXT05Mzk1MjQwOTYrKHhhLTEwMjQ8PDEzKTtyZXR1cm4gYWF9ZnVuY3Rpb24gY29tcHV0ZUZsb2F0MTZFeHBvbmVudFRhYmxlKCl7Y29uc3QgaGE9bmV3IFVpbnQzMkFycmF5KDY0KTtoYVswXT0wLGhhWzMxXT0xMTk5NTcwOTQ0LGhhWzMyXT0yMTQ3NDgzNjQ4LGhhWzYzXT0zMzQ3MDU0NTkyO2ZvcihsZXQgYWE9MTthYTwzMTthYSsrKWhhW2FhXT1hYTw8MjM7Zm9yKGxldCBhYT0zMzthYTw2MzthYSsrKWhhW2FhXT0yMTQ3NDgzNjQ4KyhhYS0zMjw8MjMpO3JldHVybiBoYX1mdW5jdGlvbiBjb21wdXRlRmxvYXQxNk9mZnNldFRhYmxlKCl7Y29uc3QgaGE9bmV3IFVpbnQzMkFycmF5KDY0KTtmb3IobGV0IGFhPTA7YWE8NjQ7YWErKyloYVthYV09MTAyNDtyZXR1cm4gaGFbMF09aGFbMzJdPTAsaGF9ZnVuY3Rpb24gZ2V0RmxvYXQxNkRlY29kZXIoKXtjb25zdCBoYT1jb21wdXRlRmxvYXQxNk1hbnRpc2FUYWJsZSgpLGFhPWNvbXB1dGVGbG9hdDE2RXhwb25lbnRUYWJsZSgpLHhhPWNvbXB1dGVGbG9hdDE2T2Zmc2V0VGFibGUoKTtyZXR1cm4gYmE9Pntjb25zdCBTYT1uZXcgQXJyYXlCdWZmZXIoNCpiYS5sZW5ndGgpLFRhPW5ldyBVaW50MzJBcnJheShTYSk7Zm9yKGxldCB3YT0wO3dhPGJhLmxlbmd0aDt3YSsrKXtjb25zdCBFYT1iYVt3YV0sa2E9aGFbeGFbRWE+PjEwXSsoRWEmMTAyMyldK2FhW0VhPj4xMF07VGFbd2FdPWthfXJldHVybiBuZXcgRmxvYXQzMkFycmF5KFNhKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IElPUm91dGVyUmVnaXN0cnkkMT1jbGFzcyBLbHtjb25zdHJ1Y3Rvcigpe3RoaXMuc2F2ZVJvdXRlcnM9W10sdGhpcy5sb2FkUm91dGVycz1bXX1zdGF0aWMgZ2V0SW5zdGFuY2UoKXtyZXR1cm4gS2wuaW5zdGFuY2U9PW51bGwmJihLbC5pbnN0YW5jZT1uZXcgS2wpLEtsLmluc3RhbmNlfXN0YXRpYyByZWdpc3RlclNhdmVSb3V0ZXIoYWEpe0tsLmdldEluc3RhbmNlKCkuc2F2ZVJvdXRlcnMucHVzaChhYSl9c3RhdGljIHJlZ2lzdGVyTG9hZFJvdXRlcihhYSl7S2wuZ2V0SW5zdGFuY2UoKS5sb2FkUm91dGVycy5wdXNoKGFhKX1zdGF0aWMgZ2V0U2F2ZUhhbmRsZXJzKGFhKXtyZXR1cm4gS2wuZ2V0SGFuZGxlcnMoYWEsInNhdmUiKX1zdGF0aWMgZ2V0TG9hZEhhbmRsZXJzKGFhLHhhKXtyZXR1cm4gS2wuZ2V0SGFuZGxlcnMoYWEsImxvYWQiLHhhKX1zdGF0aWMgZ2V0SGFuZGxlcnMoYWEseGEsYmEpe2NvbnN0IFNhPVtdO3JldHVybih4YT09PSJsb2FkIj9LbC5nZXRJbnN0YW5jZSgpLmxvYWRSb3V0ZXJzOktsLmdldEluc3RhbmNlKCkuc2F2ZVJvdXRlcnMpLmZvckVhY2god2E9Pntjb25zdCBFYT13YShhYSxiYSk7RWEhPT1udWxsJiZTYS5wdXNoKEVhKX0pLFNhfX07Y29uc3QgcmVnaXN0ZXJTYXZlUm91dGVyPWhhPT5JT1JvdXRlclJlZ2lzdHJ5JDEucmVnaXN0ZXJTYXZlUm91dGVyKGhhKSxyZWdpc3RlckxvYWRSb3V0ZXI9aGE9PklPUm91dGVyUmVnaXN0cnkkMS5yZWdpc3RlckxvYWRSb3V0ZXIoaGEpLGdldFNhdmVIYW5kbGVycz1oYT0+SU9Sb3V0ZXJSZWdpc3RyeSQxLmdldFNhdmVIYW5kbGVycyhoYSksZ2V0TG9hZEhhbmRsZXJzPShoYSxhYSk9PklPUm91dGVyUmVnaXN0cnkkMS5nZXRMb2FkSGFuZGxlcnMoaGEsYWEpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IERBVEFCQVNFX05BTUUkMT0idGVuc29yZmxvd2pzIixEQVRBQkFTRV9WRVJTSU9OJDE9MSxNT0RFTF9TVE9SRV9OQU1FJDE9Im1vZGVsc19zdG9yZSIsSU5GT19TVE9SRV9OQU1FJDE9Im1vZGVsX2luZm9fc3RvcmUiO2Z1bmN0aW9uIGdldEluZGV4ZWREQkZhY3RvcnkkMSgpe2lmKCFlbnYkMSgpLmdldEJvb2woIklTX0JST1dTRVIiKSl0aHJvdyBuZXcgRXJyb3IoIkZhaWxlZCB0byBvYnRhaW4gSW5kZXhlZERCIGZhY3RvcnkgYmVjYXVzZSB0aGUgY3VycmVudCBlbnZpcm9ubWVudGlzIG5vdCBhIHdlYiBicm93c2VyLiIpO2NvbnN0IGhhPXR5cGVvZiB3aW5kb3c+InUiP3NlbGY6d2luZG93LGFhPWhhLmluZGV4ZWREQnx8aGEubW96SW5kZXhlZERCfHxoYS53ZWJraXRJbmRleGVkREJ8fGhhLm1zSW5kZXhlZERCfHxoYS5zaGltSW5kZXhlZERCO2lmKGFhPT1udWxsKXRocm93IG5ldyBFcnJvcigiVGhlIGN1cnJlbnQgYnJvd3NlciBkb2VzIG5vdCBhcHBlYXIgdG8gc3VwcG9ydCBJbmRleGVkREIuIik7cmV0dXJuIGFhfWZ1bmN0aW9uIHNldFVwRGF0YWJhc2UkMShoYSl7Y29uc3QgYWE9aGEucmVzdWx0O2FhLmNyZWF0ZU9iamVjdFN0b3JlKE1PREVMX1NUT1JFX05BTUUkMSx7a2V5UGF0aDoibW9kZWxQYXRoIn0pLGFhLmNyZWF0ZU9iamVjdFN0b3JlKElORk9fU1RPUkVfTkFNRSQxLHtrZXlQYXRoOiJtb2RlbFBhdGgifSl9bGV0IEJyb3dzZXJJbmRleGVkREIkMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7aWYodGhpcy5pbmRleGVkREI9Z2V0SW5kZXhlZERCRmFjdG9yeSQxKCksYWE9PW51bGx8fCFhYSl0aHJvdyBuZXcgRXJyb3IoIkZvciBJbmRleGVkREIsIG1vZGVsUGF0aCBtdXN0IG5vdCBiZSBudWxsLCB1bmRlZmluZWQgb3IgZW1wdHkuIik7dGhpcy5tb2RlbFBhdGg9YWF9YXN5bmMgc2F2ZShhYSl7aWYoYWEubW9kZWxUb3BvbG9neSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXRocm93IG5ldyBFcnJvcigiQnJvd3NlckxvY2FsU3RvcmFnZS5zYXZlKCkgZG9lcyBub3Qgc3VwcG9ydCBzYXZpbmcgbW9kZWwgdG9wb2xvZ3kgaW4gYmluYXJ5IGZvcm1hdHMgeWV0LiIpO3JldHVybiB0aGlzLmRhdGFiYXNlQWN0aW9uKHRoaXMubW9kZWxQYXRoLGFhKX1hc3luYyBsb2FkKCl7cmV0dXJuIHRoaXMuZGF0YWJhc2VBY3Rpb24odGhpcy5tb2RlbFBhdGgpfWRhdGFiYXNlQWN0aW9uKGFhLHhhKXtyZXR1cm4gbmV3IFByb21pc2UoKGJhLFNhKT0+e2NvbnN0IFRhPXRoaXMuaW5kZXhlZERCLm9wZW4oREFUQUJBU0VfTkFNRSQxLERBVEFCQVNFX1ZFUlNJT04kMSk7VGEub251cGdyYWRlbmVlZGVkPSgpPT5zZXRVcERhdGFiYXNlJDEoVGEpLFRhLm9uc3VjY2Vzcz0oKT0+e2NvbnN0IHdhPVRhLnJlc3VsdDtpZih4YT09bnVsbCl7Y29uc3QgRWE9d2EudHJhbnNhY3Rpb24oTU9ERUxfU1RPUkVfTkFNRSQxLCJyZWFkb25seSIpLEFhPUVhLm9iamVjdFN0b3JlKE1PREVMX1NUT1JFX05BTUUkMSkuZ2V0KHRoaXMubW9kZWxQYXRoKTtBYS5vbnN1Y2Nlc3M9KCk9PntpZihBYS5yZXN1bHQ9PW51bGwpcmV0dXJuIHdhLmNsb3NlKCksU2EobmV3IEVycm9yKGBDYW5ub3QgZmluZCBtb2RlbCB3aXRoIHBhdGggJyR7dGhpcy5tb2RlbFBhdGh9JyBpbiBJbmRleGVkREIuYCkpO2JhKEFhLnJlc3VsdC5tb2RlbEFydGlmYWN0cyl9LEFhLm9uZXJyb3I9RmE9Pih3YS5jbG9zZSgpLFNhKEFhLmVycm9yKSksRWEub25jb21wbGV0ZT0oKT0+d2EuY2xvc2UoKX1lbHNle3hhLndlaWdodERhdGE9Q29tcG9zaXRlQXJyYXlCdWZmZXIkMS5qb2luKHhhLndlaWdodERhdGEpO2NvbnN0IEVhPWdldE1vZGVsQXJ0aWZhY3RzSW5mb0ZvckpTT04kMSh4YSksa2E9d2EudHJhbnNhY3Rpb24oSU5GT19TVE9SRV9OQU1FJDEsInJlYWR3cml0ZSIpO2xldCBBYT1rYS5vYmplY3RTdG9yZShJTkZPX1NUT1JFX05BTUUkMSksRmE7dHJ5e0ZhPUFhLnB1dCh7bW9kZWxQYXRoOnRoaXMubW9kZWxQYXRoLG1vZGVsQXJ0aWZhY3RzSW5mbzpFYX0pfWNhdGNoKGVsKXtyZXR1cm4gU2EoZWwpfWxldCBMYTtGYS5vbnN1Y2Nlc3M9KCk9PntMYT13YS50cmFuc2FjdGlvbihNT0RFTF9TVE9SRV9OQU1FJDEsInJlYWR3cml0ZSIpO2NvbnN0IGVsPUxhLm9iamVjdFN0b3JlKE1PREVMX1NUT1JFX05BTUUkMSk7bGV0IHRsO3RyeXt0bD1lbC5wdXQoe21vZGVsUGF0aDp0aGlzLm1vZGVsUGF0aCxtb2RlbEFydGlmYWN0czp4YSxtb2RlbEFydGlmYWN0c0luZm86RWF9KX1jYXRjaChubCl7cmV0dXJuIFNhKG5sKX10bC5vbnN1Y2Nlc3M9KCk9PmJhKHttb2RlbEFydGlmYWN0c0luZm86RWF9KSx0bC5vbmVycm9yPW5sPT57QWE9a2Eub2JqZWN0U3RvcmUoSU5GT19TVE9SRV9OQU1FJDEpO2NvbnN0IHNsPUFhLmRlbGV0ZSh0aGlzLm1vZGVsUGF0aCk7c2wub25zdWNjZXNzPSgpPT4od2EuY2xvc2UoKSxTYSh0bC5lcnJvcikpLHNsLm9uZXJyb3I9cmw9Pih3YS5jbG9zZSgpLFNhKHRsLmVycm9yKSl9fSxGYS5vbmVycm9yPWVsPT4od2EuY2xvc2UoKSxTYShGYS5lcnJvcikpLGthLm9uY29tcGxldGU9KCk9PntMYT09bnVsbD93YS5jbG9zZSgpOkxhLm9uY29tcGxldGU9KCk9PndhLmNsb3NlKCl9fX0sVGEub25lcnJvcj13YT0+U2EoVGEuZXJyb3IpfSl9fTtCcm93c2VySW5kZXhlZERCJDEuVVJMX1NDSEVNRT0iaW5kZXhlZGRiOi8vIjtjb25zdCBpbmRleGVkREJSb3V0ZXIkMT1oYT0+ZW52JDEoKS5nZXRCb29sKCJJU19CUk9XU0VSIikmJiFBcnJheS5pc0FycmF5KGhhKSYmaGEuc3RhcnRzV2l0aChCcm93c2VySW5kZXhlZERCJDEuVVJMX1NDSEVNRSk/YnJvd3NlckluZGV4ZWREQiQxKGhhLnNsaWNlKEJyb3dzZXJJbmRleGVkREIkMS5VUkxfU0NIRU1FLmxlbmd0aCkpOm51bGw7SU9Sb3V0ZXJSZWdpc3RyeSQxLnJlZ2lzdGVyU2F2ZVJvdXRlcihpbmRleGVkREJSb3V0ZXIkMSksSU9Sb3V0ZXJSZWdpc3RyeSQxLnJlZ2lzdGVyTG9hZFJvdXRlcihpbmRleGVkREJSb3V0ZXIkMSk7ZnVuY3Rpb24gYnJvd3NlckluZGV4ZWREQiQxKGhhKXtyZXR1cm4gbmV3IEJyb3dzZXJJbmRleGVkREIkMShoYSl9ZnVuY3Rpb24gbWF5YmVTdHJpcFNjaGVtZSQzKGhhKXtyZXR1cm4gaGEuc3RhcnRzV2l0aChCcm93c2VySW5kZXhlZERCJDEuVVJMX1NDSEVNRSk/aGEuc2xpY2UoQnJvd3NlckluZGV4ZWREQiQxLlVSTF9TQ0hFTUUubGVuZ3RoKTpoYX1sZXQgQnJvd3NlckluZGV4ZWREQk1hbmFnZXIkMT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMuaW5kZXhlZERCPWdldEluZGV4ZWREQkZhY3RvcnkkMSgpfWFzeW5jIGxpc3RNb2RlbHMoKXtyZXR1cm4gbmV3IFByb21pc2UoKGFhLHhhKT0+e2NvbnN0IGJhPXRoaXMuaW5kZXhlZERCLm9wZW4oREFUQUJBU0VfTkFNRSQxLERBVEFCQVNFX1ZFUlNJT04kMSk7YmEub251cGdyYWRlbmVlZGVkPSgpPT5zZXRVcERhdGFiYXNlJDEoYmEpLGJhLm9uc3VjY2Vzcz0oKT0+e2NvbnN0IFNhPWJhLnJlc3VsdCxUYT1TYS50cmFuc2FjdGlvbihJTkZPX1NUT1JFX05BTUUkMSwicmVhZG9ubHkiKSxFYT1UYS5vYmplY3RTdG9yZShJTkZPX1NUT1JFX05BTUUkMSkuZ2V0QWxsKCk7RWEub25zdWNjZXNzPSgpPT57Y29uc3Qga2E9e307Zm9yKGNvbnN0IEFhIG9mIEVhLnJlc3VsdClrYVtBYS5tb2RlbFBhdGhdPUFhLm1vZGVsQXJ0aWZhY3RzSW5mbzthYShrYSl9LEVhLm9uZXJyb3I9a2E9PihTYS5jbG9zZSgpLHhhKEVhLmVycm9yKSksVGEub25jb21wbGV0ZT0oKT0+U2EuY2xvc2UoKX0sYmEub25lcnJvcj1TYT0+eGEoYmEuZXJyb3IpfSl9YXN5bmMgcmVtb3ZlTW9kZWwoYWEpe3JldHVybiBhYT1tYXliZVN0cmlwU2NoZW1lJDMoYWEpLG5ldyBQcm9taXNlKCh4YSxiYSk9Pntjb25zdCBTYT10aGlzLmluZGV4ZWREQi5vcGVuKERBVEFCQVNFX05BTUUkMSxEQVRBQkFTRV9WRVJTSU9OJDEpO1NhLm9udXBncmFkZW5lZWRlZD0oKT0+c2V0VXBEYXRhYmFzZSQxKFNhKSxTYS5vbnN1Y2Nlc3M9KCk9Pntjb25zdCBUYT1TYS5yZXN1bHQsd2E9VGEudHJhbnNhY3Rpb24oSU5GT19TVE9SRV9OQU1FJDEsInJlYWR3cml0ZSIpLEVhPXdhLm9iamVjdFN0b3JlKElORk9fU1RPUkVfTkFNRSQxKSxrYT1FYS5nZXQoYWEpO2xldCBBYTtrYS5vbnN1Y2Nlc3M9KCk9PntpZihrYS5yZXN1bHQ9PW51bGwpcmV0dXJuIFRhLmNsb3NlKCksYmEobmV3IEVycm9yKGBDYW5ub3QgZmluZCBtb2RlbCB3aXRoIHBhdGggJyR7YWF9JyBpbiBJbmRleGVkREIuYCkpO3tjb25zdCBGYT1FYS5kZWxldGUoYWEpLExhPSgpPT57QWE9VGEudHJhbnNhY3Rpb24oTU9ERUxfU1RPUkVfTkFNRSQxLCJyZWFkd3JpdGUiKTtjb25zdCB0bD1BYS5vYmplY3RTdG9yZShNT0RFTF9TVE9SRV9OQU1FJDEpLmRlbGV0ZShhYSk7dGwub25zdWNjZXNzPSgpPT54YShrYS5yZXN1bHQubW9kZWxBcnRpZmFjdHNJbmZvKSx0bC5vbmVycm9yPW5sPT5iYShrYS5lcnJvcil9O0ZhLm9uc3VjY2Vzcz1MYSxGYS5vbmVycm9yPWVsPT4oTGEoKSxUYS5jbG9zZSgpLGJhKGthLmVycm9yKSl9fSxrYS5vbmVycm9yPUZhPT4oVGEuY2xvc2UoKSxiYShrYS5lcnJvcikpLHdhLm9uY29tcGxldGU9KCk9PntBYT09bnVsbD9UYS5jbG9zZSgpOkFhLm9uY29tcGxldGU9KCk9PlRhLmNsb3NlKCl9fSxTYS5vbmVycm9yPVRhPT5iYShTYS5lcnJvcil9KX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFBBVEhfU0VQQVJBVE9SJDE9Ii8iLFBBVEhfUFJFRklYJDE9InRlbnNvcmZsb3dqc19tb2RlbHMiLElORk9fU1VGRklYJDE9ImluZm8iLE1PREVMX1RPUE9MT0dZX1NVRkZJWCQxPSJtb2RlbF90b3BvbG9neSIsV0VJR0hUX1NQRUNTX1NVRkZJWCQxPSJ3ZWlnaHRfc3BlY3MiLFdFSUdIVF9EQVRBX1NVRkZJWCQxPSJ3ZWlnaHRfZGF0YSIsTU9ERUxfTUVUQURBVEFfU1VGRklYJDE9Im1vZGVsX21ldGFkYXRhIjtmdW5jdGlvbiBnZXRNb2RlbEtleXMkMShoYSl7cmV0dXJue2luZm86W1BBVEhfUFJFRklYJDEsaGEsSU5GT19TVUZGSVgkMV0uam9pbihQQVRIX1NFUEFSQVRPUiQxKSx0b3BvbG9neTpbUEFUSF9QUkVGSVgkMSxoYSxNT0RFTF9UT1BPTE9HWV9TVUZGSVgkMV0uam9pbihQQVRIX1NFUEFSQVRPUiQxKSx3ZWlnaHRTcGVjczpbUEFUSF9QUkVGSVgkMSxoYSxXRUlHSFRfU1BFQ1NfU1VGRklYJDFdLmpvaW4oUEFUSF9TRVBBUkFUT1IkMSksd2VpZ2h0RGF0YTpbUEFUSF9QUkVGSVgkMSxoYSxXRUlHSFRfREFUQV9TVUZGSVgkMV0uam9pbihQQVRIX1NFUEFSQVRPUiQxKSxtb2RlbE1ldGFkYXRhOltQQVRIX1BSRUZJWCQxLGhhLE1PREVMX01FVEFEQVRBX1NVRkZJWCQxXS5qb2luKFBBVEhfU0VQQVJBVE9SJDEpfX1mdW5jdGlvbiByZW1vdmVJdGVtcyQxKGhhKXtmb3IoY29uc3QgYWEgb2YgT2JqZWN0LnZhbHVlcyhoYSkpd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGFhKX1mdW5jdGlvbiBnZXRNb2RlbFBhdGhGcm9tS2V5JDEoaGEpe2NvbnN0IGFhPWhhLnNwbGl0KFBBVEhfU0VQQVJBVE9SJDEpO2lmKGFhLmxlbmd0aDwzKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBrZXkgZm9ybWF0OiAke2hhfWApO3JldHVybiBhYS5zbGljZSgxLGFhLmxlbmd0aC0xKS5qb2luKFBBVEhfU0VQQVJBVE9SJDEpfWZ1bmN0aW9uIG1heWJlU3RyaXBTY2hlbWUkMihoYSl7cmV0dXJuIGhhLnN0YXJ0c1dpdGgoQnJvd3NlckxvY2FsU3RvcmFnZSQxLlVSTF9TQ0hFTUUpP2hhLnNsaWNlKEJyb3dzZXJMb2NhbFN0b3JhZ2UkMS5VUkxfU0NIRU1FLmxlbmd0aCk6aGF9bGV0IEJyb3dzZXJMb2NhbFN0b3JhZ2UkMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7aWYoIWVudiQxKCkuZ2V0Qm9vbCgiSVNfQlJPV1NFUiIpfHx0eXBlb2Ygd2luZG93PiJ1Inx8dHlwZW9mIHdpbmRvdy5sb2NhbFN0b3JhZ2U+InUiKXRocm93IG5ldyBFcnJvcigiVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBsb2NhbCBzdG9yYWdlLiIpO2lmKHRoaXMuTFM9d2luZG93LmxvY2FsU3RvcmFnZSxhYT09bnVsbHx8IWFhKXRocm93IG5ldyBFcnJvcigiRm9yIGxvY2FsIHN0b3JhZ2UsIG1vZGVsUGF0aCBtdXN0IG5vdCBiZSBudWxsLCB1bmRlZmluZWQgb3IgZW1wdHkuIik7dGhpcy5tb2RlbFBhdGg9YWEsdGhpcy5rZXlzPWdldE1vZGVsS2V5cyQxKHRoaXMubW9kZWxQYXRoKX1hc3luYyBzYXZlKGFhKXtpZihhYS5tb2RlbFRvcG9sb2d5IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpdGhyb3cgbmV3IEVycm9yKCJCcm93c2VyTG9jYWxTdG9yYWdlLnNhdmUoKSBkb2VzIG5vdCBzdXBwb3J0IHNhdmluZyBtb2RlbCB0b3BvbG9neSBpbiBiaW5hcnkgZm9ybWF0cyB5ZXQuIik7e2NvbnN0IHhhPUpTT04uc3RyaW5naWZ5KGFhLm1vZGVsVG9wb2xvZ3kpLGJhPUpTT04uc3RyaW5naWZ5KGFhLndlaWdodFNwZWNzKSxTYT1nZXRNb2RlbEFydGlmYWN0c0luZm9Gb3JKU09OJDEoYWEpLFRhPUNvbXBvc2l0ZUFycmF5QnVmZmVyJDEuam9pbihhYS53ZWlnaHREYXRhKTt0cnl7dGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy5pbmZvLEpTT04uc3RyaW5naWZ5KFNhKSksdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy50b3BvbG9neSx4YSksdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy53ZWlnaHRTcGVjcyxiYSksdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy53ZWlnaHREYXRhLGFycmF5QnVmZmVyVG9CYXNlNjRTdHJpbmckMShUYSkpO2NvbnN0IHdhPXtmb3JtYXQ6YWEuZm9ybWF0LGdlbmVyYXRlZEJ5OmFhLmdlbmVyYXRlZEJ5LGNvbnZlcnRlZEJ5OmFhLmNvbnZlcnRlZEJ5LHNpZ25hdHVyZTphYS5zaWduYXR1cmUhPW51bGw/YWEuc2lnbmF0dXJlOnZvaWQgMCx1c2VyRGVmaW5lZE1ldGFkYXRhOmFhLnVzZXJEZWZpbmVkTWV0YWRhdGEhPW51bGw/YWEudXNlckRlZmluZWRNZXRhZGF0YTp2b2lkIDAsbW9kZWxJbml0aWFsaXplcjphYS5tb2RlbEluaXRpYWxpemVyIT1udWxsP2FhLm1vZGVsSW5pdGlhbGl6ZXI6dm9pZCAwLGluaXRpYWxpemVyU2lnbmF0dXJlOmFhLmluaXRpYWxpemVyU2lnbmF0dXJlIT1udWxsP2FhLmluaXRpYWxpemVyU2lnbmF0dXJlOnZvaWQgMCx0cmFpbmluZ0NvbmZpZzphYS50cmFpbmluZ0NvbmZpZyE9bnVsbD9hYS50cmFpbmluZ0NvbmZpZzp2b2lkIDB9O3JldHVybiB0aGlzLkxTLnNldEl0ZW0odGhpcy5rZXlzLm1vZGVsTWV0YWRhdGEsSlNPTi5zdHJpbmdpZnkod2EpKSx7bW9kZWxBcnRpZmFjdHNJbmZvOlNhfX1jYXRjaHt0aHJvdyByZW1vdmVJdGVtcyQxKHRoaXMua2V5cyksbmV3IEVycm9yKGBGYWlsZWQgdG8gc2F2ZSBtb2RlbCAnJHt0aGlzLm1vZGVsUGF0aH0nIHRvIGxvY2FsIHN0b3JhZ2U6IHNpemUgcXVvdGEgYmVpbmcgZXhjZWVkZWQgaXMgYSBwb3NzaWJsZSBjYXVzZSBvZiB0aGlzIGZhaWx1cmU6IG1vZGVsVG9wb2xvZ3lCeXRlcz0ke1NhLm1vZGVsVG9wb2xvZ3lCeXRlc30sIHdlaWdodFNwZWNzQnl0ZXM9JHtTYS53ZWlnaHRTcGVjc0J5dGVzfSwgd2VpZ2h0RGF0YUJ5dGVzPSR7U2Eud2VpZ2h0RGF0YUJ5dGVzfS5gKX19fWFzeW5jIGxvYWQoKXtjb25zdCBhYT1KU09OLnBhcnNlKHRoaXMuTFMuZ2V0SXRlbSh0aGlzLmtleXMuaW5mbykpO2lmKGFhPT1udWxsKXRocm93IG5ldyBFcnJvcihgSW4gbG9jYWwgc3RvcmFnZSwgdGhlcmUgaXMgbm8gbW9kZWwgd2l0aCBuYW1lICcke3RoaXMubW9kZWxQYXRofSdgKTtpZihhYS5tb2RlbFRvcG9sb2d5VHlwZSE9PSJKU09OIil0aHJvdyBuZXcgRXJyb3IoIkJyb3dzZXJMb2NhbFN0b3JhZ2UgZG9lcyBub3Qgc3VwcG9ydCBsb2FkaW5nIG5vbi1KU09OIG1vZGVsIHRvcG9sb2d5IHlldC4iKTtjb25zdCB4YT17fSxiYT1KU09OLnBhcnNlKHRoaXMuTFMuZ2V0SXRlbSh0aGlzLmtleXMudG9wb2xvZ3kpKTtpZihiYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYEluIGxvY2FsIHN0b3JhZ2UsIHRoZSB0b3BvbG9neSBvZiBtb2RlbCAnJHt0aGlzLm1vZGVsUGF0aH0nIGlzIG1pc3NpbmcuYCk7eGEubW9kZWxUb3BvbG9neT1iYTtjb25zdCBTYT1KU09OLnBhcnNlKHRoaXMuTFMuZ2V0SXRlbSh0aGlzLmtleXMud2VpZ2h0U3BlY3MpKTtpZihTYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYEluIGxvY2FsIHN0b3JhZ2UsIHRoZSB3ZWlnaHQgc3BlY3Mgb2YgbW9kZWwgJyR7dGhpcy5tb2RlbFBhdGh9JyBhcmUgbWlzc2luZy5gKTt4YS53ZWlnaHRTcGVjcz1TYTtjb25zdCBUYT10aGlzLkxTLmdldEl0ZW0odGhpcy5rZXlzLm1vZGVsTWV0YWRhdGEpO2lmKFRhIT1udWxsKXtjb25zdCBFYT1KU09OLnBhcnNlKFRhKTt4YS5mb3JtYXQ9RWEuZm9ybWF0LHhhLmdlbmVyYXRlZEJ5PUVhLmdlbmVyYXRlZEJ5LHhhLmNvbnZlcnRlZEJ5PUVhLmNvbnZlcnRlZEJ5LEVhLnNpZ25hdHVyZSE9bnVsbCYmKHhhLnNpZ25hdHVyZT1FYS5zaWduYXR1cmUpLEVhLnVzZXJEZWZpbmVkTWV0YWRhdGEhPW51bGwmJih4YS51c2VyRGVmaW5lZE1ldGFkYXRhPUVhLnVzZXJEZWZpbmVkTWV0YWRhdGEpLEVhLm1vZGVsSW5pdGlhbGl6ZXIhPW51bGwmJih4YS5tb2RlbEluaXRpYWxpemVyPUVhLm1vZGVsSW5pdGlhbGl6ZXIpLEVhLmluaXRpYWxpemVyU2lnbmF0dXJlIT1udWxsJiYoeGEuaW5pdGlhbGl6ZXJTaWduYXR1cmU9RWEuaW5pdGlhbGl6ZXJTaWduYXR1cmUpLEVhLnRyYWluaW5nQ29uZmlnIT1udWxsJiYoeGEudHJhaW5pbmdDb25maWc9RWEudHJhaW5pbmdDb25maWcpfWNvbnN0IHdhPXRoaXMuTFMuZ2V0SXRlbSh0aGlzLmtleXMud2VpZ2h0RGF0YSk7aWYod2E9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBJbiBsb2NhbCBzdG9yYWdlLCB0aGUgYmluYXJ5IHdlaWdodCB2YWx1ZXMgb2YgbW9kZWwgJyR7dGhpcy5tb2RlbFBhdGh9JyBhcmUgbWlzc2luZy5gKTtyZXR1cm4geGEud2VpZ2h0RGF0YT1iYXNlNjRTdHJpbmdUb0FycmF5QnVmZmVyJDEod2EpLHhhfX07QnJvd3NlckxvY2FsU3RvcmFnZSQxLlVSTF9TQ0hFTUU9ImxvY2Fsc3RvcmFnZTovLyI7Y29uc3QgbG9jYWxTdG9yYWdlUm91dGVyJDE9aGE9PmVudiQxKCkuZ2V0Qm9vbCgiSVNfQlJPV1NFUiIpJiYhQXJyYXkuaXNBcnJheShoYSkmJmhhLnN0YXJ0c1dpdGgoQnJvd3NlckxvY2FsU3RvcmFnZSQxLlVSTF9TQ0hFTUUpP2Jyb3dzZXJMb2NhbFN0b3JhZ2UkMShoYS5zbGljZShCcm93c2VyTG9jYWxTdG9yYWdlJDEuVVJMX1NDSEVNRS5sZW5ndGgpKTpudWxsO0lPUm91dGVyUmVnaXN0cnkkMS5yZWdpc3RlclNhdmVSb3V0ZXIobG9jYWxTdG9yYWdlUm91dGVyJDEpLElPUm91dGVyUmVnaXN0cnkkMS5yZWdpc3RlckxvYWRSb3V0ZXIobG9jYWxTdG9yYWdlUm91dGVyJDEpO2Z1bmN0aW9uIGJyb3dzZXJMb2NhbFN0b3JhZ2UkMShoYSl7cmV0dXJuIG5ldyBCcm93c2VyTG9jYWxTdG9yYWdlJDEoaGEpfWxldCBCcm93c2VyTG9jYWxTdG9yYWdlTWFuYWdlciQxPWNsYXNze2NvbnN0cnVjdG9yKCl7YXNzZXJ0JDIoZW52JDEoKS5nZXRCb29sKCJJU19CUk9XU0VSIiksKCk9PiJDdXJyZW50IGVudmlyb25tZW50IGlzIG5vdCBhIHdlYiBicm93c2VyIiksYXNzZXJ0JDIodHlwZW9mIHdpbmRvdz4idSJ8fHR5cGVvZiB3aW5kb3cubG9jYWxTdG9yYWdlPCJ1IiwoKT0+IkN1cnJlbnQgYnJvd3NlciBkb2VzIG5vdCBhcHBlYXIgdG8gc3VwcG9ydCBsb2NhbFN0b3JhZ2UiKSx0aGlzLkxTPXdpbmRvdy5sb2NhbFN0b3JhZ2V9YXN5bmMgbGlzdE1vZGVscygpe2NvbnN0IGFhPXt9LHhhPVBBVEhfUFJFRklYJDErUEFUSF9TRVBBUkFUT1IkMSxiYT1QQVRIX1NFUEFSQVRPUiQxK0lORk9fU1VGRklYJDE7Zm9yKGxldCBTYT0wO1NhPHRoaXMuTFMubGVuZ3RoOysrU2Epe2NvbnN0IFRhPXRoaXMuTFMua2V5KFNhKTtpZihUYS5zdGFydHNXaXRoKHhhKSYmVGEuZW5kc1dpdGgoYmEpKXtjb25zdCB3YT1nZXRNb2RlbFBhdGhGcm9tS2V5JDEoVGEpO2FhW3dhXT1KU09OLnBhcnNlKHRoaXMuTFMuZ2V0SXRlbShUYSkpfX1yZXR1cm4gYWF9YXN5bmMgcmVtb3ZlTW9kZWwoYWEpe2FhPW1heWJlU3RyaXBTY2hlbWUkMihhYSk7Y29uc3QgeGE9Z2V0TW9kZWxLZXlzJDEoYWEpO2lmKHRoaXMuTFMuZ2V0SXRlbSh4YS5pbmZvKT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIG1vZGVsIGF0IHBhdGggJyR7YWF9J2ApO2NvbnN0IGJhPUpTT04ucGFyc2UodGhpcy5MUy5nZXRJdGVtKHhhLmluZm8pKTtyZXR1cm4gcmVtb3ZlSXRlbXMkMSh4YSksYmF9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBVUkxfU0NIRU1FX1NVRkZJWCQxPSI6Ly8iO2xldCBNb2RlbFN0b3JlTWFuYWdlclJlZ2lzdHJ5JDE9Y2xhc3MgUWx7Y29uc3RydWN0b3IoKXt0aGlzLm1hbmFnZXJzPXt9fXN0YXRpYyBnZXRJbnN0YW5jZSgpe3JldHVybiBRbC5pbnN0YW5jZT09bnVsbCYmKFFsLmluc3RhbmNlPW5ldyBRbCksUWwuaW5zdGFuY2V9c3RhdGljIHJlZ2lzdGVyTWFuYWdlcihhYSx4YSl7YXNzZXJ0JDIoYWEhPW51bGwsKCk9PiJzY2hlbWUgbXVzdCBub3QgYmUgdW5kZWZpbmVkIG9yIG51bGwuIiksYWEuZW5kc1dpdGgoVVJMX1NDSEVNRV9TVUZGSVgkMSkmJihhYT1hYS5zbGljZSgwLGFhLmluZGV4T2YoVVJMX1NDSEVNRV9TVUZGSVgkMSkpKSxhc3NlcnQkMihhYS5sZW5ndGg+MCwoKT0+InNjaGVtZSBtdXN0IG5vdCBiZSBhbiBlbXB0eSBzdHJpbmcuIik7Y29uc3QgYmE9UWwuZ2V0SW5zdGFuY2UoKTthc3NlcnQkMihiYS5tYW5hZ2Vyc1thYV09PW51bGwsKCk9PmBBIG1vZGVsIHN0b3JlIG1hbmFnZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkIGZvciBzY2hlbWUgJyR7YWF9Jy5gKSxiYS5tYW5hZ2Vyc1thYV09eGF9c3RhdGljIGdldE1hbmFnZXIoYWEpe2NvbnN0IHhhPVFsLmdldEluc3RhbmNlKCkubWFuYWdlcnNbYWFdO2lmKHhhPT1udWxsKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGZpbmQgbW9kZWwgbWFuYWdlciBmb3Igc2NoZW1lICcke2FhfSdgKTtyZXR1cm4geGF9c3RhdGljIGdldFNjaGVtZXMoKXtyZXR1cm4gT2JqZWN0LmtleXMoUWwuZ2V0SW5zdGFuY2UoKS5tYW5hZ2Vycyl9fTtmdW5jdGlvbiBwYXJzZVVSTChoYSl7aWYoaGEuaW5kZXhPZihVUkxfU0NIRU1FX1NVRkZJWCQxKT09PS0xKXRocm93IG5ldyBFcnJvcihgVGhlIHVybCBzdHJpbmcgcHJvdmlkZWQgZG9lcyBub3QgY29udGFpbiBhIHNjaGVtZS4gU3VwcG9ydGVkIHNjaGVtZXMgYXJlOiAke01vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkkMS5nZXRTY2hlbWVzKCkuam9pbigiLCIpfWApO3JldHVybntzY2hlbWU6aGEuc3BsaXQoVVJMX1NDSEVNRV9TVUZGSVgkMSlbMF0scGF0aDpoYS5zcGxpdChVUkxfU0NIRU1FX1NVRkZJWCQxKVsxXX19YXN5bmMgZnVuY3Rpb24gY2xvbmVNb2RlbEludGVybmFsKGhhLGFhLHhhPSExKXthc3NlcnQkMihoYSE9PWFhLCgpPT5gT2xkIHBhdGggYW5kIG5ldyBwYXRoIGFyZSB0aGUgc2FtZTogJyR7aGF9J2ApO2NvbnN0IGJhPUlPUm91dGVyUmVnaXN0cnkkMS5nZXRMb2FkSGFuZGxlcnMoaGEpO2Fzc2VydCQyKGJhLmxlbmd0aD4wLCgpPT5gQ29weWluZyBmYWlsZWQgYmVjYXVzZSBubyBsb2FkIGhhbmRsZXIgaXMgZm91bmQgZm9yIHNvdXJjZSBVUkwgJHtoYX0uYCksYXNzZXJ0JDIoYmEubGVuZ3RoPDIsKCk9PmBDb3B5aW5nIGZhaWxlZCBiZWNhdXNlIG1vcmUgdGhhbiBvbmUgKCR7YmEubGVuZ3RofSkgbG9hZCBoYW5kbGVycyBmb3Igc291cmNlIFVSTCAke2hhfS5gKTtjb25zdCBTYT1iYVswXSxUYT1JT1JvdXRlclJlZ2lzdHJ5JDEuZ2V0U2F2ZUhhbmRsZXJzKGFhKTthc3NlcnQkMihUYS5sZW5ndGg+MCwoKT0+YENvcHlpbmcgZmFpbGVkIGJlY2F1c2Ugbm8gc2F2ZSBoYW5kbGVyIGlzIGZvdW5kIGZvciBkZXN0aW5hdGlvbiBVUkwgJHthYX0uYCksYXNzZXJ0JDIoVGEubGVuZ3RoPDIsKCk9PmBDb3B5aW5nIGZhaWxlZCBiZWNhdXNlIG1vcmUgdGhhbiBvbmUgKCR7YmEubGVuZ3RofSkgc2F2ZSBoYW5kbGVycyBmb3IgZGVzdGluYXRpb24gVVJMICR7YWF9LmApO2NvbnN0IHdhPVRhWzBdLEVhPXBhcnNlVVJMKGhhKS5zY2hlbWUsa2E9cGFyc2VVUkwoaGEpLnBhdGgsQWE9RWE9PT1wYXJzZVVSTChoYSkuc2NoZW1lLEZhPWF3YWl0IFNhLmxvYWQoKTt4YSYmQWEmJmF3YWl0IE1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkkMS5nZXRNYW5hZ2VyKEVhKS5yZW1vdmVNb2RlbChrYSk7Y29uc3QgTGE9YXdhaXQgd2Euc2F2ZShGYSk7cmV0dXJuIHhhJiYhQWEmJmF3YWl0IE1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkkMS5nZXRNYW5hZ2VyKEVhKS5yZW1vdmVNb2RlbChrYSksTGEubW9kZWxBcnRpZmFjdHNJbmZvfWFzeW5jIGZ1bmN0aW9uIGxpc3RNb2RlbHMoKXtjb25zdCBoYT1Nb2RlbFN0b3JlTWFuYWdlclJlZ2lzdHJ5JDEuZ2V0U2NoZW1lcygpLGFhPXt9O2Zvcihjb25zdCB4YSBvZiBoYSl7Y29uc3QgYmE9YXdhaXQgTW9kZWxTdG9yZU1hbmFnZXJSZWdpc3RyeSQxLmdldE1hbmFnZXIoeGEpLmxpc3RNb2RlbHMoKTtmb3IoY29uc3QgU2EgaW4gYmEpe2NvbnN0IFRhPXhhK1VSTF9TQ0hFTUVfU1VGRklYJDErU2E7YWFbVGFdPWJhW1NhXX19cmV0dXJuIGFhfWFzeW5jIGZ1bmN0aW9uIHJlbW92ZU1vZGVsKGhhKXtjb25zdCBhYT1wYXJzZVVSTChoYSk7cmV0dXJuIE1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkkMS5nZXRNYW5hZ2VyKGFhLnNjaGVtZSkucmVtb3ZlTW9kZWwoYWEucGF0aCl9YXN5bmMgZnVuY3Rpb24gY29weU1vZGVsKGhhLGFhKXtyZXR1cm4gY2xvbmVNb2RlbEludGVybmFsKGhhLGFhLCExKX1hc3luYyBmdW5jdGlvbiBtb3ZlTW9kZWwoaGEsYWEpe3JldHVybiBjbG9uZU1vZGVsSW50ZXJuYWwoaGEsYWEsITApfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBQbGF0Zm9ybUJyb3dzZXIkMT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMubWVzc2FnZU5hbWU9InNldFRpbWVvdXRDdXN0b20iLHRoaXMuZnVuY3Rpb25SZWZzPVtdLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudD0wLHRoaXMuaGFzRXZlbnRMaXN0ZW5lcj0hMX1mZXRjaChhYSx4YSl7cmV0dXJuIGZldGNoKGFhLHhhKX1ub3coKXtyZXR1cm4gcGVyZm9ybWFuY2Uubm93KCl9ZW5jb2RlKGFhLHhhKXtpZih4YSE9PSJ1dGYtOCImJnhhIT09InV0ZjgiKXRocm93IG5ldyBFcnJvcihgQnJvd3NlcidzIGVuY29kZXIgb25seSBzdXBwb3J0cyB1dGYtOCwgYnV0IGdvdCAke3hhfWApO3JldHVybiB0aGlzLnRleHRFbmNvZGVyPT1udWxsJiYodGhpcy50ZXh0RW5jb2Rlcj1uZXcgVGV4dEVuY29kZXIpLHRoaXMudGV4dEVuY29kZXIuZW5jb2RlKGFhKX1kZWNvZGUoYWEseGEpe3JldHVybiBuZXcgVGV4dERlY29kZXIoeGEpLmRlY29kZShhYSl9c2V0VGltZW91dEN1c3RvbShhYSx4YSl7aWYodHlwZW9mIHdpbmRvdz4idSJ8fCFlbnYkMSgpLmdldEJvb2woIlVTRV9TRVRUSU1FT1VUQ1VTVE9NIikpe3NldFRpbWVvdXQoYWEseGEpO3JldHVybn10aGlzLmZ1bmN0aW9uUmVmcy5wdXNoKGFhKSxzZXRUaW1lb3V0KCgpPT57d2luZG93LnBvc3RNZXNzYWdlKHtuYW1lOnRoaXMubWVzc2FnZU5hbWUsaW5kZXg6dGhpcy5mdW5jdGlvblJlZnMubGVuZ3RoLTF9LCIqIil9LHhhKSx0aGlzLmhhc0V2ZW50TGlzdGVuZXJ8fCh0aGlzLmhhc0V2ZW50TGlzdGVuZXI9ITAsd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGJhPT57aWYoYmEuc291cmNlPT09d2luZG93JiZiYS5kYXRhLm5hbWU9PT10aGlzLm1lc3NhZ2VOYW1lKXtiYS5zdG9wUHJvcGFnYXRpb24oKTtjb25zdCBTYT10aGlzLmZ1bmN0aW9uUmVmc1tiYS5kYXRhLmluZGV4XTtTYSgpLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudCsrLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudD09PXRoaXMuZnVuY3Rpb25SZWZzLmxlbmd0aCYmKHRoaXMuZnVuY3Rpb25SZWZzPVtdLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudD0wKX19LCEwKSl9aXNUeXBlZEFycmF5KGFhKXtyZXR1cm4gaXNUeXBlZEFycmF5QnJvd3NlciQxKGFhKX19O2lmKGVudiQxKCkuZ2V0KCJJU19CUk9XU0VSIikpe2VudiQxKCkuc2V0UGxhdGZvcm0oImJyb3dzZXIiLG5ldyBQbGF0Zm9ybUJyb3dzZXIkMSk7dHJ5e01vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkkMS5yZWdpc3Rlck1hbmFnZXIoQnJvd3NlckxvY2FsU3RvcmFnZSQxLlVSTF9TQ0hFTUUsbmV3IEJyb3dzZXJMb2NhbFN0b3JhZ2VNYW5hZ2VyJDEpfWNhdGNoe310cnl7TW9kZWxTdG9yZU1hbmFnZXJSZWdpc3RyeSQxLnJlZ2lzdGVyTWFuYWdlcihCcm93c2VySW5kZXhlZERCJDEuVVJMX1NDSEVNRSxuZXcgQnJvd3NlckluZGV4ZWREQk1hbmFnZXIkMSl9Y2F0Y2h7fX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBnZXROb2RlRmV0Y2gkMT17aW1wb3J0RmV0Y2g6KCk9PnJlcXVpcmUoIm5vZGUtZmV0Y2giKX07bGV0IHN5c3RlbUZldGNoJDEsUGxhdGZvcm1Ob2RlJDE9Y2xhc3N7Y29uc3RydWN0b3IoKXt0aGlzLnV0aWw9cmVxdWlyZSgidXRpbCIpLHRoaXMudGV4dEVuY29kZXI9bmV3IHRoaXMudXRpbC5UZXh0RW5jb2Rlcn1mZXRjaChhYSx4YSl7cmV0dXJuIGVudiQxKCkuZ2xvYmFsLmZldGNoIT1udWxsP2VudiQxKCkuZ2xvYmFsLmZldGNoKGFhLHhhKTooc3lzdGVtRmV0Y2gkMT09bnVsbCYmKHN5c3RlbUZldGNoJDE9Z2V0Tm9kZUZldGNoJDEuaW1wb3J0RmV0Y2goKSksc3lzdGVtRmV0Y2gkMShhYSx4YSkpfW5vdygpe2NvbnN0IGFhPXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJuIGFhWzBdKjFlMythYVsxXS8xZTZ9ZW5jb2RlKGFhLHhhKXtpZih4YSE9PSJ1dGYtOCImJnhhIT09InV0ZjgiKXRocm93IG5ldyBFcnJvcihgTm9kZSBidWlsdC1pbiBlbmNvZGVyIG9ubHkgc3VwcG9ydHMgdXRmLTgsIGJ1dCBnb3QgJHt4YX1gKTtyZXR1cm4gdGhpcy50ZXh0RW5jb2Rlci5lbmNvZGUoYWEpfWRlY29kZShhYSx4YSl7cmV0dXJuIGFhLmxlbmd0aD09PTA/IiI6bmV3IHRoaXMudXRpbC5UZXh0RGVjb2Rlcih4YSkuZGVjb2RlKGFhKX1pc1R5cGVkQXJyYXkoYWEpe3JldHVybiB0aGlzLnV0aWwudHlwZXMuaXNGbG9hdDMyQXJyYXkoYWEpfHx0aGlzLnV0aWwudHlwZXMuaXNJbnQzMkFycmF5KGFhKXx8dGhpcy51dGlsLnR5cGVzLmlzVWludDhBcnJheShhYSl8fHRoaXMudXRpbC50eXBlcy5pc1VpbnQ4Q2xhbXBlZEFycmF5KGFhKX19O2VudiQxKCkuZ2V0KCJJU19OT0RFIikmJiFlbnYkMSgpLmdldCgiSVNfQlJPV1NFUiIpJiZlbnYkMSgpLnNldFBsYXRmb3JtKCJub2RlIixuZXcgUGxhdGZvcm1Ob2RlJDEpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJ1ZmZlciQxKGhhLGFhPSJmbG9hdDMyIix4YSl7cmV0dXJuIGFhPWFhfHwiZmxvYXQzMiIsYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKGhhKSxuZXcgVGVuc29yQnVmZmVyJDEoaGEsYWEseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNhc3RfJDEoaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiY2FzdCIpO2lmKCFpc1ZhbGlkRHR5cGUkMShhYSkpdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY2FzdCB0byB1bmtub3duIGR0eXBlICR7YWF9YCk7aWYoYWE9PT0ic3RyaW5nIiYmeGEuZHR5cGUhPT0ic3RyaW5nInx8YWEhPT0ic3RyaW5nIiYmeGEuZHR5cGU9PT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIk9ubHkgc3RyaW5ncyBjYW4gYmUgY2FzdGVkIHRvIHN0cmluZ3MiKTtjb25zdCBiYT17eDp4YX0sU2E9e2R0eXBlOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKENhc3QkMSxiYSxTYSl9Y29uc3QgY2FzdCQ1PW9wJDEoe2Nhc3RfOmNhc3RfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjbG9uZV8kMShoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJjbG9uZSIsInN0cmluZ19vcl9udW1lcmljIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoSWRlbnRpdHkkMix4YSl9Y29uc3QgY2xvbmUkMT1vcCQxKHtjbG9uZV86Y2xvbmVfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwcmludCQxKGhhLGFhPSExKXtjb25zb2xlLmxvZyhoYS50b1N0cmluZyhhYSkpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldE9yTWFrZUVuZ2luZSQxKCk7Y29uc3Qgb3BIYW5kbGVyJDI9e2J1ZmZlcjpidWZmZXIkMSxjYXN0OmNhc3QkNSxjbG9uZTpjbG9uZSQxLHByaW50OnByaW50JDF9O3NldE9wSGFuZGxlciQxKG9wSGFuZGxlciQyKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhZGRfJDEoaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsImFkZCIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwiYWRkIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEFkZCQyLFNhKX1jb25zdCBhZGQkMz1vcCQxKHthZGRfOmFkZF8kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZsb29yRGl2XyQxKGhhLGFhKXtsZXQgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJmbG9vckRpdiIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwiZmxvb3JEaXYiKTtbeGEsYmFdPW1ha2VUeXBlc01hdGNoJDEoeGEsYmEpO2NvbnN0IFNhPXthOnhhLGI6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoRmxvb3JEaXYkMSxTYSl9Y29uc3QgZmxvb3JEaXYkND1vcCQxKHtmbG9vckRpdl86Zmxvb3JEaXZfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkaXZfJDEoaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsImRpdiIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwiZGl2Iik7aWYoW3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKSx4YS5kdHlwZT09PSJpbnQzMiImJmJhLmR0eXBlPT09ImludDMyIilyZXR1cm4gZmxvb3JEaXYkNCh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX0sVGE9e307cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChSZWFsRGl2JDEsU2EsVGEpfWNvbnN0IGRpdiQyPW9wJDEoe2Rpdl86ZGl2XyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbXVsXyQxKGhhLGFhKXtsZXQgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJtdWwiKSxiYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYiIsIm11bCIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChNdWx0aXBseSQyLFNhKX1jb25zdCBtdWwkMT1vcCQxKHttdWxfOm11bF8kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFic18kMShoYSl7Y29uc3QgYWE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJhYnMiKTtpZihhYS5kdHlwZT09PSJjb21wbGV4NjQiKXtjb25zdCB4YT17eDphYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChDb21wbGV4QWJzJDEseGEpfWVsc2V7Y29uc3QgeGE9e3g6YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQWJzJDEseGEpfX1jb25zdCBhYnMkND1vcCQxKHthYnNfOmFic18kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFjb3NfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImFjb3MiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChBY29zJDEseGEpfWNvbnN0IGFjb3MkMz1vcCQxKHthY29zX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFjb3NoXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJhY29zaCIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEFjb3NoJDEseGEpfWNvbnN0IGFjb3NoJDM9b3AkMSh7YWNvc2hffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYWRkTl8oaGEpe2Fzc2VydCQyKEFycmF5LmlzQXJyYXkoaGEpLCgpPT4iVGhlIGFyZ3VtZW50IHBhc3NlZCB0byB0Zi5hZGROKCkgbXVzdCBiZSBhIGxpc3Qgb2YgdGVuc29ycyIpLGFzc2VydCQyKGhhLmxlbmd0aD49MSwoKT0+YE11c3QgcGFzcyBhdCBsZWFzdCBvbmUgdGVuc29yIHRvIHRmLmFkZE4oKSwgYnV0IGdvdCAke2hhLmxlbmd0aH1gKTtjb25zdCBhYT1oYS5tYXAoKFNhLFRhKT0+Y29udmVydFRvVGVuc29yJDEoU2EsYHRlbnNvcnMke1RhfWAsImFkZE4iKSkseGE9YWFbMF07YWEuZm9yRWFjaChTYT0+e2lmKFNhLmR0eXBlIT09eGEuZHR5cGUpdGhyb3cgbmV3IEVycm9yKCJBbGwgdGVuc29ycyBwYXNzZWQgdG8gdGYuYWRkTigpIG11c3QgaGF2ZSB0aGUgc2FtZSBkdHlwZSIpfSksYWEuZm9yRWFjaChTYT0+e2lmKCFhcnJheXNFcXVhbCQxKFNhLnNoYXBlLHhhLnNoYXBlKSl0aHJvdyBuZXcgRXJyb3IoIkFsbCB0ZW5zb3JzIHBhc3NlZCB0byB0Zi5hZGROKCkgbXVzdCBoYXZlIHRoZSBzYW1lIHNoYXBlIil9KTtjb25zdCBiYT1hYTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEFkZE4kMSxiYSl9Y29uc3QgYWRkTiQzPW9wJDEoe2FkZE5ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYWxsXyhoYSxhYT1udWxsLHhhPSExKXtjb25zdCBTYT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImFsbCIsImJvb2wiKX0sVGE9e2F4aXM6YWEsa2VlcERpbXM6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQWxsJDEsU2EsVGEpfWNvbnN0IGFsbCQzPW9wJDEoe2FsbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhbnlfKGhhLGFhPW51bGwseGE9ITEpe2NvbnN0IFNhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiYW55IiwiYm9vbCIpfSxUYT17YXhpczphYSxrZWVwRGltczp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChBbnkkMSxTYSxUYSl9Y29uc3QgYW55JDM9b3AkMSh7YW55X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFyZ01heF8oaGEsYWE9MCl7Y29uc3QgYmE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJhcmdNYXgiKX0sU2E9e2F4aXM6YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQXJnTWF4JDEsYmEsU2EpfWNvbnN0IGFyZ01heCQzPW9wJDEoe2FyZ01heF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhcmdNaW5fKGhhLGFhPTApe2NvbnN0IGJhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiYXJnTWluIil9LFNhPXtheGlzOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEFyZ01pbiQxLGJhLFNhKX1jb25zdCBhcmdNaW4kMz1vcCQxKHthcmdNaW5ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXNpbl8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiYXNpbiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEFzaW4kMSx4YSl9Y29uc3QgYXNpbiQzPW9wJDEoe2FzaW5ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXNpbmhfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImFzaW5oIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQXNpbmgkMSx4YSl9Y29uc3QgYXNpbmgkMz1vcCQxKHthc2luaF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhdGFuXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJhdGFuIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQXRhbiQxLHhhKX1jb25zdCBhdGFuJDM9b3AkMSh7YXRhbl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhdGFuMl8oaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsImF0YW4yIiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsImIiLCJhdGFuMiIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChBdGFuMiQxLFNhKX1jb25zdCBhdGFuMiQzPW9wJDEoe2F0YW4yX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF0YW5oXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJhdGFuaCIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEF0YW5oJDEseGEpfWNvbnN0IGF0YW5oJDM9b3AkMSh7YXRhbmhffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29tcHV0ZURpbGF0aW9uMkRJbmZvJDEoaGEsYWEseGEsYmEsU2E9Ik5IV0MiLFRhKXtjb25zdCB3YT1oYVszXSxFYT1bLi4uYWEsd2FdLGthPWNvbnZlcnRDb252MkREYXRhRm9ybWF0JDEoU2EpO3JldHVybiBjb21wdXRlQ29udjJESW5mbyQxKGhhLEVhLHhhLFRhLGJhLG51bGwsbnVsbCxrYSl9ZnVuY3Rpb24gY29tcHV0ZVBvb2wyREluZm8kMShoYSxhYSx4YSxiYSxTYSxUYSx3YT0iY2hhbm5lbHNMYXN0Iil7Y29uc3RbRWEsa2FdPXBhcnNlVHVwbGVQYXJhbSQxKGFhKTtsZXQgQWE7aWYod2E9PT0iY2hhbm5lbHNMYXN0IilBYT1bRWEsa2EsaGFbM10saGFbM11dO2Vsc2UgaWYod2E9PT0iY2hhbm5lbHNGaXJzdCIpQWE9W0VhLGthLGhhWzFdLGhhWzFdXTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhRm9ybWF0ICR7d2F9YCk7cmV0dXJuIGNvbXB1dGVDb252MkRJbmZvJDEoaGEsQWEseGEsYmEsU2EsVGEsITEsd2EpfWZ1bmN0aW9uIGNvbXB1dGVQb29sM0RJbmZvJDEoaGEsYWEseGEsYmEsU2EsVGEsd2E9Ik5ESFdDIil7Y29uc3RbRWEsa2EsQWFdPXBhcnNlM1R1cGxlUGFyYW0kMShhYSk7bGV0IEZhLExhO2lmKHdhPT09Ik5ESFdDIilMYT0iY2hhbm5lbHNMYXN0IixGYT1bRWEsa2EsQWEsaGFbNF0saGFbNF1dO2Vsc2UgaWYod2E9PT0iTkNESFciKUxhPSJjaGFubmVsc0ZpcnN0IixGYT1bRWEsa2EsQWEsaGFbMV0saGFbMV1dO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGFGb3JtYXQgJHt3YX1gKTtyZXR1cm4gY29tcHV0ZUNvbnYzREluZm8kMShoYSxGYSx4YSxiYSxTYSwhMSxMYSxUYSl9ZnVuY3Rpb24gY29tcHV0ZUNvbnYyREluZm8kMShoYSxhYSx4YSxiYSxTYSxUYSx3YT0hMSxFYT0iY2hhbm5lbHNMYXN0Iil7bGV0W2thLEFhLEZhLExhXT1bLTEsLTEsLTEsLTFdO2lmKEVhPT09ImNoYW5uZWxzTGFzdCIpW2thLEFhLEZhLExhXT1oYTtlbHNlIGlmKEVhPT09ImNoYW5uZWxzRmlyc3QiKVtrYSxMYSxBYSxGYV09aGE7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YUZvcm1hdCAke0VhfWApO2NvbnN0W2VsLHRsLCxubF09YWEsW3NsLHJsXT1wYXJzZVR1cGxlUGFyYW0kMSh4YSksW29sLGFsXT1wYXJzZVR1cGxlUGFyYW0kMShiYSksbGw9Z2V0RWZmZWN0aXZlRmlsdGVyU2l6ZSQxKGVsLG9sKSxpbD1nZXRFZmZlY3RpdmVGaWx0ZXJTaXplJDEodGwsYWwpLHtwYWRJbmZvOmNsLG91dEhlaWdodDp1bCxvdXRXaWR0aDpkbH09Z2V0UGFkQW5kT3V0SW5mbyQxKFNhLEFhLEZhLHNsLHJsLGxsLGlsLFRhLEVhKSxobD13YT9ubCpMYTpubDtsZXQgcGw7cmV0dXJuIEVhPT09ImNoYW5uZWxzRmlyc3QiP3BsPVtrYSxobCx1bCxkbF06RWE9PT0iY2hhbm5lbHNMYXN0IiYmKHBsPVtrYSx1bCxkbCxobF0pLHtiYXRjaFNpemU6a2EsZGF0YUZvcm1hdDpFYSxpbkhlaWdodDpBYSxpbldpZHRoOkZhLGluQ2hhbm5lbHM6TGEsb3V0SGVpZ2h0OnVsLG91dFdpZHRoOmRsLG91dENoYW5uZWxzOmhsLHBhZEluZm86Y2wsc3RyaWRlSGVpZ2h0OnNsLHN0cmlkZVdpZHRoOnJsLGZpbHRlckhlaWdodDplbCxmaWx0ZXJXaWR0aDp0bCxlZmZlY3RpdmVGaWx0ZXJIZWlnaHQ6bGwsZWZmZWN0aXZlRmlsdGVyV2lkdGg6aWwsZGlsYXRpb25IZWlnaHQ6b2wsZGlsYXRpb25XaWR0aDphbCxpblNoYXBlOmhhLG91dFNoYXBlOnBsLGZpbHRlclNoYXBlOmFhfX1mdW5jdGlvbiBjb21wdXRlQ29udjNESW5mbyQxKGhhLGFhLHhhLGJhLFNhLFRhPSExLHdhPSJjaGFubmVsc0xhc3QiLEVhKXtsZXRba2EsQWEsRmEsTGEsZWxdPVstMSwtMSwtMSwtMSwtMV07aWYod2E9PT0iY2hhbm5lbHNMYXN0Iilba2EsQWEsRmEsTGEsZWxdPWhhO2Vsc2UgaWYod2E9PT0iY2hhbm5lbHNGaXJzdCIpW2thLGVsLEFhLEZhLExhXT1oYTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhRm9ybWF0ICR7d2F9YCk7Y29uc3RbdGwsbmwsc2wsLHJsXT1hYSxbb2wsYWwsbGxdPXBhcnNlM1R1cGxlUGFyYW0kMSh4YSksW2lsLGNsLHVsXT1wYXJzZTNUdXBsZVBhcmFtJDEoYmEpLGRsPWdldEVmZmVjdGl2ZUZpbHRlclNpemUkMSh0bCxpbCksaGw9Z2V0RWZmZWN0aXZlRmlsdGVyU2l6ZSQxKG5sLGNsKSxwbD1nZXRFZmZlY3RpdmVGaWx0ZXJTaXplJDEoc2wsdWwpLHtwYWRJbmZvOmZsLG91dERlcHRoOm1sLG91dEhlaWdodDpnbCxvdXRXaWR0aDokbH09Z2V0M0RQYWRBbmRPdXRJbmZvJDEoU2EsQWEsRmEsTGEsb2wsYWwsbGwsZGwsaGwscGwsRWEpLHhsPVRhP3JsKmVsOnJsO2xldCB5bDtyZXR1cm4gd2E9PT0iY2hhbm5lbHNGaXJzdCI/eWw9W2thLHhsLG1sLGdsLCRsXTp3YT09PSJjaGFubmVsc0xhc3QiJiYoeWw9W2thLG1sLGdsLCRsLHhsXSkse2JhdGNoU2l6ZTprYSxkYXRhRm9ybWF0OndhLGluRGVwdGg6QWEsaW5IZWlnaHQ6RmEsaW5XaWR0aDpMYSxpbkNoYW5uZWxzOmVsLG91dERlcHRoOm1sLG91dEhlaWdodDpnbCxvdXRXaWR0aDokbCxvdXRDaGFubmVsczp4bCxwYWRJbmZvOmZsLHN0cmlkZURlcHRoOm9sLHN0cmlkZUhlaWdodDphbCxzdHJpZGVXaWR0aDpsbCxmaWx0ZXJEZXB0aDp0bCxmaWx0ZXJIZWlnaHQ6bmwsZmlsdGVyV2lkdGg6c2wsZWZmZWN0aXZlRmlsdGVyRGVwdGg6ZGwsZWZmZWN0aXZlRmlsdGVySGVpZ2h0OmhsLGVmZmVjdGl2ZUZpbHRlcldpZHRoOnBsLGRpbGF0aW9uRGVwdGg6aWwsZGlsYXRpb25IZWlnaHQ6Y2wsZGlsYXRpb25XaWR0aDp1bCxpblNoYXBlOmhhLG91dFNoYXBlOnlsLGZpbHRlclNoYXBlOmFhfX1mdW5jdGlvbiBjb21wdXRlT3V0cHV0U2hhcGUyRCQxKGhhLGFhLHhhLGJhLFNhKXtiYT09bnVsbCYmKGJhPWNvbXB1dGVEZWZhdWx0UGFkJDEoaGEsYWEseGEpKTtjb25zdCBUYT1oYVswXSx3YT1oYVsxXSxFYT1yb3VuZCQ1KChUYS1hYSsyKmJhKS94YSsxLFNhKSxrYT1yb3VuZCQ1KCh3YS1hYSsyKmJhKS94YSsxLFNhKTtyZXR1cm5bRWEsa2FdfWZ1bmN0aW9uIGNvbXB1dGVPdXRwdXRTaGFwZTREJDEoaGEsYWEseGEsYmEsU2EsVGEpe1NhPT1udWxsJiYoU2E9Y29tcHV0ZURlZmF1bHRQYWQkMShoYSxhYVswXSxiYVswXSkpO2NvbnN0IHdhPVswLDAsMCx4YV07Zm9yKGxldCBFYT0wO0VhPDM7RWErKyloYVtFYV0rMipTYT49YWFbRWFdJiYod2FbRWFdPXJvdW5kJDUoKGhhW0VhXS1hYVtFYV0rMipTYSkvYmFbRWFdKzEsVGEpKTtyZXR1cm4gd2F9ZnVuY3Rpb24gY29tcHV0ZURlZmF1bHRQYWQkMShoYSxhYSx4YSxiYT0xKXtjb25zdCBTYT1nZXRFZmZlY3RpdmVGaWx0ZXJTaXplJDEoYWEsYmEpO3JldHVybiBNYXRoLmZsb29yKChoYVswXSooeGEtMSkteGErU2EpLzIpfWZ1bmN0aW9uIHBhcnNlVHVwbGVQYXJhbSQxKGhhKXtyZXR1cm4gdHlwZW9mIGhhPT0ibnVtYmVyIj9baGEsaGEsaGFdOmhhLmxlbmd0aD09PTI/W2hhWzBdLGhhWzFdLDFdOmhhfWZ1bmN0aW9uIHBhcnNlM1R1cGxlUGFyYW0kMShoYSl7cmV0dXJuIHR5cGVvZiBoYT09Im51bWJlciI/W2hhLGhhLGhhXTpoYX1mdW5jdGlvbiBnZXRFZmZlY3RpdmVGaWx0ZXJTaXplJDEoaGEsYWEpe3JldHVybiBhYTw9MT9oYTpoYSsoaGEtMSkqKGFhLTEpfWZ1bmN0aW9uIGdldFBhZEFuZE91dEluZm8kMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSl7bGV0IEFhLEZhLExhO2lmKHR5cGVvZiBoYT09Im51bWJlciIpe0FhPXt0b3A6aGEsYm90dG9tOmhhLGxlZnQ6aGEscmlnaHQ6aGEsdHlwZTpoYT09PTA/IlZBTElEIjoiTlVNQkVSIn07Y29uc3QgdGw9Y29tcHV0ZU91dHB1dFNoYXBlMkQkMShbYWEseGFdLFRhLGJhLGhhLEVhKTtGYT10bFswXSxMYT10bFsxXX1lbHNlIGlmKGhhPT09InNhbWUiKXtGYT1NYXRoLmNlaWwoYWEvYmEpLExhPU1hdGguY2VpbCh4YS9TYSk7Y29uc3QgZWw9TWF0aC5tYXgoMCwoRmEtMSkqYmErVGEtYWEpLHRsPU1hdGgubWF4KDAsKExhLTEpKlNhK3dhLXhhKSxubD1NYXRoLmZsb29yKGVsLzIpLHNsPWVsLW5sLHJsPU1hdGguZmxvb3IodGwvMiksb2w9dGwtcmw7QWE9e3RvcDpubCxib3R0b206c2wsbGVmdDpybCxyaWdodDpvbCx0eXBlOiJTQU1FIn19ZWxzZSBpZihoYT09PSJ2YWxpZCIpQWE9e3RvcDowLGJvdHRvbTowLGxlZnQ6MCxyaWdodDowLHR5cGU6IlZBTElEIn0sRmE9TWF0aC5jZWlsKChhYS1UYSsxKS9iYSksTGE9TWF0aC5jZWlsKCh4YS13YSsxKS9TYSk7ZWxzZSBpZih0eXBlb2YgaGE9PSJvYmplY3QiKXtjb25zdCBlbD1rYT09PSJjaGFubmVsc0xhc3QiP2hhWzFdWzBdOmhhWzJdWzBdLHRsPWthPT09ImNoYW5uZWxzTGFzdCI/aGFbMV1bMV06aGFbMl1bMV0sbmw9a2E9PT0iY2hhbm5lbHNMYXN0Ij9oYVsyXVswXTpoYVszXVswXSxzbD1rYT09PSJjaGFubmVsc0xhc3QiP2hhWzJdWzFdOmhhWzNdWzFdO0FhPXt0b3A6ZWwsYm90dG9tOnRsLGxlZnQ6bmwscmlnaHQ6c2wsdHlwZTplbD09PTAmJnRsPT09MCYmbmw9PT0wJiZzbD09PTA/IlZBTElEIjoiRVhQTElDSVQifSxGYT1yb3VuZCQ1KChhYS1UYStlbCt0bCkvYmErMSxFYSksTGE9cm91bmQkNSgoeGEtd2Erbmwrc2wpL1NhKzEsRWEpfWVsc2UgdGhyb3cgRXJyb3IoYFVua25vd24gcGFkZGluZyBwYXJhbWV0ZXI6ICR7aGF9YCk7cmV0dXJue3BhZEluZm86QWEsb3V0SGVpZ2h0OkZhLG91dFdpZHRoOkxhfX1mdW5jdGlvbiBnZXQzRFBhZEFuZE91dEluZm8kMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSxGYSl7bGV0IExhLGVsLHRsLG5sO2lmKGhhPT09InZhbGlkIiYmKGhhPTApLHR5cGVvZiBoYT09Im51bWJlciIpe0xhPXt0b3A6aGEsYm90dG9tOmhhLGxlZnQ6aGEscmlnaHQ6aGEsZnJvbnQ6aGEsYmFjazpoYSx0eXBlOmhhPT09MD8iVkFMSUQiOiJOVU1CRVIifTtjb25zdCBybD1jb21wdXRlT3V0cHV0U2hhcGU0RCQxKFthYSx4YSxiYSwxXSxbRWEsa2EsQWFdLDEsW1NhLFRhLHdhXSxoYSxGYSk7ZWw9cmxbMF0sdGw9cmxbMV0sbmw9cmxbMl19ZWxzZSBpZihoYT09PSJzYW1lIil7ZWw9TWF0aC5jZWlsKGFhL1NhKSx0bD1NYXRoLmNlaWwoeGEvVGEpLG5sPU1hdGguY2VpbChiYS93YSk7Y29uc3Qgc2w9KGVsLTEpKlNhK0VhLWFhLHJsPSh0bC0xKSpUYStrYS14YSxvbD0obmwtMSkqd2ErQWEtYmEsYWw9TWF0aC5mbG9vcihzbC8yKSxsbD1zbC1hbCxpbD1NYXRoLmZsb29yKHJsLzIpLGNsPXJsLWlsLHVsPU1hdGguZmxvb3Iob2wvMiksZGw9b2wtdWw7TGE9e3RvcDppbCxib3R0b206Y2wsbGVmdDp1bCxyaWdodDpkbCxmcm9udDphbCxiYWNrOmxsLHR5cGU6IlNBTUUifX1lbHNlIHRocm93IEVycm9yKGBVbmtub3duIHBhZGRpbmcgcGFyYW1ldGVyOiAke2hhfWApO3JldHVybntwYWRJbmZvOkxhLG91dERlcHRoOmVsLG91dEhlaWdodDp0bCxvdXRXaWR0aDpubH19ZnVuY3Rpb24gcm91bmQkNShoYSxhYSl7aWYoIWFhKXJldHVybiBNYXRoLnRydW5jKGhhKTtzd2l0Y2goYWEpe2Nhc2Uicm91bmQiOnJldHVybiBNYXRoLnJvdW5kKGhhKTtjYXNlImNlaWwiOnJldHVybiBNYXRoLmNlaWwoaGEpO2Nhc2UiZmxvb3IiOnJldHVybiBNYXRoLmZsb29yKGhhKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgVW5rbm93biByb3VuZGluZ01vZGUgJHthYX1gKX19ZnVuY3Rpb24gdHVwbGVWYWx1ZXNBcmVPbmUkMShoYSl7Y29uc3RbYWEseGEsYmFdPXBhcnNlVHVwbGVQYXJhbSQxKGhhKTtyZXR1cm4gYWE9PT0xJiZ4YT09PTEmJmJhPT09MX1mdW5jdGlvbiBlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUkMShoYSxhYSl7cmV0dXJuIHR1cGxlVmFsdWVzQXJlT25lJDEoaGEpfHx0dXBsZVZhbHVlc0FyZU9uZSQxKGFhKX1mdW5jdGlvbiBzdHJpZGVzT3JEaWxhdGlvbnNBcmVQb3NpdGl2ZSQxKGhhKXtyZXR1cm4gcGFyc2VUdXBsZVBhcmFtJDEoaGEpLmV2ZXJ5KGFhPT5hYT4wKX1mdW5jdGlvbiBjb252ZXJ0Q29udjJERGF0YUZvcm1hdCQxKGhhKXtpZihoYT09PSJOSFdDIilyZXR1cm4iY2hhbm5lbHNMYXN0IjtpZihoYT09PSJOQ0hXIilyZXR1cm4iY2hhbm5lbHNGaXJzdCI7dGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGFGb3JtYXQgJHtoYX1gKX1mdW5jdGlvbiBjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlJDEoaGEsYWEseGEpe2lmKHhhIT1udWxsKXtpZih0eXBlb2YgYWE9PSJzdHJpbmciKXRocm93IEVycm9yKGBFcnJvciBpbiAke2hhfTogcGFkIG11c3QgYmUgYW4gaW50ZWdlciB3aGVuIHVzaW5nIGRpbVJvdW5kaW5nTW9kZSAke3hhfSBidXQgZ290IHBhZCAke2FhfS5gKTtpZih0eXBlb2YgYWE9PSJudW1iZXIiKWFzc2VydCQyKGlzSW50JDEoYWEpLCgpPT5gRXJyb3IgaW4gJHtoYX06IHBhZCBtdXN0IGJlIGFuIGludGVnZXIgd2hlbiB1c2luZyBkaW1Sb3VuZGluZ01vZGUgJHt4YX0gYnV0IGdvdCBwYWQgJHthYX0uYCk7ZWxzZSBpZih0eXBlb2YgYWE9PSJvYmplY3QiKWFhLmZvckVhY2goYmE9PntiYS5mb3JFYWNoKFNhPT57YXNzZXJ0JDIoaXNJbnQkMShTYSksKCk9PmBFcnJvciBpbiAke2hhfTogcGFkIG11c3QgYmUgYW4gaW50ZWdlciB3aGVuIHVzaW5nIGRpbVJvdW5kaW5nTW9kZSAke3hhfSBidXQgZ290IHBhZCAke1NhfS5gKX0pfSk7ZWxzZSB0aHJvdyBFcnJvcihgRXJyb3IgaW4gJHtoYX06IFVua25vd24gcGFkZGluZyBwYXJhbWV0ZXI6ICR7YWF9YCl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJlc2hhcGVfJDEoaGEsYWEpe2NvbnN0IGJhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwicmVzaGFwZSIsInN0cmluZ19vcl9udW1lcmljIil9LFNhPXtzaGFwZTphYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChSZXNoYXBlJDIsYmEsU2EpfWNvbnN0IHJlc2hhcGUkND1vcCQxKHtyZXNoYXBlXzpyZXNoYXBlXyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXZnUG9vbF8oaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiYXZnUG9vbCIsImZsb2F0MzIiKSx3YT0xO2Fzc2VydCQyKGVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZSQxKHhhLHdhKSwoKT0+YEVycm9yIGluIGF2Z1Bvb2w6IEVpdGhlciBzdHJpZGVzIG9yIGRpbGF0aW9ucyBtdXN0IGJlIDEuIEdvdCBzdHJpZGVzICR7eGF9IGFuZCBkaWxhdGlvbnMgJyR7d2F9J2ApO2xldCBFYT1UYSxrYT0hMTtUYS5yYW5rPT09MyYmKGthPSEwLEVhPXJlc2hhcGUkNChUYSxbMSxUYS5zaGFwZVswXSxUYS5zaGFwZVsxXSxUYS5zaGFwZVsyXV0pKSxhc3NlcnQkMihFYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIGF2Z1Bvb2w6IHggbXVzdCBiZSByYW5rIDQgYnV0IGdvdCByYW5rICR7RWEucmFua30uYCksY2hlY2tQYWRPbkRpbVJvdW5kaW5nTW9kZSQxKCJhdmdQb29sIixiYSxTYSk7Y29uc3QgQWE9e3g6RWF9LEZhPXtmaWx0ZXJTaXplOmFhLHN0cmlkZXM6eGEscGFkOmJhLGRpbVJvdW5kaW5nTW9kZTpTYX07bGV0IExhPUVOR0lORSQxLnJ1bktlcm5lbChBdmdQb29sJDEsQWEsRmEpO3JldHVybiBMYT1jYXN0JDUoTGEsVGEuZHR5cGUpLGthP3Jlc2hhcGUkNChMYSxbTGEuc2hhcGVbMV0sTGEuc2hhcGVbMl0sTGEuc2hhcGVbM11dKTpMYX1jb25zdCBhdmdQb29sJDM9b3AkMSh7YXZnUG9vbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhdmdQb29sM2RfKGhhLGFhLHhhLGJhLFNhLFRhPSJOREhXQyIpe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiYXZnUG9vbDNkIiwiZmxvYXQzMiIpO2xldCBFYT13YSxrYT0hMTt3YS5yYW5rPT09NCYmKGthPSEwLEVhPXJlc2hhcGUkNCh3YSxbMSx3YS5zaGFwZVswXSx3YS5zaGFwZVsxXSx3YS5zaGFwZVsyXSx3YS5zaGFwZVszXV0pKSxhc3NlcnQkMihFYS5yYW5rPT09NSwoKT0+YEVycm9yIGluIGF2Z1Bvb2wzZDogeCBtdXN0IGJlIHJhbmsgNSBidXQgZ290IHJhbmsgJHtFYS5yYW5rfS5gKSxhc3NlcnQkMihUYT09PSJOREhXQyIsKCk9PmBFcnJvciBpbiBhdmdQb29sM2Q6IE9ubHkgTkRIV0MgaXMgY3VycmVudGx5IHN1cHBvcnRlZCwgYnV0IGdvdCBkYXRhRm9ybWF0IG9mICR7VGF9YCksYXNzZXJ0JDIodHlwZW9mIHhhPT0ibnVtYmVyIiYmeGE+MHx8QXJyYXkuaXNBcnJheSh4YSkmJnhhWzBdPjAmJnhhWzFdPjAmJnhhWzJdPjAsKCk9PmBFcnJvciBpbiBhdmdQb29sM2Q6IFN0cmlkZSBtdXN0IGJlID4gMCwgYnV0IGdvdCAnJHt4YX0nYCksY2hlY2tQYWRPbkRpbVJvdW5kaW5nTW9kZSQxKCJhdmdQb29sM2QiLGJhLFNhKTtjb25zdCBBYT17eDpFYX0sRmE9e2ZpbHRlclNpemU6YWEsc3RyaWRlczp4YSxwYWQ6YmEsZGltUm91bmRpbmdNb2RlOlNhLGRhdGFGb3JtYXQ6VGF9O2xldCBMYT1FTkdJTkUkMS5ydW5LZXJuZWwoQXZnUG9vbDNEJDEsQWEsRmEpO3JldHVybiBMYT1jYXN0JDUoTGEsRWEuZHR5cGUpLGthP3Jlc2hhcGUkNChMYSxbTGEuc2hhcGVbMV0sTGEuc2hhcGVbMl0sTGEuc2hhcGVbM10sTGEuc2hhcGVbNF1dKTpMYX1jb25zdCBhdmdQb29sM2Q9b3AkMSh7YXZnUG9vbDNkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbmNhdF8oaGEsYWE9MCl7YXNzZXJ0JDIoaGEubGVuZ3RoPj0xLCgpPT4iUGFzcyBhdCBsZWFzdCBvbmUgdGVuc29yIHRvIGNvbmNhdCIpO2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvckFycmF5KGhhLCJ0ZW5zb3JzIiwiY29uY2F0Iiwic3RyaW5nX29yX251bWVyaWMiKTtpZih4YVswXS5kdHlwZT09PSJjb21wbGV4NjQiJiZ4YS5mb3JFYWNoKFRhPT57aWYoVGEuZHR5cGUhPT0iY29tcGxleDY0Iil0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb25jYXRlbmF0ZSBjb21wbGV4NjQgdGVuc29ycyB3aXRoIGEgdGVuc29yCiAgICAgICAgICB3aXRoIGR0eXBlICR7VGEuZHR5cGV9LiBgKX0pLHhhLmxlbmd0aD09PTEpcmV0dXJuIGNsb25lJDEoeGFbMF0pO2NvbnN0IGJhPXhhLFNhPXtheGlzOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKENvbmNhdCQxLGJhLFNhKX1jb25zdCBjb25jYXQkMz1vcCQxKHtjb25jYXRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF0TXVsXyhoYSxhYSx4YT0hMSxiYT0hMSl7bGV0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwibWF0TXVsIiksVGE9Y29udmVydFRvVGVuc29yJDEoYWEsImIiLCJtYXRNdWwiKTtbU2EsVGFdPW1ha2VUeXBlc01hdGNoJDEoU2EsVGEpO2NvbnN0IHdhPXthOlNhLGI6VGF9LEVhPXt0cmFuc3Bvc2VBOnhhLHRyYW5zcG9zZUI6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQmF0Y2hNYXRNdWwkMSx3YSxFYSl9Y29uc3QgbWF0TXVsJDE9b3AkMSh7bWF0TXVsX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNpZ21vaWRfJDEoaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic2lnbW9pZCIsImZsb2F0MzIiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTaWdtb2lkJDIseGEpfWNvbnN0IHNpZ21vaWQkND1vcCQxKHtzaWdtb2lkXzpzaWdtb2lkXyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2xpY2VfKGhhLGFhLHhhKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNsaWNlIiwic3RyaW5nX29yX251bWVyaWMiKTtpZihiYS5yYW5rPT09MCl0aHJvdyBuZXcgRXJyb3IoIlNsaWNpbmcgc2NhbGFyIGlzIG5vdCBwb3NzaWJsZSIpO2NvbnN0IFNhPXt4OmJhfSxUYT17YmVnaW46YWEsc2l6ZTp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTbGljZSQxLFNhLFRhKX1jb25zdCBzbGljZSQzPW9wJDEoe3NsaWNlX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRhbmhfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInRhbmgiLCJmbG9hdDMyIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoVGFuaCQyLHhhKX1jb25zdCB0YW5oJDM9b3AkMSh7dGFuaF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiYXNpY0xTVE1DZWxsXyhoYSxhYSx4YSxiYSxTYSxUYSl7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoaGEsImZvcmdldEJpYXMiLCJiYXNpY0xTVE1DZWxsIiksRWE9Y29udmVydFRvVGVuc29yJDEoYWEsImxzdG1LZXJuZWwiLCJiYXNpY0xTVE1DZWxsIiksa2E9Y29udmVydFRvVGVuc29yJDEoeGEsImxzdG1CaWFzIiwiYmFzaWNMU1RNQ2VsbCIpLEFhPWNvbnZlcnRUb1RlbnNvciQxKGJhLCJkYXRhIiwiYmFzaWNMU1RNQ2VsbCIpLEZhPWNvbnZlcnRUb1RlbnNvciQxKFNhLCJjIiwiYmFzaWNMU1RNQ2VsbCIpLExhPWNvbnZlcnRUb1RlbnNvciQxKFRhLCJoIiwiYmFzaWNMU1RNQ2VsbCIpLGVsPWNvbmNhdCQzKFtBYSxMYV0sMSksdGw9bWF0TXVsJDEoZWwsRWEpLG5sPWFkZCQzKHRsLGthKSxzbD1ubC5zaGFwZVswXSxybD1ubC5zaGFwZVsxXS80LG9sPVtzbCxybF0sYWw9c2xpY2UkMyhubCxbMCwwXSxvbCksbGw9c2xpY2UkMyhubCxbMCxybF0sb2wpLGlsPXNsaWNlJDMobmwsWzAscmwqMl0sb2wpLGNsPXNsaWNlJDMobmwsWzAscmwqM10sb2wpLHVsPWFkZCQzKG11bCQxKHNpZ21vaWQkNChhbCksdGFuaCQzKGxsKSksbXVsJDEoRmEsc2lnbW9pZCQ0KGFkZCQzKHdhLGlsKSkpKSxkbD1tdWwkMSh0YW5oJDModWwpLHNpZ21vaWQkNChjbCkpO3JldHVyblt1bCxkbF19Y29uc3QgYmFzaWNMU1RNQ2VsbD1vcCQxKHtiYXNpY0xTVE1DZWxsX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJhdGNoVG9TcGFjZU5EXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJiYXRjaFRvU3BhY2VORCIpLFNhPWFhLnJlZHVjZSgoRWEsa2EpPT5FYSprYSk7YXNzZXJ0JDIoYmEucmFuaz49MSthYS5sZW5ndGgsKCk9PmBpbnB1dCByYW5rIGlzICR7YmEucmFua30gYnV0IHNob3VsZCBiZSA+IHRoYW4gYmxvY2tTaGFwZS5sZW5ndGggJHthYS5sZW5ndGh9YCksYXNzZXJ0JDIoeGEubGVuZ3RoPT09YWEubGVuZ3RoLCgpPT5gY3JvcHMubGVuZ3RoIGlzICR7eGEubGVuZ3RofSBidXQgc2hvdWxkIGJlIGVxdWFsIHRvIGJsb2NrU2hhcGUubGVuZ3RoICAke2FhLmxlbmd0aH1gKSxhc3NlcnQkMihiYS5zaGFwZVswXSVTYT09PTAsKCk9PmBpbnB1dCB0ZW5zb3IgYmF0Y2ggaXMgJHtiYS5zaGFwZVswXX0gYnV0IGlzIG5vdCBkaXZpc2libGUgYnkgdGhlIHByb2R1Y3Qgb2YgdGhlIGVsZW1lbnRzIG9mIGJsb2NrU2hhcGUgJHthYS5qb2luKCIgKiAiKX0gPT09ICR7U2F9YCk7Y29uc3QgVGE9e3g6YmF9LHdhPXtibG9ja1NoYXBlOmFhLGNyb3BzOnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEJhdGNoVG9TcGFjZU5EJDEsVGEsd2EpfWNvbnN0IGJhdGNoVG9TcGFjZU5EJDM9b3AkMSh7YmF0Y2hUb1NwYWNlTkRffSk7ZnVuY3Rpb24geEFzNEQoaGEpe2xldCBhYTtyZXR1cm4gaGEucmFuaz09PTB8fGhhLnJhbms9PT0xP2FhPXJlc2hhcGUkNChoYSxbMSwxLDEsaGEuc2l6ZV0pOmhhLnJhbms9PT0yP2FhPXJlc2hhcGUkNChoYSxbMSwxLGhhLnNoYXBlWzBdLGhhLnNoYXBlWzFdXSk6aGEucmFuaz09PTM/YWE9cmVzaGFwZSQ0KGhhLFsxLGhhLnNoYXBlWzBdLGhhLnNoYXBlWzFdLGhhLnNoYXBlWzJdXSk6YWE9aGEsYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYmF0Y2hOb3JtXyhoYSxhYSx4YSxiYSxTYSxUYSl7VGE9PW51bGwmJihUYT0uMDAxKTtjb25zdCB3YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImJhdGNoTm9ybSIpLEVhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJtZWFuIiwiYmF0Y2hOb3JtIiksa2E9Y29udmVydFRvVGVuc29yJDEoeGEsInZhcmlhbmNlIiwiYmF0Y2hOb3JtIik7bGV0IEFhO1NhIT1udWxsJiYoQWE9Y29udmVydFRvVGVuc29yJDEoU2EsInNjYWxlIiwiYmF0Y2hOb3JtIikpO2xldCBGYTtiYSE9bnVsbCYmKEZhPWNvbnZlcnRUb1RlbnNvciQxKGJhLCJvZmZzZXQiLCJiYXRjaE5vcm0iKSksYXNzZXJ0JDIoRWEucmFuaz09PWthLnJhbmssKCk9PiJCYXRjaCBub3JtYWxpemF0aW9uIGdyYWRpZW50IHJlcXVpcmVzIG1lYW4gYW5kIHZhcmlhbmNlIHRvIGhhdmUgZXF1YWwgcmFua3MuIiksYXNzZXJ0JDIoRmE9PW51bGx8fEVhLnJhbms9PT1GYS5yYW5rLCgpPT4iQmF0Y2ggbm9ybWFsaXphdGlvbiBncmFkaWVudCByZXF1aXJlcyBtZWFuIGFuZCBvZmZzZXQgdG8gaGF2ZSBlcXVhbCByYW5rcy4iKSxhc3NlcnQkMihBYT09bnVsbHx8RWEucmFuaz09PUFhLnJhbmssKCk9PiJCYXRjaCBub3JtYWxpemF0aW9uIGdyYWRpZW50IHJlcXVpcmVzIG1lYW4gYW5kIHNjYWxlIHRvIGhhdmUgZXF1YWwgcmFua3MuIik7Y29uc3QgZWw9e3g6eEFzNEQod2EpLHNjYWxlOkFhLG9mZnNldDpGYSxtZWFuOkVhLHZhcmlhbmNlOmthfSx0bD17dmFyaWFuY2VFcHNpbG9uOlRhfSxubD1FTkdJTkUkMS5ydW5LZXJuZWwoRnVzZWRCYXRjaE5vcm0kMSxlbCx0bCk7cmV0dXJuIHJlc2hhcGUkNChubCx3YS5zaGFwZSl9Y29uc3QgYmF0Y2hOb3JtJDM9b3AkMSh7YmF0Y2hOb3JtX30pO2Z1bmN0aW9uIGJhdGNoTm9ybTJkXyhoYSxhYSx4YSxiYSxTYSxUYSl7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJiYXRjaE5vcm0iKSxFYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwibWVhbiIsImJhdGNoTm9ybSIpLGthPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ2YXJpYW5jZSIsImJhdGNoTm9ybSIpO2xldCBBYTtTYSE9bnVsbCYmKEFhPWNvbnZlcnRUb1RlbnNvciQxKFNhLCJzY2FsZSIsImJhdGNoTm9ybSIpKTtsZXQgRmE7cmV0dXJuIGJhIT1udWxsJiYoRmE9Y29udmVydFRvVGVuc29yJDEoYmEsIm9mZnNldCIsImJhdGNoTm9ybSIpKSxhc3NlcnQkMih3YS5yYW5rPT09MiwoKT0+YEVycm9yIGluIGJhdGNoTm9ybTJEOiB4IG11c3QgYmUgcmFuayAyIGJ1dCBnb3QgcmFuayAke3dhLnJhbmt9LmApLGFzc2VydCQyKEVhLnJhbms9PT0yfHxFYS5yYW5rPT09MSwoKT0+YEVycm9yIGluIGJhdGNoTm9ybTJEOiBtZWFuIG11c3QgYmUgcmFuayAyIG9yIHJhbmsgMSBidXQgZ290IHJhbmsgJHtFYS5yYW5rfS5gKSxhc3NlcnQkMihrYS5yYW5rPT09Mnx8a2EucmFuaz09PTEsKCk9PmBFcnJvciBpbiBiYXRjaE5vcm0yRDogdmFyaWFuY2UgbXVzdCBiZSByYW5rIDIgb3IgcmFuayAxIGJ1dCBnb3QgcmFuayAke2thLnJhbmt9LmApLEFhIT1udWxsJiZhc3NlcnQkMihBYS5yYW5rPT09Mnx8QWEucmFuaz09PTEsKCk9PmBFcnJvciBpbiBiYXRjaE5vcm0yRDogc2NhbGUgbXVzdCBiZSByYW5rIDIgb3IgcmFuayAxIGJ1dCBnb3QgcmFuayAke0FhLnJhbmt9LmApLEZhIT1udWxsJiZhc3NlcnQkMihGYS5yYW5rPT09Mnx8RmEucmFuaz09PTEsKCk9PmBFcnJvciBpbiBiYXRjaE5vcm0yRDogb2Zmc2V0IG11c3QgYmUgcmFuayAyIG9yIHJhbmsgMSBidXQgZ290IHJhbmsgJHtGYS5yYW5rfS5gKSxiYXRjaE5vcm0kMyh3YSxFYSxrYSxGYSxBYSxUYSl9Y29uc3QgYmF0Y2hOb3JtMmQ9b3AkMSh7YmF0Y2hOb3JtMmRffSk7ZnVuY3Rpb24gYmF0Y2hOb3JtM2RfKGhhLGFhLHhhLGJhLFNhLFRhKXtjb25zdCB3YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImJhdGNoTm9ybSIpLEVhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJtZWFuIiwiYmF0Y2hOb3JtIiksa2E9Y29udmVydFRvVGVuc29yJDEoeGEsInZhcmlhbmNlIiwiYmF0Y2hOb3JtIik7bGV0IEFhO1NhIT1udWxsJiYoQWE9Y29udmVydFRvVGVuc29yJDEoU2EsInNjYWxlIiwiYmF0Y2hOb3JtIikpO2xldCBGYTtyZXR1cm4gYmEhPW51bGwmJihGYT1jb252ZXJ0VG9UZW5zb3IkMShiYSwib2Zmc2V0IiwiYmF0Y2hOb3JtIikpLGFzc2VydCQyKHdhLnJhbms9PT0zLCgpPT5gRXJyb3IgaW4gYmF0Y2hOb3JtM0Q6IHggbXVzdCBiZSByYW5rIDMgYnV0IGdvdCByYW5rICR7d2EucmFua30uYCksYXNzZXJ0JDIoRWEucmFuaz09PTN8fEVhLnJhbms9PT0xLCgpPT5gRXJyb3IgaW4gYmF0Y2hOb3JtM0Q6IG1lYW4gbXVzdCBiZSByYW5rIDMgb3IgcmFuayAxIGJ1dCBnb3QgcmFuayAke0VhLnJhbmt9LmApLGFzc2VydCQyKGthLnJhbms9PT0zfHxrYS5yYW5rPT09MSwoKT0+YEVycm9yIGluIGJhdGNoTm9ybTNEOiB2YXJpYW5jZSBtdXN0IGJlIHJhbmsgMyBvciByYW5rIDEgYnV0IGdvdCByYW5rICR7a2EucmFua30uYCksQWEhPW51bGwmJmFzc2VydCQyKEFhLnJhbms9PT0zfHxBYS5yYW5rPT09MSwoKT0+YEVycm9yIGluIGJhdGNoTm9ybTNEOiBzY2FsZSBtdXN0IGJlIHJhbmsgMyBvciByYW5rIDEgYnV0IGdvdCByYW5rICR7QWEucmFua30uYCksRmEhPW51bGwmJmFzc2VydCQyKEZhLnJhbms9PT0zfHxGYS5yYW5rPT09MSwoKT0+YEVycm9yIGluIGJhdGNoTm9ybTNEOiBvZmZzZXQgbXVzdCBiZSByYW5rIDMgb3IgcmFuayAxIGJ1dCBnb3QgcmFuayAke0ZhLnJhbmt9LmApLGJhdGNoTm9ybSQzKHdhLEVhLGthLEZhLEFhLFRhKX1jb25zdCBiYXRjaE5vcm0zZD1vcCQxKHtiYXRjaE5vcm0zZF99KTtmdW5jdGlvbiBiYXRjaE5vcm00ZF8oaGEsYWEseGEsYmEsU2EsVGEpe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiYmF0Y2hOb3JtIiksRWE9Y29udmVydFRvVGVuc29yJDEoYWEsIm1lYW4iLCJiYXRjaE5vcm0iKSxrYT1jb252ZXJ0VG9UZW5zb3IkMSh4YSwidmFyaWFuY2UiLCJiYXRjaE5vcm0iKTtsZXQgQWE7U2EhPW51bGwmJihBYT1jb252ZXJ0VG9UZW5zb3IkMShTYSwic2NhbGUiLCJiYXRjaE5vcm0iKSk7bGV0IEZhO3JldHVybiBiYSE9bnVsbCYmKEZhPWNvbnZlcnRUb1RlbnNvciQxKGJhLCJvZmZzZXQiLCJiYXRjaE5vcm0iKSksYXNzZXJ0JDIod2EucmFuaz09PTQsKCk9PmBFcnJvciBpbiBiYXRjaE5vcm00RDogeCBtdXN0IGJlIHJhbmsgNCBidXQgZ290IHJhbmsgJHt3YS5yYW5rfS5gKSxhc3NlcnQkMihFYS5yYW5rPT09NHx8RWEucmFuaz09PTEsKCk9PmBFcnJvciBpbiBiYXRjaE5vcm00RDogbWVhbiBtdXN0IGJlIHJhbmsgNCBvciByYW5rIDEgYnV0IGdvdCByYW5rICR7RWEucmFua30uYCksYXNzZXJ0JDIoa2EucmFuaz09PTR8fGthLnJhbms9PT0xLCgpPT5gRXJyb3IgaW4gYmF0Y2hOb3JtNEQ6IHZhcmlhbmNlIG11c3QgYmUgcmFuayA0IG9yIHJhbmsgMSBidXQgZ290IHJhbmsgJHtrYS5yYW5rfS5gKSxBYSE9bnVsbCYmYXNzZXJ0JDIoQWEucmFuaz09PTR8fEFhLnJhbms9PT0xLCgpPT5gRXJyb3IgaW4gYmF0Y2hOb3JtNEQ6IHNjYWxlIG11c3QgYmUgcmFuayA0IG9yIHJhbmsgMSBidXQgZ290IHJhbmsgJHtBYS5yYW5rfS5gKSxGYSE9bnVsbCYmYXNzZXJ0JDIoRmEucmFuaz09PTR8fEZhLnJhbms9PT0xLCgpPT5gRXJyb3IgaW4gYmF0Y2hOb3JtNEQ6IG9mZnNldCBtdXN0IGJlIHJhbmsgNCBvciByYW5rIDEgYnV0IGdvdCByYW5rICR7RmEucmFua30uYCksYmF0Y2hOb3JtJDMod2EsRWEsa2EsRmEsQWEsVGEpfWNvbnN0IGJhdGNoTm9ybTRkPW9wJDEoe2JhdGNoTm9ybTRkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJpbmNvdW50XyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJiaW5jb3VudCIpLFNhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJ3ZWlnaHRzIiwiYmluY291bnQiKTthc3NlcnQkMihiYS5kdHlwZT09PSJpbnQzMiIsKCk9PmBFcnJvciBpbiBiaW5jb3VudDogaW5wdXQgZHR5cGUgbXVzdCBiZSBpbnQzMiwgYnV0IGdvdCAke2JhLmR0eXBlfWApLGFzc2VydCQyKHhhPj0wLCgpPT5gc2l6ZSBtdXN0IGJlIG5vbi1uZWdhdGl2ZSwgYnV0IGdvdCAke3hhfS5gKSxhc3NlcnQkMihTYS5zaXplPT09YmEuc2l6ZXx8U2Euc2l6ZT09PTAsKCk9PmBFcnJvciBpbiBiaW5jb3VudDogd2VpZ2h0cyBtdXN0IGhhdmUgdGhlIHNhbWUgc2l6ZSBhcyBpbnB1dCBvcjAtbGVuZ3RoLCBidXQgZ290IGlucHV0IHNoYXBlOiAke2JhLnNoYXBlfSwgd2VpZ2h0cyBzaGFwZTogJHtTYS5zaGFwZX0uYCk7Y29uc3QgVGE9e3g6YmEsd2VpZ2h0czpTYX0sd2E9e3NpemU6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQmluY291bnQkMSxUYSx3YSl9Y29uc3QgYmluY291bnQkMz1vcCQxKHtiaW5jb3VudF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiaXR3aXNlQW5kXyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJiaXR3aXNlQW5kIiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsInkiLCJiaXR3aXNlQW5kIik7aWYoIWFycmF5c0VxdWFsJDEoeGEuc2hhcGUsYmEuc2hhcGUpKXRocm93IG5ldyBFcnJvcihgQml0d2lzZUFuZDogVGVuc29ycyBtdXN0IGhhdmUgdGhlIHNhbWUgc2hhcGUuIHg6ICR7eGEuc2hhcGV9LCB5OiAke2JhLnNoYXBlfWApO2lmKHhhLmR0eXBlIT09ImludDMyInx8YmEuZHR5cGUhPT0iaW50MzIiKXRocm93IG5ldyBFcnJvcihgQml0d2lzZUFuZDogT25seSBzdXBwb3J0cyAnaW50MzInIHZhbHVlcyBpbiB0ZW5zb3IsIGZvdW5kIHR5cGUgb2YgeDogJHt4YS5kdHlwZX0gYW5kIHR5cGUgb2YgeTogJHtiYS5kdHlwZX1gKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEJpdHdpc2VBbmQkMSxTYSl9Y29uc3QgYml0d2lzZUFuZCQzPW9wJDEoe2JpdHdpc2VBbmRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYnJvYWRjYXN0QXJnc18oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJzMCIsImJyb2FkY2FzdEFyZ3MiLCJpbnQzMiIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJzMSIsImJyb2FkY2FzdEFyZ3MiLCJpbnQzMiIpO2lmKHhhLnJhbmshPT0xKXRocm93IG5ldyBFcnJvcihgYnJvYWRjYXN0QXJncygpOiBmaXJzdCBpbnB1dCBtdXN0IGJlIGEgdmVjdG9yIChyYW5rPTEpLiBIYXMgcmFuayAke3hhLnJhbmt9YCk7aWYoYmEucmFuayE9PTEpdGhyb3cgbmV3IEVycm9yKGBicm9hZGNhc3RBcmdzKCk6IHNlY29uZCBpbnB1dCBtdXN0IGJlIGEgdmVjdG9yIChyYW5rPTEpLiBIYXMgcmFuayAke2JhLnJhbmt9YCk7Y29uc3QgU2E9e3MwOnhhLHMxOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEJyb2FkY2FzdEFyZ3MkMSxTYSl9Y29uc3QgYnJvYWRjYXN0QXJncyQzPW9wJDEoe2Jyb2FkY2FzdEFyZ3NffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYnJvYWRjYXN0VG9fJDEoaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYnJvYWRjYXN0VG8iLCJ4Iik7Y29uc3QgYmE9eGEuc2hhcGU7aWYoYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKGFhKSxhYS5sZW5ndGg8eGEucmFuayl0aHJvdyBuZXcgRXJyb3IoYGJyb2FkY2FzdFRvKCk6IHNoYXBlLmxlbmd0aD0ke2FhLmxlbmd0aH0gPCBpbnB1dC5yYW5rPSR7eGEucmFua30uYCk7aWYoYWEubGVuZ3RoPnhhLnJhbmspe2NvbnN0IEFhPXhhLnNoYXBlLnNsaWNlKCk7Zm9yKDtBYS5sZW5ndGg8YWEubGVuZ3RoOylBYS51bnNoaWZ0KDEpO3hhPXJlc2hhcGUkNCh4YSxBYSl9Y29uc3QgU2E9eGEuc2hhcGUsVGE9QXJyYXkuZnJvbShhYSk7Zm9yKGxldCBBYT1hYS5sZW5ndGgtMTtBYT49MDtBYS0tKWlmKFNhW0FhXT09PWFhW0FhXSlUYVtBYV09MTtlbHNlIGlmKHhhLnNoYXBlW0FhXSE9PTEpdGhyb3cgbmV3IEVycm9yKGBicm9hZGNhc3RUbygpOiBbJHtiYX1dIGNhbm5vdCBiZSBicm9hZGNhc3QgdG8gWyR7YWF9XS5gKTtpZihUYS5tYXAoKEFhLEZhKT0+QWE+MT9GYTotMSkuZmlsdGVyKEFhPT5BYT49MCkubGVuZ3RoPT09MClyZXR1cm4gY2xvbmUkMSh4YSk7Y29uc3QgRWE9e3g6eGF9LGthPXtyZXBzOlRhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFRpbGUkMSxFYSxrYSl9Y29uc3QgYnJvYWRjYXN0VG8kMT1vcCQxKHticm9hZGNhc3RUb186YnJvYWRjYXN0VG9fJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjZWlsXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJjZWlsIiwiZmxvYXQzMiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKENlaWwkMSx4YSl9Y29uc3QgY2VpbCQzPW9wJDEoe2NlaWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZmlsbCQ0KGhhLGFhLHhhKXthc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zJDEoaGEpLHhhPXhhfHxpbmZlckR0eXBlJDEoYWEpO2NvbnN0IGJhPXtzaGFwZTpoYSx2YWx1ZTphYSxkdHlwZTp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChGaWxsJDEse30sYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNsaXBCeVZhbHVlXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJjbGlwQnlWYWx1ZSIpO2lmKGFzc2VydCQyKGFhPD14YSwoKT0+YEVycm9yIGluIGNsaXA6IG1pbiAoJHthYX0pIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIG1heCAoJHt4YX0pLmApLGFhPT09eGEpcmV0dXJuIGZpbGwkNChiYS5zaGFwZSxhYSxiYS5kdHlwZSk7Y29uc3QgU2E9e3g6YmF9LFRhPXtjbGlwVmFsdWVNaW46YWEsY2xpcFZhbHVlTWF4OnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKENsaXBCeVZhbHVlJDEsU2EsVGEpfWNvbnN0IGNsaXBCeVZhbHVlJDM9b3AkMSh7Y2xpcEJ5VmFsdWVffSk7ZnVuY3Rpb24gY29uY2F0MWRfKGhhKXtyZXR1cm4gY29uY2F0JDMoaGEsMCl9Y29uc3QgY29uY2F0MWQ9b3AkMSh7Y29uY2F0MWRffSk7ZnVuY3Rpb24gY29uY2F0MmRfKGhhLGFhKXtyZXR1cm4gY29uY2F0JDMoaGEsYWEpfWNvbnN0IGNvbmNhdDJkPW9wJDEoe2NvbmNhdDJkX30pO2Z1bmN0aW9uIGNvbmNhdDNkXyhoYSxhYSl7cmV0dXJuIGNvbmNhdCQzKGhhLGFhKX1jb25zdCBjb25jYXQzZD1vcCQxKHtjb25jYXQzZF99KTtmdW5jdGlvbiBjb25jYXQ0ZF8oaGEsYWEpe3JldHVybiBjb25jYXQkMyhoYSxhYSl9Y29uc3QgY29uY2F0NGQ9b3AkMSh7Y29uY2F0NGRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjJkXyhoYSxhYSx4YSxiYSxTYT0iTkhXQyIsVGE9WzEsMV0sd2Epe2NvbnN0IEVhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiY29udjJkIiwiZmxvYXQzMiIpLGthPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJmaWx0ZXIiLCJjb252MmQiLCJmbG9hdDMyIik7bGV0IEFhPUVhLEZhPSExO0VhLnJhbms9PT0zJiYoRmE9ITAsQWE9cmVzaGFwZSQ0KEVhLFsxLEVhLnNoYXBlWzBdLEVhLnNoYXBlWzFdLEVhLnNoYXBlWzJdXSkpLGFzc2VydCQyKEFhLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gY29udjJkOiBpbnB1dCBtdXN0IGJlIHJhbmsgNCwgYnV0IGdvdCByYW5rICR7QWEucmFua30uYCksYXNzZXJ0JDIoa2EucmFuaz09PTQsKCk9PmBFcnJvciBpbiBjb252MmQ6IGZpbHRlciBtdXN0IGJlIHJhbmsgNCwgYnV0IGdvdCByYW5rICR7a2EucmFua30uYCksY2hlY2tQYWRPbkRpbVJvdW5kaW5nTW9kZSQxKCJjb252MmQiLGJhLHdhKTtjb25zdCBMYT1TYT09PSJOSFdDIj9BYS5zaGFwZVszXTpBYS5zaGFwZVsxXTthc3NlcnQkMihMYT09PWthLnNoYXBlWzJdLCgpPT5gRXJyb3IgaW4gY29udjJkOiBkZXB0aCBvZiBpbnB1dCAoJHtMYX0pIG11c3QgbWF0Y2ggaW5wdXQgZGVwdGggZm9yIGZpbHRlciAke2thLnNoYXBlWzJdfS5gKSxhc3NlcnQkMihlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUkMSh4YSxUYSksKCk9PmBFcnJvciBpbiBjb252MkQ6IEVpdGhlciBzdHJpZGVzIG9yIGRpbGF0aW9ucyBtdXN0IGJlIDEuIEdvdCBzdHJpZGVzICR7eGF9IGFuZCBkaWxhdGlvbnMgJyR7VGF9J2ApLGFzc2VydCQyKHN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlJDEoVGEpLCgpPT4iRXJyb3IgaW4gY29udjJEOiBEaWxhdGVkIHJhdGVzIHNob3VsZCBiZSBsYXJnZXIgdGhhbiAwLiIpLGFzc2VydCQyKHN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlJDEoeGEpLCgpPT4iRXJyb3IgaW4gY29udjJEOiBTdHJpZGVzIHNob3VsZCBiZSBsYXJnZXIgdGhhbiAwLiIpO2NvbnN0IGVsPXt4OkFhLGZpbHRlcjprYX0sdGw9e3N0cmlkZXM6eGEscGFkOmJhLGRhdGFGb3JtYXQ6U2EsZGlsYXRpb25zOlRhLGRpbVJvdW5kaW5nTW9kZTp3YX0sbmw9RU5HSU5FJDEucnVuS2VybmVsKENvbnYyRCQyLGVsLHRsKTtyZXR1cm4gRmE/cmVzaGFwZSQ0KG5sLFtubC5zaGFwZVsxXSxubC5zaGFwZVsyXSxubC5zaGFwZVszXV0pOm5sfWNvbnN0IGNvbnYyZCQzPW9wJDEoe2NvbnYyZF99KTtmdW5jdGlvbiBjb252MWRfKGhhLGFhLHhhLGJhLFNhPSJOV0MiLFRhPTEsd2Epe2NvbnN0IEVhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiY29udjFkIiksa2E9Y29udmVydFRvVGVuc29yJDEoYWEsImZpbHRlciIsImNvbnYxZCIpO2xldCBBYT1FYSxGYT0hMTtFYS5yYW5rPT09MiYmKEZhPSEwLEFhPXJlc2hhcGUkNChFYSxbMSxFYS5zaGFwZVswXSxFYS5zaGFwZVsxXV0pKSxhc3NlcnQkMihBYS5yYW5rPT09MywoKT0+YEVycm9yIGluIGNvbnYxZDogaW5wdXQgbXVzdCBiZSByYW5rIDMsIGJ1dCBnb3QgcmFuayAke0FhLnJhbmt9LmApLGFzc2VydCQyKGthLnJhbms9PT0zLCgpPT5gRXJyb3IgaW4gY29udjFkOiBmaWx0ZXIgbXVzdCBiZSByYW5rIDMsIGJ1dCBnb3QgcmFuayAke2thLnJhbmt9LmApLGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGUkMSgiY29udjFkIixiYSx3YSksYXNzZXJ0JDIoQWEuc2hhcGVbMl09PT1rYS5zaGFwZVsxXSwoKT0+YEVycm9yIGluIGNvbnYxZDogZGVwdGggb2YgaW5wdXQgKCR7QWEuc2hhcGVbMl19KSBtdXN0IG1hdGNoIGlucHV0IGRlcHRoIGZvciBmaWx0ZXIgJHtrYS5zaGFwZVsxXX0uYCksYXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEoeGEsVGEpLCgpPT5gRXJyb3IgaW4gY29udjFEOiBFaXRoZXIgc3RyaWRlIG9yIGRpbGF0aW9uIG11c3QgYmUgMS4gR290IHN0cmlkZSAke3hhfSBhbmQgZGlsYXRpb24gJyR7VGF9J2ApLGFzc2VydCQyKHN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlJDEoVGEpLCgpPT4iRXJyb3IgaW4gY29udjFEOiBEaWxhdGVkIHJhdGVzIHNob3VsZCBiZSBsYXJnZXIgdGhhbiAwLiIpLGFzc2VydCQyKHN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlJDEoeGEpLCgpPT4iRXJyb3IgaW4gY29udjFEOiBTdHJpZGUgc2hvdWxkIGJlIGxhcmdlciB0aGFuIDAuIiksYXNzZXJ0JDIoU2E9PT0iTldDIiwoKT0+YEVycm9yIGluIGNvbnYxZDogZ290IGRhdGFGb3JtYXQgb2YgJHtTYX0gYnV0IG9ubHkgTldDIGlzIGN1cnJlbnRseSBzdXBwb3J0ZWQuYCk7Y29uc3QgTGE9cmVzaGFwZSQ0KGthLFsxLGthLnNoYXBlWzBdLGthLnNoYXBlWzFdLGthLnNoYXBlWzJdXSksZWw9cmVzaGFwZSQ0KEFhLFtBYS5zaGFwZVswXSwxLEFhLnNoYXBlWzFdLEFhLnNoYXBlWzJdXSkscmw9Y29udjJkJDMoZWwsTGEsWzEseGFdLGJhLCJOSFdDIixbMSxUYV0sd2EpO3JldHVybiBGYT9yZXNoYXBlJDQocmwsW3JsLnNoYXBlWzJdLHJsLnNoYXBlWzNdXSk6cmVzaGFwZSQ0KHJsLFtybC5zaGFwZVswXSxybC5zaGFwZVsyXSxybC5zaGFwZVszXV0pfWNvbnN0IGNvbnYxZD1vcCQxKHtjb252MWRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjJEQmFja3Byb3BJbnB1dF8oaGEsYWEseGEsYmEsU2EsVGE9Ik5IV0MiLHdhKXthc3NlcnQkMihoYS5sZW5ndGg9PT1hYS5yYW5rLCgpPT5gTGVuZ3RoIG9mIGluU2hhcGUgKCR7aGEubGVuZ3RofSkgYW5kIHJhbmsgb2YgZHkgKCR7YWEucmFua30pIG11c3QgbWF0Y2hgKTtsZXQgRWE9aGEsa2E9YWEsQWE9ITE7YWEucmFuaz09PTMmJihBYT0hMCxrYT1yZXNoYXBlJDQoYWEsWzEsYWEuc2hhcGVbMF0sYWEuc2hhcGVbMV0sYWEuc2hhcGVbMl1dKSxFYT1bMSxoYVswXSxoYVsxXSxoYVsyXV0pLGFzc2VydCQyKEVhLmxlbmd0aD09PTQsKCk9PmBFcnJvciBpbiBjb252MmREZXJJbnB1dDogaW5TaGFwZSBtdXN0IGJlIGxlbmd0aCA0LCBidXQgZ290IGxlbmd0aCAke0VhLmxlbmd0aH0uYCksYXNzZXJ0JDIoa2EucmFuaz09PTQsKCk9PmBFcnJvciBpbiBjb252MmREZXJJbnB1dDogZHkgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke2thLnJhbmt9YCksYXNzZXJ0JDIoeGEucmFuaz09PTQsKCk9PmBFcnJvciBpbiBjb252MmREZXJJbnB1dDogZmlsdGVyIG11c3QgYmUgcmFuayA0LCBidXQgZ290IHJhbmsgJHt4YS5yYW5rfWApO2NvbnN0IEZhPVRhPT09Ik5IV0MiP0VhWzNdOkVhWzFdLExhPVRhPT09Ik5IV0MiP2thLnNoYXBlWzNdOmthLnNoYXBlWzFdO2Fzc2VydCQyKEZhPT09eGEuc2hhcGVbMl0sKCk9PmBFcnJvciBpbiBjb252MmREZXJJbnB1dDogZGVwdGggb2YgaW5wdXQgKCR7RmF9KSBtdXN0IG1hdGNoIGlucHV0IGRlcHRoIGZvciBmaWx0ZXIgJHt4YS5zaGFwZVsyXX0uYCksYXNzZXJ0JDIoTGE9PT14YS5zaGFwZVszXSwoKT0+YEVycm9yIGluIGNvbnYyZERlcklucHV0OiBkZXB0aCBvZiBvdXRwdXQgKCR7TGF9KSBtdXN0IG1hdGNoIG91dHB1dCBkZXB0aCBmb3IgZmlsdGVyICR7eGEuc2hhcGVbM119LmApLGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGUkMSgiY29udjJkRGVySW5wdXQiLFNhLHdhKTtjb25zdCBlbD17ZHk6a2EsZmlsdGVyOnhhfSx0bD17c3RyaWRlczpiYSxwYWQ6U2EsZGF0YUZvcm1hdDpUYSxkaW1Sb3VuZGluZ01vZGU6d2EsaW5wdXRTaGFwZTpFYX0sbmw9RU5HSU5FJDEucnVuS2VybmVsKENvbnYyREJhY2twcm9wSW5wdXQkMSxlbCx0bCk7cmV0dXJuIEFhP3Jlc2hhcGUkNChubCxbbmwuc2hhcGVbMV0sbmwuc2hhcGVbMl0sbmwuc2hhcGVbM11dKTpubH1jb25zdCBjb252MkRCYWNrcHJvcElucHV0JDM9b3AkMSh7Y29udjJEQmFja3Byb3BJbnB1dF99KTtmdW5jdGlvbiBjb252MmRUcmFuc3Bvc2VfKGhhLGFhLHhhLGJhLFNhLFRhKXtjb25zdCB3YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImNvbnYyZFRyYW5zcG9zZSIpLEVhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJmaWx0ZXIiLCJjb252MmRUcmFuc3Bvc2UiKTtyZXR1cm4gY29udjJEQmFja3Byb3BJbnB1dCQzKHhhLHdhLEVhLGJhLFNhLCJOSFdDIixUYSl9Y29uc3QgY29udjJkVHJhbnNwb3NlPW9wJDEoe2NvbnYyZFRyYW5zcG9zZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252M2RfKGhhLGFhLHhhLGJhLFNhPSJOREhXQyIsVGE9WzEsMSwxXSl7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJjb252M2QiKSxFYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiZmlsdGVyIiwiY29udjNkIik7bGV0IGthPXdhLEFhPSExO3dhLnJhbms9PT00JiYoQWE9ITAsa2E9cmVzaGFwZSQ0KHdhLFsxLHdhLnNoYXBlWzBdLHdhLnNoYXBlWzFdLHdhLnNoYXBlWzJdLHdhLnNoYXBlWzNdXSkpLGFzc2VydCQyKGthLnJhbms9PT01LCgpPT5gRXJyb3IgaW4gY29udjNkOiBpbnB1dCBtdXN0IGJlIHJhbmsgNSwgYnV0IGdvdCByYW5rICR7a2EucmFua30uYCksYXNzZXJ0JDIoRWEucmFuaz09PTUsKCk9PmBFcnJvciBpbiBjb252M2Q6IGZpbHRlciBtdXN0IGJlIHJhbmsgNSwgYnV0IGdvdCByYW5rICR7RWEucmFua30uYCksYXNzZXJ0JDIoa2Euc2hhcGVbNF09PT1FYS5zaGFwZVszXSwoKT0+YEVycm9yIGluIGNvbnYzZDogZGVwdGggb2YgaW5wdXQgKCR7a2Euc2hhcGVbNF19KSBtdXN0IG1hdGNoIGlucHV0IGRlcHRoIGZvciBmaWx0ZXIgJHtFYS5zaGFwZVszXX0uYCksYXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEoeGEsVGEpLCgpPT5gRXJyb3IgaW4gY29udjNEOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke3hhfSBhbmQgZGlsYXRpb25zICcke1RhfSdgKSxhc3NlcnQkMihTYT09PSJOREhXQyIsKCk9PmBFcnJvciBpbiBjb252M2Q6IGdvdCBkYXRhRm9ybWF0IG9mICR7U2F9IGJ1dCBvbmx5IE5ESFdDIGlzIGN1cnJlbnRseSBzdXBwb3J0ZWQuYCksYXNzZXJ0JDIoc3RyaWRlc09yRGlsYXRpb25zQXJlUG9zaXRpdmUkMShUYSksKCk9PiJFcnJvciBpbiBjb252M0Q6IERpbGF0ZWQgcmF0ZXMgc2hvdWxkIGJlIGxhcmdlciB0aGFuIDAuIiksYXNzZXJ0JDIoc3RyaWRlc09yRGlsYXRpb25zQXJlUG9zaXRpdmUkMSh4YSksKCk9PiJFcnJvciBpbiBjb252M0Q6IFN0cmlkZXMgc2hvdWxkIGJlIGxhcmdlciB0aGFuIDAuIik7Y29uc3QgRmE9e3g6a2EsZmlsdGVyOkVhfSxMYT17c3RyaWRlczp4YSxwYWQ6YmEsZGF0YUZvcm1hdDpTYSxkaWxhdGlvbnM6VGF9LGVsPUVOR0lORSQxLnJ1bktlcm5lbChDb252M0QkMixGYSxMYSk7cmV0dXJuIEFhP3Jlc2hhcGUkNChlbCxbZWwuc2hhcGVbMV0sZWwuc2hhcGVbMl0sZWwuc2hhcGVbM10sZWwuc2hhcGVbNF1dKTplbH1jb25zdCBjb252M2Q9b3AkMSh7Y29udjNkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYzREJhY2twcm9wSW5wdXRfKGhhLGFhLHhhLGJhLFNhKXthc3NlcnQkMihoYS5sZW5ndGg9PT1hYS5yYW5rLCgpPT5gTGVuZ3RoIG9mIGluU2hhcGUgKCR7aGEubGVuZ3RofSkgYW5kIHJhbmsgb2YgZHkgKCR7YWEucmFua30pIG11c3QgbWF0Y2hgKTtsZXQgVGE9aGEsd2E9YWEsRWE9ITE7YWEucmFuaz09PTQmJihFYT0hMCx3YT1yZXNoYXBlJDQoYWEsWzEsYWEuc2hhcGVbMF0sYWEuc2hhcGVbMV0sYWEuc2hhcGVbMl0sYWEuc2hhcGVbM11dKSxUYT1bMSxoYVswXSxoYVsxXSxoYVsyXSxoYVszXV0pO2NvbnN0IGthPVRhWzRdLEFhPXdhLnNoYXBlWzRdO2Fzc2VydCQyKFRhLmxlbmd0aD09PTUsKCk9PmBFcnJvciBpbiBjb252M2REZXJJbnB1dDogaW5TaGFwZSBtdXN0IGJlIGxlbmd0aCA1LCBidXQgZ290IGxlbmd0aCAke1RhLmxlbmd0aH0uYCksYXNzZXJ0JDIod2EucmFuaz09PTUsKCk9PmBFcnJvciBpbiBjb252M2REZXJJbnB1dDogZHkgbXVzdCBiZSByYW5rIDUsIGJ1dCBnb3QgcmFuayAke3dhLnJhbmt9YCksYXNzZXJ0JDIoeGEucmFuaz09PTUsKCk9PmBFcnJvciBpbiBjb252M2REZXJJbnB1dDogZmlsdGVyIG11c3QgYmUgcmFuayA1LCBidXQgZ290IHJhbmsgJHt4YS5yYW5rfWApLGFzc2VydCQyKGthPT09eGEuc2hhcGVbM10sKCk9PmBFcnJvciBpbiBjb252M2REZXJJbnB1dDogZGVwdGggb2YgaW5wdXQgKCR7a2F9KSBtdXN0IG1hdGNoIGlucHV0IGRlcHRoIGZvciBmaWx0ZXIgJHt4YS5zaGFwZVszXX0uYCksYXNzZXJ0JDIoQWE9PT14YS5zaGFwZVs0XSwoKT0+YEVycm9yIGluIGNvbnYzZERlcklucHV0OiBkZXB0aCBvZiBvdXRwdXQgKCR7QWF9KSBtdXN0IG1hdGNoIG91dHB1dCBkZXB0aCBmb3IgZmlsdGVyICR7eGEuc2hhcGVbNF19LmApO2NvbnN0IEZhPXtkeTp3YSxmaWx0ZXI6eGF9LExhPXtwYWQ6U2Esc3RyaWRlczpiYSxpbnB1dFNoYXBlOlRhfSxlbD1FTkdJTkUkMS5ydW5LZXJuZWwoQ29udjNEQmFja3Byb3BJbnB1dFYyJDEsRmEsTGEpO3JldHVybiBFYT9yZXNoYXBlJDQoZWwsW2VsLnNoYXBlWzFdLGVsLnNoYXBlWzJdLGVsLnNoYXBlWzNdLGVsLnNoYXBlWzRdXSk6ZWx9Y29uc3QgY29udjNEQmFja3Byb3BJbnB1dCQyPW9wJDEoe2NvbnYzREJhY2twcm9wSW5wdXRffSk7ZnVuY3Rpb24gY29udjNkVHJhbnNwb3NlXyhoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJjb252M2RUcmFuc3Bvc2UiKSx3YT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiZmlsdGVyIiwiY29udjNkVHJhbnNwb3NlIik7cmV0dXJuIGNvbnYzREJhY2twcm9wSW5wdXQkMih4YSxUYSx3YSxiYSxTYSl9Y29uc3QgY29udjNkVHJhbnNwb3NlPW9wJDEoe2NvbnYzZFRyYW5zcG9zZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb3NfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImNvcyIsImZsb2F0MzIiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChDb3MkMSx4YSl9Y29uc3QgY29zJDM9b3AkMSh7Y29zX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvc2hfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImNvc2giLCJmbG9hdDMyIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQ29zaCQxLHhhKX1jb25zdCBjb3NoJDM9b3AkMSh7Y29zaF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICdMaWNlbnNlJyk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICdBUyBJUycgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjdW1wcm9kXyhoYSxhYT0wLHhhPSExLGJhPSExKXtjb25zdCBUYT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImN1bXByb2QiKX0sd2E9e2F4aXM6YWEsZXhjbHVzaXZlOnhhLHJldmVyc2U6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQ3VtcHJvZCQxLFRhLHdhKX1jb25zdCBjdW1wcm9kJDM9b3AkMSh7Y3VtcHJvZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjdW1zdW1fKGhhLGFhPTAseGE9ITEsYmE9ITEpe2NvbnN0IFRhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiY3Vtc3VtIil9LHdhPXtheGlzOmFhLGV4Y2x1c2l2ZTp4YSxyZXZlcnNlOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEN1bXN1bSQxLFRhLHdhKX1jb25zdCBjdW1zdW0kMz1vcCQxKHtjdW1zdW1ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGVuc2VCaW5jb3VudF8oaGEsYWEseGEsYmE9ITEpe2NvbnN0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiZGVuc2VCaW5jb3VudCIpLFRhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJ3ZWlnaHRzIiwiZGVuc2VCaW5jb3VudCIpO2Fzc2VydCQyKFNhLmR0eXBlPT09ImludDMyIiwoKT0+YEVycm9yIGluIGRlbnNlQmluY291bnQ6IGlucHV0IGR0eXBlIG11c3QgYmUgaW50MzIsIGJ1dCBnb3QgJHtTYS5kdHlwZX1gKSxhc3NlcnQkMihTYS5yYW5rPD0yLCgpPT5gRXJyb3IgaW4gZGVuc2VCaW5jb3VudDogaW5wdXQgbXVzdCBiZSBhdCBtb3N0IHJhbmsgMiwgYnV0IGdvdCByYW5rICR7U2EucmFua30uYCksYXNzZXJ0JDIoeGE+PTAsKCk9PmBzaXplIG11c3QgYmUgbm9uLW5lZ2F0aXZlLCBidXQgZ290ICR7eGF9LmApLGFzc2VydCQyKFRhLnNpemU9PT1TYS5zaXplfHxUYS5zaXplPT09MCwoKT0+YEVycm9yIGluIGRlbnNlQmluY291bnQ6IHdlaWdodHMgbXVzdCBoYXZlIHRoZSBzYW1lIHNoYXBlIGFzIHggb3IgMC1sZW5ndGgsIGJ1dCBnb3QgeCBzaGFwZTogJHtTYS5zaGFwZX0sIHdlaWdodHMgc2hhcGU6ICR7VGEuc2hhcGV9LmApO2NvbnN0IHdhPXt4OlNhLHdlaWdodHM6VGF9LEVhPXtzaXplOnhhLGJpbmFyeU91dHB1dDpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChEZW5zZUJpbmNvdW50JDEsd2EsRWEpfWNvbnN0IGRlbnNlQmluY291bnQkMz1vcCQxKHtkZW5zZUJpbmNvdW50X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRoVG9TcGFjZV8oaGEsYWEseGE9Ik5IV0MiKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImRlcHRoVG9TcGFjZSIsImZsb2F0MzIiKSxTYT14YT09PSJOSFdDIj9iYS5zaGFwZVsxXTpiYS5zaGFwZVsyXSxUYT14YT09PSJOSFdDIj9iYS5zaGFwZVsyXTpiYS5zaGFwZVszXSx3YT14YT09PSJOSFdDIj9iYS5zaGFwZVszXTpiYS5zaGFwZVsxXTthc3NlcnQkMihhYT4xLCgpPT5gYmxvY2tTaXplIHNob3VsZCBiZSA+IDEgZm9yIGRlcHRoVG9TcGFjZSwgYnV0IHdhczogJHthYX1gKSxhc3NlcnQkMihTYSphYT49MCwoKT0+YE5lZ2F0aXZlIGRpbWVuc2lvbiBzaXplIGNhdXNlZCBieSBvdmVyZmxvdyB3aGVuIG11bHRpcGx5aW5nCiAgICAke1NhfSBhbmQgJHthYX0gIGZvciBkZXB0aFRvU3BhY2Ugd2l0aCBpbnB1dCBzaGFwZQogICAgJHtiYS5zaGFwZX1gKSxhc3NlcnQkMihUYSphYT49MCwoKT0+YE5lZ2F0aXZlIGRpbWVuc2lvbiBzaXplIGNhdXNlZCBieSBvdmVyZmxvdyB3aGVuIG11bHRpcGx5aW5nCiAgICAke1RhfSBhbmQgJHthYX0gZm9yIGRlcHRoVG9TcGFjZSB3aXRoIGlucHV0IHNoYXBlCiAgICAgICAgJHtiYS5zaGFwZX1gKSxhc3NlcnQkMih3YSUoYWEqYWEpPT09MCwoKT0+YERpbWVuc2lvbiBzaXplIG11c3QgYmUgZXZlbmx5IGRpdmlzaWJsZSBieSAke2FhKmFhfSBidXQgaXMgJHt3YX0gZm9yIGRlcHRoVG9TcGFjZSB3aXRoIGlucHV0IHNoYXBlICR7YmEuc2hhcGV9YCk7Y29uc3QgRWE9e3g6YmF9LGthPXtibG9ja1NpemU6YWEsZGF0YUZvcm1hdDp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChEZXB0aFRvU3BhY2UkMSxFYSxrYSl9Y29uc3QgZGVwdGhUb1NwYWNlJDM9b3AkMSh7ZGVwdGhUb1NwYWNlX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZF8oaGEsYWEseGEsYmEsU2E9Ik5IV0MiLFRhPVsxLDFdLHdhKXtjb25zdCBFYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImRlcHRod2lzZUNvbnYyZCIsImZsb2F0MzIiKSxrYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiZmlsdGVyIiwiZGVwdGh3aXNlQ29udjJkIiwiZmxvYXQzMiIpO2xldCBBYT1FYSxGYT0hMTtFYS5yYW5rPT09MyYmKEZhPSEwLEFhPXJlc2hhcGUkNChFYSxbMSxFYS5zaGFwZVswXSxFYS5zaGFwZVsxXSxFYS5zaGFwZVsyXV0pKSxhc3NlcnQkMihBYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIGRlcHRod2lzZUNvbnYyZDogaW5wdXQgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke0FhLnJhbmt9LmApLGFzc2VydCQyKGthLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gZGVwdGh3aXNlQ29udjJkOiBmaWx0ZXIgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke2thLnJhbmt9LmApO2NvbnN0IExhPVNhPT09Ik5IV0MiP0FhLnNoYXBlWzNdOkFhLnNoYXBlWzFdO2Fzc2VydCQyKExhPT09a2Euc2hhcGVbMl0sKCk9PmBFcnJvciBpbiBkZXB0aHdpc2VDb252MmQ6IG51bWJlciBvZiBpbnB1dCBjaGFubmVscyAoJHtMYX0pIG11c3QgbWF0Y2ggdGhlIGluQ2hhbm5lbHMgZGltZW5zaW9uIGluIGZpbHRlciAke2thLnNoYXBlWzJdfS5gKSxjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlJDEoImRlcHRod2lzZUNvbnYyZCIsYmEsd2EpO2NvbnN0IGVsPXt4OkFhLGZpbHRlcjprYX0sdGw9e3N0cmlkZXM6eGEscGFkOmJhLGRhdGFGb3JtYXQ6U2EsZGlsYXRpb25zOlRhLGRpbVJvdW5kaW5nTW9kZTp3YX0sbmw9RU5HSU5FJDEucnVuS2VybmVsKERlcHRod2lzZUNvbnYyZE5hdGl2ZSQxLGVsLHRsKTtyZXR1cm4gRmE/cmVzaGFwZSQ0KG5sLFtubC5zaGFwZVsxXSxubC5zaGFwZVsyXSxubC5zaGFwZVszXV0pOm5sfWNvbnN0IGRlcHRod2lzZUNvbnYyZCQyPW9wJDEoe2RlcHRod2lzZUNvbnYyZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkaWFnXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJkaWFnIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoRGlhZyQxLHhhKX1jb25zdCBkaWFnJDM9b3AkMSh7ZGlhZ199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkaWxhdGlvbjJkXyhoYSxhYSx4YSxiYSxTYT1bMSwxXSxUYT0iTkhXQyIpe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiZGlsYXRpb24yZCIpLEVhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJmaWx0ZXIiLCJkaWxhdGlvbjJkIik7YXNzZXJ0JDIod2EucmFuaz09PTN8fHdhLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gZGlsYXRpb24yZDogaW5wdXQgbXVzdCBiZSByYW5rIDMgb3IgNCwgYnV0IGdvdCByYW5rICR7d2EucmFua30uYCksYXNzZXJ0JDIoRWEucmFuaz09PTMsKCk9PmBFcnJvciBpbiBkaWxhdGlvbjJkOiBmaWx0ZXIgbXVzdCBiZSByYW5rIDMsIGJ1dCBnb3QgcmFuayAke0VhLnJhbmt9LmApLGFzc2VydCQyKFRhPT09Ik5IV0MiLCgpPT5gRXJyb3IgaW4gZGlsYXRpb24yZDogT25seSBOSFdDIGlzIGN1cnJlbnRseSBzdXBwb3J0ZWQsIGJ1dCBnb3QgZGF0YUZvcm1hdCBvZiAke1RhfWApO2xldCBrYT13YSxBYT0hMTt3YS5yYW5rPT09MyYmKGthPXJlc2hhcGUkNCh3YSxbMSx3YS5zaGFwZVswXSx3YS5zaGFwZVsxXSx3YS5zaGFwZVsyXV0pLEFhPSEwKSxhc3NlcnQkMihrYS5zaGFwZVszXT09PUVhLnNoYXBlWzJdLCgpPT5gRXJyb3IgaW4gZGlsYXRpb24yZDogIGlucHV0IGFuZCBmaWx0ZXIgbXVzdCBoYXZlIHRoZSBzYW1lIGRlcHRoOiAke2thLnNoYXBlWzNdfSB2cyAke0VhLnNoYXBlWzJdfWApO2NvbnN0IEZhPXt4OmthLGZpbHRlcjpFYX0sTGE9e3N0cmlkZXM6eGEscGFkOmJhLGRpbGF0aW9uczpTYX0sZWw9RU5HSU5FJDEucnVuS2VybmVsKERpbGF0aW9uMkQkMSxGYSxMYSk7cmV0dXJuIEFhP3Jlc2hhcGUkNChlbCxbZWwuc2hhcGVbMV0sZWwuc2hhcGVbMl0sZWwuc2hhcGVbM11dKTplbH1jb25zdCBkaWxhdGlvbjJkPW9wJDEoe2RpbGF0aW9uMmRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0QnJvYWRjYXN0RGltcyQzKGhhLGFhKXtjb25zdCB4YT1oYS5sZW5ndGgsYmE9W107Zm9yKGxldCBTYT0wO1NhPHhhO1NhKyspe2NvbnN0IFRhPXhhLTEtU2Esd2E9aGFbVGFdfHwxOyhhYVthYS5sZW5ndGgtMS1TYV18fDEpPjEmJndhPT09MSYmYmEudW5zaGlmdChUYSl9cmV0dXJuIGJhfWZ1bmN0aW9uIGdldFJlZHVjdGlvbkF4ZXMkMShoYSxhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aDtiYSsrKXtjb25zdCBTYT1oYVtoYS5sZW5ndGgtYmEtMV0sVGE9YWEubGVuZ3RoLWJhLTEsd2E9YWFbVGFdOyhTYT09bnVsbHx8U2E9PT0xJiZ3YT4xKSYmeGEudW5zaGlmdChUYSl9cmV0dXJuIHhhfWZ1bmN0aW9uIGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoaGEsYWEpe2NvbnN0IHhhPU1hdGgubWF4KGhhLmxlbmd0aCxhYS5sZW5ndGgpLGJhPW5ldyBBcnJheSh4YSk7Zm9yKGxldCBTYT0wO1NhPHhhO1NhKyspe2xldCBUYT1oYVtoYS5sZW5ndGgtU2EtMV07VGE9PW51bGwmJihUYT0xKTtsZXQgd2E9YWFbYWEubGVuZ3RoLVNhLTFdO2lmKHdhPT1udWxsJiYod2E9MSksVGE9PT0xKWJhW3hhLVNhLTFdPXdhO2Vsc2UgaWYod2E9PT0xKWJhW3hhLVNhLTFdPVRhO2Vsc2UgaWYoVGEhPT13YSl7Y29uc3QgRWE9YE9wZXJhbmRzIGNvdWxkIG5vdCBiZSBicm9hZGNhc3QgdG9nZXRoZXIgd2l0aCBzaGFwZXMgJHtoYX0gYW5kICR7YWF9LmA7dGhyb3cgRXJyb3IoRWEpfWVsc2UgYmFbeGEtU2EtMV09VGF9cmV0dXJuIGJhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGVxdWFsXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwiZXF1YWwiLCJzdHJpbmdfb3JfbnVtZXJpYyIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwiZXF1YWwiLCJzdHJpbmdfb3JfbnVtZXJpYyIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSksYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMSh4YS5zaGFwZSxiYS5zaGFwZSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChFcXVhbCQxLFNhKX1jb25zdCBlcXVhbCQzPW9wJDEoe2VxdWFsX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHdoZXJlXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoYWEsImEiLCJ3aGVyZSIpLFNhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJiIiwid2hlcmUiKSxUYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiY29uZGl0aW9uIiwid2hlcmUiLCJib29sIiksd2E9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKFRhLnNoYXBlLGJhLnNoYXBlKSxTYS5zaGFwZSksRWE9YnJvYWRjYXN0VG8kMShUYSx3YSksa2E9YnJvYWRjYXN0VG8kMShiYSx3YSksQWE9YnJvYWRjYXN0VG8kMShTYSx3YSksRmE9e2NvbmRpdGlvbjpFYSx0OmthLGU6QWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU2VsZWN0JDEsRmEpfWNvbnN0IHdoZXJlPW9wJDEoe3doZXJlX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHplcm9zTGlrZV8kMShoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJ6ZXJvc0xpa2UiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChaZXJvc0xpa2UkMSx4YSl9Y29uc3QgemVyb3NMaWtlJDQ9b3AkMSh7emVyb3NMaWtlXzp6ZXJvc0xpa2VfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkaXZOb05hbl8oaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsImRpdiIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwiZGl2Iik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKTtjb25zdCBTYT1kaXYkMih4YSxiYSksVGE9emVyb3NMaWtlJDQoU2EpLHdhPWVxdWFsJDMoYmEsVGEpO3JldHVybiB3aGVyZSh3YSxUYSxTYSl9Y29uc3QgZGl2Tm9OYW49b3AkMSh7ZGl2Tm9OYW5ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZG90XyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsInQxIiwiZG90IiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsInQyIiwiZG90Iik7YXNzZXJ0JDIoKHhhLnJhbms9PT0xfHx4YS5yYW5rPT09MikmJihiYS5yYW5rPT09MXx8YmEucmFuaz09PTIpLCgpPT5gRXJyb3IgaW4gZG90OiBpbnB1dHMgbXVzdCBhbGwgYmUgcmFuayAxIG9yIDIsIGJ1dCBnb3QgcmFua3MgJHt4YS5yYW5rfSBhbmQgJHtiYS5yYW5rfS5gKTtjb25zdCBTYT14YS5yYW5rPT09MT94YS5zaXplOnhhLnNoYXBlWzFdLFRhPWJhLnJhbms9PT0xP2JhLnNpemU6YmEuc2hhcGVbMF07aWYoYXNzZXJ0JDIoU2E9PT1UYSwoKT0+YEVycm9yIGluIGRvdDogaW5uZXIgZGltZW5zaW9ucyBvZiBpbnB1dHMgbXVzdCBtYXRjaCwgYnV0IGdvdCAke1NhfSBhbmQgJHtUYX0uYCkseGEucmFuaz09PTEmJmJhLnJhbms9PT0xKXtjb25zdCB3YT1yZXNoYXBlJDQoeGEsWzEsLTFdKSxFYT1yZXNoYXBlJDQoYmEsWy0xLDFdKSxrYT1tYXRNdWwkMSh3YSxFYSk7cmV0dXJuIHJlc2hhcGUkNChrYSxbXSl9ZWxzZSBpZih4YS5yYW5rPT09MSYmYmEucmFuaz09PTIpe2NvbnN0IHdhPXJlc2hhcGUkNCh4YSxbMSwtMV0pLEVhPXJlc2hhcGUkNChiYSxbYmEuc2hhcGVbMF0sYmEuc2hhcGVbMV1dKSxrYT1tYXRNdWwkMSh3YSxFYSk7cmV0dXJuIHJlc2hhcGUkNChrYSxba2Euc2l6ZV0pfWVsc2UgaWYoeGEucmFuaz09PTImJmJhLnJhbms9PT0xKXtjb25zdCB3YT1yZXNoYXBlJDQoYmEsWy0xLDFdKSxFYT1tYXRNdWwkMSh4YSx3YSk7cmV0dXJuIHJlc2hhcGUkNChFYSxbRWEuc2l6ZV0pfWVsc2V7Y29uc3Qgd2E9cmVzaGFwZSQ0KGJhLFtiYS5zaGFwZVswXSxiYS5zaGFwZVsxXV0pO3JldHVybiBtYXRNdWwkMSh4YSx3YSl9fWNvbnN0IGRvdCQxPW9wJDEoe2RvdF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBlaW5zdW1fKGhhLC4uLmFhKXtjb25zdCB4YT1hYS5tYXAoKFNhLFRhKT0+Y29udmVydFRvVGVuc29yJDEoU2EsYHRlbnNvcnMke1RhfWAsImVpbnN1bSIpKSxiYT17ZXF1YXRpb246aGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoRWluc3VtJDEseGEsYmEpfWNvbnN0IGVpbnN1bSQzPW9wJDEoe2VpbnN1bV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBlbHVfJDEoaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiZWx1IiwiZmxvYXQzMiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEVsdSQyLHhhKX1jb25zdCBlbHUkNT1vcCQxKHtlbHVfOmVsdV8kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGVuc3VyZVNoYXBlXyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJlbnN1cmVTaGFwZSIsInN0cmluZ19vcl9udW1lcmljIik7aWYoIWFycmF5c0VxdWFsV2l0aE51bGwoeGEuc2hhcGUsYWEpKXRocm93IG5ldyBFcnJvcihgRW5zdXJlU2hhcGU6IFNoYXBlIG9mIHRlbnNvciAke3hhLnNoYXBlfSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIGV4cGVjdGVkIHNoYXBlICR7YWF9YCk7cmV0dXJuIGhhfWNvbnN0IGVuc3VyZVNoYXBlPW9wJDEoe2Vuc3VyZVNoYXBlX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGVyZl8oaGEpe2xldCBhYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImVyZiIpO2Fzc2VydCQyKGFhLmR0eXBlPT09ImludDMyInx8YWEuZHR5cGU9PT0iZmxvYXQzMiIsKCk9PiJJbnB1dCBkdHlwZSBtdXN0IGJlIGBpbnQzMmAgb3IgYGZsb2F0MzJgLiIpLGFhLmR0eXBlPT09ImludDMyIiYmKGFhPWNhc3QkNShhYSwiZmxvYXQzMiIpKTtjb25zdCB4YT17eDphYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChFcmYkMSx4YSl9Y29uc3QgZXJmJDM9b3AkMSh7ZXJmX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF4ZXNBcmVJbm5lck1vc3REaW1zJDEoaGEsYWEpe2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7Kyt4YSlpZihoYVtoYS5sZW5ndGgteGEtMV0hPT1hYS0xLXhhKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIGNvbWJpbmVMb2NhdGlvbnMkMShoYSxhYSx4YSl7Y29uc3QgYmE9aGEubGVuZ3RoK2FhLmxlbmd0aCxTYT1bXTtsZXQgVGE9MCx3YT0wO2ZvcihsZXQgRWE9MDtFYTxiYTtFYSsrKXhhLmluZGV4T2YoRWEpPT09LTE/U2EucHVzaChoYVtUYSsrXSk6U2EucHVzaChhYVt3YSsrXSk7cmV0dXJuIFNhfWZ1bmN0aW9uIGNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShoYSxhYSl7Y29uc3QgeGE9W10sYmE9aGEubGVuZ3RoO2ZvcihsZXQgVGE9MDtUYTxiYTtUYSsrKWFhLmluZGV4T2YoVGEpPT09LTEmJnhhLnB1c2goaGFbVGFdKTtjb25zdCBTYT1hYS5tYXAoVGE9PmhhW1RhXSk7cmV0dXJuW3hhLFNhXX1mdW5jdGlvbiBleHBhbmRTaGFwZVRvS2VlcERpbSQxKGhhLGFhKXtjb25zdCB4YT1hYS5tYXAoYmE9PjEpO3JldHVybiBjb21iaW5lTG9jYXRpb25zJDEoaGEseGEsYWEpfWZ1bmN0aW9uIGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zJDEoaGEsYWEseGEpe2Fzc2VydCQyKGF4ZXNBcmVJbm5lck1vc3REaW1zJDEoYWEseGEpLCgpPT5gJHtoYX0gc3VwcG9ydHMgb25seSBpbm5lci1tb3N0IGF4ZXMgZm9yIG5vdy4gR290IGF4ZXMgJHthYX0gYW5kIHJhbmstJHt4YX0gaW5wdXQuYCl9ZnVuY3Rpb24gZ2V0QXhlc1Blcm11dGF0aW9uJDEoaGEsYWEpe2lmKGF4ZXNBcmVJbm5lck1vc3REaW1zJDEoaGEsYWEpKXJldHVybiBudWxsO2NvbnN0IHhhPVtdO2ZvcihsZXQgYmE9MDtiYTxhYTsrK2JhKWhhLmluZGV4T2YoYmEpPT09LTEmJnhhLnB1c2goYmEpO3JldHVybiBoYS5mb3JFYWNoKGJhPT54YS5wdXNoKGJhKSkseGF9ZnVuY3Rpb24gZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbiQxKGhhKXtyZXR1cm4gaGEubWFwKChhYSx4YSk9Plt4YSxhYV0pLnNvcnQoKGFhLHhhKT0+YWFbMV0teGFbMV0pLm1hcChhYT0+YWFbMF0pfWZ1bmN0aW9uIGdldElubmVyTW9zdEF4ZXMkMShoYSxhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBiYT1hYS1oYTtiYTxhYTsrK2JhKXhhLnB1c2goYmEpO3JldHVybiB4YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhfKGhhLGFhPW51bGwseGE9ITEpe2NvbnN0IFNhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibWF4Iil9LFRhPXtyZWR1Y3Rpb25JbmRpY2VzOmFhLGtlZXBEaW1zOnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKE1heCQxLFNhLFRhKX1jb25zdCBtYXgkND1vcCQxKHttYXhffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWluXyhoYSxhYT1udWxsLHhhPSExKXtjb25zdCBTYT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsIm1pbiIpfSxUYT17YXhpczphYSxrZWVwRGltczp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChNaW4kMSxTYSxUYSl9Y29uc3QgbWluJDQ9b3AkMSh7bWluX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHBvd18kMShoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJiYXNlIiwicG93IiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsImV4cCIsInBvdyIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChQb3ckMSxTYSl9Y29uc3QgcG93JDQ9b3AkMSh7cG93Xzpwb3dfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzY2FsYXIkMShoYSxhYSl7aWYoKGlzVHlwZWRBcnJheSQxKGhhKSYmYWEhPT0ic3RyaW5nInx8QXJyYXkuaXNBcnJheShoYSkpJiZhYSE9PSJjb21wbGV4NjQiKXRocm93IG5ldyBFcnJvcigiRXJyb3IgY3JlYXRpbmcgYSBuZXcgU2NhbGFyOiB2YWx1ZSBtdXN0IGJlIGEgcHJpbWl0aXZlIChudW1iZXJ8Ym9vbGVhbnxzdHJpbmcpIik7aWYoYWE9PT0ic3RyaW5nIiYmaXNUeXBlZEFycmF5JDEoaGEpJiYhKGhhIGluc3RhbmNlb2YgVWludDhBcnJheSkpdGhyb3cgbmV3IEVycm9yKCJXaGVuIG1ha2luZyBhIHNjYWxhciBmcm9tIGVuY29kZWQgc3RyaW5nLCB0aGUgdmFsdWUgbXVzdCBiZSBgVWludDhBcnJheWAuIik7cmV0dXJuIG1ha2VUZW5zb3IkMShoYSxbXSxbXSxhYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3FydF8kMShoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJzcXJ0IiwiZmxvYXQzMiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFNxcnQkMSx4YSl9Y29uc3Qgc3FydCQ0PW9wJDEoe3NxcnRfOnNxcnRfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcXVhcmVfJDEoaGEpe2NvbnN0IGFhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic3F1YXJlIikseGE9e307cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbCgiU3F1YXJlIix7eDphYX0seGEpfWNvbnN0IHNxdWFyZSQ0PW9wJDEoe3NxdWFyZV86c3F1YXJlXyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3VtXyQxKGhhLGFhPW51bGwseGE9ITEpe2xldCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInN1bSIpO2JhLmR0eXBlPT09ImJvb2wiJiYoYmE9Y2FzdCQ1KGJhLCJpbnQzMiIpKTtjb25zdCBTYT17eDpiYX0sVGE9e2F4aXM6YWEsa2VlcERpbXM6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU3VtJDEsU2EsVGEpfWNvbnN0IHN1bSQ1PW9wJDEoe3N1bV86c3VtXyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbm9ybV8oaGEsYWE9ImV1Y2xpZGVhbiIseGE9bnVsbCxiYT0hMSl7aGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJub3JtIik7Y29uc3QgU2E9bm9ybUltcGwoaGEsYWEseGEpO2xldCBUYT1TYS5zaGFwZTtpZihiYSl7Y29uc3Qgd2E9cGFyc2VBeGlzUGFyYW0kMSh4YSxoYS5zaGFwZSk7VGE9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShTYS5zaGFwZSx3YSl9cmV0dXJuIHJlc2hhcGUkNChTYSxUYSl9ZnVuY3Rpb24gbm9ybUltcGwoaGEsYWEseGE9bnVsbCl7aWYoaGEucmFuaz09PTApcmV0dXJuIGFicyQ0KGhhKTtpZihoYS5yYW5rIT09MSYmeGE9PT1udWxsKXJldHVybiBub3JtSW1wbChyZXNoYXBlJDQoaGEsWy0xXSksYWEseGEpO2lmKGhhLnJhbms9PT0xfHx0eXBlb2YgeGE9PSJudW1iZXIifHxBcnJheS5pc0FycmF5KHhhKSYmeGEubGVuZ3RoPT09MSl7aWYoYWE9PT0xKXJldHVybiBzdW0kNShhYnMkNChoYSkseGEpO2lmKGFhPT09MS8wKXJldHVybiBtYXgkNChhYnMkNChoYSkseGEpO2lmKGFhPT09LTEvMClyZXR1cm4gbWluJDQoYWJzJDQoaGEpLHhhKTtpZihhYT09PSJldWNsaWRlYW4ifHxhYT09PTIpcmV0dXJuIHNxcnQkNChzdW0kNShwb3ckNChhYnMkNChoYSksc2NhbGFyJDEoMiwiaW50MzIiKSkseGEpKTt0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGluIG5vcm06IGludmFsaWQgb3JkIHZhbHVlOiAke2FhfWApfWlmKEFycmF5LmlzQXJyYXkoeGEpJiZ4YS5sZW5ndGg9PT0yKXtpZihhYT09PTEpcmV0dXJuIG1heCQ0KHN1bSQ1KGFicyQ0KGhhKSx4YVswXSkseGFbMV0tMSk7aWYoYWE9PT0xLzApcmV0dXJuIG1heCQ0KHN1bSQ1KGFicyQ0KGhhKSx4YVsxXSkseGFbMF0pO2lmKGFhPT09LTEvMClyZXR1cm4gbWluJDQoc3VtJDUoYWJzJDQoaGEpLHhhWzFdKSx4YVswXSk7aWYoYWE9PT0iZnJvInx8YWE9PT0iZXVjbGlkZWFuIilyZXR1cm4gc3FydCQ0KHN1bSQ1KHNxdWFyZSQ0KGhhKSx4YSkpO3Rocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gbm9ybTogaW52YWxpZCBvcmQgdmFsdWU6ICR7YWF9YCl9dGhyb3cgbmV3IEVycm9yKGBFcnJvciBpbiBub3JtOiBpbnZhbGlkIGF4aXM6ICR7eGF9YCl9Y29uc3Qgbm9ybT1vcCQxKHtub3JtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGV1Y2xpZGVhbk5vcm1fKGhhLGFhPW51bGwseGE9ITEpe3JldHVybiBub3JtKGhhLCJldWNsaWRlYW4iLGFhLHhhKX1jb25zdCBldWNsaWRlYW5Ob3JtPW9wJDEoe2V1Y2xpZGVhbk5vcm1ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZXhwXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJleHAiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChFeHAkMSx4YSl9Y29uc3QgZXhwJDM9b3AkMSh7ZXhwX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGV4cGFuZERpbXNfKGhhLGFhPTApe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiZXhwYW5kRGltcyIsInN0cmluZ19vcl9udW1lcmljIik7YXNzZXJ0JDIoYWE8PXhhLnJhbmssKCk9PiJBeGlzIG11c3QgYmUgPD0gcmFuayBvZiB0aGUgdGVuc29yIik7Y29uc3QgYmE9e2lucHV0OnhhfSxTYT17ZGltOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEV4cGFuZERpbXMkMSxiYSxTYSl9Y29uc3QgZXhwYW5kRGltcyQ0PW9wJDEoe2V4cGFuZERpbXNffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZXhwbTFfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImV4cG0xIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoRXhwbTEkMSx4YSl9Y29uc3QgZXhwbTEkMz1vcCQxKHtleHBtMV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0aWxlXyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJ0aWxlIiwic3RyaW5nX29yX251bWVyaWMiKTthc3NlcnQkMih4YS5yYW5rPT09YWEubGVuZ3RoLCgpPT5gRXJyb3IgaW4gdHJhbnNwb3NlOiByYW5rIG9mIGlucHV0ICR7eGEucmFua30gbXVzdCBtYXRjaCBsZW5ndGggb2YgcmVwcyAke2FhfS5gKTtjb25zdCBiYT17eDp4YX0sU2E9e3JlcHM6YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoVGlsZSQxLGJhLFNhKX1jb25zdCB0aWxlJDQ9b3AkMSh7dGlsZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBleWVfKGhhLGFhLHhhLGJhPSJmbG9hdDMyIil7YWE9PW51bGwmJihhYT1oYSk7Y29uc3QgU2E9YnVmZmVyJDEoW2hhLGFhXSxiYSksVGE9aGE8PWFhP2hhOmFhO2ZvcihsZXQgRWE9MDtFYTxUYTsrK0VhKVNhLnNldCgxLEVhLEVhKTtjb25zdCB3YT1yZXNoYXBlJDQoU2EudG9UZW5zb3IoKSxbaGEsYWFdKTtpZih4YT09bnVsbClyZXR1cm4gd2E7aWYoeGEubGVuZ3RoPT09MSlyZXR1cm4gdGlsZSQ0KGV4cGFuZERpbXMkNCh3YSwwKSxbeGFbMF0sMSwxXSk7aWYoeGEubGVuZ3RoPT09MilyZXR1cm4gdGlsZSQ0KGV4cGFuZERpbXMkNChleHBhbmREaW1zJDQod2EsMCksMCksW3hhWzBdLHhhWzFdLDEsMV0pO2lmKHhhLmxlbmd0aD09PTMpcmV0dXJuIHRpbGUkNChleHBhbmREaW1zJDQoZXhwYW5kRGltcyQ0KGV4cGFuZERpbXMkNCh3YSwwKSwwKSwwKSxbeGFbMF0seGFbMV0seGFbMl0sMSwxXSk7dGhyb3cgbmV3IEVycm9yKGBleWUoKSBjdXJyZW50bHkgc3VwcG9ydHMgb25seSAxRCBhbmQgMkQgYmF0Y2hTaGFwZXMsIGJ1dCByZWNlaXZlZCAke3hhLmxlbmd0aH1ELmApfWNvbnN0IGV5ZT1vcCQxKHtleWVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZmxvb3JfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImZsb29yIiwiZmxvYXQzMiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEZsb29yJDEseGEpfWNvbnN0IGZsb29yJDM9b3AkMSh7Zmxvb3JffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2F0aGVyXyhoYSxhYSx4YT0wLGJhPTApe2NvbnN0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiZ2F0aGVyIiksVGE9Y29udmVydFRvVGVuc29yJDEoYWEsImluZGljZXMiLCJnYXRoZXIiLCJpbnQzMiIpLHdhPXt4OlNhLGluZGljZXM6VGF9LEVhPXtheGlzOnhhLGJhdGNoRGltczpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChHYXRoZXJWMiQxLHdhLEVhKX1jb25zdCBnYXRoZXIkMT1vcCQxKHtnYXRoZXJffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ3JlYXRlcl8oaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsImdyZWF0ZXIiLCJzdHJpbmdfb3JfbnVtZXJpYyIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwiZ3JlYXRlciIsInN0cmluZ19vcl9udW1lcmljIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEdyZWF0ZXIkMSxTYSl9Y29uc3QgZ3JlYXRlciQzPW9wJDEoe2dyZWF0ZXJffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ3JlYXRlckVxdWFsXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwiZ3JlYXRlckVxdWFsIiwic3RyaW5nX29yX251bWVyaWMiKSxiYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYiIsImdyZWF0ZXJFcXVhbCIsInN0cmluZ19vcl9udW1lcmljIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKEdyZWF0ZXJFcXVhbCQxLFNhKX1jb25zdCBncmVhdGVyRXF1YWwkMz1vcCQxKHtncmVhdGVyRXF1YWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaW1hZ18oaGEpe2NvbnN0IHhhPXtpbnB1dDpjb252ZXJ0VG9UZW5zb3IkMShoYSwiaW5wdXQiLCJpbWFnIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoSW1hZyQxLHhhKX1jb25zdCBpbWFnJDM9b3AkMSh7aW1hZ199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpc0Zpbml0ZV8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiaXNGaW5pdGUiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChJc0Zpbml0ZSQxLHhhKX1jb25zdCBpc0Zpbml0ZSQ0PW9wJDEoe2lzRmluaXRlX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlzSW5mXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJpc0luZiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKElzSW5mJDEseGEpfWNvbnN0IGlzSW5mJDM9b3AkMSh7aXNJbmZffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaXNOYU5fKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImlzTmFOIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoSXNOYW4kMSx4YSl9Y29uc3QgaXNOYU4kND1vcCQxKHtpc05hTl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsZWFreVJlbHVfJDEoaGEsYWE9LjIpe2NvbnN0IGJhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibGVha3lSZWx1Iil9LFNhPXthbHBoYTphYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChMZWFreVJlbHUkMSxiYSxTYSl9Y29uc3QgbGVha3lSZWx1JDQ9b3AkMSh7bGVha3lSZWx1XzpsZWFreVJlbHVfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsZXNzXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwibGVzcyIsInN0cmluZ19vcl9udW1lcmljIiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsImIiLCJsZXNzIiwic3RyaW5nX29yX251bWVyaWMiKTtbeGEsYmFdPW1ha2VUeXBlc01hdGNoJDEoeGEsYmEpLGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO2NvbnN0IFNhPXthOnhhLGI6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTGVzcyQxLFNhKX1jb25zdCBsZXNzJDM9b3AkMSh7bGVzc199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsZXNzRXF1YWxfKGhhLGFhKXtsZXQgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJsZXNzRXF1YWwiLCJzdHJpbmdfb3JfbnVtZXJpYyIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwibGVzc0VxdWFsIiwic3RyaW5nX29yX251bWVyaWMiKTtbeGEsYmFdPW1ha2VUeXBlc01hdGNoJDEoeGEsYmEpLGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO2NvbnN0IFNhPXthOnhhLGI6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTGVzc0VxdWFsJDEsU2EpfWNvbnN0IGxlc3NFcXVhbCQzPW9wJDEoe2xlc3NFcXVhbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsaW5zcGFjZShoYSxhYSx4YSl7aWYoeGE8PTApdGhyb3cgbmV3IEVycm9yKCJUaGUgbnVtYmVyIG9mIHZhbHVlcyBzaG91bGQgYmUgcG9zaXRpdmUuIik7Y29uc3QgYmE9e3N0YXJ0OmhhLHN0b3A6YWEsbnVtOnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKExpblNwYWNlJDEse30sYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvY2FsUmVzcG9uc2VOb3JtYWxpemF0aW9uXyhoYSxhYT01LHhhPTEsYmE9MSxTYT0uNSl7Y29uc3QgVGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJsb2NhbFJlc3BvbnNlTm9ybWFsaXphdGlvbiIpO2Fzc2VydCQyKFRhLnJhbms9PT00fHxUYS5yYW5rPT09MywoKT0+YEVycm9yIGluIGxvY2FsUmVzcG9uc2VOb3JtYWxpemF0aW9uOiB4IG11c3QgYmUgcmFuayAzIG9yIDQgYnV0IGdvdAogICAgICAgICAgICAgICByYW5rICR7VGEucmFua30uYCksYXNzZXJ0JDIoaXNJbnQkMShhYSksKCk9PmBFcnJvciBpbiBsb2NhbFJlc3BvbnNlTm9ybWFsaXphdGlvbjogZGVwdGhSYWRpdXMgbXVzdCBiZSBhbiBpbnRlZ2VyIGJ1dCBnb3QgZGVwdGhSYWRpdXMgJHthYX0uYCk7bGV0IHdhPVRhLEVhPSExO1RhLnJhbms9PT0zJiYoRWE9ITAsd2E9cmVzaGFwZSQ0KFRhLFsxLFRhLnNoYXBlWzBdLFRhLnNoYXBlWzFdLFRhLnNoYXBlWzJdXSkpO2NvbnN0IGthPXt4OndhfSxBYT17ZGVwdGhSYWRpdXM6YWEsYmlhczp4YSxhbHBoYTpiYSxiZXRhOlNhfSxGYT1FTkdJTkUkMS5ydW5LZXJuZWwoTFJOJDEsa2EsQWEpO3JldHVybiBFYT9yZXNoYXBlJDQoRmEsW0ZhLnNoYXBlWzFdLEZhLnNoYXBlWzJdLEZhLnNoYXBlWzNdXSk6RmF9Y29uc3QgbG9jYWxSZXNwb25zZU5vcm1hbGl6YXRpb249b3AkMSh7bG9jYWxSZXNwb25zZU5vcm1hbGl6YXRpb25ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbG9nXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJsb2ciLCJmbG9hdDMyIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTG9nJDEseGEpfWNvbnN0IGxvZyQ0PW9wJDEoe2xvZ199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsb2cxcF8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibG9nMXAiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChMb2cxcCQxLHhhKX1jb25zdCBsb2cxcCQzPW9wJDEoe2xvZzFwX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHZhcmlhYmxlR3JhZHMkMShoYSxhYSl7YXNzZXJ0JDIoaXNGdW5jdGlvbiQxKGhhKSwoKT0+IlRoZSBmIHBhc3NlZCBpbiB2YXJpYWJsZUdyYWRzKGYpIG11c3QgYmUgYSBmdW5jdGlvbiIpLGFzc2VydCQyKGFhPT1udWxsfHxBcnJheS5pc0FycmF5KGFhKSYmYWEuZXZlcnkoQWE9PkFhIGluc3RhbmNlb2YgVmFyaWFibGUkMSksKCk9PiJUaGUgdmFyTGlzdCBwYXNzZWQgaW4gdmFyaWFibGVHcmFkcyhmLCB2YXJMaXN0KSBtdXN0IGJlIGFuIGFycmF5IG9mIHZhcmlhYmxlcyIpO2NvbnN0IHhhPWFhIT1udWxsO2lmKCF4YSl7YWE9W107Zm9yKGNvbnN0IEFhIGluIEVOR0lORSQxLnJlZ2lzdGVyZWRWYXJpYWJsZXMpYWEucHVzaChFTkdJTkUkMS5yZWdpc3RlcmVkVmFyaWFibGVzW0FhXSl9Y29uc3QgYmE9eGE/YWEuZmlsdGVyKEFhPT4hQWEudHJhaW5hYmxlKTpudWxsLFNhPWFhLmxlbmd0aDthYT1hYS5maWx0ZXIoQWE9PkFhLnRyYWluYWJsZSksYXNzZXJ0JDIoYWEubGVuZ3RoPjAsKCk9PmB2YXJpYWJsZUdyYWRzKCkgZXhwZWN0cyBhdCBsZWFzdCBvbmUgb2YgdGhlIGlucHV0IHZhcmlhYmxlcyB0byBiZSB0cmFpbmFibGUsIGJ1dCBub25lIG9mIHRoZSAke1NhfSB2YXJpYWJsZXMgaXMgdHJhaW5hYmxlLmApO2NvbnN0IFRhPSEwLHt2YWx1ZTp3YSxncmFkczpFYX09RU5HSU5FJDEuZ3JhZGllbnRzKGhhLGFhLG51bGwsVGEpO2Fzc2VydCQyKEVhLnNvbWUoQWE9PkFhIT1udWxsKSwoKT0+IkNhbm5vdCBmaW5kIGEgY29ubmVjdGlvbiBiZXR3ZWVuIGFueSB2YXJpYWJsZSBhbmQgdGhlIHJlc3VsdCBvZiB0aGUgbG9zcyBmdW5jdGlvbiB5PWYoeCkuIFBsZWFzZSBtYWtlIHN1cmUgdGhlIG9wZXJhdGlvbnMgdGhhdCB1c2UgdmFyaWFibGVzIGFyZSBpbnNpZGUgdGhlIGZ1bmN0aW9uIGYgcGFzc2VkIHRvIG1pbmltaXplKCkuIiksYXNzZXJ0JDIod2EucmFuaz09PTAsKCk9PmBUaGUgZiBwYXNzZWQgaW4gdmFyaWFibGVHcmFkcyhmKSBtdXN0IHJldHVybiBhIHNjYWxhciwgYnV0IGl0IHJldHVybmVkIGEgcmFuay0ke3dhLnJhbmt9IHRlbnNvcmApO2NvbnN0IGthPXt9O3JldHVybiBhYS5mb3JFYWNoKChBYSxGYSk9PntFYVtGYV0hPW51bGwmJihrYVtBYS5uYW1lXT1FYVtGYV0pfSksYmEhPW51bGwmJmJhLmZvckVhY2goQWE9PmthW0FhLm5hbWVdPW51bGwpLHt2YWx1ZTp3YSxncmFkczprYX19ZnVuY3Rpb24gY3VzdG9tR3JhZChoYSl7cmV0dXJuIEVOR0lORSQxLmN1c3RvbUdyYWQoaGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5lZ18oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibmVnIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTmVnJDEseGEpfWNvbnN0IG5lZyQzPW9wJDEoe25lZ199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzb2Z0cGx1c18oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic29mdHBsdXMiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTb2Z0cGx1cyQyLHhhKX1jb25zdCBzb2Z0cGx1cyQzPW9wJDEoe3NvZnRwbHVzX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvZ1NpZ21vaWRfKGhhKXtjb25zdCBhYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImxvZ1NpZ21vaWQiKTtyZXR1cm4gY3VzdG9tR3JhZChiYT0+KHt2YWx1ZTpuZWckMyhzb2Z0cGx1cyQzKG5lZyQzKGJhKSkpLGdyYWRGdW5jOndhPT5tdWwkMSh3YSxzaWdtb2lkJDQobmVnJDMoYmEpKSl9KSkoYWEpfWNvbnN0IGxvZ1NpZ21vaWQ9b3AkMSh7bG9nU2lnbW9pZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdWJfJDEoaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsInN1YiIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwic3ViIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFN1YiQxLFNhKX1jb25zdCBzdWIkND1vcCQxKHtzdWJfOnN1Yl8kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvZ1NvZnRtYXhfKGhhLGFhPS0xKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwibG9naXRzIiwibG9nU29mdG1heCIpO2lmKGFhPT09LTEmJihhYT14YS5yYW5rLTEpLGFhIT09eGEucmFuay0xKXRocm93IEVycm9yKGBMb2cgU29mdG1heCBhbG9uZyBhIG5vbi1sYXN0IGRpbWVuc2lvbiBpcyBub3QgeWV0IHN1cHBvcnRlZC4gTG9naXRzIHdhcyByYW5rICR7eGEucmFua30gYW5kIGF4aXMgd2FzICR7YWF9YCk7cmV0dXJuIGN1c3RvbUdyYWQoKFNhLFRhKT0+e2NvbnN0IEVhPW1heCQ0KFNhLGFhLCEwKSxrYT1zdWIkNChTYSxFYSksQWE9c3ViJDQoY2FzdCQ1KGthLCJmbG9hdDMyIiksbG9nJDQoc3VtJDUoZXhwJDMoa2EpLGFhLCEwKSkpO3JldHVybiBUYShbQWFdKSx7dmFsdWU6QWEsZ3JhZEZ1bmM6KExhLGVsKT0+e2NvbnN0W3RsXT1lbCxubD0hMCxzbD1leHAkMyh0bCk7cmV0dXJuIHN1YiQ0KExhLG11bCQxKHN1bSQ1KExhLGFhLG5sKSxzbCkpfX19KSh4YSl9Y29uc3QgbG9nU29mdG1heD1vcCQxKHtsb2dTb2Z0bWF4X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvZ1N1bUV4cF8oaGEsYWE9bnVsbCx4YT0hMSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJsb2dTdW1FeHAiKSxTYT1wYXJzZUF4aXNQYXJhbSQxKGFhLGJhLnNoYXBlKSxUYT1tYXgkNChiYSxTYSwhMCksd2E9c3ViJDQoYmEsVGEpLEVhPWV4cCQzKHdhKSxrYT1zdW0kNShFYSxTYSksQWE9bG9nJDQoa2EpLEZhPWFkZCQzKHJlc2hhcGUkNChUYSxBYS5zaGFwZSksQWEpO2lmKHhhKXtjb25zdCBMYT1leHBhbmRTaGFwZVRvS2VlcERpbSQxKEZhLnNoYXBlLFNhKTtyZXR1cm4gcmVzaGFwZSQ0KEZhLExhKX1yZXR1cm4gRmF9Y29uc3QgbG9nU3VtRXhwPW9wJDEoe2xvZ1N1bUV4cF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsb2dpY2FsQW5kXyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJsb2dpY2FsQW5kIiwiYm9vbCIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwibG9naWNhbEFuZCIsImJvb2wiKTthc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKExvZ2ljYWxBbmQkMSxTYSl9Y29uc3QgbG9naWNhbEFuZCQzPW9wJDEoe2xvZ2ljYWxBbmRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbG9naWNhbE5vdF8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibG9naWNhbE5vdCIsImJvb2wiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChMb2dpY2FsTm90JDEseGEpfWNvbnN0IGxvZ2ljYWxOb3QkMz1vcCQxKHtsb2dpY2FsTm90X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvZ2ljYWxPcl8oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwibG9naWNhbE9yIiwiYm9vbCIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwibG9naWNhbE9yIiwiYm9vbCIpO2Fzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO2NvbnN0IFNhPXthOnhhLGI6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTG9naWNhbE9yJDEsU2EpfWNvbnN0IGxvZ2ljYWxPciQzPW9wJDEoe2xvZ2ljYWxPcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsb2dpY2FsWG9yXyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJsb2dpY2FsWG9yIiwiYm9vbCIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwibG9naWNhbFhvciIsImJvb2wiKTtyZXR1cm4gYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMSh4YS5zaGFwZSxiYS5zaGFwZSksbG9naWNhbEFuZCQzKGxvZ2ljYWxPciQzKGhhLGFhKSxsb2dpY2FsTm90JDMobG9naWNhbEFuZCQzKGhhLGFhKSkpfWNvbnN0IGxvZ2ljYWxYb3I9b3AkMSh7bG9naWNhbFhvcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBJTlQzMl9NQVgkMj0yMTQ3NDgzNjQ4O2Z1bmN0aW9uIHNlYXJjaFNvcnRlZF8oaGEsYWEseGE9ImxlZnQiKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwic29ydGVkU2VxdWVuY2UiLCJzZWFyY2hTb3J0ZWQiKSxTYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwidmFsdWVzIiwic2VhcmNoU29ydGVkIiksVGE9YmEuc2hhcGVbYmEuc2hhcGUubGVuZ3RoLTFdLHdhPVNhLnNoYXBlW1NhLnNoYXBlLmxlbmd0aC0xXSxFYT1yZXNoYXBlJDQoYmEsWy0xLFRhXSksa2E9cmVzaGFwZSQ0KFNhLFstMSx3YV0pO2lmKEVhLnJhbms8Mil0aHJvdyBuZXcgRXJyb3IoIlNvcnRlZCBpbnB1dCBhcmd1bWVudCBtdXN0IGJlIGF0IGxlYXN0IDItZGltZW5zaW9uYWwiKTtpZihFYS5zaGFwZVswXSE9PWthLnNoYXBlWzBdKXRocm93IG5ldyBFcnJvcigiTGVhZGluZyBkaW1lbnNpb24gb2YgJ3NvcnRlZFNlcXVlbmNlJyBhbmQgJ3ZhbHVlcycgbXVzdCBtYXRjaC4iKTtpZihzaXplRnJvbVNoYXBlJDEoa2Euc2hhcGUpPj1JTlQzMl9NQVgkMil0aHJvdyBuZXcgRXJyb3IoYHZhbHVlcyB0ZW5zb3Igc2l6ZSBtdXN0IGxlc3MgdGhhbiAke0lOVDMyX01BWCQyfWApO2lmKEVhLnNoYXBlWzFdPj1JTlQzMl9NQVgkMil0aHJvdyBuZXcgRXJyb3IoYHRyYWlsaW5nIGRpbV9zaXplIG11c3QgbGVzcyB0aGFuICR7SU5UMzJfTUFYJDJ9IGZvciBpbnQzMiBvdXRwdXQgdHlwZSwgd2FzICR7RWEuc2hhcGVbMV19YCk7Y29uc3QgQWE9e3NvcnRlZFNlcXVlbmNlOkVhLHZhbHVlczprYX0sRmE9e3NpZGU6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU2VhcmNoU29ydGVkJDEsQWEsRmEpfWNvbnN0IHNlYXJjaFNvcnRlZCQzPW9wJDEoe3NlYXJjaFNvcnRlZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsb3dlckJvdW5kJDEoaGEsYWEpe3JldHVybiBzZWFyY2hTb3J0ZWQkMyhoYSxhYSwibGVmdCIpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2xfKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsIm1heFBvb2wiKSx3YT0xO2xldCBFYT1UYSxrYT0hMTtUYS5yYW5rPT09MyYmKGthPSEwLEVhPXJlc2hhcGUkNChUYSxbMSxUYS5zaGFwZVswXSxUYS5zaGFwZVsxXSxUYS5zaGFwZVsyXV0pKSxhc3NlcnQkMihFYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIG1heFBvb2w6IGlucHV0IG11c3QgYmUgcmFuayA0IGJ1dCBnb3QgcmFuayAke0VhLnJhbmt9LmApLGFzc2VydCQyKGVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZSQxKHhhLHdhKSwoKT0+YEVycm9yIGluIG1heFBvb2w6IEVpdGhlciBzdHJpZGVzIG9yIGRpbGF0aW9ucyBtdXN0IGJlIDEuIEdvdCBzdHJpZGVzICR7eGF9IGFuZCBkaWxhdGlvbnMgJyR7d2F9J2ApLGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGUkMSgibWF4UG9vbCIsYmEsU2EpO2NvbnN0IEFhPXt4OkVhfSxGYT17ZmlsdGVyU2l6ZTphYSxzdHJpZGVzOnhhLHBhZDpiYSxkaW1Sb3VuZGluZ01vZGU6U2F9LExhPUVOR0lORSQxLnJ1bktlcm5lbChNYXhQb29sJDEsQWEsRmEpO3JldHVybiBrYT9yZXNoYXBlJDQoTGEsW0xhLnNoYXBlWzFdLExhLnNoYXBlWzJdLExhLnNoYXBlWzNdXSk6TGF9Y29uc3QgbWF4UG9vbCQzPW9wJDEoe21heFBvb2xffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4UG9vbDNkXyhoYSxhYT1bMSwxLDFdLHhhLGJhLFNhLFRhPSJOREhXQyIpe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibWF4UG9vbDNkIik7bGV0IEVhPXdhLGthPSExO3dhLnJhbms9PT00JiYoa2E9ITAsRWE9cmVzaGFwZSQ0KHdhLFsxLHdhLnNoYXBlWzBdLHdhLnNoYXBlWzFdLHdhLnNoYXBlWzJdLHdhLnNoYXBlWzNdXSkpLGFzc2VydCQyKEVhLnJhbms9PT01LCgpPT5gRXJyb3IgaW4gbWF4UG9vbDNkOiB4IG11c3QgYmUgcmFuayA1IGJ1dCBnb3QgcmFuayAke0VhLnJhbmt9LmApLGFzc2VydCQyKFRhPT09Ik5ESFdDIiwoKT0+YEVycm9yIGluIG1heFBvb2wzZDogT25seSBOREhXQyBpcyBjdXJyZW50bHkgc3VwcG9ydGVkLCBidXQgZ290IGRhdGFGb3JtYXQgb2YgJHtUYX1gKSxjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlJDEoIm1heFBvb2wzZCIsYmEsU2EpO2NvbnN0IEFhPXt4OkVhfSxGYT17ZmlsdGVyU2l6ZTphYSxzdHJpZGVzOnhhLHBhZDpiYSxkaW1Sb3VuZGluZ01vZGU6U2EsZGF0YUZvcm1hdDpUYX0sTGE9RU5HSU5FJDEucnVuS2VybmVsKE1heFBvb2wzRCQxLEFhLEZhKTtyZXR1cm4ga2E/cmVzaGFwZSQ0KExhLFtMYS5zaGFwZVsxXSxMYS5zaGFwZVsyXSxMYS5zaGFwZVszXSxMYS5zaGFwZVs0XV0pOkxhfWNvbnN0IG1heFBvb2wzZCQyPW9wJDEoe21heFBvb2wzZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhQb29sV2l0aEFyZ21heF8oaGEsYWEseGEsYmEsU2E9ITEpe2NvbnN0IHdhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibWF4UG9vbFdpdGhBcmdtYXgiKX0sRWE9e2ZpbHRlclNpemU6YWEsc3RyaWRlczp4YSxwYWQ6YmEsaW5jbHVkZUJhdGNoSW5JbmRleDpTYX0sa2E9RU5HSU5FJDEucnVuS2VybmVsKE1heFBvb2xXaXRoQXJnbWF4JDEsd2EsRWEpO3JldHVybntyZXN1bHQ6a2FbMF0saW5kZXhlczprYVsxXX19Y29uc3QgbWF4UG9vbFdpdGhBcmdtYXg9b3AkMSh7bWF4UG9vbFdpdGhBcmdtYXhffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4aW11bV8kMShoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwibWF4aW11bSIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwibWF4aW11bSIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSkseGEuZHR5cGU9PT0iYm9vbCImJih4YT1jYXN0JDUoeGEsImludDMyIiksYmE9Y2FzdCQ1KGJhLCJpbnQzMiIpKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKE1heGltdW0kMixTYSl9Y29uc3QgbWF4aW11bSQ0PW9wJDEoe21heGltdW1fOm1heGltdW1fJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtZWFuXyhoYSxhYT1udWxsLHhhPSExKXtjb25zdCBTYT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsIm1lYW4iKX0sVGE9e2F4aXM6YWEsa2VlcERpbXM6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTWVhbiQxLFNhLFRhKX1jb25zdCBtZWFuJDE9b3AkMSh7bWVhbl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB6ZXJvcyQyKGhhLGFhPSJmbG9hdDMyIil7aWYoYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKGhhKSxhYT09PSJjb21wbGV4NjQiKXtjb25zdCBiYT16ZXJvcyQyKGhhLCJmbG9hdDMyIiksU2E9emVyb3MkMihoYSwiZmxvYXQzMiIpO3JldHVybiBjb21wbGV4JDQoYmEsU2EpfWNvbnN0IHhhPW1ha2VaZXJvc1R5cGVkQXJyYXkkMShzaXplRnJvbVNoYXBlJDEoaGEpLGFhKTtyZXR1cm4gRU5HSU5FJDEubWFrZVRlbnNvcih4YSxoYSxhYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gb25lcyQxKGhhLGFhPSJmbG9hdDMyIil7aWYoYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKGhhKSxhYT09PSJjb21wbGV4NjQiKXtjb25zdCBiYT1vbmVzJDEoaGEsImZsb2F0MzIiKSxTYT16ZXJvcyQyKGhhLCJmbG9hdDMyIik7cmV0dXJuIGNvbXBsZXgkNChiYSxTYSl9Y29uc3QgeGE9bWFrZU9uZXNUeXBlZEFycmF5JDEoc2l6ZUZyb21TaGFwZSQxKGhhKSxhYSk7cmV0dXJuIEVOR0lORSQxLm1ha2VUZW5zb3IoeGEsaGEsYWEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1lc2hncmlkKGhhLGFhLHtpbmRleGluZzp4YT0ieHkifT17fSl7aWYoeGEhPT0ieHkiJiZ4YSE9PSJpaiIpdGhyb3cgbmV3IFR5cGVFcnJvcihgJHt4YX0gaXMgbm90IGEgdmFsaWQgdGhpcmQgYXJndW1lbnQgdG8gbWVzaGdyaWRgKTtpZihoYT09PXZvaWQgMClyZXR1cm5bXTtsZXQgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJtZXNoZ3JpZCIsaGEgaW5zdGFuY2VvZiBUZW5zb3IkMT9oYS5kdHlwZToiZmxvYXQzMiIpO2lmKGFhPT09dm9pZCAwKXJldHVybltiYV07bGV0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJ5IiwibWVzaGdyaWQiLGFhIGluc3RhbmNlb2YgVGVuc29yJDE/YWEuZHR5cGU6ImZsb2F0MzIiKTtjb25zdCBUYT1zaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpLHdhPXNpemVGcm9tU2hhcGUkMShTYS5zaGFwZSk7cmV0dXJuIHhhPT09Inh5Ij8oYmE9cmVzaGFwZSQ0KGJhLFsxLC0xXSksU2E9cmVzaGFwZSQ0KFNhLFstMSwxXSksW21hdE11bCQxKG9uZXMkMShbd2EsMV0sYmEuZHR5cGUpLGJhKSxtYXRNdWwkMShTYSxvbmVzJDEoWzEsVGFdLFNhLmR0eXBlKSldKTooYmE9cmVzaGFwZSQ0KGJhLFstMSwxXSksU2E9cmVzaGFwZSQ0KFNhLFsxLC0xXSksW21hdE11bCQxKGJhLG9uZXMkMShbMSx3YV0sYmEuZHR5cGUpKSxtYXRNdWwkMShvbmVzJDEoW1RhLDFdLFNhLmR0eXBlKSxTYSldKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtaW5pbXVtXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwibWluaW11bSIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJiIiwibWluaW11bSIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSkseGEuZHR5cGU9PT0iYm9vbCImJih4YT1jYXN0JDUoeGEsImludDMyIiksYmE9Y2FzdCQ1KGJhLCJpbnQzMiIpKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKE1pbmltdW0kMixTYSl9Y29uc3QgbWluaW11bSQzPW9wJDEoe21pbmltdW1ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWlycm9yUGFkXyhoYSxhYSx4YSl7YXNzZXJ0JDIoeGE9PT0icmVmbGVjdCJ8fHhhPT09InN5bW1ldHJpYyIsKCk9PmBJbnZhbGlkIG1vZGUuIE1vZGUgbXVzdCBiZSBlaXRoZXIgcmVmbGVjdCBvciBzeW1tZXRyaWMuIEdvdCAke3hhfS5gKTtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsIm1pcnJvclBhZCIpO2lmKGJhLnJhbms9PT0wKXRocm93IG5ldyBFcnJvcigibWlycm9yUGFkKHNjYWxhcikgaXMgbm90IGRlZmluZWQuIFBhc3Mgbm9uLXNjYWxhciB0byBtaXJyb3JQYWQiKTthc3NlcnQkMihhYS5sZW5ndGg9PT1iYS5yYW5rLCgpPT5gUGFkZGluZyBkb2Vzbid0IG1hdGNoIGlucHV0LiBNdXN0IGJlICR7YmEucmFua30uIEdvdCAke2FhLmxlbmd0aH0uYCk7Y29uc3QgU2E9eGE9PT0icmVmbGVjdCI/MTowO2ZvcihsZXQgRWE9MDtFYTxiYS5yYW5rO0VhKyspYXNzZXJ0JDIoYWFbRWFdLmxlbmd0aD09PTIsKCk9PiJJbnZhbGlkIG51bWJlciBvZiBwYWRkaW5ncy4gTXVzdCBiZSBsZW5ndGggb2YgMiBlYWNoLiIpLGFzc2VydCQyKGFhW0VhXVswXT49MCYmYWFbRWFdWzBdPD1iYS5zaGFwZVtFYV0tU2EmJmFhW0VhXVsxXT49MCYmYWFbRWFdWzFdPD1iYS5zaGFwZVtFYV0tU2EsKCk9PmBQYWRkaW5nIGluIGRpbWVuc2lvbiAke0VhfSBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7YmEuc2hhcGVbRWFdLVNhfSBvciBsZXNzIHRoYW4gMCBmb3IgaW5wdXQgb2Ygc2hhcGUgJHtiYS5zaGFwZX1gKTtjb25zdCBUYT17cGFkZGluZ3M6YWEsbW9kZTp4YX0sd2E9e3g6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTWlycm9yUGFkJDEsd2EsVGEpfWNvbnN0IG1pcnJvclBhZCQxPW9wJDEoe21pcnJvclBhZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtb2RfKGhhLGFhKXtsZXQgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJtb2QiKSxiYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYiIsIm1vZCIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2gkMSh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChNb2QkMSxTYSl9Y29uc3QgbW9kJDM9b3AkMSh7bW9kX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1vbWVudHNfKGhhLGFhPW51bGwseGE9ITEpe2hhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwibW9tZW50cyIpO2NvbnN0IGJhPXBhcnNlQXhpc1BhcmFtJDEoYWEsaGEuc2hhcGUpLFNhPW1lYW4kMShoYSxiYSx4YSk7bGV0IFRhPVNhLnNoYXBlO3hhfHwoVGE9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShTYS5zaGFwZSxiYSkpO2NvbnN0IHdhPXNxdWFyZSQ0KHN1YiQ0KGNhc3QkNShoYSwiZmxvYXQzMiIpLHJlc2hhcGUkNChTYSxUYSkpKSxFYT1tZWFuJDEod2EsYmEseGEpO3JldHVybnttZWFuOlNhLHZhcmlhbmNlOkVhfX1jb25zdCBtb21lbnRzPW9wJDEoe21vbWVudHNffSk7ZnVuY3Rpb24gbXVsdGlSTk5DZWxsXyhoYSxhYSx4YSxiYSl7Y29uc3QgU2E9Y29udmVydFRvVGVuc29yJDEoYWEsImRhdGEiLCJtdWx0aVJOTkNlbGwiKSxUYT1jb252ZXJ0VG9UZW5zb3JBcnJheSh4YSwiYyIsIm11bHRpUk5OQ2VsbCIpLHdhPWNvbnZlcnRUb1RlbnNvckFycmF5KGJhLCJoIiwibXVsdGlSTk5DZWxsIik7bGV0IEVhPVNhO2NvbnN0IGthPVtdO2ZvcihsZXQgTGE9MDtMYTxoYS5sZW5ndGg7TGErKyl7Y29uc3QgZWw9aGFbTGFdKEVhLFRhW0xhXSx3YVtMYV0pO2thLnB1c2goZWxbMF0pLGthLnB1c2goZWxbMV0pLEVhPWVsWzFdfWNvbnN0IEFhPVtdLEZhPVtdO2ZvcihsZXQgTGE9MDtMYTxrYS5sZW5ndGg7TGErPTIpQWEucHVzaChrYVtMYV0pLEZhLnB1c2goa2FbTGErMV0pO3JldHVybltBYSxGYV19Y29uc3QgbXVsdGlSTk5DZWxsPW9wJDEoe211bHRpUk5OQ2VsbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtdWx0aW5vbWlhbF8oaGEsYWEseGEsYmE9ITEpe2NvbnN0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJsb2dpdHMiLCJtdWx0aW5vbWlhbCIpLFRhPVNhLnNpemUsd2E9U2EucmFuaztpZihUYTwyKXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gbXVsdGlub21pYWw6IHlvdSBuZWVkIGF0IGxlYXN0IDIgb3V0Y29tZXMsIGJ1dCBnb3QgJHtUYX0uYCk7aWYod2E+Mil0aHJvdyBuZXcgRXJyb3IoYFJhbmsgb2YgcHJvYmFiaWxpdGllcyBtdXN0IGJlIDEgb3IgMiwgYnV0IGlzICR7d2F9YCk7eGE9eGF8fE1hdGgucmFuZG9tKCk7Y29uc3Qga2E9e2xvZ2l0czp3YT09PTE/cmVzaGFwZSQ0KFNhLFsxLC0xXSk6U2F9LEFhPXtudW1TYW1wbGVzOmFhLHNlZWQ6eGEsbm9ybWFsaXplZDpiYX0sRmE9RU5HSU5FJDEucnVuS2VybmVsKE11bHRpbm9taWFsJDEsa2EsQWEpO3JldHVybiB3YT09PTE/cmVzaGFwZSQ0KEZhLFtGYS5zaXplXSk6RmF9Y29uc3QgbXVsdGlub21pYWwkMz1vcCQxKHttdWx0aW5vbWlhbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBub3RFcXVhbF8oaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYSIsIm5vdEVxdWFsIiwic3RyaW5nX29yX251bWVyaWMiKSxiYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYiIsIm5vdEVxdWFsIiwic3RyaW5nX29yX251bWVyaWMiKTtbeGEsYmFdPW1ha2VUeXBlc01hdGNoJDEoeGEsYmEpLGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO2NvbnN0IFNhPXthOnhhLGI6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTm90RXF1YWwkMSxTYSl9Y29uc3Qgbm90RXF1YWwkMz1vcCQxKHtub3RFcXVhbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBvbmVIb3RfKGhhLGFhLHhhPTEsYmE9MCxTYT0iaW50MzIiKXtpZihhYTwyKXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gb25lSG90OiBkZXB0aCBtdXN0IGJlID49MiwgYnV0IGl0IGlzICR7YWF9YCk7Y29uc3Qgd2E9e2luZGljZXM6Y29udmVydFRvVGVuc29yJDEoaGEsImluZGljZXMiLCJvbmVIb3QiLCJpbnQzMiIpfSxFYT17ZHR5cGU6U2EsZGVwdGg6YWEsb25WYWx1ZTp4YSxvZmZWYWx1ZTpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChPbmVIb3QkMSx3YSxFYSl9Y29uc3Qgb25lSG90JDM9b3AkMSh7b25lSG90X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG9uZXNMaWtlXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJvbmVzTGlrZSIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKE9uZXNMaWtlJDEseGEpfWNvbnN0IG9uZXNMaWtlJDM9b3AkMSh7b25lc0xpa2VffSk7ZnVuY3Rpb24gb3V0ZXJQcm9kdWN0XyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsInYxIiwib3V0ZXJQcm9kdWN0IiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsInYyIiwib3V0ZXJQcm9kdWN0Iik7YXNzZXJ0JDIoeGEucmFuaz09PTEmJmJhLnJhbms9PT0xLCgpPT5gRXJyb3IgaW4gb3V0ZXJQcm9kdWN0OiBpbnB1dHMgbXVzdCBiZSByYW5rIDEsIGJ1dCBnb3QgcmFua3MgJHt4YS5yYW5rfSBhbmQgJHtiYS5yYW5rfS5gKTtjb25zdCBTYT1yZXNoYXBlJDQoeGEsWy0xLDFdKSxUYT1yZXNoYXBlJDQoYmEsWzEsLTFdKTtyZXR1cm4gbWF0TXVsJDEoU2EsVGEpfWNvbnN0IG91dGVyUHJvZHVjdD1vcCQxKHtvdXRlclByb2R1Y3RffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcGFkXyhoYSxhYSx4YT0wKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInBhZCIpO2lmKGJhLnJhbms9PT0wKXRocm93IG5ldyBFcnJvcigicGFkKHNjYWxhcikgaXMgbm90IGRlZmluZWQuIFBhc3Mgbm9uLXNjYWxhciB0byBwYWQiKTtjb25zdCBTYT17cGFkZGluZ3M6YWEsY29uc3RhbnRWYWx1ZTp4YX0sVGE9e3g6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoUGFkVjIkMSxUYSxTYSl9Y29uc3QgcGFkPW9wJDEoe3BhZF99KTtmdW5jdGlvbiBwYWQxZF8oaGEsYWEseGE9MCl7cmV0dXJuIGFzc2VydCQyKGFhLmxlbmd0aD09PTIsKCk9PiJJbnZhbGlkIG51bWJlciBvZiBwYWRkaW5ncy4gTXVzdCBiZSBsZW5ndGggb2YgMi4iKSxwYWQoaGEsW2FhXSx4YSl9Y29uc3QgcGFkMWQ9b3AkMSh7cGFkMWRffSk7ZnVuY3Rpb24gcGFkMmRfKGhhLGFhLHhhPTApe3JldHVybiBhc3NlcnQkMihhYS5sZW5ndGg9PT0yJiZhYVswXS5sZW5ndGg9PT0yJiZhYVsxXS5sZW5ndGg9PT0yLCgpPT4iSW52YWxpZCBudW1iZXIgb2YgcGFkZGluZ3MuIE11c3QgYmUgbGVuZ3RoIG9mIDIgZWFjaC4iKSxwYWQoaGEsYWEseGEpfWNvbnN0IHBhZDJkPW9wJDEoe3BhZDJkX30pO2Z1bmN0aW9uIHBhZDNkXyhoYSxhYSx4YT0wKXtyZXR1cm4gYXNzZXJ0JDIoYWEubGVuZ3RoPT09MyYmYWFbMF0ubGVuZ3RoPT09MiYmYWFbMV0ubGVuZ3RoPT09MiYmYWFbMl0ubGVuZ3RoPT09MiwoKT0+IkludmFsaWQgbnVtYmVyIG9mIHBhZGRpbmdzLiBNdXN0IGJlIGxlbmd0aCBvZiAyIGVhY2guIikscGFkKGhhLGFhLHhhKX1jb25zdCBwYWQzZD1vcCQxKHtwYWQzZF99KTtmdW5jdGlvbiBwYWQ0ZF8oaGEsYWEseGE9MCl7cmV0dXJuIGFzc2VydCQyKGFhLmxlbmd0aD09PTQmJmFhWzBdLmxlbmd0aD09PTImJmFhWzFdLmxlbmd0aD09PTImJmFhWzJdLmxlbmd0aD09PTImJmFhWzNdLmxlbmd0aD09PTIsKCk9PiJJbnZhbGlkIG51bWJlciBvZiBwYWRkaW5ncy4gTXVzdCBiZSBsZW5ndGggb2YgMiBlYWNoLiIpLHBhZChoYSxhYSx4YSl9Y29uc3QgcGFkNGQ9b3AkMSh7cGFkNGRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhY2VUb0JhdGNoTkRfKGhhLGFhLHhhKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNwYWNlVG9CYXRjaE5EIik7YXNzZXJ0JDIoYmEucmFuaz49MSthYS5sZW5ndGgsKCk9PmBpbnB1dCByYW5rICR7YmEucmFua30gc2hvdWxkIGJlID4gdGhhbiBbYmxvY2tTaGFwZV0gJHthYS5sZW5ndGh9YCksYXNzZXJ0JDIoeGEubGVuZ3RoPT09YWEubGVuZ3RoLCgpPT5gcGFkZGluZ3Muc2hhcGVbMF0gJHt4YS5sZW5ndGh9IG11c3QgYmUgZXF1YWwgdG8gW2Jsb2NrU2hhcGVdICR7YWEubGVuZ3RofWApLGFzc2VydCQyKGJhLnNoYXBlLnJlZHVjZSgod2EsRWEsa2EpPT5rYT4wJiZrYTw9YWEubGVuZ3RoP3dhJiYoRWEreGFba2EtMV1bMF0reGFba2EtMV1bMV0pJWFhW2thLTFdPT09MDp3YSwhMCksKCk9PmBpbnB1dCBzcGF0aWFsIGRpbWVuc2lvbnMgJHtiYS5zaGFwZS5zbGljZSgxKX0gd2l0aCBwYWRkaW5ncyAke3hhLnRvU3RyaW5nKCl9IG11c3QgYmUgZGl2aXNpYmxlIGJ5IGJsb2NrU2hhcGVzICR7YWEudG9TdHJpbmcoKX1gKTtjb25zdCBTYT17eDpiYX0sVGE9e2Jsb2NrU2hhcGU6YWEscGFkZGluZ3M6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU3BhY2VUb0JhdGNoTkQkMSxTYSxUYSl9Y29uc3Qgc3BhY2VUb0JhdGNoTkQkMz1vcCQxKHtzcGFjZVRvQmF0Y2hORF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwb29sXyhoYSxhYSx4YSxiYSxTYSxUYSx3YSl7U2E9PW51bGwmJihTYT1bMSwxXSksVGE9PW51bGwmJihUYT0xKSxiYT09PTAmJihiYT0idmFsaWQiKTtjb25zdCBFYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsIm1heFBvb2wiKTtsZXQga2E9RWEsQWE9ITE7RWEucmFuaz09PTMmJihBYT0hMCxrYT1yZXNoYXBlJDQoRWEsWzEsRWEuc2hhcGVbMF0sRWEuc2hhcGVbMV0sRWEuc2hhcGVbMl1dKSksYXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEoVGEsU2EpLCgpPT5gRXJyb3IgaW4gcG9vbDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHtUYX0gYW5kIGRpbGF0aW9ucyAnJHtTYX0nYCk7Y29uc3QgRmE9Y29tcHV0ZVBvb2wyREluZm8kMShrYS5zaGFwZSxhYSxUYSxTYSxiYSksTGE9W0ZhLmRpbGF0aW9uSGVpZ2h0LEZhLmRpbGF0aW9uV2lkdGhdO2xldCBlbDtiYT09PSJzYW1lIj9lbD13aXRoU3BhY2VUb0JhdGNoQmFzZVBhZGRpbmdzKFtGYS5maWx0ZXJIZWlnaHQsRmEuZmlsdGVyV2lkdGhdLExhKTplbD1bWzAsMF0sWzAsMF1dO2NvbnN0IHRsPUxhWzBdPT09MSYmTGFbMV09PT0xLFtubCxzbF09cmVxdWlyZWRTcGFjZVRvQmF0Y2hQYWRkaW5ncyhbRmEuaW5IZWlnaHQsRmEuaW5XaWR0aF0sTGEsZWwpLHJsPXRsP2JhOiJ2YWxpZCIsb2w9dGw/a2E6c3BhY2VUb0JhdGNoTkQkMyhrYSxMYSxubCksbGw9KHhhPT09ImF2ZyI/KCk9PmF2Z1Bvb2wkMyhvbCxhYSxUYSxybCx3YSk6KCk9Pm1heFBvb2wkMyhvbCxhYSxUYSxybCx3YSkpKCksaWw9dGw/bGw6YmF0Y2hUb1NwYWNlTkQkMyhsbCxMYSxzbCk7cmV0dXJuIEFhP3Jlc2hhcGUkNChpbCxbaWwuc2hhcGVbMV0saWwuc2hhcGVbMl0saWwuc2hhcGVbM11dKTppbH1mdW5jdGlvbiByZXF1aXJlZFNwYWNlVG9CYXRjaFBhZGRpbmdzKGhhLGFhLHhhKXtjb25zdCBiYT14YS5tYXAoRmE9PkZhWzBdKSxTYT14YS5tYXAoRmE9PkZhWzFdKSxUYT1oYS5jb25jYXQoYmEsU2EpLHdhPWFhLm1hcCgoRmEsTGEpPT4oRmEtVGFbTGFdJUZhKSVGYSksRWE9U2EubWFwKChGYSxMYSk9PkZhK3dhW0xhXSksa2E9YWEubWFwKChGYSxMYSk9PltiYVtMYV0sRWFbTGFdXSksQWE9YWEubWFwKChGYSxMYSk9PlswLHdhW0xhXV0pO3JldHVybltrYSxBYV19ZnVuY3Rpb24gd2l0aFNwYWNlVG9CYXRjaEJhc2VQYWRkaW5ncyhoYSxhYSl7Y29uc3QgYmE9aGEubWFwKCh3YSxFYSk9PndhKyh3YS0xKSooYWFbRWFdLTEpKS5tYXAod2E9PndhLTEpLFNhPWJhLm1hcCh3YT0+TWF0aC5mbG9vcih3YS8yKSksVGE9YmEubWFwKCh3YSxFYSk9PndhLVNhW0VhXSk7cmV0dXJuIGJhLm1hcCgod2EsRWEpPT5bU2FbRWFdLFRhW0VhXV0pfWNvbnN0IHBvb2wkMT1vcCQxKHtwb29sX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHByZWx1XyQxKGhhLGFhKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInByZWx1IiksYmE9Y29udmVydFRvVGVuc29yJDEoYWEsImFscGhhIiwicHJlbHUiKSxTYT17eDp4YSxhbHBoYTpiYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChQcmVsdSQxLFNhKX1jb25zdCBwcmVsdSQ0PW9wJDEoe3ByZWx1XzpwcmVsdV8kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHByb2RfKGhhLGFhPW51bGwseGE9ITEpe2xldCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInByb2QiKTtiYS5kdHlwZT09PSJib29sIiYmKGJhPWNhc3QkNShiYSwiaW50MzIiKSk7Y29uc3QgU2E9e3g6YmF9LFRhPXtheGlzOmFhLGtlZXBEaW1zOnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFByb2QkMSxTYSxUYSl9Y29uc3QgcHJvZCQzPW9wJDEoe3Byb2RffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFnZ2VkR2F0aGVyXyhoYSxhYSx4YSxiYSl7Y29uc3QgU2E9aGEubWFwKChGYSxMYSk9PmNvbnZlcnRUb1RlbnNvciQxKEZhLGB0ZW5zb3JzJHtMYX1gLCJyYWdnZWRHYXRoZXIiLCJpbnQzMiIpKSxUYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwicGFyYW1zRGVuc2VWYWx1ZXMiLCJyYWdnZWRHYXRoZXIiKSx3YT1jb252ZXJ0VG9UZW5zb3IkMSh4YSwiaW5kaWNlcyIsInJhZ2dlZEdhdGhlciIsImludDMyIiksRWE9e3BhcmFtc05lc3RlZFNwbGl0czpTYSxwYXJhbXNEZW5zZVZhbHVlczpUYSxpbmRpY2VzOndhfSxrYT17b3V0cHV0UmFnZ2VkUmFuazpiYX0sQWE9RU5HSU5FJDEucnVuS2VybmVsKFJhZ2dlZEdhdGhlciQxLEVhLGthKTtyZXR1cm57b3V0cHV0TmVzdGVkU3BsaXRzOkFhLnNsaWNlKDAsQWEubGVuZ3RoLTEpLG91dHB1dERlbnNlVmFsdWVzOkFhW0FhLmxlbmd0aC0xXX19Y29uc3QgcmFnZ2VkR2F0aGVyJDM9b3AkMSh7cmFnZ2VkR2F0aGVyX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhZ2dlZFJhbmdlXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsInN0YXJ0cyIsInJhZ2dlZFJhbmdlIiksU2E9Y29udmVydFRvVGVuc29yJDEoYWEsImxpbWl0cyIsInJhZ2dlZFJhbmdlIixiYS5kdHlwZSksVGE9Y29udmVydFRvVGVuc29yJDEoeGEsImRlbHRhcyIsInJhZ2dlZFJhbmdlIixiYS5kdHlwZSksd2E9e3N0YXJ0czpiYSxsaW1pdHM6U2EsZGVsdGFzOlRhfSxFYT1FTkdJTkUkMS5ydW5LZXJuZWwoUmFnZ2VkUmFuZ2UkMSx3YSk7cmV0dXJue3J0TmVzdGVkU3BsaXRzOkVhWzBdLHJ0RGVuc2VWYWx1ZXM6RWFbMV19fWNvbnN0IHJhZ2dlZFJhbmdlJDM9b3AkMSh7cmFnZ2VkUmFuZ2VffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFnZ2VkVGVuc29yVG9UZW5zb3JfKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwic2hhcGUiLCJyYWdnZWRUZW5zb3JUb1RlbnNvciIsImludDMyIiksd2E9Y29udmVydFRvVGVuc29yJDEoYWEsInZhbHVlcyIsInJhZ2dlZFRlbnNvclRvVGVuc29yIiksRWE9Y29udmVydFRvVGVuc29yJDEoeGEsImRlZmF1bHRWYWx1ZSIsInJhZ2dlZFRlbnNvclRvVGVuc29yIix3YS5kdHlwZSksa2E9YmEubWFwKChMYSxlbCk9PmNvbnZlcnRUb1RlbnNvciQxKExhLGB0ZW5zb3JzJHtlbH1gLCJyYWdnZWRUZW5zb3JUb1RlbnNvciIsImludDMyIikpLEFhPXtzaGFwZTpUYSx2YWx1ZXM6d2EsZGVmYXVsdFZhbHVlOkVhLHJvd1BhcnRpdGlvblRlbnNvcnM6a2F9LEZhPXtyb3dQYXJ0aXRpb25UeXBlczpTYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChSYWdnZWRUZW5zb3JUb1RlbnNvciQxLEFhLEZhKX1jb25zdCByYWdnZWRUZW5zb3JUb1RlbnNvciQzPW9wJDEoe3JhZ2dlZFRlbnNvclRvVGVuc29yX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhbmRfKGhhLGFhLHhhKXthc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zJDEoaGEpO2NvbnN0IGJhPXNpemVGcm9tU2hhcGUkMShoYSk7bGV0IFNhPW51bGw7aWYoeGE9PW51bGx8fHhhPT09ImZsb2F0MzIiKVNhPW5ldyBGbG9hdDMyQXJyYXkoYmEpO2Vsc2UgaWYoeGE9PT0iaW50MzIiKVNhPW5ldyBJbnQzMkFycmF5KGJhKTtlbHNlIGlmKHhhPT09ImJvb2wiKVNhPW5ldyBVaW50OEFycmF5KGJhKTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhIHR5cGUgJHt4YX1gKTtmb3IobGV0IFRhPTA7VGE8YmE7VGErKylTYVtUYV09YWEoKTtyZXR1cm4gRU5HSU5FJDEubWFrZVRlbnNvcihTYSxoYSx4YSl9Y29uc3QgcmFuZD1vcCQxKHtyYW5kX30pO3ZhciBhbGVhJDE9e2V4cG9ydHM6e319O2FsZWEkMS5leHBvcnRzLGZ1bmN0aW9uKGhhKXsoZnVuY3Rpb24oYWEseGEsYmEpe2Z1bmN0aW9uIFNhKGthKXt2YXIgQWE9dGhpcyxGYT1FYSgpO0FhLm5leHQ9ZnVuY3Rpb24oKXt2YXIgTGE9MjA5MTYzOSpBYS5zMCtBYS5jKjIzMjgzMDY0MzY1Mzg2OTYzZS0yNjtyZXR1cm4gQWEuczA9QWEuczEsQWEuczE9QWEuczIsQWEuczI9TGEtKEFhLmM9TGF8MCl9LEFhLmM9MSxBYS5zMD1GYSgiICIpLEFhLnMxPUZhKCIgIiksQWEuczI9RmEoIiAiKSxBYS5zMC09RmEoa2EpLEFhLnMwPDAmJihBYS5zMCs9MSksQWEuczEtPUZhKGthKSxBYS5zMTwwJiYoQWEuczErPTEpLEFhLnMyLT1GYShrYSksQWEuczI8MCYmKEFhLnMyKz0xKSxGYT1udWxsfWZ1bmN0aW9uIFRhKGthLEFhKXtyZXR1cm4gQWEuYz1rYS5jLEFhLnMwPWthLnMwLEFhLnMxPWthLnMxLEFhLnMyPWthLnMyLEFhfWZ1bmN0aW9uIHdhKGthLEFhKXt2YXIgRmE9bmV3IFNhKGthKSxMYT1BYSYmQWEuc3RhdGUsZWw9RmEubmV4dDtyZXR1cm4gZWwuaW50MzI9ZnVuY3Rpb24oKXtyZXR1cm4gRmEubmV4dCgpKjQyOTQ5NjcyOTZ8MH0sZWwuZG91YmxlPWZ1bmN0aW9uKCl7cmV0dXJuIGVsKCkrKGVsKCkqMjA5NzE1MnwwKSoxMTEwMjIzMDI0NjI1MTU2NWUtMzJ9LGVsLnF1aWNrPWVsLExhJiYodHlwZW9mIExhPT0ib2JqZWN0IiYmVGEoTGEsRmEpLGVsLnN0YXRlPWZ1bmN0aW9uKCl7cmV0dXJuIFRhKEZhLHt9KX0pLGVsfWZ1bmN0aW9uIEVhKCl7dmFyIGthPTQwMjI4NzExOTcsQWE9ZnVuY3Rpb24oRmEpe0ZhPVN0cmluZyhGYSk7Zm9yKHZhciBMYT0wO0xhPEZhLmxlbmd0aDtMYSsrKXtrYSs9RmEuY2hhckNvZGVBdChMYSk7dmFyIGVsPS4wMjUxOTYwMzI4MjQxNjkzOCprYTtrYT1lbD4+PjAsZWwtPWthLGVsKj1rYSxrYT1lbD4+PjAsZWwtPWthLGthKz1lbCo0Mjk0OTY3Mjk2fXJldHVybihrYT4+PjApKjIzMjgzMDY0MzY1Mzg2OTYzZS0yNn07cmV0dXJuIEFhfXhhJiZ4YS5leHBvcnRzP3hhLmV4cG9ydHM9d2E6dGhpcy5hbGVhPXdhfSkoY29tbW9uanNHbG9iYWwsaGEpfShhbGVhJDEpO3ZhciBhbGVhRXhwb3J0cz1hbGVhJDEuZXhwb3J0cyx4b3IxMjgkMT17ZXhwb3J0czp7fX07eG9yMTI4JDEuZXhwb3J0cyxmdW5jdGlvbihoYSl7KGZ1bmN0aW9uKGFhLHhhLGJhKXtmdW5jdGlvbiBTYShFYSl7dmFyIGthPXRoaXMsQWE9IiI7a2EueD0wLGthLnk9MCxrYS56PTAsa2Eudz0wLGthLm5leHQ9ZnVuY3Rpb24oKXt2YXIgTGE9a2EueF5rYS54PDwxMTtyZXR1cm4ga2EueD1rYS55LGthLnk9a2EueixrYS56PWthLncsa2Eud149a2Eudz4+PjE5XkxhXkxhPj4+OH0sRWE9PT0oRWF8MCk/a2EueD1FYTpBYSs9RWE7Zm9yKHZhciBGYT0wO0ZhPEFhLmxlbmd0aCs2NDtGYSsrKWthLnhePUFhLmNoYXJDb2RlQXQoRmEpfDAsa2EubmV4dCgpfWZ1bmN0aW9uIFRhKEVhLGthKXtyZXR1cm4ga2EueD1FYS54LGthLnk9RWEueSxrYS56PUVhLnosa2Eudz1FYS53LGthfWZ1bmN0aW9uIHdhKEVhLGthKXt2YXIgQWE9bmV3IFNhKEVhKSxGYT1rYSYma2Euc3RhdGUsTGE9ZnVuY3Rpb24oKXtyZXR1cm4oQWEubmV4dCgpPj4+MCkvNDI5NDk2NzI5Nn07cmV0dXJuIExhLmRvdWJsZT1mdW5jdGlvbigpe2RvIHZhciBlbD1BYS5uZXh0KCk+Pj4xMSx0bD0oQWEubmV4dCgpPj4+MCkvNDI5NDk2NzI5NixubD0oZWwrdGwpLygxPDwyMSk7d2hpbGUobmw9PT0wKTtyZXR1cm4gbmx9LExhLmludDMyPUFhLm5leHQsTGEucXVpY2s9TGEsRmEmJih0eXBlb2YgRmE9PSJvYmplY3QiJiZUYShGYSxBYSksTGEuc3RhdGU9ZnVuY3Rpb24oKXtyZXR1cm4gVGEoQWEse30pfSksTGF9eGEmJnhhLmV4cG9ydHM/eGEuZXhwb3J0cz13YTp0aGlzLnhvcjEyOD13YX0pKGNvbW1vbmpzR2xvYmFsLGhhKX0oeG9yMTI4JDEpO3ZhciB4b3IxMjhFeHBvcnRzPXhvcjEyOCQxLmV4cG9ydHMseG9yd293JDE9e2V4cG9ydHM6e319O3hvcndvdyQxLmV4cG9ydHMsZnVuY3Rpb24oaGEpeyhmdW5jdGlvbihhYSx4YSxiYSl7ZnVuY3Rpb24gU2EoRWEpe3ZhciBrYT10aGlzLEFhPSIiO2thLm5leHQ9ZnVuY3Rpb24oKXt2YXIgTGE9a2EueF5rYS54Pj4+MjtyZXR1cm4ga2EueD1rYS55LGthLnk9a2EueixrYS56PWthLncsa2Eudz1rYS52LChrYS5kPWthLmQrMzYyNDM3fDApKyhrYS52PWthLnZea2Eudjw8NF4oTGFeTGE8PDEpKXwwfSxrYS54PTAsa2EueT0wLGthLno9MCxrYS53PTAsa2Eudj0wLEVhPT09KEVhfDApP2thLng9RWE6QWErPUVhO2Zvcih2YXIgRmE9MDtGYTxBYS5sZW5ndGgrNjQ7RmErKylrYS54Xj1BYS5jaGFyQ29kZUF0KEZhKXwwLEZhPT1BYS5sZW5ndGgmJihrYS5kPWthLng8PDEwXmthLng+Pj40KSxrYS5uZXh0KCl9ZnVuY3Rpb24gVGEoRWEsa2Epe3JldHVybiBrYS54PUVhLngsa2EueT1FYS55LGthLno9RWEueixrYS53PUVhLncsa2Eudj1FYS52LGthLmQ9RWEuZCxrYX1mdW5jdGlvbiB3YShFYSxrYSl7dmFyIEFhPW5ldyBTYShFYSksRmE9a2EmJmthLnN0YXRlLExhPWZ1bmN0aW9uKCl7cmV0dXJuKEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTZ9O3JldHVybiBMYS5kb3VibGU9ZnVuY3Rpb24oKXtkbyB2YXIgZWw9QWEubmV4dCgpPj4+MTEsdGw9KEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTYsbmw9KGVsK3RsKS8oMTw8MjEpO3doaWxlKG5sPT09MCk7cmV0dXJuIG5sfSxMYS5pbnQzMj1BYS5uZXh0LExhLnF1aWNrPUxhLEZhJiYodHlwZW9mIEZhPT0ib2JqZWN0IiYmVGEoRmEsQWEpLExhLnN0YXRlPWZ1bmN0aW9uKCl7cmV0dXJuIFRhKEFhLHt9KX0pLExhfXhhJiZ4YS5leHBvcnRzP3hhLmV4cG9ydHM9d2E6dGhpcy54b3J3b3c9d2F9KShjb21tb25qc0dsb2JhbCxoYSl9KHhvcndvdyQxKTt2YXIgeG9yd293RXhwb3J0cz14b3J3b3ckMS5leHBvcnRzLHhvcnNoaWZ0NyQxPXtleHBvcnRzOnt9fTt4b3JzaGlmdDckMS5leHBvcnRzLGZ1bmN0aW9uKGhhKXsoZnVuY3Rpb24oYWEseGEsYmEpe2Z1bmN0aW9uIFNhKEVhKXt2YXIga2E9dGhpcztrYS5uZXh0PWZ1bmN0aW9uKCl7dmFyIEZhPWthLngsTGE9a2EuaSxlbCx0bDtyZXR1cm4gZWw9RmFbTGFdLGVsXj1lbD4+PjcsdGw9ZWxeZWw8PDI0LGVsPUZhW0xhKzEmN10sdGxePWVsXmVsPj4+MTAsZWw9RmFbTGErMyY3XSx0bF49ZWxeZWw+Pj4zLGVsPUZhW0xhKzQmN10sdGxePWVsXmVsPDw3LGVsPUZhW0xhKzcmN10sZWw9ZWxeZWw8PDEzLHRsXj1lbF5lbDw8OSxGYVtMYV09dGwsa2EuaT1MYSsxJjcsdGx9O2Z1bmN0aW9uIEFhKEZhLExhKXt2YXIgZWwsdGw9W107aWYoTGE9PT0oTGF8MCkpdGxbMF09TGE7ZWxzZSBmb3IoTGE9IiIrTGEsZWw9MDtlbDxMYS5sZW5ndGg7KytlbCl0bFtlbCY3XT10bFtlbCY3XTw8MTVeTGEuY2hhckNvZGVBdChlbCkrdGxbZWwrMSY3XTw8MTM7Zm9yKDt0bC5sZW5ndGg8ODspdGwucHVzaCgwKTtmb3IoZWw9MDtlbDw4JiZ0bFtlbF09PT0wOysrZWwpO2ZvcihlbD09OD90bFs3XT0tMTp0bFtlbF0sRmEueD10bCxGYS5pPTAsZWw9MjU2O2VsPjA7LS1lbClGYS5uZXh0KCl9QWEoa2EsRWEpfWZ1bmN0aW9uIFRhKEVhLGthKXtyZXR1cm4ga2EueD1FYS54LnNsaWNlKCksa2EuaT1FYS5pLGthfWZ1bmN0aW9uIHdhKEVhLGthKXtFYT09bnVsbCYmKEVhPStuZXcgRGF0ZSk7dmFyIEFhPW5ldyBTYShFYSksRmE9a2EmJmthLnN0YXRlLExhPWZ1bmN0aW9uKCl7cmV0dXJuKEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTZ9O3JldHVybiBMYS5kb3VibGU9ZnVuY3Rpb24oKXtkbyB2YXIgZWw9QWEubmV4dCgpPj4+MTEsdGw9KEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTYsbmw9KGVsK3RsKS8oMTw8MjEpO3doaWxlKG5sPT09MCk7cmV0dXJuIG5sfSxMYS5pbnQzMj1BYS5uZXh0LExhLnF1aWNrPUxhLEZhJiYoRmEueCYmVGEoRmEsQWEpLExhLnN0YXRlPWZ1bmN0aW9uKCl7cmV0dXJuIFRhKEFhLHt9KX0pLExhfXhhJiZ4YS5leHBvcnRzP3hhLmV4cG9ydHM9d2E6dGhpcy54b3JzaGlmdDc9d2F9KShjb21tb25qc0dsb2JhbCxoYSl9KHhvcnNoaWZ0NyQxKTt2YXIgeG9yc2hpZnQ3RXhwb3J0cz14b3JzaGlmdDckMS5leHBvcnRzLHhvcjQwOTYkMT17ZXhwb3J0czp7fX07eG9yNDA5NiQxLmV4cG9ydHMsZnVuY3Rpb24oaGEpeyhmdW5jdGlvbihhYSx4YSxiYSl7ZnVuY3Rpb24gU2EoRWEpe3ZhciBrYT10aGlzO2thLm5leHQ9ZnVuY3Rpb24oKXt2YXIgRmE9a2EudyxMYT1rYS5YLGVsPWthLmksdGwsbmw7cmV0dXJuIGthLnc9RmE9RmErMTY0MDUzMTUyN3wwLG5sPUxhW2VsKzM0JjEyN10sdGw9TGFbZWw9ZWwrMSYxMjddLG5sXj1ubDw8MTMsdGxePXRsPDwxNyxubF49bmw+Pj4xNSx0bF49dGw+Pj4xMixubD1MYVtlbF09bmxedGwsa2EuaT1lbCxubCsoRmFeRmE+Pj4xNil8MH07ZnVuY3Rpb24gQWEoRmEsTGEpe3ZhciBlbCx0bCxubCxzbCxybCxvbD1bXSxhbD0xMjg7Zm9yKExhPT09KExhfDApPyh0bD1MYSxMYT1udWxsKTooTGE9TGErIlwwIix0bD0wLGFsPU1hdGgubWF4KGFsLExhLmxlbmd0aCkpLG5sPTAsc2w9LTMyO3NsPGFsOysrc2wpTGEmJih0bF49TGEuY2hhckNvZGVBdCgoc2wrMzIpJUxhLmxlbmd0aCkpLHNsPT09MCYmKHJsPXRsKSx0bF49dGw8PDEwLHRsXj10bD4+PjE1LHRsXj10bDw8NCx0bF49dGw+Pj4xMyxzbD49MCYmKHJsPXJsKzE2NDA1MzE1Mjd8MCxlbD1vbFtzbCYxMjddXj10bCtybCxubD1lbD09MD9ubCsxOjApO2ZvcihubD49MTI4JiYob2xbKExhJiZMYS5sZW5ndGh8fDApJjEyN109LTEpLG5sPTEyNyxzbD00KjEyODtzbD4wOy0tc2wpdGw9b2xbbmwrMzQmMTI3XSxlbD1vbFtubD1ubCsxJjEyN10sdGxePXRsPDwxMyxlbF49ZWw8PDE3LHRsXj10bD4+PjE1LGVsXj1lbD4+PjEyLG9sW25sXT10bF5lbDtGYS53PXJsLEZhLlg9b2wsRmEuaT1ubH1BYShrYSxFYSl9ZnVuY3Rpb24gVGEoRWEsa2Epe3JldHVybiBrYS5pPUVhLmksa2Eudz1FYS53LGthLlg9RWEuWC5zbGljZSgpLGthfWZ1bmN0aW9uIHdhKEVhLGthKXtFYT09bnVsbCYmKEVhPStuZXcgRGF0ZSk7dmFyIEFhPW5ldyBTYShFYSksRmE9a2EmJmthLnN0YXRlLExhPWZ1bmN0aW9uKCl7cmV0dXJuKEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTZ9O3JldHVybiBMYS5kb3VibGU9ZnVuY3Rpb24oKXtkbyB2YXIgZWw9QWEubmV4dCgpPj4+MTEsdGw9KEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTYsbmw9KGVsK3RsKS8oMTw8MjEpO3doaWxlKG5sPT09MCk7cmV0dXJuIG5sfSxMYS5pbnQzMj1BYS5uZXh0LExhLnF1aWNrPUxhLEZhJiYoRmEuWCYmVGEoRmEsQWEpLExhLnN0YXRlPWZ1bmN0aW9uKCl7cmV0dXJuIFRhKEFhLHt9KX0pLExhfXhhJiZ4YS5leHBvcnRzP3hhLmV4cG9ydHM9d2E6dGhpcy54b3I0MDk2PXdhfSkoY29tbW9uanNHbG9iYWwsaGEpfSh4b3I0MDk2JDEpO3ZhciB4b3I0MDk2RXhwb3J0cz14b3I0MDk2JDEuZXhwb3J0cyx0eWNoZWkkMT17ZXhwb3J0czp7fX07dHljaGVpJDEuZXhwb3J0cyxmdW5jdGlvbihoYSl7KGZ1bmN0aW9uKGFhLHhhLGJhKXtmdW5jdGlvbiBTYShFYSl7dmFyIGthPXRoaXMsQWE9IiI7a2EubmV4dD1mdW5jdGlvbigpe3ZhciBMYT1rYS5iLGVsPWthLmMsdGw9a2EuZCxubD1rYS5hO3JldHVybiBMYT1MYTw8MjVeTGE+Pj43XmVsLGVsPWVsLXRsfDAsdGw9dGw8PDI0XnRsPj4+OF5ubCxubD1ubC1MYXwwLGthLmI9TGE9TGE8PDIwXkxhPj4+MTJeZWwsa2EuYz1lbD1lbC10bHwwLGthLmQ9dGw8PDE2XmVsPj4+MTZebmwsa2EuYT1ubC1MYXwwfSxrYS5hPTAsa2EuYj0wLGthLmM9LTE2NDA1MzE1Mjcsa2EuZD0xMzY3MTMwNTUxLEVhPT09TWF0aC5mbG9vcihFYSk/KGthLmE9RWEvNDI5NDk2NzI5NnwwLGthLmI9RWF8MCk6QWErPUVhO2Zvcih2YXIgRmE9MDtGYTxBYS5sZW5ndGgrMjA7RmErKylrYS5iXj1BYS5jaGFyQ29kZUF0KEZhKXwwLGthLm5leHQoKX1mdW5jdGlvbiBUYShFYSxrYSl7cmV0dXJuIGthLmE9RWEuYSxrYS5iPUVhLmIsa2EuYz1FYS5jLGthLmQ9RWEuZCxrYX1mdW5jdGlvbiB3YShFYSxrYSl7dmFyIEFhPW5ldyBTYShFYSksRmE9a2EmJmthLnN0YXRlLExhPWZ1bmN0aW9uKCl7cmV0dXJuKEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTZ9O3JldHVybiBMYS5kb3VibGU9ZnVuY3Rpb24oKXtkbyB2YXIgZWw9QWEubmV4dCgpPj4+MTEsdGw9KEFhLm5leHQoKT4+PjApLzQyOTQ5NjcyOTYsbmw9KGVsK3RsKS8oMTw8MjEpO3doaWxlKG5sPT09MCk7cmV0dXJuIG5sfSxMYS5pbnQzMj1BYS5uZXh0LExhLnF1aWNrPUxhLEZhJiYodHlwZW9mIEZhPT0ib2JqZWN0IiYmVGEoRmEsQWEpLExhLnN0YXRlPWZ1bmN0aW9uKCl7cmV0dXJuIFRhKEFhLHt9KX0pLExhfXhhJiZ4YS5leHBvcnRzP3hhLmV4cG9ydHM9d2E6dGhpcy50eWNoZWk9d2F9KShjb21tb25qc0dsb2JhbCxoYSl9KHR5Y2hlaSQxKTt2YXIgdHljaGVpRXhwb3J0cz10eWNoZWkkMS5leHBvcnRzLHNlZWRyYW5kb20kMT17ZXhwb3J0czp7fX0sX192aXRlQnJvd3NlckV4dGVybmFsPXt9LF9fdml0ZUJyb3dzZXJFeHRlcm5hbCQxPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGRlZmF1bHQ6X192aXRlQnJvd3NlckV4dGVybmFsfSkscmVxdWlyZSQkMD1nZXRBdWdtZW50ZWROYW1lc3BhY2UoX192aXRlQnJvd3NlckV4dGVybmFsJDEpOyhmdW5jdGlvbihoYSl7KGZ1bmN0aW9uKGFhLHhhLGJhKXt2YXIgU2E9MjU2LFRhPTYsd2E9NTIsRWE9InJhbmRvbSIsa2E9YmEucG93KFNhLFRhKSxBYT1iYS5wb3coMix3YSksRmE9QWEqMixMYT1TYS0xLGVsO2Z1bmN0aW9uIHRsKGlsLGNsLHVsKXt2YXIgZGw9W107Y2w9Y2w9PSEwP3tlbnRyb3B5OiEwfTpjbHx8e307dmFyIGhsPW9sKHJsKGNsLmVudHJvcHk/W2lsLGxsKHhhKV06aWw/P2FsKCksMyksZGwpLHBsPW5ldyBubChkbCksZmw9ZnVuY3Rpb24oKXtmb3IodmFyIG1sPXBsLmcoVGEpLGdsPWthLCRsPTA7bWw8QWE7KW1sPShtbCskbCkqU2EsZ2wqPVNhLCRsPXBsLmcoMSk7Zm9yKDttbD49RmE7KW1sLz0yLGdsLz0yLCRsPj4+PTE7cmV0dXJuKG1sKyRsKS9nbH07cmV0dXJuIGZsLmludDMyPWZ1bmN0aW9uKCl7cmV0dXJuIHBsLmcoNCl8MH0sZmwucXVpY2s9ZnVuY3Rpb24oKXtyZXR1cm4gcGwuZyg0KS80Mjk0OTY3Mjk2fSxmbC5kb3VibGU9Zmwsb2wobGwocGwuUykseGEpLChjbC5wYXNzfHx1bHx8ZnVuY3Rpb24obWwsZ2wsJGwseGwpe3JldHVybiB4bCYmKHhsLlMmJnNsKHhsLHBsKSxtbC5zdGF0ZT1mdW5jdGlvbigpe3JldHVybiBzbChwbCx7fSl9KSwkbD8oYmFbRWFdPW1sLGdsKTptbH0pKGZsLGhsLCJnbG9iYWwiaW4gY2w/Y2wuZ2xvYmFsOnRoaXM9PWJhLGNsLnN0YXRlKX1mdW5jdGlvbiBubChpbCl7dmFyIGNsLHVsPWlsLmxlbmd0aCxkbD10aGlzLGhsPTAscGw9ZGwuaT1kbC5qPTAsZmw9ZGwuUz1bXTtmb3IodWx8fChpbD1bdWwrK10pO2hsPFNhOylmbFtobF09aGwrKztmb3IoaGw9MDtobDxTYTtobCsrKWZsW2hsXT1mbFtwbD1MYSZwbCtpbFtobCV1bF0rKGNsPWZsW2hsXSldLGZsW3BsXT1jbDsoZGwuZz1mdW5jdGlvbihtbCl7Zm9yKHZhciBnbCwkbD0wLHhsPWRsLmkseWw9ZGwuaixibD1kbC5TO21sLS07KWdsPWJsW3hsPUxhJnhsKzFdLCRsPSRsKlNhK2JsW0xhJihibFt4bF09YmxbeWw9TGEmeWwrZ2xdKSsoYmxbeWxdPWdsKV07cmV0dXJuIGRsLmk9eGwsZGwuaj15bCwkbH0pKFNhKX1mdW5jdGlvbiBzbChpbCxjbCl7cmV0dXJuIGNsLmk9aWwuaSxjbC5qPWlsLmosY2wuUz1pbC5TLnNsaWNlKCksY2x9ZnVuY3Rpb24gcmwoaWwsY2wpe3ZhciB1bD1bXSxkbD10eXBlb2YgaWwsaGw7aWYoY2wmJmRsPT0ib2JqZWN0Iilmb3IoaGwgaW4gaWwpdHJ5e3VsLnB1c2gocmwoaWxbaGxdLGNsLTEpKX1jYXRjaHt9cmV0dXJuIHVsLmxlbmd0aD91bDpkbD09InN0cmluZyI/aWw6aWwrIlwwIn1mdW5jdGlvbiBvbChpbCxjbCl7Zm9yKHZhciB1bD1pbCsiIixkbCxobD0wO2hsPHVsLmxlbmd0aDspY2xbTGEmaGxdPUxhJihkbF49Y2xbTGEmaGxdKjE5KSt1bC5jaGFyQ29kZUF0KGhsKyspO3JldHVybiBsbChjbCl9ZnVuY3Rpb24gYWwoKXt0cnl7dmFyIGlsO3JldHVybiBlbCYmKGlsPWVsLnJhbmRvbUJ5dGVzKT9pbD1pbChTYSk6KGlsPW5ldyBVaW50OEFycmF5KFNhKSwoYWEuY3J5cHRvfHxhYS5tc0NyeXB0bykuZ2V0UmFuZG9tVmFsdWVzKGlsKSksbGwoaWwpfWNhdGNoe3ZhciBjbD1hYS5uYXZpZ2F0b3IsdWw9Y2wmJmNsLnBsdWdpbnM7cmV0dXJuWytuZXcgRGF0ZSxhYSx1bCxhYS5zY3JlZW4sbGwoeGEpXX19ZnVuY3Rpb24gbGwoaWwpe3JldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KDAsaWwpfWlmKG9sKGJhLnJhbmRvbSgpLHhhKSxoYS5leHBvcnRzKXtoYS5leHBvcnRzPXRsO3RyeXtlbD1yZXF1aXJlJCQwfWNhdGNoe319ZWxzZSBiYVsic2VlZCIrRWFdPXRsfSkodHlwZW9mIHNlbGY8InUiP3NlbGY6Y29tbW9uanNHbG9iYWwsW10sTWF0aCl9KShzZWVkcmFuZG9tJDEpO3ZhciBzZWVkcmFuZG9tRXhwb3J0cz1zZWVkcmFuZG9tJDEuZXhwb3J0cyxhbGVhPWFsZWFFeHBvcnRzLHhvcjEyOD14b3IxMjhFeHBvcnRzLHhvcndvdz14b3J3b3dFeHBvcnRzLHhvcnNoaWZ0Nz14b3JzaGlmdDdFeHBvcnRzLHhvcjQwOTY9eG9yNDA5NkV4cG9ydHMsdHljaGVpPXR5Y2hlaUV4cG9ydHMsc3IkMT1zZWVkcmFuZG9tRXhwb3J0cztzciQxLmFsZWE9YWxlYSxzciQxLnhvcjEyOD14b3IxMjgsc3IkMS54b3J3b3c9eG9yd293LHNyJDEueG9yc2hpZnQ3PXhvcnNoaWZ0NyxzciQxLnhvcjQwOTY9eG9yNDA5NixzciQxLnR5Y2hlaT10eWNoZWk7dmFyIHNlZWRyYW5kb209c3IkMTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBNUFJhbmRHYXVzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy5tZWFuPWFhLHRoaXMuc3RkRGV2PXhhLHRoaXMuZHR5cGU9YmEsdGhpcy5uZXh0VmFsPU5hTix0aGlzLnRydW5jYXRlZD1TYSx0aGlzLnRydW5jYXRlZCYmKHRoaXMudXBwZXI9dGhpcy5tZWFuK3RoaXMuc3RkRGV2KjIsdGhpcy5sb3dlcj10aGlzLm1lYW4tdGhpcy5zdGREZXYqMik7Y29uc3Qgd2E9VGF8fE1hdGgucmFuZG9tKCk7dGhpcy5yYW5kb209c2VlZHJhbmRvbS5hbGVhKHdhLnRvU3RyaW5nKCkpfW5leHRWYWx1ZSgpe2lmKCFpc05hTih0aGlzLm5leHRWYWwpKXtjb25zdCBTYT10aGlzLm5leHRWYWw7cmV0dXJuIHRoaXMubmV4dFZhbD1OYU4sU2F9bGV0IGFhLHhhLGJhPSExO2Zvcig7IWJhOyl7bGV0IFNhLFRhLHdhO2RvIFNhPTIqdGhpcy5yYW5kb20oKS0xLFRhPTIqdGhpcy5yYW5kb20oKS0xLHdhPVNhKlNhK1RhKlRhO3doaWxlKHdhPj0xfHx3YT09PTApO2NvbnN0IEVhPU1hdGguc3FydCgtMipNYXRoLmxvZyh3YSkvd2EpO2FhPXRoaXMubWVhbit0aGlzLnN0ZERldipTYSpFYSx4YT10aGlzLm1lYW4rdGhpcy5zdGREZXYqVGEqRWEsKCF0aGlzLnRydW5jYXRlZHx8dGhpcy5pc1ZhbGlkVHJ1bmNhdGVkKGFhKSkmJihiYT0hMCl9cmV0dXJuKCF0aGlzLnRydW5jYXRlZHx8dGhpcy5pc1ZhbGlkVHJ1bmNhdGVkKHhhKSkmJih0aGlzLm5leHRWYWw9dGhpcy5jb252ZXJ0VmFsdWUoeGEpKSx0aGlzLmNvbnZlcnRWYWx1ZShhYSl9Y29udmVydFZhbHVlKGFhKXtyZXR1cm4gdGhpcy5kdHlwZT09bnVsbHx8dGhpcy5kdHlwZT09PSJmbG9hdDMyIj9hYTpNYXRoLnJvdW5kKGFhKX1pc1ZhbGlkVHJ1bmNhdGVkKGFhKXtyZXR1cm4gYWE8PXRoaXMudXBwZXImJmFhPj10aGlzLmxvd2VyfX1jbGFzcyBSYW5kR2FtbWF7Y29uc3RydWN0b3IoYWEseGEsYmEsU2Epe3RoaXMuYWxwaGE9YWEsdGhpcy5iZXRhPTEveGEsdGhpcy5kdHlwZT1iYTtjb25zdCBUYT1TYXx8TWF0aC5yYW5kb20oKTt0aGlzLnJhbmR1PXNlZWRyYW5kb20uYWxlYShUYS50b1N0cmluZygpKSx0aGlzLnJhbmRuPW5ldyBNUFJhbmRHYXVzcygwLDEsYmEsITEsdGhpcy5yYW5kdSgpKSxhYTwxP3RoaXMuZD1hYSsyLzM6dGhpcy5kPWFhLTEvMyx0aGlzLmM9MS9NYXRoLnNxcnQoOSp0aGlzLmQpfW5leHRWYWx1ZSgpe2xldCBhYSx4YSxiYSxTYSxUYSx3YTtmb3IoOzspe2RvIFNhPXRoaXMucmFuZG4ubmV4dFZhbHVlKCksd2E9MSt0aGlzLmMqU2E7d2hpbGUod2E8PTApO2lmKHdhKj13YSp3YSxhYT1TYSpTYSx4YT0xLS4zMzEqYWEqYWEsYmE9LjUqYWErdGhpcy5kKigxLXdhK01hdGgubG9nKHdhKSksVGE9dGhpcy5yYW5kdSgpLFRhPHhhfHxNYXRoLmxvZyhUYSk8YmEpYnJlYWt9cmV0dXJuIHdhPTEvdGhpcy5iZXRhKnRoaXMuZCp3YSx0aGlzLmFscGhhPDEmJih3YSo9TWF0aC5wb3codGhpcy5yYW5kdSgpLDEvdGhpcy5hbHBoYSkpLHRoaXMuY29udmVydFZhbHVlKHdhKX1jb252ZXJ0VmFsdWUoYWEpe3JldHVybiB0aGlzLmR0eXBlPT09ImZsb2F0MzIiP2FhOk1hdGgucm91bmQoYWEpfX1jbGFzcyBVbmlmb3JtUmFuZG9te2NvbnN0cnVjdG9yKGFhPTAseGE9MSxiYSxTYSl7aWYodGhpcy5jYW5SZXR1cm5GbG9hdD0oKT0+dGhpcy5kdHlwZT09bnVsbHx8dGhpcy5kdHlwZT09PSJmbG9hdDMyIix0aGlzLm1pbj1hYSx0aGlzLnJhbmdlPXhhLWFhLHRoaXMuZHR5cGU9YmEsU2E9PW51bGwmJihTYT1NYXRoLnJhbmRvbSgpKSx0eXBlb2YgU2E9PSJudW1iZXIiJiYoU2E9U2EudG9TdHJpbmcoKSksIXRoaXMuY2FuUmV0dXJuRmxvYXQoKSYmdGhpcy5yYW5nZTw9MSl0aHJvdyBuZXcgRXJyb3IoYFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJHthYX0gLSAke3hhfSA8PSAxIGFuZCBkdHlwZSBpcyBub3QgZmxvYXRgKTt0aGlzLnJhbmRvbT1zZWVkcmFuZG9tLmFsZWEoU2EpfWNvbnZlcnRWYWx1ZShhYSl7cmV0dXJuIHRoaXMuY2FuUmV0dXJuRmxvYXQoKT9hYTpNYXRoLnJvdW5kKGFhKX1uZXh0VmFsdWUoKXtyZXR1cm4gdGhpcy5jb252ZXJ0VmFsdWUodGhpcy5taW4rdGhpcy5yYW5nZSp0aGlzLnJhbmRvbSgpKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFuZG9tR2FtbWFfKGhhLGFhLHhhPTEsYmE9ImZsb2F0MzIiLFNhKXtpZihhc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zJDEoaGEpLHhhPT1udWxsJiYoeGE9MSksYmE9PW51bGwmJihiYT0iZmxvYXQzMiIpLGJhIT09ImZsb2F0MzIiJiZiYSE9PSJpbnQzMiIpdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGUgJHtiYX1gKTtjb25zdCBUYT1uZXcgUmFuZEdhbW1hKGFhLHhhLGJhLFNhKSx3YT1idWZmZXIkMShoYSxiYSk7Zm9yKGxldCBFYT0wO0VhPHdhLnZhbHVlcy5sZW5ndGg7RWErKyl3YS52YWx1ZXNbRWFdPVRhLm5leHRWYWx1ZSgpO3JldHVybiB3YS50b1RlbnNvcigpfWNvbnN0IHJhbmRvbUdhbW1hPW9wJDEoe3JhbmRvbUdhbW1hX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhbmRvbU5vcm1hbF8oaGEsYWE9MCx4YT0xLGJhLFNhKXtpZihhc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zJDEoaGEpLGJhIT1udWxsJiZiYT09PSJib29sIil0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGRhdGEgdHlwZSAke2JhfWApO2NvbnN0IFRhPW5ldyBNUFJhbmRHYXVzcyhhYSx4YSxiYSwhMSxTYSksd2E9YnVmZmVyJDEoaGEsYmEpO2ZvcihsZXQgRWE9MDtFYTx3YS52YWx1ZXMubGVuZ3RoO0VhKyspd2EudmFsdWVzW0VhXT1UYS5uZXh0VmFsdWUoKTtyZXR1cm4gd2EudG9UZW5zb3IoKX1jb25zdCByYW5kb21Ob3JtYWwkMT1vcCQxKHtyYW5kb21Ob3JtYWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFuZG9tU3RhbmRhcmROb3JtYWxfKGhhLGFhLHhhKXtpZihhYSE9bnVsbCYmYWE9PT0iYm9vbCIpdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGUgJHthYX1gKTtyZXR1cm4gcmFuZG9tTm9ybWFsJDEoaGEsMCwxLGFhLHhhKX1jb25zdCByYW5kb21TdGFuZGFyZE5vcm1hbD1vcCQxKHtyYW5kb21TdGFuZGFyZE5vcm1hbF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByYW5kb21Vbmlmb3JtXyhoYSxhYT0wLHhhPTEsYmE9ImZsb2F0MzIiLFNhKXthc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zJDEoaGEpO2NvbnN0IFRhPWJ1ZmZlciQxKGhhLGJhKSx3YT1uZXcgVW5pZm9ybVJhbmRvbShhYSx4YSxudWxsLFNhKTtmb3IobGV0IEVhPTA7RWE8VGEudmFsdWVzLmxlbmd0aDtFYSsrKVRhLnZhbHVlc1tFYV09d2EubmV4dFZhbHVlKCk7cmV0dXJuIFRhLnRvVGVuc29yKCl9Y29uc3QgcmFuZG9tVW5pZm9ybT1vcCQxKHtyYW5kb21Vbmlmb3JtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhbmRvbVVuaWZvcm1JbnRfKGhhLGFhLHhhLGJhKXtyZXR1cm4gcmFuZG9tVW5pZm9ybShoYSxhYSx4YSwiaW50MzIiLGJhKX1jb25zdCByYW5kb21Vbmlmb3JtSW50PW9wJDEoe3JhbmRvbVVuaWZvcm1JbnRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFuZ2UkNChoYSxhYSx4YT0xLGJhPSJmbG9hdDMyIil7aWYoeGE9PT0wKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IGhhdmUgYSBzdGVwIG9mIHplcm8iKTtjb25zdCBTYT17c3RhcnQ6aGEsc3RvcDphYSxzdGVwOnhhLGR0eXBlOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJhbmdlJDEse30sU2EpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJlYWxfKGhhKXtjb25zdCB4YT17aW5wdXQ6Y29udmVydFRvVGVuc29yJDEoaGEsImlucHV0IiwicmVhbCIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJlYWwkMSx4YSl9Y29uc3QgcmVhbCQzPW9wJDEoe3JlYWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVjaXByb2NhbF8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwicmVjaXByb2NhbCIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJlY2lwcm9jYWwkMSx4YSl9Y29uc3QgcmVjaXByb2NhbCQzPW9wJDEoe3JlY2lwcm9jYWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVsdV8kMShoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJyZWx1Iil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoUmVsdSQyLHhhKX1jb25zdCByZWx1JDQ9b3AkMSh7cmVsdV86cmVsdV8kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJlbHU2XyQxKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInJlbHU2Iil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoUmVsdTYkMix4YSl9Y29uc3QgcmVsdTYkND1vcCQxKHtyZWx1Nl86cmVsdTZfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXZlcnNlXyhoYSxhYSl7Y29uc3QgYmE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJyZXZlcnNlIil9LFNhPXtkaW1zOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJldmVyc2UkMSxiYSxTYSl9Y29uc3QgcmV2ZXJzZSQzPW9wJDEoe3JldmVyc2VffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmV2ZXJzZTFkXyhoYSl7Y29uc3QgYWE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJyZXZlcnNlIik7cmV0dXJuIGFzc2VydCQyKGFhLnJhbms9PT0xLCgpPT5gRXJyb3IgaW4gcmV2ZXJzZTFEOiB4IG11c3QgYmUgcmFuayAxIGJ1dCBnb3QgcmFuayAke2FhLnJhbmt9LmApLHJldmVyc2UkMyhhYSwwKX1jb25zdCByZXZlcnNlMWQ9b3AkMSh7cmV2ZXJzZTFkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJldmVyc2UyZF8oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwicmV2ZXJzZSIpO3JldHVybiBhc3NlcnQkMih4YS5yYW5rPT09MiwoKT0+YEVycm9yIGluIHJldmVyc2UyRDogeCBtdXN0IGJlIHJhbmsgMiBidXQgZ290IHJhbmsgJHt4YS5yYW5rfS5gKSxyZXZlcnNlJDMoeGEsYWEpfWNvbnN0IHJldmVyc2UyZD1vcCQxKHtyZXZlcnNlMmRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmV2ZXJzZTNkXyhoYSxhYSl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJyZXZlcnNlIik7cmV0dXJuIGFzc2VydCQyKHhhLnJhbms9PT0zLCgpPT5gRXJyb3IgaW4gcmV2ZXJzZTNEOiB4IG11c3QgYmUgcmFuayAzIGJ1dCBnb3QgcmFuayAke3hhLnJhbmt9LmApLHJldmVyc2UkMyh4YSxhYSl9Y29uc3QgcmV2ZXJzZTNkPW9wJDEoe3JldmVyc2UzZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXZlcnNlNGRfKGhhLGFhKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInJldmVyc2UiKTtyZXR1cm4gYXNzZXJ0JDIoeGEucmFuaz09PTQsKCk9PmBFcnJvciBpbiByZXZlcnNlNEQ6IHggbXVzdCBiZSByYW5rIDQgYnV0IGdvdCByYW5rICR7eGEucmFua30uYCkscmV2ZXJzZSQzKHhhLGFhKX1jb25zdCByZXZlcnNlNGQ9b3AkMSh7cmV2ZXJzZTRkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJvdW5kXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJyb3VuZCIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJvdW5kJDEseGEpfWNvbnN0IHJvdW5kJDQ9b3AkMSh7cm91bmRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcnNxcnRfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInJzcXJ0IiwiZmxvYXQzMiIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJzcXJ0JDEseGEpfWNvbnN0IHJzcXJ0JDM9b3AkMSh7cnNxcnRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2VsdV8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic2VsdSIpfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFNlbHUkMix4YSl9Y29uc3Qgc2VsdSQzPW9wJDEoe3NlbHVffSk7ZnVuY3Rpb24gc2VwYXJhYmxlQ29udjJkXyhoYSxhYSx4YSxiYSxTYSxUYT1bMSwxXSx3YT0iTkhXQyIpe2NvbnN0IEVhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic2VwYXJhYmxlQ29udjJkIiksa2E9Y29udmVydFRvVGVuc29yJDEoYWEsImRlcHRod2lzZUZpbHRlciIsInNlcGFyYWJsZUNvbnYyZCIpLEFhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJwb2ludHdpc2VGaWx0ZXIiLCJzZXBhcmFibGVDb252MmQiKTtsZXQgRmE9RWEsTGE9ITE7aWYoRWEucmFuaz09PTMmJihMYT0hMCxGYT1yZXNoYXBlJDQoRWEsWzEsRWEuc2hhcGVbMF0sRWEuc2hhcGVbMV0sRWEuc2hhcGVbMl1dKSksd2E9PT0iTkNIVyIpdGhyb3cgbmV3IEVycm9yKCJzZXBhcmFibGVDb252MmQgY3VycmVudGx5IGRvZXMgbm90IHN1cHBvcnQgZGF0YUZvcm1hdCBOQ0hXOyBvbmx5IE5IV0MgaXMgc3VwcG9ydGVkIik7YXNzZXJ0JDIoRmEucmFuaz09PTQsKCk9PmBFcnJvciBpbiBzZXBhcmFibGVDb252MmQ6IGlucHV0IG11c3QgYmUgcmFuayA0LCBidXQgZ290IHJhbmsgJHtGYS5yYW5rfS5gKSxhc3NlcnQkMihrYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIHNlcGFyYWJsZUNvbnYyZDogZGVwdGh3aXNlIGZpbHRlciBtdXN0IGJlIHJhbmsgNCwgYnV0IGdvdCByYW5rICR7a2EucmFua30uYCksYXNzZXJ0JDIoQWEucmFuaz09PTQsKCk9PmBFcnJvciBpbiBzZXBhcmFibGVDb252MmQ6IHBvaW50d2lzZSBmaWx0ZXIgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke2thLnJhbmt9LmApLGFzc2VydCQyKEFhLnNoYXBlWzBdPT09MSwoKT0+YEVycm9yIGluIHNlcGFyYWJsZUNvbnYyZDogdGhlIGZpcnN0IGRpbWVuc2lvbiBvZiBwb2ludHdpc2UgZmlsdGVyICBtdXN0IGJlIDEsIGJ1dCBnb3QgJHtBYS5zaGFwZVswXX0uYCksYXNzZXJ0JDIoQWEuc2hhcGVbMV09PT0xLCgpPT5gRXJyb3IgaW4gc2VwYXJhYmxlQ29udjJkOiB0aGUgc2Vjb25kIGRpbWVuc2lvbiBvZiBwb2ludHdpc2UgZmlsdGVyIG11c3QgYmUgMSwgYnV0IGdvdCAke0FhLnNoYXBlWzFdfS5gKTtjb25zdCBlbD1rYS5zaGFwZVsyXSx0bD1rYS5zaGFwZVszXTthc3NlcnQkMihBYS5zaGFwZVsyXT09PWVsKnRsLCgpPT5gRXJyb3IgaW4gc2VwYXJhYmxlQ29udjJkOiB0aGUgdGhpcmQgZGltZW5zaW9uIG9mIHBvaW50d2lzZSBmaWx0ZXIgbXVzdCBiZSAke2VsKnRsfSwgYnV0IGdvdCAke0FhLnNoYXBlWzJdfS5gKTtjb25zdCBubD1kZXB0aHdpc2VDb252MmQkMihGYSxrYSxiYSxTYSx3YSxUYSkscmw9Y29udjJkJDMobmwsQWEsMSwidmFsaWQiLHdhKTtyZXR1cm4gTGE/cmVzaGFwZSQ0KHJsLFtybC5zaGFwZVsxXSxybC5zaGFwZVsyXSxybC5zaGFwZVszXV0pOnJsfWNvbnN0IHNlcGFyYWJsZUNvbnYyZD1vcCQxKHtzZXBhcmFibGVDb252MmRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovYXN5bmMgZnVuY3Rpb24gc2V0ZGlmZjFkQXN5bmNfKGhhLGFhKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNldGRpZmYxZCIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJ5Iiwic2V0ZGlmZjFkIik7YXNzZXJ0JDIoeGEuZHR5cGU9PT1iYS5kdHlwZSwoKT0+YHggYW5kIHkgc2hvdWxkIGhhdmUgdGhlIHNhbWUgZHR5cGUsIGJ1dCBnb3QgeCAoJHt4YS5kdHlwZX0pIGFuZCB5ICgke2JhLmR0eXBlfSkuYCksYXNzZXJ0JDIoeGEucmFuaz09PTEsKCk9PmB4IHNob3VsZCBiZSAxRCB0ZW5zb3IsIGJ1dCBnb3QgeCAoJHt4YS5zaGFwZX0pLmApLGFzc2VydCQyKGJhLnJhbms9PT0xLCgpPT5geSBzaG91bGQgYmUgMUQgdGVuc29yLCBidXQgZ290IHkgKCR7YmEuc2hhcGV9KS5gKTtjb25zdCBTYT1hd2FpdCB4YS5kYXRhKCksVGE9YXdhaXQgYmEuZGF0YSgpLHdhPW5ldyBTZXQoVGEpO2xldCBFYT0wO2ZvcihsZXQgRmE9MDtGYTxTYS5sZW5ndGg7RmErKyl3YS5oYXMoU2FbRmFdKXx8RWErKztjb25zdCBrYT1uZXcgVGVuc29yQnVmZmVyJDEoW0VhXSx4YS5kdHlwZSksQWE9bmV3IFRlbnNvckJ1ZmZlciQxKFtFYV0sImludDMyIik7Zm9yKGxldCBGYT0wLExhPTA7RmE8U2EubGVuZ3RoO0ZhKyspd2EuaGFzKFNhW0ZhXSl8fChrYS52YWx1ZXNbTGFdPVNhW0ZhXSxBYS52YWx1ZXNbTGFdPUZhLExhKyspO3JldHVybltrYS50b1RlbnNvcigpLEFhLnRvVGVuc29yKCldfWNvbnN0IHNldGRpZmYxZEFzeW5jPXNldGRpZmYxZEFzeW5jXzsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzaWduXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJzaWduIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU2lnbiQxLHhhKX1jb25zdCBzaWduJDM9b3AkMSh7c2lnbl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzaW5fKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNpbiIsImZsb2F0MzIiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTaW4kMSx4YSl9Y29uc3Qgc2luJDM9b3AkMSh7c2luX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNpbmhfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNpbmgiKX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTaW5oJDEseGEpfWNvbnN0IHNpbmgkMz1vcCQxKHtzaW5oX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNsaWNlMWRfKGhhLGFhLHhhKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNsaWNlMWQiKTtyZXR1cm4gYXNzZXJ0JDIoYmEucmFuaz09PTEsKCk9PmBzbGljZTFkIGV4cGVjdHMgYSByYW5rLTEgdGVuc29yLCBidXQgZ290IGEgcmFuay0ke2JhLnJhbmt9IHRlbnNvcmApLHNsaWNlJDMoYmEsW2FhXSxbeGFdKX1jb25zdCBzbGljZTFkPW9wJDEoe3NsaWNlMWRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2xpY2UyZF8oaGEsYWEseGEpe2NvbnN0IGJhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic2xpY2UyZCIpO3JldHVybiBhc3NlcnQkMihiYS5yYW5rPT09MiwoKT0+YHNsaWNlMmQgZXhwZWN0cyBhIHJhbmstMiB0ZW5zb3IsIGJ1dCBnb3QgYSByYW5rLSR7YmEucmFua30gdGVuc29yYCksc2xpY2UkMyhiYSxhYSx4YSl9Y29uc3Qgc2xpY2UyZD1vcCQxKHtzbGljZTJkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNsaWNlM2RfKGhhLGFhLHhhKXtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInNsaWNlM2QiKTtyZXR1cm4gYXNzZXJ0JDIoYmEucmFuaz09PTMsKCk9PmBzbGljZTNkIGV4cGVjdHMgYSByYW5rLTMgdGVuc29yLCBidXQgZ290IGEgcmFuay0ke2JhLnJhbmt9IHRlbnNvcmApLHNsaWNlJDMoYmEsYWEseGEpfWNvbnN0IHNsaWNlM2Q9b3AkMSh7c2xpY2UzZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzbGljZTRkXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJzbGljZTRkIik7cmV0dXJuIGFzc2VydCQyKGJhLnJhbms9PT00LCgpPT5gc2xpY2U0ZCBleHBlY3RzIGEgcmFuay00IHRlbnNvciwgYnV0IGdvdCBhIHJhbmstJHtiYS5yYW5rfSB0ZW5zb3JgKSxzbGljZSQzKGJhLGFhLHhhKX1jb25zdCBzbGljZTRkPW9wJDEoe3NsaWNlNGRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc29mdG1heF8oaGEsYWE9LTEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJsb2dpdHMiLCJzb2Z0bWF4IiwiZmxvYXQzMiIpO2lmKGFhPT09LTEmJihhYT14YS5yYW5rLTEpLGFhIT09eGEucmFuay0xKXRocm93IEVycm9yKGBTb2Z0bWF4IGFsb25nIGEgbm9uLWxhc3QgZGltZW5zaW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkLiBMb2dpdHMgd2FzIHJhbmsgJHt4YS5yYW5rfSBhbmQgZGltIHdhcyAke2FhfWApO2NvbnN0IGJhPXtsb2dpdHM6eGF9LFNhPXtkaW06YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU29mdG1heCQzLGJhLFNhKX1jb25zdCBzb2Z0bWF4JDM9b3AkMSh7c29mdG1heF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmZnRfKGhhKXthc3NlcnQkMihoYS5kdHlwZT09PSJjb21wbGV4NjQiLCgpPT5gVGhlIGR0eXBlIGZvciB0Zi5zcGVjdHJhbC5mZnQoKSBtdXN0IGJlIGNvbXBsZXg2NCBidXQgZ290ICR7aGEuZHR5cGV9LmApO2NvbnN0IGFhPXtpbnB1dDpoYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChGRlQkMSxhYSl9Y29uc3QgZmZ0JDM9b3AkMSh7ZmZ0X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlmZnRfKGhhKXthc3NlcnQkMihoYS5kdHlwZT09PSJjb21wbGV4NjQiLCgpPT5gVGhlIGR0eXBlIGZvciB0Zi5zcGVjdHJhbC5pZmZ0KCkgbXVzdCBiZSBjb21wbGV4NjQgYnV0IGdvdCAke2hhLmR0eXBlfS5gKTtjb25zdCBhYT17aW5wdXQ6aGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoSUZGVCQxLGFhKX1jb25zdCBpZmZ0JDM9b3AkMSh7aWZmdF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpcmZmdF8oaGEpe2NvbnN0IGFhPWhhLnNoYXBlW2hhLnNoYXBlLmxlbmd0aC0xXSx4YT1oYS5zaXplL2FhO2xldCBiYTtpZihhYTw9Mil7Y29uc3QgU2E9cmVzaGFwZSQ0KGhhLFt4YSxhYV0pO2JhPWlmZnQkMyhTYSl9ZWxzZXtjb25zdCBTYT1beGEsMiooYWEtMSldLFRhPXJlc2hhcGUkNChyZWFsJDMoaGEpLFt4YSxhYV0pLHdhPXJlc2hhcGUkNChpbWFnJDMoaGEpLFt4YSxhYV0pLEVhPXJldmVyc2UkMyhzbGljZSQzKFRhLFswLDFdLFt4YSxhYS0yXSksMSksa2E9bXVsJDEocmV2ZXJzZSQzKHNsaWNlJDMod2EsWzAsMV0sW3hhLGFhLTJdKSwxKSxzY2FsYXIkMSgtMSkpLEFhPWNvbmNhdCQzKFtUYSxFYV0sMSksRmE9Y29uY2F0JDMoW3dhLGthXSwxKSxMYT1yZXNoYXBlJDQoY29tcGxleCQ0KEFhLEZhKSxbU2FbMF0sU2FbMV1dKTtiYT1pZmZ0JDMoTGEpfWlmKGJhPXJlYWwkMyhiYSksaGEucmFuaz09PTMmJmhhLnNoYXBlWzBdIT09MCl7Y29uc3QgU2E9YmEsVGE9aGEuc2hhcGVbMF07YmE9cmVzaGFwZSQ0KGJhLFtUYSxiYS5zaGFwZVswXS9UYSxiYS5zaGFwZVsxXV0pLFNhLmRpc3Bvc2UoKX1yZXR1cm4gYmF9Y29uc3QgaXJmZnQ9b3AkMSh7aXJmZnRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BsaXRfKGhhLGFhLHhhPTApe2NvbnN0IFNhPXt4OmNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic3BsaXQiKX0sVGE9e251bU9yU2l6ZVNwbGl0czphYSxheGlzOnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFNwbGl0ViQxLFNhLFRhKX1jb25zdCBzcGxpdCQzPW9wJDEoe3NwbGl0X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJmZnRfKGhhLGFhKXthc3NlcnQkMihoYS5kdHlwZT09PSJmbG9hdDMyIiwoKT0+YFRoZSBkdHlwZSBmb3IgcmZmdCgpIG11c3QgYmUgcmVhbCB2YWx1ZSBidXQgZ290ICR7aGEuZHR5cGV9YCk7bGV0IHhhPWhhLnNoYXBlW2hhLnNoYXBlLmxlbmd0aC0xXTtjb25zdCBiYT1oYS5zaXplL3hhO2xldCBTYTtpZihhYSE9bnVsbCYmYWE8eGEpe2NvbnN0IG5sPWhhLnNoYXBlLm1hcChybD0+MCksc2w9aGEuc2hhcGUubWFwKHJsPT5ybCk7c2xbaGEuc2hhcGUubGVuZ3RoLTFdPWFhLFNhPXNsaWNlJDMoaGEsbmwsc2wpLHhhPWFhfWVsc2UgaWYoYWEhPW51bGwmJmFhPnhhKXtjb25zdCBubD1oYS5zaGFwZS5tYXAoc2w9PnNsKTtubFtoYS5zaGFwZS5sZW5ndGgtMV09YWEteGEsU2E9Y29uY2F0JDMoW2hhLHplcm9zJDIobmwpXSxoYS5zaGFwZS5sZW5ndGgtMSkseGE9YWF9ZWxzZSBTYT1oYTtjb25zdCBUYT16ZXJvc0xpa2UkNChTYSksd2E9cmVzaGFwZSQ0KGNvbXBsZXgkNChTYSxUYSksW2JhLHhhXSksRWE9ZmZ0JDMod2EpLGthPU1hdGguZmxvb3IoeGEvMikrMSxBYT1yZWFsJDMoRWEpLEZhPWltYWckMyhFYSksTGE9c3BsaXQkMyhBYSxba2EseGEta2FdLEFhLnNoYXBlLmxlbmd0aC0xKSxlbD1zcGxpdCQzKEZhLFtrYSx4YS1rYV0sRmEuc2hhcGUubGVuZ3RoLTEpLHRsPVNhLnNoYXBlLnNsaWNlKCk7cmV0dXJuIHRsW1NhLnNoYXBlLmxlbmd0aC0xXT1rYSxyZXNoYXBlJDQoY29tcGxleCQ0KExhWzBdLGVsWzBdKSx0bCl9Y29uc3QgcmZmdD1vcCQxKHtyZmZ0X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNxdWFyZWREaWZmZXJlbmNlXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJhIiwic3F1YXJlZERpZmZlcmVuY2UiKSxiYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYiIsInNxdWFyZWREaWZmZXJlbmNlIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCQxKHhhLGJhKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtjb25zdCBTYT17YTp4YSxiOmJhfSxUYT17fTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFNxdWFyZWREaWZmZXJlbmNlJDEsU2EsVGEpfWNvbnN0IHNxdWFyZWREaWZmZXJlbmNlJDM9b3AkMSh7c3F1YXJlZERpZmZlcmVuY2VffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3F1ZWV6ZV8oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4Iiwic3F1ZWV6ZSIsInN0cmluZ19vcl9udW1lcmljIik7cmV0dXJuIHJlc2hhcGUkNCh4YSxzcXVlZXplU2hhcGUkMSh4YS5zaGFwZSxhYSkubmV3U2hhcGUpfWNvbnN0IHNxdWVlemU9b3AkMSh7c3F1ZWV6ZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdGFja18oaGEsYWE9MCl7Y29uc3QgeGE9Y29udmVydFRvVGVuc29yQXJyYXkoaGEsInRlbnNvcnMiLCJzdGFjayIsInN0cmluZ19vcl9udW1lcmljIik7YXNzZXJ0JDIoeGEubGVuZ3RoPj0xLCgpPT4iUGFzcyBhdCBsZWFzdCBvbmUgdGVuc29yIHRvIHRmLnN0YWNrIikseGEubGVuZ3RoPjAmJmFzc2VydCQyKGFhPD14YVswXS5yYW5rLCgpPT4iQXhpcyBtdXN0IGJlIDw9IHJhbmsgb2YgdGhlIHRlbnNvciIpO2NvbnN0IGJhPXhhLFNhPXtheGlzOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFBhY2skMSxiYSxTYSl9Y29uc3Qgc3RhY2s9b3AkMSh7c3RhY2tffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RlcF8kMShoYSxhYT0wKXtjb25zdCBiYT17eDpjb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInN0ZXAiKX0sU2E9e2FscGhhOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFN0ZXAkMSxiYSxTYSl9Y29uc3Qgc3RlcCQ0PW9wJDEoe3N0ZXBfOnN0ZXBfJDF9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdHJpZGVkU2xpY2VfKGhhLGFhLHhhLGJhLFNhPTAsVGE9MCx3YT0wLEVhPTAsa2E9MCl7Y29uc3QgRmE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJzdHJpZGVkU2xpY2UiLCJzdHJpbmdfb3JfbnVtZXJpYyIpfSxMYT17YmVnaW46YWEsZW5kOnhhLHN0cmlkZXM6YmEsYmVnaW5NYXNrOlNhLGVuZE1hc2s6VGEsZWxsaXBzaXNNYXNrOndhLG5ld0F4aXNNYXNrOkVhLHNocmlua0F4aXNNYXNrOmthfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFN0cmlkZWRTbGljZSQxLEZhLExhKX1jb25zdCBzdHJpZGVkU2xpY2UkMz1vcCQxKHtzdHJpZGVkU2xpY2VffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdGFuXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJ0YW4iLCJmbG9hdDMyIil9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoVGFuJDEseGEpfWNvbnN0IHRhbiQzPW9wJDEoe3Rhbl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0ZW5zb3IxZChoYSxhYSl7YXNzZXJ0Tm9uTnVsbChoYSk7Y29uc3QgeGE9aW5mZXJTaGFwZSQxKGhhLGFhKTtpZih4YS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcigidGVuc29yMWQoKSByZXF1aXJlcyB2YWx1ZXMgdG8gYmUgYSBmbGF0L1R5cGVkQXJyYXkiKTtyZXR1cm4gbWFrZVRlbnNvciQxKGhhLG51bGwseGEsYWEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRlbnNvcjJkKGhhLGFhLHhhKXtpZihhc3NlcnROb25OdWxsKGhhKSxhYSE9bnVsbCYmYWEubGVuZ3RoIT09Mil0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjJkKCkgcmVxdWlyZXMgc2hhcGUgdG8gaGF2ZSB0d28gbnVtYmVycyIpO2NvbnN0IGJhPWluZmVyU2hhcGUkMShoYSx4YSk7aWYoYmEubGVuZ3RoIT09MiYmYmEubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjJkKCkgcmVxdWlyZXMgdmFsdWVzIHRvIGJlIG51bWJlcltdW10gb3IgZmxhdC9UeXBlZEFycmF5Iik7aWYoYmEubGVuZ3RoPT09MSYmYWE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJ0ZW5zb3IyZCgpIHJlcXVpcmVzIHNoYXBlIHRvIGJlIHByb3ZpZGVkIHdoZW4gYHZhbHVlc2AgYXJlIGEgZmxhdC9UeXBlZEFycmF5Iik7cmV0dXJuIG1ha2VUZW5zb3IkMShoYSxhYSxiYSx4YSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdGVuc29yM2QoaGEsYWEseGEpe2lmKGFzc2VydE5vbk51bGwoaGEpLGFhIT1udWxsJiZhYS5sZW5ndGghPT0zKXRocm93IG5ldyBFcnJvcigidGVuc29yM2QoKSByZXF1aXJlcyBzaGFwZSB0byBoYXZlIHRocmVlIG51bWJlcnMiKTtjb25zdCBiYT1pbmZlclNoYXBlJDEoaGEseGEpO2lmKGJhLmxlbmd0aCE9PTMmJmJhLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKCJ0ZW5zb3IzZCgpIHJlcXVpcmVzIHZhbHVlcyB0byBiZSBudW1iZXJbXVtdW10gb3IgZmxhdC9UeXBlZEFycmF5Iik7aWYoYmEubGVuZ3RoPT09MSYmYWE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJ0ZW5zb3IzZCgpIHJlcXVpcmVzIHNoYXBlIHRvIGJlIHByb3ZpZGVkIHdoZW4gYHZhbHVlc2AgYXJlIGEgZmxhdCBhcnJheSIpO3JldHVybiBtYWtlVGVuc29yJDEoaGEsYWEsYmEseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRlbnNvcjRkKGhhLGFhLHhhKXtpZihhc3NlcnROb25OdWxsKGhhKSxhYSE9bnVsbCYmYWEubGVuZ3RoIT09NCl0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjRkKCkgcmVxdWlyZXMgc2hhcGUgdG8gaGF2ZSBmb3VyIG51bWJlcnMiKTtjb25zdCBiYT1pbmZlclNoYXBlJDEoaGEseGEpO2lmKGJhLmxlbmd0aCE9PTQmJmJhLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKCJ0ZW5zb3I0ZCgpIHJlcXVpcmVzIHZhbHVlcyB0byBiZSBudW1iZXJbXVtdW11bXSBvciBmbGF0L1R5cGVkQXJyYXkiKTtpZihiYS5sZW5ndGg9PT0xJiZhYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjRkKCkgcmVxdWlyZXMgc2hhcGUgdG8gYmUgcHJvdmlkZWQgd2hlbiBgdmFsdWVzYCBhcmUgYSBmbGF0IGFycmF5Iik7cmV0dXJuIG1ha2VUZW5zb3IkMShoYSxhYSxiYSx4YSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdGVuc29yNWQoaGEsYWEseGEpe2lmKGFzc2VydE5vbk51bGwoaGEpLGFhIT1udWxsJiZhYS5sZW5ndGghPT01KXRocm93IG5ldyBFcnJvcigidGVuc29yNWQoKSByZXF1aXJlcyBzaGFwZSB0byBoYXZlIGZpdmUgbnVtYmVycyIpO2NvbnN0IGJhPWluZmVyU2hhcGUkMShoYSx4YSk7aWYoYmEubGVuZ3RoIT09NSYmYmEubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjVkKCkgcmVxdWlyZXMgdmFsdWVzIHRvIGJlIG51bWJlcltdW11bXVtdW10gb3IgZmxhdC9UeXBlZEFycmF5Iik7aWYoYmEubGVuZ3RoPT09MSYmYWE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJ0ZW5zb3I1ZCgpIHJlcXVpcmVzIHNoYXBlIHRvIGJlIHByb3ZpZGVkIHdoZW4gYHZhbHVlc2AgYXJlIGEgZmxhdCBhcnJheSIpO3JldHVybiBtYWtlVGVuc29yJDEoaGEsYWEsYmEseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRlbnNvcjZkKGhhLGFhLHhhKXtpZihhc3NlcnROb25OdWxsKGhhKSxhYSE9bnVsbCYmYWEubGVuZ3RoIT09Nil0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjZkKCkgcmVxdWlyZXMgc2hhcGUgdG8gaGF2ZSBzaXggbnVtYmVycyIpO2NvbnN0IGJhPWluZmVyU2hhcGUkMShoYSx4YSk7aWYoYmEubGVuZ3RoIT09NiYmYmEubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjZkKCkgcmVxdWlyZXMgdmFsdWVzIHRvIGJlIG51bWJlcltdW11bXVtdW11bXSBvciBmbGF0L1R5cGVkQXJyYXkiKTtpZihiYS5sZW5ndGg9PT0xJiZhYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoInRlbnNvcjZkKCkgcmVxdWlyZXMgc2hhcGUgdG8gYmUgcHJvdmlkZWQgd2hlbiBgdmFsdWVzYCBhcmUgYSBmbGF0IGFycmF5Iik7cmV0dXJuIGFhPWFhfHxiYSxtYWtlVGVuc29yJDEoaGEsYWEsYmEseGEpfWZ1bmN0aW9uIHZhbGlkYXRlVXBkYXRlU2hhcGUkMShoYSxhYSx4YSl7Y29uc3QgYmE9YWEucmFuaz4xP2FhLnNoYXBlW2FhLnJhbmstMV06MSxTYT1hYS5yYW5rPjE/YWEucmFuay0xOjEsVGE9YE11c3QgaGF2ZSB1cGRhdGVzLnNoYXBlID0gaW5kaWNlcy5zaGFwZVs6YmF0Y2hEaW1dICsgc2hhcGVbc2xpY2VEaW06XSwgZ290IHVwZGF0ZXMuc2hhcGU6ICR7eGEuc2hhcGV9LCBpbmRpY2VzLnNoYXBlOiAke2FhLnNoYXBlfSwgc2hhcGU6ICR7aGF9LCBzbGljZURpbTogJHtiYX0sIGFuZCBiYXRjaERpbTogJHtTYX0uYDtpZih4YS5yYW5rPFNhKXRocm93IG5ldyBFcnJvcihUYStgIHVwZGF0ZS5yYW5rIDwgJHtTYX0uIGApO2lmKGhhLmxlbmd0aDxiYSsoeGEucmFuay1TYSkpdGhyb3cgbmV3IEVycm9yKFRhK2AgT3V0cHV0IHNoYXBlIGxlbmd0aCA8ICR7YmErKHhhLnJhbmstU2EpfWApO2lmKHhhLnJhbmshPT1TYStoYS5sZW5ndGgtYmEpdGhyb3cgbmV3IEVycm9yKFRhK2AgdXBkYXRlLnJhbmsgIT0gJHtTYStoYS5sZW5ndGgtYmF9YCk7Zm9yKGxldCB3YT0wO3dhPFNhOysrd2EpaWYoeGEuc2hhcGVbd2FdIT09YWEuc2hhcGVbd2FdKXRocm93IG5ldyBFcnJvcihUYStgIHVwZGF0ZXMuc2hhcGVbJHt3YX1dICgke3hhLnNoYXBlW3dhXX0pICE9IGluZGljZXMuc2hhcGVbJHt3YX1dICgke2FhLnNoYXBlW3dhXX0pLmApO2ZvcihsZXQgd2E9MDt3YTx4YS5yYW5rLVNhOysrd2EpaWYoeGEuc2hhcGVbd2ErU2FdIT09aGFbd2ErYmFdKXRocm93IG5ldyBFcnJvcihUYStgIHVwZGF0ZXMuc2hhcGVbJHt3YStTYX1dICgke3hhLnNoYXBlW3dhK1NhXX0pICE9IHNoYXBlWyR7d2ErU2F9XSAoJHtoYVt3YStTYV19KWApfWZ1bmN0aW9uIHZhbGlkYXRlSW5wdXQkMihoYSxhYSx4YSl7aWYoYWEucmFuazwxKXRocm93IG5ldyBFcnJvcihgdGYuc2NhdHRlck5EKCkgZXhwZWN0cyB0aGUgaW5kaWNlcyB0byBiZSByYW5rIDEgb3IgaGlnaGVyLCBidXQgdGhlIHJhbmsgd2FzICR7YWEucmFua30uYCk7aWYoaGEucmFuazwxKXRocm93IG5ldyBFcnJvcihgdGYuc2NhdHRlck5EKCkgZXhwZWN0cyB0aGUgdXBkYXRlcyB0byBiZSByYW5rIDEgb3IgaGlnaGVyLCBidXQgdGhlIHJhbmsgd2FzICR7aGEucmFua30uYCk7aWYoYWEuZHR5cGUhPT0iaW50MzIiKXRocm93IG5ldyBFcnJvcihgVGhlIGR0eXBlIG9mICdpbmRpY2VzJyBzaG91bGQgYmUgaW50MzIsIGJ1dCBnb3QgZHR5cGU6ICR7YWEuZHR5cGV9YCk7aWYoeGEubGVuZ3RoPDEpdGhyb3cgbmV3IEVycm9yKGBPdXRwdXQgcmFuayBtdXN0IGJlIGdyZWF0ZXIgb3IgZXF1YWwgdG8gMSwgYnV0IGdvdCBzaGFwZTogJHt4YX1gKTtpZih4YS5sZW5ndGg9PT0wKXtpZihhYS5zaXplPT09MCl0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc3BlY2lmaWVkIGZvciBlbXB0eSBvdXRwdXQuIGluZGljZXMgc2hhcGU6ICR7YWEuc2hhcGV9YCk7aWYoaGEuc2l6ZT09PTApdGhyb3cgbmV3IEVycm9yKGBVcGRhdGVzIHNwZWNpZmllZCBmb3IgZW1wdHkgb3V0cHV0LiB1cGRhdGVzIHNoYXBlOiAke2hhLnNoYXBlfWApfXZhbGlkYXRlVXBkYXRlU2hhcGUkMSh4YSxhYSxoYSl9ZnVuY3Rpb24gY2FsY3VsYXRlU2hhcGVzJDEoaGEsYWEseGEpe2NvbnN0IGJhPWFhLnNoYXBlLmxlbmd0aCxTYT1iYT4xP2FhLnNoYXBlW2JhLTFdOjEsVGE9eGEubGVuZ3RoO2xldCB3YT0xO2ZvcihsZXQgTGE9U2E7TGE8VGE7KytMYSl3YSo9eGFbTGFdO2NvbnN0IEVhPVNhPDE/MTpTYSxrYT1zaXplRnJvbVNoYXBlJDEoYWEuc2hhcGUpL0VhLEFhPVsuLi5jb21wdXRlU3RyaWRlcyQxKHhhLnNsaWNlKDAsU2EpKSwxXSxGYT1zaXplRnJvbVNoYXBlJDEoeGEpO3JldHVybntzbGljZVJhbms6U2EsbnVtVXBkYXRlczprYSxzbGljZVNpemU6d2Esc3RyaWRlczpBYSxvdXRwdXRTaXplOkZhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0ZW5zb3JTY2F0dGVyVXBkYXRlXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsInRlbnNvciIsInRlbnNvclNjYXR0ZXJ1cGRhdGUiKSxTYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiaW5kaWNlcyIsInRlbnNvclNjYXR0ZXJ1cGRhdGUiLCJpbnQzMiIpLFRhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ1cGRhdGVzIiwidGVuc29yU2NhdHRlcnVwZGF0ZSIpO2lmKHZhbGlkYXRlSW5wdXQkMihUYSxTYSxiYS5zaGFwZSksYmEuZHR5cGUhPT1UYS5kdHlwZSl0aHJvdyBuZXcgRXJyb3IoYHRlbnNvciBhbmQgdXBkYXRlcyBtdXN0IGhhdmUgdGhlIHNhbWUgZHR5cGUsIGluc3RlYWQgdGhleSBhcmUgJHtiYS5kdHlwZX0gYW5kICR7VGEuZHR5cGV9LmApO2NvbnN0IHdhPXt0ZW5zb3I6YmEsaW5kaWNlczpTYSx1cGRhdGVzOlRhfSxFYT17fTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFRlbnNvclNjYXR0ZXJVcGRhdGUkMSx3YSxFYSl9Y29uc3QgdGVuc29yU2NhdHRlclVwZGF0ZSQzPW9wJDEoe3RlbnNvclNjYXR0ZXJVcGRhdGVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdG9wa18oaGEsYWE9MSx4YT0hMCl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJ0b3BrIik7aWYoYmEucmFuaz09PTApdGhyb3cgbmV3IEVycm9yKCJ0b3BrKCkgZXhwZWN0cyB0aGUgaW5wdXQgdG8gYmUgb2YgcmFuayAxIG9yIGhpZ2hlciIpO2NvbnN0IFNhPWJhLnNoYXBlW2JhLnNoYXBlLmxlbmd0aC0xXTtpZihhYTwwKXRocm93IG5ldyBFcnJvcihgJ2snIHBhc3NlZCB0byB0b3BrKCkgbXVzdCBiZSA+PSAwIGJ1dCBnb3QgJHthYX1gKTtpZihhYT5TYSl0aHJvdyBuZXcgRXJyb3IoYCdrJyBwYXNzZWQgdG8gdG9waygpIG11c3QgYmUgPD0gdGhlIGxhc3QgZGltZW5zaW9uICgke1NhfSkgYnV0IGdvdCAke2FhfWApO2NvbnN0IFRhPXt4OmJhfSx3YT17azphYSxzb3J0ZWQ6eGF9LFtFYSxrYV09RU5HSU5FJDEucnVuS2VybmVsKFRvcEskMSxUYSx3YSk7cmV0dXJue3ZhbHVlczpFYSxpbmRpY2VzOmthfX1jb25zdCB0b3BrPW9wJDEoe3RvcGtffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdHJ1bmNhdGVkTm9ybWFsXyhoYSxhYT0wLHhhPTEsYmEsU2Epe2lmKGFzc2VydE5vbk5lZ2F0aXZlSW50ZWdlckRpbWVuc2lvbnMkMShoYSksYmEhPW51bGwmJmJhPT09ImJvb2wiKXRocm93IG5ldyBFcnJvcigiVW5zdXBwb3J0ZWQgZGF0YSB0eXBlICQgeyBkdHlwZSB9Iik7Y29uc3QgVGE9bmV3IE1QUmFuZEdhdXNzKGFhLHhhLGJhLCEwLFNhKSx3YT1idWZmZXIkMShoYSxiYSk7Zm9yKGxldCBFYT0wO0VhPHdhLnZhbHVlcy5sZW5ndGg7RWErKyl3YS52YWx1ZXNbRWFdPVRhLm5leHRWYWx1ZSgpO3JldHVybiB3YS50b1RlbnNvcigpfWNvbnN0IHRydW5jYXRlZE5vcm1hbD1vcCQxKHt0cnVuY2F0ZWROb3JtYWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5pcXVlXyhoYSxhYT0wKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsInVuaXF1ZSIsInN0cmluZ19vcl9udW1lcmljIik7YXNzZXJ0JDIoeGEucmFuaz4wLCgpPT4iVGhlIGlucHV0IHRlbnNvciBtdXN0IGJlIGF0IGxlYXN0IDFEIik7Y29uc3QgYmE9e3g6eGF9LFNhPXtheGlzOmFhfSxbVGEsd2FdPUVOR0lORSQxLnJ1bktlcm5lbChVbmlxdWUkMSxiYSxTYSk7cmV0dXJue3ZhbHVlczpUYSxpbmRpY2VzOndhfX1jb25zdCB1bmlxdWUkND1vcCQxKHt1bmlxdWVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5zb3J0ZWRTZWdtZW50U3VtXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJ1bnNvcnRlZFNlZ21lbnRTdW0iKSxTYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwic2VnbWVudElkcyIsInVuc29ydGVkU2VnbWVudFN1bSIsImludDMyIik7YXNzZXJ0JDIoaXNJbnQkMSh4YSksKCk9PiJudW1TZWdtZW50cyBtdXN0IGJlIG9mIGR0eXBlIGludCIpO2NvbnN0IFRhPXt4OmJhLHNlZ21lbnRJZHM6U2F9LHdhPXtudW1TZWdtZW50czp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChVbnNvcnRlZFNlZ21lbnRTdW0kMSxUYSx3YSl9Y29uc3QgdW5zb3J0ZWRTZWdtZW50U3VtJDM9b3AkMSh7dW5zb3J0ZWRTZWdtZW50U3VtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHVuc3RhY2tfKGhhLGFhPTApe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwidW5zdGFjayIsInN0cmluZ19vcl9udW1lcmljIik7YXNzZXJ0JDIoYWE+PS14YS5zaGFwZS5sZW5ndGgmJmFhPHhhLnNoYXBlLmxlbmd0aCwoKT0+YEF4aXMgPSAke2FhfSBpcyBub3QgaW4gWy0ke3hhLnNoYXBlLmxlbmd0aH0sICR7eGEuc2hhcGUubGVuZ3RofSlgKTtjb25zdCBiYT17dmFsdWU6eGF9LFNhPXtheGlzOmFhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFVucGFjayQxLGJhLFNhKX1jb25zdCB1bnN0YWNrPW9wJDEoe3Vuc3RhY2tffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdXBwZXJCb3VuZCQxKGhhLGFhKXtyZXR1cm4gc2VhcmNoU29ydGVkJDMoaGEsYWEsInJpZ2h0Iil9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdmFyaWFibGUoaGEsYWE9ITAseGEsYmEpe3JldHVybiBFTkdJTkUkMS5tYWtlVmFyaWFibGUoaGEsYWEseGEsYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHdoZXJlSW1wbCQ0KGhhLGFhKXtjb25zdCB4YT1bXTtmb3IobGV0IFRhPTA7VGE8YWEubGVuZ3RoO1RhKyspYWFbVGFdJiZ4YS5wdXNoKFRhKTtjb25zdCBiYT1idWZmZXIkMShoYSwiaW50MzIiKSxTYT1idWZmZXIkMShbeGEubGVuZ3RoLGhhLmxlbmd0aF0sImludDMyIik7Zm9yKGxldCBUYT0wO1RhPHhhLmxlbmd0aDtUYSsrKXtjb25zdCB3YT1iYS5pbmRleFRvTG9jKHhhW1RhXSksRWE9VGEqaGEubGVuZ3RoO1NhLnZhbHVlcy5zZXQod2EsRWEpfXJldHVybiBTYS50b1RlbnNvcigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2FzeW5jIGZ1bmN0aW9uIHdoZXJlQXN5bmNfKGhhKXtjb25zdCBhYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiY29uZGl0aW9uIiwid2hlcmVBc3luYyIsImJvb2wiKSx4YT1hd2FpdCBhYS5kYXRhKCksYmE9d2hlcmVJbXBsJDQoYWEuc2hhcGUseGEpO3JldHVybiBoYSE9PWFhJiZhYS5kaXNwb3NlKCksYmF9Y29uc3Qgd2hlcmVBc3luYz13aGVyZUFzeW5jXzsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9hc3luYyBmdW5jdGlvbiBib29sZWFuTWFza0FzeW5jXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsInRlbnNvciIsImJvb2xNYXNrIiksU2E9Y29udmVydFRvVGVuc29yJDEoYWEsIm1hc2siLCJib29sTWFzayIsImJvb2wiKSxUYT14YT8/MCx3YT1TYS5yYW5rLEVhPWJhLnNoYXBlO2Fzc2VydCQyKHdhPjAsKCk9PiJtYXNrIGNhbm5vdCBiZSBzY2FsYXIiKSxhc3NlcnRTaGFwZXNNYXRjaCQxKEVhLnNsaWNlKFRhLFRhK3dhKSxTYS5zaGFwZSwibWFzaydzIHNoYXBlIG11c3QgbWF0Y2ggdGhlIGZpcnN0IEsgZGltZW5zaW9ucyBvZiB0ZW5zb3IncyBzaGFwZSwiKTtsZXQga2E9MTtmb3IobGV0IHNsPVRhO3NsPFRhK3dhO3NsKyspa2EqPUVhW3NsXTtjb25zdCBBYT1FYS5zbGljZSgwLFRhKS5jb25jYXQoW2thXSxFYS5zbGljZShUYSt3YSkpLEZhPXJlc2hhcGUkNChiYSxBYSksTGE9cmVzaGFwZSQ0KFNhLFstMV0pLGVsPWF3YWl0IHdoZXJlQXN5bmMoTGEpLHRsPXNxdWVlemUoZWwsWzFdKSxubD1nYXRoZXIkMShGYSx0bCxUYSk7cmV0dXJuIGhhIT09YmEmJmJhLmRpc3Bvc2UoKSxhYSE9PVNhJiZTYS5kaXNwb3NlKCksdGwuZGlzcG9zZSgpLEZhLmRpc3Bvc2UoKSxMYS5kaXNwb3NlKCksZWwuZGlzcG9zZSgpLG5sfWNvbnN0IGJvb2xlYW5NYXNrQXN5bmM9Ym9vbGVhbk1hc2tBc3luY187LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdHJhbnNwb3NlXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJ0cmFuc3Bvc2UiKTtpZihhYT09bnVsbCYmKGFhPWJhLnNoYXBlLm1hcCgod2EsRWEpPT5FYSkucmV2ZXJzZSgpKSxhc3NlcnQkMihiYS5yYW5rPT09YWEubGVuZ3RoLCgpPT5gRXJyb3IgaW4gdHJhbnNwb3NlOiByYW5rIG9mIGlucHV0ICR7YmEucmFua30gbXVzdCBtYXRjaCBsZW5ndGggb2YgcGVybSAke2FhfS5gKSxhYS5mb3JFYWNoKHdhPT57YXNzZXJ0JDIod2E+PTAmJndhPGJhLnJhbmssKCk9PmBBbGwgZW50cmllcyBpbiAncGVybScgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kICR7YmEucmFuay0xfSBidXQgZ290ICR7YWF9YCl9KSxiYS5yYW5rPD0xKXJldHVybiBiYS5jbG9uZSgpO2NvbnN0IFNhPXt4OmJhfSxUYT17cGVybTphYX07cmV0dXJuIGJhLmR0eXBlPT09ImNvbXBsZXg2NCI/dGlkeSQxKCgpPT57bGV0IHdhPXJlYWwkMyhiYSksRWE9aW1hZyQzKGJhKTtyZXR1cm4gd2E9RU5HSU5FJDEucnVuS2VybmVsKFRyYW5zcG9zZSQxLHt4OndhfSxUYSksRWE9RU5HSU5FJDEucnVuS2VybmVsKFRyYW5zcG9zZSQxLHt4OkVhfSxUYSkseGEmJihFYT1uZWckMyhFYSkpLGNvbXBsZXgkNCh3YSxFYSl9KTpFTkdJTkUkMS5ydW5LZXJuZWwoVHJhbnNwb3NlJDEsU2EsVGEpfWNvbnN0IHRyYW5zcG9zZSQzPW9wJDEoe3RyYW5zcG9zZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtb3ZpbmdBdmVyYWdlXyhoYSxhYSx4YSxiYSxTYT0hMCl7Y29uc3QgVGE9Y29udmVydFRvVGVuc29yJDEoaGEsInYiLCJtb3ZpbmdBdmVyYWdlIiksd2E9Y29udmVydFRvVGVuc29yJDEoYWEsIngiLCJtb3ZpbmdBdmVyYWdlIiksRWE9Y29udmVydFRvVGVuc29yJDEoeGEsImRlY2F5IiwibW92aW5nQXZlcmFnZSIpO2Fzc2VydFR5cGVzTWF0Y2goVGEsd2EpLGFzc2VydCQyKGFycmF5c0VxdWFsJDEoVGEuc2hhcGUsd2Euc2hhcGUpLCgpPT4iU2hhcGUgbWlzbWF0Y2ggaW4gdiBhbmQgeCIpO2NvbnN0IGthPXNjYWxhciQxKDEpLEFhPXN1YiQ0KGthLEVhKTtsZXQgRmE9bXVsJDEoc3ViJDQod2EsVGEpLEFhKTtpZihTYSl7YXNzZXJ0JDIoYmEhPW51bGwsKCk9PiJXaGVuIHVzaW5nIHplcm9EZWJpYXM6IHRydWUsIHN0ZXAgaXMgcmVxdWlyZWQuIik7Y29uc3QgTGE9Y29udmVydFRvVGVuc29yJDEoYmEsInN0ZXAiLCJtb3ZpbmdBdmVyYWdlIik7RmE9ZGl2JDIoRmEsc3ViJDQoa2EscG93JDQoRWEsTGEpKSl9cmV0dXJuIGFkZCQzKFRhLEZhKX1jb25zdCBtb3ZpbmdBdmVyYWdlPW9wJDEoe21vdmluZ0F2ZXJhZ2VffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2NhdHRlck5EXyhoYSxhYSx4YSl7YXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyQxKHhhKTtjb25zdCBiYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiaW5kaWNlcyIsInNjYXR0ZXJORCIsImludDMyIiksU2E9Y29udmVydFRvVGVuc29yJDEoYWEsInVwZGF0ZXMiLCJzY2F0dGVyTkQiKTt2YWxpZGF0ZUlucHV0JDIoU2EsYmEseGEpO2NvbnN0IFRhPXtpbmRpY2VzOmJhLHVwZGF0ZXM6U2F9LHdhPXtzaGFwZTp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTY2F0dGVyTmQkMSxUYSx3YSl9Y29uc3Qgc2NhdHRlck5EPW9wJDEoe3NjYXR0ZXJORF99KTtmdW5jdGlvbiB2YWxpZGF0ZUlucHV0JDEoaGEsYWEseGEsYmEpe2lmKGhhLmR0eXBlIT09ImludDMyIil0aHJvdyBuZXcgRXJyb3IoYHRmLnNwYXJzZVRvRGVuc2UoKSBleHBlY3RzIHRoZSBpbmRpY2VzIHRvIGJlIGludDMyIHR5cGUsIGJ1dCB0aGUgZHR5cGUgd2FzICR7aGEuZHR5cGV9LmApO2lmKGhhLnJhbms+Mil0aHJvdyBuZXcgRXJyb3IoYHNwYXJzZUluZGljZXMgc2hvdWxkIGJlIGEgc2NhbGFyLCB2ZWN0b3IsIG9yIG1hdHJpeCwgYnV0IGdvdCBzaGFwZSAke2hhLnNoYXBlfS5gKTtjb25zdCBTYT1oYS5yYW5rPjA/aGEuc2hhcGVbMF06MSxUYT1oYS5yYW5rPjE/aGEuc2hhcGVbMV06MTtpZih4YS5sZW5ndGghPT1UYSl0aHJvdyBuZXcgRXJyb3IoYG91dHB1dFNoYXBlIGhhcyBpbmNvcnJlY3QgbnVtYmVyIG9mIGVsZW1lbnRzOiwgJHt4YS5sZW5ndGh9LCBzaG91bGQgYmU6ICR7VGF9LmApO2NvbnN0IHdhPWFhLnNpemU7aWYoIShhYS5yYW5rPT09MHx8YWEucmFuaz09PTEmJndhPT09U2EpKXRocm93IG5ldyBFcnJvcihgc3BhcnNlVmFsdWVzIGhhcyBpbmNvcnJlY3Qgc2hhcGUgJHthYS5zaGFwZX0sIHNob3VsZCBiZSBbXSBvciBbJHtTYX1dYCk7aWYoYWEuZHR5cGUhPT1iYS5kdHlwZSl0aHJvdyBuZXcgRXJyb3IoInNwYXJzZVZhbHVlcy5kdHlwZSBtdXN0IG1hdGNoIGRlZmF1bHRWYWx1ZXMuZHR5cGUiKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFyc2VUb0RlbnNlXyhoYSxhYSx4YSxiYT0wKXthc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zJDEoeGEpO2NvbnN0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJzcGFyc2VJbmRpY2VzIiwic3BhcnNlVG9EZW5zZSIsImludDMyIiksVGE9Y29udmVydFRvVGVuc29yJDEoYWEsInNwYXJzZVZhbHVlcyIsInNwYXJzZVRvRGVuc2UiLCJzdHJpbmdfb3JfbnVtZXJpYyIpLHdhPWNvbnZlcnRUb1RlbnNvciQxKGJhLCJkZWZhdWx0VmFsdWUiLCJzcGFyc2VUb0RlbnNlIixUYS5kdHlwZSk7dmFsaWRhdGVJbnB1dCQxKFNhLFRhLHhhLHdhKTtjb25zdCBFYT17c3BhcnNlSW5kaWNlczpTYSxzcGFyc2VWYWx1ZXM6VGEsZGVmYXVsdFZhbHVlOndhfSxrYT17b3V0cHV0U2hhcGU6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU3BhcnNlVG9EZW5zZSQxLEVhLGthKX1jb25zdCBzcGFyc2VUb0RlbnNlJDM9b3AkMSh7c3BhcnNlVG9EZW5zZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnYXRoZXJORF8oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJpbmRpY2VzIiwiZ2F0aGVyTkQiLCJpbnQzMiIpLFNhPXtwYXJhbXM6Y29udmVydFRvVGVuc29yJDEoaGEsIngiLCJnYXRoZXJORCIsInN0cmluZ19vcl9udW1lcmljIiksaW5kaWNlczp4YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChHYXRoZXJOZCQxLFNhKX1jb25zdCBnYXRoZXJORD1vcCQxKHtnYXRoZXJORF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXROb2lzZVNoYXBlKGhhLGFhKXtpZihhYT09bnVsbClyZXR1cm4gaGEuc2hhcGUuc2xpY2UoKTtpZihhcnJheXNFcXVhbCQxKGhhLnNoYXBlLGFhKSlyZXR1cm4gYWE7aWYoaGEuc2hhcGUubGVuZ3RoPT09YWEubGVuZ3RoKXtjb25zdCB4YT1bXTtmb3IobGV0IGJhPTA7YmE8aGEuc2hhcGUubGVuZ3RoO2JhKyspYWFbYmFdPT1udWxsJiZoYS5zaGFwZVtiYV0hPW51bGw/eGEucHVzaChoYS5zaGFwZVtiYV0pOnhhLnB1c2goYWFbYmFdKTtyZXR1cm4geGF9cmV0dXJuIGFhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRyb3BvdXRfKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImRyb3BvdXQiKTtpZihhc3NlcnQkMihTYS5kdHlwZT09PSJmbG9hdDMyIiwoKT0+YHggaGFzIHRvIGJlIGEgZmxvYXRpbmcgcG9pbnQgdGVuc29yIHNpbmNlIGl0J3MgZ29pbmcgdG8gYmUgc2NhbGVkLCBidXQgZ290IGEgJHtTYS5kdHlwZX0gdGVuc29yIGluc3RlYWQuYCksYXNzZXJ0JDIoYWE+PTAmJmFhPDEsKCk9PmByYXRlIG11c3QgYmUgYSBmbG9hdCBpbiB0aGUgcmFuZ2UgWzAsIDEpLCBidXQgZ290ICR7YWF9LmApLGFhPT09MClyZXR1cm4gaGEgaW5zdGFuY2VvZiBUZW5zb3IkMT9TYS5jbG9uZSgpOlNhO2NvbnN0IFRhPWdldE5vaXNlU2hhcGUoU2EseGEpLHdhPTEtYWEsRWE9ZGl2JDIoZmxvb3IkMyhhZGQkMyhyYW5kb21Vbmlmb3JtKFRhLDAsMSwiZmxvYXQzMiIsYmEpLHdhKSksd2EpO3JldHVybiBtdWwkMShTYSxFYSl9Y29uc3QgZHJvcG91dCQxPW9wJDEoe2Ryb3BvdXRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZW5jbG9zaW5nUG93ZXJPZlR3byhoYSl7cmV0dXJuIE1hdGguZmxvb3IoTWF0aC5wb3coMixNYXRoLmNlaWwoTWF0aC5sb2coaGEpL01hdGgubG9nKDIpKSkpfWZ1bmN0aW9uIGNvc2luZVdpbmRvdyhoYSxhYSx4YSl7Y29uc3QgYmE9MS1oYSUyLFNhPW5ldyBGbG9hdDMyQXJyYXkoaGEpO2ZvcihsZXQgVGE9MDtUYTxoYTsrK1RhKXtjb25zdCB3YT0yKk1hdGguUEkqVGEvKGhhK2JhLTEpO1NhW1RhXT1hYS14YSpNYXRoLmNvcyh3YSl9cmV0dXJuIHRlbnNvcjFkKFNhLCJmbG9hdDMyIil9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovYXN5bmMgZnVuY3Rpb24gaW5Ub3BLQXN5bmNfKGhhLGFhLHhhPTEpe2NvbnN0IGJhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJwcmVkaWN0aW9ucyIsImluVG9wSyIpLFNhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJ0YXJnZXRzIiwiaW5Ub3BLIik7YXNzZXJ0JDIoYmEucmFuaz4xLCgpPT5gaW5Ub3BLKCkgZXhwZWN0cyB0aGUgcHJlZGljdGlvbnMgdG8gYmUgb2YgcmFuayAyIG9yIGhpZ2hlciwgYnV0IGdvdCAke2JhLnJhbmt9YCksYXNzZXJ0JDIoYmEucmFuay0xPT09U2EucmFuaywoKT0+YHByZWRpY3Rpb25zIHJhbmsgc2hvdWxkIGJlIDEgbGFyZ2VyIHRoYW4gdGFyZ2V0cyByYW5rLCBidXQgZ290IHByZWRpY3Rpb25zIHJhbmsgJHtiYS5yYW5rfSBhbmQgdGFyZ2V0cyByYW5rICR7U2EucmFua31gKSxhc3NlcnRTaGFwZXNNYXRjaCQxKGJhLnNoYXBlLnNsaWNlKDAsYmEuc2hhcGUubGVuZ3RoLTEpLFNhLnNoYXBlLCJwcmVkaWN0aW9ucydzIHNoYXBlIHNob3VsZCBiZSBhbGlnbiB3aXRoIHRoZSB0YXJnZXRzJyBzaGFwZSwgZXhjZXB0IHRoZSBsYXN0IGRpbWVuc2lvbi4iKTtjb25zdCBUYT1iYS5zaGFwZVtiYS5zaGFwZS5sZW5ndGgtMV07YXNzZXJ0JDIoeGE+MCYmeGE8PVRhLCgpPT5gJ2snIHBhc3NlZCB0byBpblRvcEsoKSBtdXN0IGJlID4gMCAmJiA8PSB0aGUgcHJlZGljdGlvbnMgbGFzdCBkaW1lbnNpb24gKCR7VGF9KSwgYnV0IGdvdCAke3hhfWApO2NvbnN0IHdhPWF3YWl0IGJhLmRhdGEoKSxFYT1hd2FpdCBTYS5kYXRhKCksW2thLEFhXT1bd2EubGVuZ3RoL1RhLFRhXSxGYT1nZXRUeXBlZEFycmF5RnJvbURUeXBlJDEoImJvb2wiLGthKTtmb3IobGV0IExhPTA7TGE8a2E7TGErKyl7Y29uc3QgZWw9TGEqQWEsdGw9d2Euc3ViYXJyYXkoZWwsZWwrQWEpLG5sPVtdO2ZvcihsZXQgc2w9MDtzbDx0bC5sZW5ndGg7c2wrKylubC5wdXNoKHt2YWx1ZTp0bFtzbF0saW5kZXg6c2x9KTtubC5zb3J0KChzbCxybCk9PnJsLnZhbHVlLXNsLnZhbHVlKSxGYVtMYV09MDtmb3IobGV0IHNsPTA7c2w8eGE7c2wrKylpZihubFtzbF0uaW5kZXg9PT1FYVtMYV0pe0ZhW0xhXT0xO2JyZWFrfX1yZXR1cm4gaGEhPT1iYSYmYmEuZGlzcG9zZSgpLGFhIT09U2EmJlNhLmRpc3Bvc2UoKSx0ZW5zb3IoRmEsU2Euc2hhcGUsImJvb2wiKX1jb25zdCBpblRvcEtBc3luYz1pblRvcEtBc3luY187LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjJEQmFja3Byb3BGaWx0ZXJfKGhhLGFhLHhhLGJhLFNhLFRhPSJOSFdDIix3YSl7bGV0IEVhPWhhO2hhLnJhbms9PT0zJiYoRWE9cmVzaGFwZSQ0KGhhLFsxLGhhLnNoYXBlWzBdLGhhLnNoYXBlWzFdLGhhLnNoYXBlWzJdXSkpO2xldCBrYT1hYTtrYS5yYW5rPT09MyYmKGthPXJlc2hhcGUkNChhYSxbMSxhYS5zaGFwZVswXSxhYS5zaGFwZVsxXSxhYS5zaGFwZVsyXV0pKSxhc3NlcnQkMihFYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIGNvbnYyZERlckZpbHRlcjogaW5wdXQgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3Qgc2hhcGUgJHtFYS5zaGFwZX0uYCksYXNzZXJ0JDIoa2EucmFuaz09PTQsKCk9PmBFcnJvciBpbiBjb252MmREZXJGaWx0ZXI6IGR5IG11c3QgYmUgcmFuayA0LCBidXQgZ290IHNoYXBlICR7a2Euc2hhcGV9LmApLGFzc2VydCQyKHhhLmxlbmd0aD09PTQsKCk9PmBFcnJvciBpbiBjb252MmREZXJGaWx0ZXI6IGZpbHRlclNoYXBlIG11c3QgYmUgbGVuZ3RoIDQsIGJ1dCBnb3QgJHt4YX0uYCk7Y29uc3QgQWE9VGE9PT0iTkhXQyI/RWEuc2hhcGVbM106RWEuc2hhcGVbMV0sRmE9VGE9PT0iTkhXQyI/a2Euc2hhcGVbM106a2Euc2hhcGVbMV07YXNzZXJ0JDIoQWE9PT14YVsyXSwoKT0+YEVycm9yIGluIGNvbnYyZERlckZpbHRlcjogZGVwdGggb2YgaW5wdXQgJHtBYX0pIG11c3QgbWF0Y2ggaW5wdXQgZGVwdGggaW4gZmlsdGVyICgke3hhWzJdfS5gKSxhc3NlcnQkMihGYT09PXhhWzNdLCgpPT5gRXJyb3IgaW4gY29udjJkRGVyRmlsdGVyOiBkZXB0aCBvZiBkeSAoJHtGYX0pIG11c3QgbWF0Y2ggb3V0cHV0IGRlcHRoIGZvciBmaWx0ZXIgKCR7eGFbM119KS5gKSxjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlJDEoImNvbnYyZERlckZpbHRlciIsU2Esd2EpO2NvbnN0IExhPXt4OkVhLGR5OmthfSxlbD17c3RyaWRlczpiYSxwYWQ6U2EsZGF0YUZvcm1hdDpUYSxkaW1Sb3VuZGluZ01vZGU6d2EsZmlsdGVyU2hhcGU6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQ29udjJEQmFja3Byb3BGaWx0ZXIkMSxMYSxlbCl9Y29uc3QgY29udjJEQmFja3Byb3BGaWx0ZXIkMz1vcCQxKHtjb252MkRCYWNrcHJvcEZpbHRlcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRGdXNlZER5QWN0aXZhdGlvbiQxKGhhLGFhLHhhKXtpZih4YT09bnVsbHx8eGE9PT0ibGluZWFyIilyZXR1cm4gaGE7aWYoeGE9PT0icmVsdSIpcmV0dXJuIG11bCQxKGhhLHN0ZXAkNChhYSkpO3Rocm93IG5ldyBFcnJvcihgQ2Fubm90IGNvbXB1dGUgZ3JhZGllbnQgZm9yIGZ1c2VkIGFjdGl2YXRpb24gJHt4YX0uYCl9ZnVuY3Rpb24gZ2V0RnVzZWRCaWFzR3JhZGllbnQkMShoYSxhYSl7bGV0IHhhPWFhO2NvbnN0IGJhPWdldFJlZHVjdGlvbkF4ZXMkMShoYS5zaGFwZSxhYS5zaGFwZSk7cmV0dXJuIGJhLmxlbmd0aD4wJiYoeGE9c3VtJDUoeGEsYmEpKSxyZXNoYXBlJDQoeGEsaGEuc2hhcGUpfWZ1bmN0aW9uIGFwcGx5QWN0aXZhdGlvbiQyKGhhLGFhLHhhLGJhKXtpZihhYT09PSJsaW5lYXIiKXJldHVybiBoYTtpZihhYT09PSJyZWx1IilyZXR1cm4gcmVsdSQ0KGhhKTtpZihhYT09PSJlbHUiKXJldHVybiBlbHUkNShoYSk7aWYoYWE9PT0icmVsdTYiKXJldHVybiByZWx1NiQ0KGhhKTtpZihhYT09PSJwcmVsdSIpcmV0dXJuIHByZWx1JDQoaGEseGEpO2lmKGFhPT09ImxlYWt5cmVsdSIpcmV0dXJuIGxlYWt5UmVsdSQ0KGhhLGJhKTtpZihhYT09PSJzaWdtb2lkIilyZXR1cm4gc2lnbW9pZCQ0KGhhKTt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZnVzZWQgYWN0aXZhdGlvbiAke2FhfS5gKX1jb25zdCBzaG91bGRGdXNlJDE9KGhhLGFhKT0+IShoYT4wKXx8YWE9PT0ibGluZWFyIjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmdXNlZENvbnYyZF8oe3g6aGEsZmlsdGVyOmFhLHN0cmlkZXM6eGEscGFkOmJhLGRhdGFGb3JtYXQ6U2E9Ik5IV0MiLGRpbGF0aW9uczpUYT1bMSwxXSxkaW1Sb3VuZGluZ01vZGU6d2EsYmlhczpFYSxhY3RpdmF0aW9uOmthPSJsaW5lYXIiLHByZWx1QWN0aXZhdGlvbldlaWdodHM6QWEsbGVha3lyZWx1QWxwaGE6RmF9KXtpZihrYT1rYXx8ImxpbmVhciIsc2hvdWxkRnVzZSQxKEVOR0lORSQxLnN0YXRlLmdyYWRpZW50RGVwdGgsa2EpPT09ITEpe2Fzc2VydCQyKFNhPT09Ik5IV0MiLCgpPT5gRXJyb3IgaW4gZnVzZWQgY29udjJkOiBnb3QgZGF0YUZvcm1hdCBvZiAke1NhfSBidXQgb25seSBOSFdDIGlzIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIHRoZSBjYXNlIG9mIGdyYWRpZW50IGRlcHRoIGlzIDAgYW5kIHRoZSBhY3RpdmF0aW9uIGlzIG5vdCBsaW5lYXIuYCk7bGV0IHVsPWNvbnYyZCQzKGhhLGFhLHhhLGJhLFNhLFRhLHdhKTtyZXR1cm4gRWEhPW51bGwmJih1bD1hZGQkMyh1bCxFYSkpLGFwcGx5QWN0aXZhdGlvbiQyKHVsLGthLEFhLEZhKX1jb25zdCBMYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwieCIsImNvbnYyZCIsImZsb2F0MzIiKSxlbD1jb252ZXJ0VG9UZW5zb3IkMShhYSwiZmlsdGVyIiwiY29udjJkIiwiZmxvYXQzMiIpO2xldCB0bD1MYSxubD0hMTtMYS5yYW5rPT09MyYmKG5sPSEwLHRsPXJlc2hhcGUkNChMYSxbMSxMYS5zaGFwZVswXSxMYS5zaGFwZVsxXSxMYS5zaGFwZVsyXV0pKSxhc3NlcnQkMih0bC5yYW5rPT09NCwoKT0+YEVycm9yIGluIGZ1c2VkIGNvbnYyZDogaW5wdXQgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke3RsLnJhbmt9LmApLGFzc2VydCQyKGVsLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gZnVzZWQgY29udjJkOiBmaWx0ZXIgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke2VsLnJhbmt9LmApLGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGUkMSgiZnVzZWQgY29udjJkIixiYSx3YSk7Y29uc3Qgc2w9U2E9PT0iTkhXQyI/dGwuc2hhcGVbM106dGwuc2hhcGVbMV07YXNzZXJ0JDIoZWwuc2hhcGVbMl09PT1zbCwoKT0+YEVycm9yIGluIGNvbnYyZDogZGVwdGggb2YgaW5wdXQgKCR7c2x9KSBtdXN0IG1hdGNoIGlucHV0IGRlcHRoIGZvciBmaWx0ZXIgJHtlbC5zaGFwZVsyXX0uYCksYXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEoeGEsVGEpLCgpPT5gRXJyb3IgaW4gY29udjJEOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke3hhfSBhbmQgZGlsYXRpb25zICcke1RhfSdgKTtjb25zdCBybD1jb21wdXRlQ29udjJESW5mbyQxKHRsLnNoYXBlLGVsLnNoYXBlLHhhLFRhLGJhLHdhKTtsZXQgb2w7RWEhPW51bGwmJihvbD1jb252ZXJ0VG9UZW5zb3IkMShFYSwiYmlhcyIsImZ1c2VkIGNvbnYyZCIpLFtvbF09bWFrZVR5cGVzTWF0Y2gkMShvbCxMYSksU2E9PT0iTkhXQyI/YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShybC5vdXRTaGFwZSxvbC5zaGFwZSk6KGFzc2VydCQyKG9sLnNoYXBlLmxlbmd0aDw9MSwoKT0+YEVycm9yIGluIGZ1c2VkIGNvbnYyZDogb25seSBzdXBwb3J0cyBzY2FsYXIgb3IgMS1EIFRlbnNvciBiaWFzIGZvciBOQ0hXIGZvcm1hdCBidXQgZ290IHRoZSBiaWFzIG9mIHJhbmstJHtvbC5zaGFwZS5sZW5ndGh9LmApLGFzc2VydCQyKG9sLnNoYXBlLmxlbmd0aD09PTB8fG9sLnNoYXBlWzBdPT09cmwub3V0Q2hhbm5lbHN8fG9sLnNoYXBlWzBdPT09MSwoKT0+YEVycm9yIGluIGZ1c2VkIGNvbnYyZDogYmlhcyBzaGFwZSAoJHtvbC5zaGFwZX0pIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIG51bWJlciBvZiBvdXRwdXQgY2hhbm5lbHMgKCR7cmwub3V0Q2hhbm5lbHN9KWApKSk7bGV0IGFsO2lmKEFhIT1udWxsKXtjb25zdCB1bD1BYS5zaGFwZTtpZihhc3NlcnQkMih1bC5sZW5ndGg8PTF8fHVsLmxlbmd0aD09PTMsKCk9PmBFcnJvciBpbiBmdXNlZCBjb252MmQ6IG9ubHkgc3VwcG9ydHMgc2NhbGFyLCAxLUQgVGVuc29yIG9yIDMtRCBUZW5zb3IgUFJlTFUgYWN0aXZhdGlvbiB3ZWlnaHRzIGJ1dCBnb3QgYSB0ZW5zb3Igb2YgcmFuay0ke3VsLmxlbmd0aH0uYCksdWwubGVuZ3RoPT09MSlhc3NlcnQkMih1bFswXT09PTF8fHVsWzBdPT09cmwub3V0Q2hhbm5lbHMsKCk9PmBFcnJvciBpbiBmdXNlZCBjb252MmQ6IFBSZUxVIGFjdGl2YXRpb24gd2VpZ2h0cyAoJHt1bH0pIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIG51bWJlciBvZiBvdXRwdXQgY2hhbm5lbHMgKCR7cmwub3V0Q2hhbm5lbHN9KS5gKTtlbHNlIGlmKHVsLmxlbmd0aD09PTMpdHJ5e2Fzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEodWwscmwub3V0U2hhcGUpfWNhdGNoe2NvbnN0IGhsPWBFcnJvciBpbiBmdXNlZCBjb252MmQ6IFBSZUxVIGFjdGl2YXRpb24gd2VpZ2h0cyAoJHt1bH0pIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIG91dHB1dCBzaGFwZSBvZiB0aGUgY29udjJkICgke3JsLm91dFNoYXBlfSkuYDt0aHJvdyBFcnJvcihobCl9YWw9Y29udmVydFRvVGVuc29yJDEoQWEsInByZWx1IHdlaWdodHMiLCJmdXNlZCBjb252MmQiKX1jb25zdCBsbD0odWwsZGwpPT57YXNzZXJ0JDIoU2E9PT0iTkhXQyIsKCk9PmBFcnJvciBpbiBncmFkaWVudCBvZiBmdXNlZCBjb252MkQ6IGdvdCBkYXRhRm9ybWF0IG9mICR7U2F9IGJ1dCBvbmx5IE5IV0MgaXMgY3VycmVudGx5IHN1cHBvcnRlZC5gKTtjb25zdFtobCxwbCxmbCxtbF09ZGwsZ2w9Z2V0RnVzZWREeUFjdGl2YXRpb24kMSh1bCxmbCxrYSk7YXNzZXJ0JDIodHVwbGVWYWx1ZXNBcmVPbmUkMShUYSksKCk9PmBFcnJvciBpbiBncmFkaWVudCBvZiBmdXNlZCBjb252MkQ6IGRpbGF0aW9uIHJhdGVzIGdyZWF0ZXIgdGhhbiAxIGFyZSBub3QgeWV0IHN1cHBvcnRlZCBpbiBncmFkaWVudHMuIEdvdCBkaWxhdGlvbnMgJyR7VGF9J2ApO2NvbnN0ICRsPWNvbnYyREJhY2twcm9wSW5wdXQkMyhwbC5zaGFwZSxnbCxobCx4YSxiYSkseGw9Y29udjJEQmFja3Byb3BGaWx0ZXIkMyhwbCxnbCxobC5zaGFwZSx4YSxiYSkseWw9WyRsLHhsXTtpZihtbCE9bnVsbCl7Y29uc3QgYmw9Z2V0RnVzZWRCaWFzR3JhZGllbnQkMShtbCxnbCk7eWwucHVzaChibCl9cmV0dXJuIHlsfSxpbD17eDp0bCxmaWx0ZXI6ZWwsYmlhczpvbCxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOmFsfSxjbD17c3RyaWRlczp4YSxwYWQ6YmEsZGF0YUZvcm1hdDpTYSxkaWxhdGlvbnM6VGEsZGltUm91bmRpbmdNb2RlOndhLGFjdGl2YXRpb246a2EsbGVha3lyZWx1QWxwaGE6RmF9O3JldHVybiBFYT09bnVsbD9jdXN0b21HcmFkKChkbCxobCxwbCk9PntsZXQgZmw9RU5HSU5FJDEucnVuS2VybmVsKEZ1c2VkQ29udjJEJDEsaWwsY2wpO3JldHVybiBwbChbaGwsZGwsZmxdKSxubCYmKGZsPXJlc2hhcGUkNChmbCxbZmwuc2hhcGVbMV0sZmwuc2hhcGVbMl0sZmwuc2hhcGVbM11dKSkse3ZhbHVlOmZsLGdyYWRGdW5jOmxsfX0pKHRsLGVsKTpjdXN0b21HcmFkKChkbCxobCxwbCxmbCk9PntsZXQgbWw9RU5HSU5FJDEucnVuS2VybmVsKEZ1c2VkQ29udjJEJDEsaWwsY2wpO3JldHVybiBmbChbaGwsZGwsbWwscGxdKSxubCYmKG1sPXJlc2hhcGUkNChtbCxbbWwuc2hhcGVbMV0sbWwuc2hhcGVbMl0sbWwuc2hhcGVbM11dKSkse3ZhbHVlOm1sLGdyYWRGdW5jOmxsfX0pKHRsLGVsLG9sKX1jb25zdCBjb252MmQkMj1vcCQxKHtmdXNlZENvbnYyZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlcl8oaGEsYWEseGEsYmEsU2EsVGE9WzEsMV0sd2Epe2xldCBFYT1oYTtoYS5yYW5rPT09MyYmKEVhPXJlc2hhcGUkNChoYSxbMSxoYS5zaGFwZVswXSxoYS5zaGFwZVsxXSxoYS5zaGFwZVsyXV0pKTtsZXQga2E9YWE7a2EucmFuaz09PTMmJihrYT1yZXNoYXBlJDQoYWEsWzEsYWEuc2hhcGVbMF0sYWEuc2hhcGVbMV0sYWEuc2hhcGVbMl1dKSk7Y29uc3QgQWE9e3g6RWEsZHk6a2F9LEZhPXtzdHJpZGVzOmJhLHBhZDpTYSxkaW1Sb3VuZGluZ01vZGU6d2EsZGlsYXRpb25zOlRhLGZpbHRlclNoYXBlOnhhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKERlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDEsQWEsRmEpfWNvbnN0IGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDM9b3AkMSh7ZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BGaWx0ZXJffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dF8oaGEsYWEseGEsYmEsU2EsVGE9WzEsMV0sd2Epe2xldCBFYT1hYSxrYT0hMTthYS5yYW5rPT09MyYmKGthPSEwLEVhPXJlc2hhcGUkNChhYSxbMSxhYS5zaGFwZVswXSxhYS5zaGFwZVsxXSxhYS5zaGFwZVsyXV0pKTtjb25zdCBBYT17ZHk6RWEsZmlsdGVyOnhhfSxGYT17c3RyaWRlczpiYSxwYWQ6U2EsZGltUm91bmRpbmdNb2RlOndhLGRpbGF0aW9uczpUYSxpbnB1dFNoYXBlOmhhfSxMYT1FTkdJTkUkMS5ydW5LZXJuZWwoRGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dCQxLEFhLEZhKTtyZXR1cm4ga2E/cmVzaGFwZSQ0KExhLFtMYS5zaGFwZVsxXSxMYS5zaGFwZVsyXSxMYS5zaGFwZVszXV0pOkxhfWNvbnN0IGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQkMz1vcCQxKHtkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcElucHV0X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZ1c2VkRGVwdGh3aXNlQ29udjJkXyh7eDpoYSxmaWx0ZXI6YWEsc3RyaWRlczp4YSxwYWQ6YmEsZGF0YUZvcm1hdDpTYT0iTkhXQyIsZGlsYXRpb25zOlRhPVsxLDFdLGRpbVJvdW5kaW5nTW9kZTp3YSxiaWFzOkVhLGFjdGl2YXRpb246a2E9ImxpbmVhciIscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpBYSxsZWFreXJlbHVBbHBoYTpGYX0pe2lmKHNob3VsZEZ1c2UkMShFTkdJTkUkMS5zdGF0ZS5ncmFkaWVudERlcHRoLGthKT09PSExKXtsZXQgY2w9ZGVwdGh3aXNlQ29udjJkJDIoaGEsYWEseGEsYmEsU2EsVGEsd2EpO3JldHVybiBFYSE9bnVsbCYmKGNsPWFkZCQzKGNsLEVhKSksYXBwbHlBY3RpdmF0aW9uJDIoY2wsa2EsQWEsRmEpfWNvbnN0IExhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJ4IiwiZGVwdGh3aXNlQ29udjJkIiwiZmxvYXQzMiIpLGVsPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJmaWx0ZXIiLCJkZXB0aHdpc2VDb252MmQiLCJmbG9hdDMyIik7bGV0IHRsPUxhLG5sPSExO0xhLnJhbms9PT0zJiYobmw9ITAsdGw9cmVzaGFwZSQ0KExhLFsxLExhLnNoYXBlWzBdLExhLnNoYXBlWzFdLExhLnNoYXBlWzJdXSkpLGFzc2VydCQyKHRsLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gZnVzZWQgZGVwdGh3aXNlQ29udjJkOiBpbnB1dCBtdXN0IGJlIHJhbmsgNCwgYnV0IGdvdCByYW5rICR7dGwucmFua30uYCksYXNzZXJ0JDIoZWwucmFuaz09PTQsKCk9PmBFcnJvciBpbiBmdXNlZCBkZXB0aHdpc2VDb252MmQ6IGZpbHRlciBtdXN0IGJlIHJhbmsgNCwgYnV0IGdvdCByYW5rICR7ZWwucmFua30uYCksYXNzZXJ0JDIodGwuc2hhcGVbM109PT1lbC5zaGFwZVsyXSwoKT0+YEVycm9yIGluIGZ1c2VkIGRlcHRod2lzZUNvbnYyZDogbnVtYmVyIG9mIGlucHV0IGNoYW5uZWxzICgke3RsLnNoYXBlWzNdfSkgbXVzdCBtYXRjaCB0aGUgaW5DaGFubmVscyBkaW1lbnNpb24gaW4gZmlsdGVyICR7ZWwuc2hhcGVbMl19LmApLFRhPT1udWxsJiYoVGE9WzEsMV0pLGFzc2VydCQyKGVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZSQxKHhhLFRhKSwoKT0+YEVycm9yIGluIGZ1c2VkIGRlcHRod2lzZUNvbnYyZDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt4YX0gYW5kIGRpbGF0aW9ucyAnJHtUYX0nYCksY2hlY2tQYWRPbkRpbVJvdW5kaW5nTW9kZSQxKCJmdXNlZCBkZXB0aHdpc2VDb252MmQiLGJhLHdhKTtjb25zdCBzbD1jb21wdXRlQ29udjJESW5mbyQxKHRsLnNoYXBlLGVsLnNoYXBlLHhhLFRhLGJhLHdhLCEwKTtsZXQgcmw7RWEhPW51bGwmJihybD1jb252ZXJ0VG9UZW5zb3IkMShFYSwiYmlhcyIsImZ1c2VkIGNvbnYyZCIpLFtybF09bWFrZVR5cGVzTWF0Y2gkMShybCxMYSksYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShzbC5vdXRTaGFwZSxybC5zaGFwZSkpO2xldCBvbDtBYSE9bnVsbCYmKG9sPWNvbnZlcnRUb1RlbnNvciQxKEFhLCJwcmVsdSB3ZWlnaHRzIiwiZnVzZWQgZGVwdGh3aXNlQ29udjJkIikpO2NvbnN0IGFsPShjbCx1bCk9Pnthc3NlcnQkMih0dXBsZVZhbHVlc0FyZU9uZSQxKFRhKSwoKT0+YEVycm9yIGluIGdyYWRpZW50IG9mIGZ1c2VkIGRlcHRod2lzZUNvbnYyZDogZGlsYXRpb24gcmF0ZXMgZ3JlYXRlciB0aGFuIDEgYXJlIG5vdCB5ZXQgc3VwcG9ydGVkLiBHb3QgZGlsYXRpb25zICcke1RhfSdgKTtjb25zdFtkbCxobCxwbCxmbF09dWwsbWw9Z2V0RnVzZWREeUFjdGl2YXRpb24kMShjbCxwbCxrYSksZ2w9ZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dCQzKGhsLnNoYXBlLG1sLGRsLHhhLGJhLFRhLHdhKSwkbD1kZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlciQzKGhsLG1sLGRsLnNoYXBlLHhhLGJhLFRhLHdhKTtpZihmbCE9bnVsbCl7Y29uc3QgeGw9Z2V0RnVzZWRCaWFzR3JhZGllbnQkMShybCxtbCk7cmV0dXJuW2dsLCRsLHhsXX1yZXR1cm5bZ2wsJGxdfSxsbD17eDp0bCxmaWx0ZXI6ZWwsYmlhczpybCxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOm9sfSxpbD17c3RyaWRlczp4YSxwYWQ6YmEsZGF0YUZvcm1hdDpTYSxkaWxhdGlvbnM6VGEsZGltUm91bmRpbmdNb2RlOndhLGFjdGl2YXRpb246a2EsbGVha3lyZWx1QWxwaGE6RmF9O3JldHVybiBFYT09bnVsbD9jdXN0b21HcmFkKCh1bCxkbCxobCk9PntsZXQgcGw9RU5HSU5FJDEucnVuS2VybmVsKEZ1c2VkRGVwdGh3aXNlQ29udjJEJDEsbGwsaWwpO3JldHVybiBobChbZGwsdWwscGxdKSxubCYmKHBsPXJlc2hhcGUkNChwbCxbcGwuc2hhcGVbMV0scGwuc2hhcGVbMl0scGwuc2hhcGVbM11dKSkse3ZhbHVlOnBsLGdyYWRGdW5jOmFsfX0pKHRsLGVsKTpjdXN0b21HcmFkKCh1bCxkbCxobCxwbCk9PntsZXQgZmw9RU5HSU5FJDEucnVuS2VybmVsKEZ1c2VkRGVwdGh3aXNlQ29udjJEJDEsbGwsaWwpO3JldHVybiBwbChbZGwsdWwsZmwsaGxdKSxubCYmKGZsPXJlc2hhcGUkNChmbCxbZmwuc2hhcGVbMV0sZmwuc2hhcGVbMl0sZmwuc2hhcGVbM11dKSkse3ZhbHVlOmZsLGdyYWRGdW5jOmFsfX0pKHRsLGVsLHJsKX1jb25zdCBkZXB0aHdpc2VDb252MmQkMT1vcCQxKHtmdXNlZERlcHRod2lzZUNvbnYyZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmdXNlZE1hdE11bF8oe2E6aGEsYjphYSx0cmFuc3Bvc2VBOnhhPSExLHRyYW5zcG9zZUI6YmE9ITEsYmlhczpTYSxhY3RpdmF0aW9uOlRhPSJsaW5lYXIiLHByZWx1QWN0aXZhdGlvbldlaWdodHM6d2EsbGVha3lyZWx1QWxwaGE6RWE9LjJ9KXtpZihzaG91bGRGdXNlJDEoRU5HSU5FJDEuc3RhdGUuZ3JhZGllbnREZXB0aCxUYSk9PT0hMSl7bGV0IG1sPW1hdE11bCQxKGhhLGFhLHhhLGJhKTtyZXR1cm4gU2EhPW51bGwmJihtbD1hZGQkMyhtbCxTYSkpLGFwcGx5QWN0aXZhdGlvbiQyKG1sLFRhLHdhLEVhKX1sZXQga2E9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJmdXNlZCBtYXRNdWwiKSxBYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYiIsImZ1c2VkIG1hdE11bCIpO1trYSxBYV09bWFrZVR5cGVzTWF0Y2gkMShrYSxBYSk7Y29uc3QgRmE9eGE/a2Euc2hhcGVba2EucmFuay0yXTprYS5zaGFwZVtrYS5yYW5rLTFdLExhPWJhP0FhLnNoYXBlW0FhLnJhbmstMV06QWEuc2hhcGVbQWEucmFuay0yXSxlbD14YT9rYS5zaGFwZVtrYS5yYW5rLTFdOmthLnNoYXBlW2thLnJhbmstMl0sdGw9YmE/QWEuc2hhcGVbQWEucmFuay0yXTpBYS5zaGFwZVtBYS5yYW5rLTFdLG5sPWthLnNoYXBlLnNsaWNlKDAsLTIpLHNsPUFhLnNoYXBlLnNsaWNlKDAsLTIpLHJsPXNpemVGcm9tU2hhcGUkMShubCksb2w9c2l6ZUZyb21TaGFwZSQxKHNsKTthc3NlcnQkMihGYT09PUxhLCgpPT5gRXJyb3IgaW4gZnVzZWQgbWF0TXVsOiBpbm5lciBzaGFwZXMgKCR7RmF9KSBhbmQgKCR7TGF9KSBvZiBUZW5zb3JzIHdpdGggc2hhcGVzICR7a2Euc2hhcGV9IGFuZCAke0FhLnNoYXBlfSBhbmQgdHJhbnNwb3NlQT0ke3hhfSBhbmQgdHJhbnNwb3NlQj0ke2JhfSBtdXN0IG1hdGNoLmApO2NvbnN0IGxsPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoa2Euc2hhcGUuc2xpY2UoMCwtMiksQWEuc2hhcGUuc2xpY2UoMCwtMikpLmNvbmNhdChbZWwsdGxdKSxpbD14YT9yZXNoYXBlJDQoa2EsW3JsLEZhLGVsXSk6cmVzaGFwZSQ0KGthLFtybCxlbCxGYV0pLGNsPWJhP3Jlc2hhcGUkNChBYSxbb2wsdGwsTGFdKTpyZXNoYXBlJDQoQWEsW29sLExhLHRsXSk7bGV0IHVsO1NhIT1udWxsJiYodWw9Y29udmVydFRvVGVuc29yJDEoU2EsImJpYXMiLCJmdXNlZCBtYXRNdWwiKSxbdWxdPW1ha2VUeXBlc01hdGNoJDEodWwsa2EpLGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEobGwsdWwuc2hhcGUpKTtsZXQgZGw7d2EhPW51bGwmJihkbD1jb252ZXJ0VG9UZW5zb3IkMSh3YSwicHJlbHUgd2VpZ2h0cyIsImZ1c2VkIG1hdE11bCIpKTtjb25zdCBobD0obWwsZ2wpPT57Y29uc3RbJGwseGwseWwsYmxdPWdsLFNsPWdldEZ1c2VkRHlBY3RpdmF0aW9uJDEocmVzaGFwZSQ0KG1sLHlsLnNoYXBlKSx5bCxUYSk7bGV0IENsLFRsO2lmKCF4YSYmIWJhPyhDbD1tYXRNdWwkMShTbCx4bCwhMSwhMCksVGw9bWF0TXVsJDEoJGwsU2wsITAsITEpKToheGEmJmJhPyhDbD1tYXRNdWwkMShTbCx4bCwhMSwhMSksVGw9bWF0TXVsJDEoU2wsJGwsITAsITEpKTp4YSYmIWJhPyhDbD1tYXRNdWwkMSh4bCxTbCwhMSwhMCksVGw9bWF0TXVsJDEoJGwsU2wsITEsITEpKTooQ2w9bWF0TXVsJDEoeGwsU2wsITAsITApLFRsPW1hdE11bCQxKFNsLCRsLCEwLCEwKSksU2EhPW51bGwpe2NvbnN0IHdsPWdldEZ1c2VkQmlhc0dyYWRpZW50JDEoYmwsU2wpO3JldHVybltDbCxUbCx3bF19ZWxzZSByZXR1cm5bQ2wsVGxdfSxwbD17YTppbCxiOmNsLGJpYXM6dWwscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpkbH0sZmw9e3RyYW5zcG9zZUE6eGEsdHJhbnNwb3NlQjpiYSxhY3RpdmF0aW9uOlRhLGxlYWt5cmVsdUFscGhhOkVhfTtyZXR1cm4gU2E9PW51bGw/Y3VzdG9tR3JhZCgoZ2wsJGwseGwpPT57Y29uc3QgeWw9RU5HSU5FJDEucnVuS2VybmVsKF9GdXNlZE1hdE11bCQxLHBsLGZsKTtyZXR1cm4geGwoW2dsLCRsLHlsXSkse3ZhbHVlOnJlc2hhcGUkNCh5bCxsbCksZ3JhZEZ1bmM6aGx9fSkoaWwsY2wpOmN1c3RvbUdyYWQoKGdsLCRsLHhsLHlsKT0+e2NvbnN0IGJsPUVOR0lORSQxLnJ1bktlcm5lbChfRnVzZWRNYXRNdWwkMSxwbCxmbCk7cmV0dXJuIHlsKFtnbCwkbCxibCx4bF0pLHt2YWx1ZTpyZXNoYXBlJDQoYmwsbGwpLGdyYWRGdW5jOmhsfX0pKGlsLGNsLHVsKX1jb25zdCBtYXRNdWw9b3AkMSh7ZnVzZWRNYXRNdWxffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovdmFyIGZ1c2VkX29wcz1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxjb252MmQ6Y29udjJkJDIsZGVwdGh3aXNlQ29udjJkOmRlcHRod2lzZUNvbnYyZCQxLG1hdE11bH0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGhhbW1pbmdXaW5kb3dfKGhhKXtyZXR1cm4gY29zaW5lV2luZG93KGhhLC41NCwuNDYpfWNvbnN0IGhhbW1pbmdXaW5kb3c9b3AkMSh7aGFtbWluZ1dpbmRvd199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBoYW5uV2luZG93XyhoYSl7cmV0dXJuIGNvc2luZVdpbmRvdyhoYSwuNSwuNSl9Y29uc3QgaGFubldpbmRvdz1vcCQxKHtoYW5uV2luZG93X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZyYW1lXyhoYSxhYSx4YSxiYT0hMSxTYT0wKXtsZXQgVGE9MDtjb25zdCB3YT1bXTtmb3IoO1RhK2FhPD1oYS5zaXplOyl3YS5wdXNoKHNsaWNlJDMoaGEsVGEsYWEpKSxUYSs9eGE7aWYoYmEpZm9yKDtUYTxoYS5zaXplOyl7Y29uc3QgRWE9VGErYWEtaGEuc2l6ZSxrYT1jb25jYXQkMyhbc2xpY2UkMyhoYSxUYSxhYS1FYSksZmlsbCQ0KFtFYV0sU2EpXSk7d2EucHVzaChrYSksVGErPXhhfXJldHVybiB3YS5sZW5ndGg9PT0wP3RlbnNvcjJkKFtdLFswLGFhXSk6cmVzaGFwZSQ0KGNvbmNhdCQzKHdhKSxbd2EubGVuZ3RoLGFhXSl9Y29uc3QgZnJhbWU9b3AkMSh7ZnJhbWVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RmdF8oaGEsYWEseGEsYmEsU2E9aGFubldpbmRvdyl7YmE9PW51bGwmJihiYT1lbmNsb3NpbmdQb3dlck9mVHdvKGFhKSk7Y29uc3QgVGE9ZnJhbWUoaGEsYWEseGEpLHdhPW11bCQxKFRhLFNhKGFhKSk7cmV0dXJuIHJmZnQod2EsYmEpfWNvbnN0IHN0ZnQ9b3AkMSh7c3RmdF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjcm9wQW5kUmVzaXplXyhoYSxhYSx4YSxiYSxTYT0iYmlsaW5lYXIiLFRhPTApe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbWFnZSIsImNyb3BBbmRSZXNpemUiKSxFYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiYm94ZXMiLCJjcm9wQW5kUmVzaXplIiwiZmxvYXQzMiIpLGthPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJib3hJbmQiLCJjcm9wQW5kUmVzaXplIiwiaW50MzIiKSxBYT1FYS5zaGFwZVswXTthc3NlcnQkMih3YS5yYW5rPT09NCwoKT0+YEVycm9yIGluIGNyb3BBbmRSZXNpemU6IGltYWdlIG11c3QgYmUgcmFuayA0LGJ1dCBnb3QgcmFuayAke3dhLnJhbmt9LmApLGFzc2VydCQyKEVhLnJhbms9PT0yJiZFYS5zaGFwZVsxXT09PTQsKCk9PmBFcnJvciBpbiBjcm9wQW5kUmVzaXplOiBib3hlcyBtdXN0IGJlIGhhdmUgc2l6ZSBbJHtBYX0sNF0gYnV0IGhhZCBzaGFwZSAke0VhLnNoYXBlfS5gKSxhc3NlcnQkMihrYS5yYW5rPT09MSYma2Euc2hhcGVbMF09PT1BYSwoKT0+YEVycm9yIGluIGNyb3BBbmRSZXNpemU6IGJveEluZCBtdXN0IGJlIGhhdmUgc2l6ZSBbJHtBYX1dIGJ1dCBoYWQgc2hhcGUgJHtFYS5zaGFwZX0uYCksYXNzZXJ0JDIoYmEubGVuZ3RoPT09MiwoKT0+YEVycm9yIGluIGNyb3BBbmRSZXNpemU6IGNyb3BTaXplIG11c3QgYmUgb2YgbGVuZ3RoIDIsIGJ1dCBnb3QgbGVuZ3RoICR7YmEubGVuZ3RofS5gKSxhc3NlcnQkMihiYVswXT49MSYmYmFbMV0+PTEsKCk9PmBjcm9wU2l6ZSBtdXN0IGJlIGF0bGVhc3QgWzEsMV0sIGJ1dCB3YXMgJHtiYX1gKSxhc3NlcnQkMihTYT09PSJiaWxpbmVhciJ8fFNhPT09Im5lYXJlc3QiLCgpPT5gbWV0aG9kIG11c3QgYmUgYmlsaW5lYXIgb3IgbmVhcmVzdCwgYnV0IHdhcyAke1NhfWApO2NvbnN0IEZhPXtpbWFnZTp3YSxib3hlczpFYSxib3hJbmQ6a2F9LExhPXttZXRob2Q6U2EsZXh0cmFwb2xhdGlvblZhbHVlOlRhLGNyb3BTaXplOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKENyb3BBbmRSZXNpemUkMSxGYSxMYSl9Y29uc3QgY3JvcEFuZFJlc2l6ZSQ0PW9wJDEoe2Nyb3BBbmRSZXNpemVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZmxpcExlZnRSaWdodF8oaGEpe2NvbnN0IGFhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbWFnZSIsImZsaXBMZWZ0UmlnaHQiLCJmbG9hdDMyIik7YXNzZXJ0JDIoYWEucmFuaz09PTQsKCk9PmBFcnJvciBpbiBmbGlwTGVmdFJpZ2h0OiBpbWFnZSBtdXN0IGJlIHJhbmsgNCxidXQgZ290IHJhbmsgJHthYS5yYW5rfS5gKTtjb25zdCB4YT17aW1hZ2U6YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoRmxpcExlZnRSaWdodCQxLHhhLHt9KX1jb25zdCBmbGlwTGVmdFJpZ2h0PW9wJDEoe2ZsaXBMZWZ0UmlnaHRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ3JheXNjYWxlVG9SR0JfKGhhKXtjb25zdCBhYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiaW1hZ2UiLCJncmF5c2NhbGVUb1JHQiIpLHhhPWFhLnJhbmstMSxiYT1hYS5zaGFwZVt4YV07YXNzZXJ0JDIoYWEucmFuaz49MiwoKT0+YEVycm9yIGluIGdyYXlzY2FsZVRvUkdCOiBpbWFnZXMgbXVzdCBiZSBhdCBsZWFzdCByYW5rIDIsIGJ1dCBnb3QgcmFuayAke2FhLnJhbmt9LmApLGFzc2VydCQyKGJhPT09MSwoKT0+YEVycm9yIGluIGdyYXlzY2FsZVRvUkdCOiBsYXN0IGRpbWVuc2lvbiBvZiBhIGdyYXlzY2FsZSBpbWFnZSBzaG91bGQgYmUgc2l6ZSAxLCBidXQgZ290IHNpemUgJHtiYX0uYCk7Y29uc3QgU2E9bmV3IEFycmF5KGFhLnJhbmspO3JldHVybiBTYS5maWxsKDEsMCx4YSksU2FbeGFdPTMsdGlsZSQ0KGFhLFNhKX1jb25zdCBncmF5c2NhbGVUb1JHQj1vcCQxKHtncmF5c2NhbGVUb1JHQl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZ2JUb0dyYXlzY2FsZV8oaGEpe2NvbnN0IGFhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbWFnZSIsIlJHQlRvR3JheXNjYWxlIikseGE9YWEucmFuay0xLGJhPWFhLnNoYXBlW3hhXTthc3NlcnQkMihhYS5yYW5rPj0yLCgpPT5gRXJyb3IgaW4gUkdCVG9HcmF5c2NhbGU6IGltYWdlcyBtdXN0IGJlIGF0IGxlYXN0IHJhbmsgMiwgYnV0IGdvdCByYW5rICR7YWEucmFua30uYCksYXNzZXJ0JDIoYmE9PT0zLCgpPT5gRXJyb3IgaW4gUkdCVG9HcmF5c2NhbGU6IGxhc3QgZGltZW5zaW9uIG9mIGFuIFJHQiBpbWFnZSBzaG91bGQgYmUgc2l6ZSAzLCBidXQgZ290IHNpemUgJHtiYX0uYCk7Y29uc3QgU2E9YWEuZHR5cGUsVGE9Y2FzdCQ1KGFhLCJmbG9hdDMyIiksd2E9dGVuc29yMWQoWy4yOTg5LC41ODcsLjExNF0pO2xldCBFYTtzd2l0Y2goYWEucmFuayl7Y2FzZSAyOkVhPWVpbnN1bSQzKCJpaixqLT5pIixUYSx3YSk7YnJlYWs7Y2FzZSAzOkVhPWVpbnN1bSQzKCJpamssay0+aWoiLFRhLHdhKTticmVhaztjYXNlIDQ6RWE9ZWluc3VtJDMoImlqa2wsbC0+aWprIixUYSx3YSk7YnJlYWs7Y2FzZSA1OkVhPWVpbnN1bSQzKCJpamtsbSxtLT5pamtsIixUYSx3YSk7YnJlYWs7Y2FzZSA2OkVhPWVpbnN1bSQzKCJpamtsbW4sbi0+aWprbG0iLFRhLHdhKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiTm90IGEgdmFsaWQgdGVuc29yIHJhbmsuIil9cmV0dXJuIEVhPWV4cGFuZERpbXMkNChFYSwtMSksY2FzdCQ1KEVhLFNhKX1jb25zdCByZ2JUb0dyYXlzY2FsZT1vcCQxKHtyZ2JUb0dyYXlzY2FsZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByb3RhdGVXaXRoT2Zmc2V0XyhoYSxhYSx4YT0wLGJhPS41KXtjb25zdCBTYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiaW1hZ2UiLCJyb3RhdGVXaXRoT2Zmc2V0IiwiZmxvYXQzMiIpO2Fzc2VydCQyKFNhLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gcm90YXRlV2l0aE9mZnNldDogaW1hZ2UgbXVzdCBiZSByYW5rIDQsYnV0IGdvdCByYW5rICR7U2EucmFua30uYCk7Y29uc3QgVGE9e2ltYWdlOlNhfSx3YT17cmFkaWFuczphYSxmaWxsVmFsdWU6eGEsY2VudGVyOmJhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFJvdGF0ZVdpdGhPZmZzZXQkMSxUYSx3YSl9Y29uc3Qgcm90YXRlV2l0aE9mZnNldD1vcCQxKHtyb3RhdGVXaXRoT2Zmc2V0X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5vbk1heFN1cHBTYW5pdHlDaGVjayhoYSxhYSx4YSxiYSxTYSxUYSl7YmE9PW51bGwmJihiYT0uNSksU2E9PW51bGwmJihTYT1OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpLFRhPT1udWxsJiYoVGE9MCk7Y29uc3Qgd2E9aGEuc2hhcGVbMF07cmV0dXJuIHhhPU1hdGgubWluKHhhLHdhKSxhc3NlcnQkMigwPD1iYSYmYmE8PTEsKCk9PmBpb3VUaHJlc2hvbGQgbXVzdCBiZSBpbiBbMCwgMV0sIGJ1dCB3YXMgJyR7YmF9J2ApLGFzc2VydCQyKGhhLnJhbms9PT0yLCgpPT5gYm94ZXMgbXVzdCBiZSBhIDJEIHRlbnNvciwgYnV0IHdhcyBvZiByYW5rICcke2hhLnJhbmt9J2ApLGFzc2VydCQyKGhhLnNoYXBlWzFdPT09NCwoKT0+YGJveGVzIG11c3QgaGF2ZSA0IGNvbHVtbnMsIGJ1dCAybmQgZGltZW5zaW9uIHdhcyAke2hhLnNoYXBlWzFdfWApLGFzc2VydCQyKGFhLnJhbms9PT0xLCgpPT4ic2NvcmVzIG11c3QgYmUgYSAxRCB0ZW5zb3IiKSxhc3NlcnQkMihhYS5zaGFwZVswXT09PXdhLCgpPT5gc2NvcmVzIGhhcyBpbmNvbXBhdGlibGUgc2hhcGUgd2l0aCBib3hlcy4gRXhwZWN0ZWQgJHt3YX0sIGJ1dCB3YXMgJHthYS5zaGFwZVswXX1gKSxhc3NlcnQkMigwPD1UYSYmVGE8PTEsKCk9PmBzb2Z0Tm1zU2lnbWEgbXVzdCBiZSBpbiBbMCwgMV0sIGJ1dCB3YXMgJyR7VGF9J2ApLHttYXhPdXRwdXRTaXplOnhhLGlvdVRocmVzaG9sZDpiYSxzY29yZVRocmVzaG9sZDpTYSxzb2Z0Tm1zU2lnbWE6VGF9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uXyhoYSxhYSx4YSxiYT0uNSxTYT1OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpe2NvbnN0IFRhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJib3hlcyIsIm5vbk1heFN1cHByZXNzaW9uIiwiZmxvYXQzMiIpLHdhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJzY29yZXMiLCJub25NYXhTdXBwcmVzc2lvbiIsImZsb2F0MzIiKSxFYT1ub25NYXhTdXBwU2FuaXR5Q2hlY2soVGEsd2EseGEsYmEsU2EpO3hhPUVhLm1heE91dHB1dFNpemUsYmE9RWEuaW91VGhyZXNob2xkLFNhPUVhLnNjb3JlVGhyZXNob2xkO2NvbnN0IGthPXttYXhPdXRwdXRTaXplOnhhLGlvdVRocmVzaG9sZDpiYSxzY29yZVRocmVzaG9sZDpTYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChOb25NYXhTdXBwcmVzc2lvblYzJDEse2JveGVzOlRhLHNjb3Jlczp3YX0sa2EpfWNvbnN0IG5vbk1heFN1cHByZXNzaW9uPW9wJDEoe25vbk1heFN1cHByZXNzaW9uX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJpbmFyeUluc2VydCQxKGhhLGFhLHhhKXtjb25zdCBiYT1iaW5hcnlTZWFyY2gkMShoYSxhYSx4YSksU2E9YmE8MD8tKGJhKzEpOmJhO2hhLnNwbGljZShTYSwwLGFhKX1mdW5jdGlvbiBiaW5hcnlTZWFyY2gkMShoYSxhYSx4YSl7cmV0dXJuIGJpbmFyeVNlYXJjaF8kMShoYSxhYSx4YXx8ZGVmYXVsdENvbXBhcmF0b3IkMSl9ZnVuY3Rpb24gZGVmYXVsdENvbXBhcmF0b3IkMShoYSxhYSl7cmV0dXJuIGhhPmFhPzE6aGE8YWE/LTE6MH1mdW5jdGlvbiBiaW5hcnlTZWFyY2hfJDEoaGEsYWEseGEpe2xldCBiYT0wLFNhPWhhLmxlbmd0aCxUYT0wLHdhPSExO2Zvcig7YmE8U2E7KXtUYT1iYSsoU2EtYmE+Pj4xKTtjb25zdCBFYT14YShhYSxoYVtUYV0pO0VhPjA/YmE9VGErMTooU2E9VGEsd2E9IUVhKX1yZXR1cm4gd2E/YmE6LWJhLTF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25WM0ltcGwkNChoYSxhYSx4YSxiYSxTYSl7cmV0dXJuIG5vbk1heFN1cHByZXNzaW9uSW1wbF8kMShoYSxhYSx4YSxiYSxTYSwwKX1mdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvblY0SW1wbCQ0KGhhLGFhLHhhLGJhLFNhLFRhKXtyZXR1cm4gbm9uTWF4U3VwcHJlc3Npb25JbXBsXyQxKGhhLGFhLHhhLGJhLFNhLDAsITEsVGEsITApfWZ1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uVjVJbXBsJDQoaGEsYWEseGEsYmEsU2EsVGEpe3JldHVybiBub25NYXhTdXBwcmVzc2lvbkltcGxfJDEoaGEsYWEseGEsYmEsU2EsVGEsITApfWZ1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uSW1wbF8kMShoYSxhYSx4YSxiYSxTYSxUYSx3YT0hMSxFYT0hMSxrYT0hMSl7Y29uc3QgQWE9W107Zm9yKGxldCBybD0wO3JsPGFhLmxlbmd0aDtybCsrKWFhW3JsXT5TYSYmQWEucHVzaCh7c2NvcmU6YWFbcmxdLGJveEluZGV4OnJsLHN1cHByZXNzQmVnaW5JbmRleDowfSk7QWEuc29ydChhc2NlbmRpbmdDb21wYXJhdG9yJDEpO2NvbnN0IEZhPVRhPjA/LS41L1RhOjAsTGE9W10sZWw9W107Zm9yKDtMYS5sZW5ndGg8eGEmJkFhLmxlbmd0aD4wOyl7Y29uc3Qgcmw9QWEucG9wKCkse3Njb3JlOm9sLGJveEluZGV4OmFsLHN1cHByZXNzQmVnaW5JbmRleDpsbH09cmw7aWYob2w8U2EpYnJlYWs7bGV0IGlsPSExO2ZvcihsZXQgY2w9TGEubGVuZ3RoLTE7Y2w+PWxsOy0tY2wpe2NvbnN0IHVsPWludGVyc2VjdGlvbk92ZXJVbmlvbiQxKGhhLGFsLExhW2NsXSk7aWYodWw+PWJhKXtpbD0hMDticmVha31pZihybC5zY29yZT1ybC5zY29yZSpzdXBwcmVzc1dlaWdodCQxKGJhLEZhLHVsKSxybC5zY29yZTw9U2EpYnJlYWt9cmwuc3VwcHJlc3NCZWdpbkluZGV4PUxhLmxlbmd0aCxpbHx8KHJsLnNjb3JlPT09b2w/KExhLnB1c2goYWwpLGVsLnB1c2gocmwuc2NvcmUpKTpybC5zY29yZT5TYSYmYmluYXJ5SW5zZXJ0JDEoQWEscmwsYXNjZW5kaW5nQ29tcGFyYXRvciQxKSl9Y29uc3QgdGw9TGEubGVuZ3RoLG5sPXhhLXRsO0VhJiZubD4wJiYoTGEucHVzaCguLi5uZXcgQXJyYXkobmwpLmZpbGwoMCkpLGVsLnB1c2goLi4ubmV3IEFycmF5KG5sKS5maWxsKDApKSk7Y29uc3Qgc2w9e3NlbGVjdGVkSW5kaWNlczpMYX07cmV0dXJuIHdhJiYoc2wuc2VsZWN0ZWRTY29yZXM9ZWwpLGthJiYoc2wudmFsaWRPdXRwdXRzPXRsKSxzbH1mdW5jdGlvbiBpbnRlcnNlY3Rpb25PdmVyVW5pb24kMShoYSxhYSx4YSl7Y29uc3QgYmE9aGEuc3ViYXJyYXkoYWEqNCxhYSo0KzQpLFNhPWhhLnN1YmFycmF5KHhhKjQseGEqNCs0KSxUYT1NYXRoLm1pbihiYVswXSxiYVsyXSksd2E9TWF0aC5taW4oYmFbMV0sYmFbM10pLEVhPU1hdGgubWF4KGJhWzBdLGJhWzJdKSxrYT1NYXRoLm1heChiYVsxXSxiYVszXSksQWE9TWF0aC5taW4oU2FbMF0sU2FbMl0pLEZhPU1hdGgubWluKFNhWzFdLFNhWzNdKSxMYT1NYXRoLm1heChTYVswXSxTYVsyXSksZWw9TWF0aC5tYXgoU2FbMV0sU2FbM10pLHRsPShFYS1UYSkqKGthLXdhKSxubD0oTGEtQWEpKihlbC1GYSk7aWYodGw8PTB8fG5sPD0wKXJldHVybiAwO2NvbnN0IHNsPU1hdGgubWF4KFRhLEFhKSxybD1NYXRoLm1heCh3YSxGYSksb2w9TWF0aC5taW4oRWEsTGEpLGFsPU1hdGgubWluKGthLGVsKSxsbD1NYXRoLm1heChvbC1zbCwwKSpNYXRoLm1heChhbC1ybCwwKTtyZXR1cm4gbGwvKHRsK25sLWxsKX1mdW5jdGlvbiBzdXBwcmVzc1dlaWdodCQxKGhhLGFhLHhhKXtjb25zdCBiYT1NYXRoLmV4cChhYSp4YSp4YSk7cmV0dXJuIHhhPD1oYT9iYTowfWZ1bmN0aW9uIGFzY2VuZGluZ0NvbXBhcmF0b3IkMShoYSxhYSl7cmV0dXJuIGhhLnNjb3JlLWFhLnNjb3JlfHxoYS5zY29yZT09PWFhLnNjb3JlJiZhYS5ib3hJbmRleC1oYS5ib3hJbmRleH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9hc3luYyBmdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvbkFzeW5jXyhoYSxhYSx4YSxiYT0uNSxTYT1OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpe2NvbnN0IFRhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJib3hlcyIsIm5vbk1heFN1cHByZXNzaW9uQXN5bmMiKSx3YT1jb252ZXJ0VG9UZW5zb3IkMShhYSwic2NvcmVzIiwibm9uTWF4U3VwcHJlc3Npb25Bc3luYyIpLEVhPW5vbk1heFN1cHBTYW5pdHlDaGVjayhUYSx3YSx4YSxiYSxTYSk7eGE9RWEubWF4T3V0cHV0U2l6ZSxiYT1FYS5pb3VUaHJlc2hvbGQsU2E9RWEuc2NvcmVUaHJlc2hvbGQ7Y29uc3Qga2E9YXdhaXQgUHJvbWlzZS5hbGwoW1RhLmRhdGEoKSx3YS5kYXRhKCldKSxBYT1rYVswXSxGYT1rYVsxXSx7c2VsZWN0ZWRJbmRpY2VzOkxhfT1ub25NYXhTdXBwcmVzc2lvblYzSW1wbCQ0KEFhLEZhLHhhLGJhLFNhKTtyZXR1cm4gVGEhPT1oYSYmVGEuZGlzcG9zZSgpLHdhIT09YWEmJndhLmRpc3Bvc2UoKSx0ZW5zb3IxZChMYSwiaW50MzIiKX1jb25zdCBub25NYXhTdXBwcmVzc2lvbkFzeW5jPW5vbk1heFN1cHByZXNzaW9uQXN5bmNfOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uV2l0aFNjb3JlXyhoYSxhYSx4YSxiYT0uNSxTYT1OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksVGE9MCl7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoaGEsImJveGVzIiwibm9uTWF4U3VwcHJlc3Npb24iKSxFYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwic2NvcmVzIiwibm9uTWF4U3VwcHJlc3Npb24iKSxrYT1ub25NYXhTdXBwU2FuaXR5Q2hlY2sod2EsRWEseGEsYmEsU2EsVGEpO3hhPWthLm1heE91dHB1dFNpemUsYmE9a2EuaW91VGhyZXNob2xkLFNhPWthLnNjb3JlVGhyZXNob2xkLFRhPWthLnNvZnRObXNTaWdtYTtjb25zdCBBYT17Ym94ZXM6d2Esc2NvcmVzOkVhfSxGYT17bWF4T3V0cHV0U2l6ZTp4YSxpb3VUaHJlc2hvbGQ6YmEsc2NvcmVUaHJlc2hvbGQ6U2Esc29mdE5tc1NpZ21hOlRhfSxMYT1FTkdJTkUkMS5ydW5LZXJuZWwoTm9uTWF4U3VwcHJlc3Npb25WNSQxLEFhLEZhKTtyZXR1cm57c2VsZWN0ZWRJbmRpY2VzOkxhWzBdLHNlbGVjdGVkU2NvcmVzOkxhWzFdfX1jb25zdCBub25NYXhTdXBwcmVzc2lvbldpdGhTY29yZT1vcCQxKHtub25NYXhTdXBwcmVzc2lvbldpdGhTY29yZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9hc3luYyBmdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvbldpdGhTY29yZUFzeW5jXyhoYSxhYSx4YSxiYT0uNSxTYT1OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksVGE9MCl7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoaGEsImJveGVzIiwibm9uTWF4U3VwcHJlc3Npb25Bc3luYyIpLEVhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJzY29yZXMiLCJub25NYXhTdXBwcmVzc2lvbkFzeW5jIiksa2E9bm9uTWF4U3VwcFNhbml0eUNoZWNrKHdhLEVhLHhhLGJhLFNhLFRhKTt4YT1rYS5tYXhPdXRwdXRTaXplLGJhPWthLmlvdVRocmVzaG9sZCxTYT1rYS5zY29yZVRocmVzaG9sZCxUYT1rYS5zb2Z0Tm1zU2lnbWE7Y29uc3QgQWE9YXdhaXQgUHJvbWlzZS5hbGwoW3dhLmRhdGEoKSxFYS5kYXRhKCldKSxGYT1BYVswXSxMYT1BYVsxXSx7c2VsZWN0ZWRJbmRpY2VzOmVsLHNlbGVjdGVkU2NvcmVzOnRsfT1ub25NYXhTdXBwcmVzc2lvblY1SW1wbCQ0KEZhLExhLHhhLGJhLFNhLFRhKTtyZXR1cm4gd2EhPT1oYSYmd2EuZGlzcG9zZSgpLEVhIT09YWEmJkVhLmRpc3Bvc2UoKSx7c2VsZWN0ZWRJbmRpY2VzOnRlbnNvcjFkKGVsLCJpbnQzMiIpLHNlbGVjdGVkU2NvcmVzOnRlbnNvcjFkKHRsKX19Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25XaXRoU2NvcmVBc3luYz1ub25NYXhTdXBwcmVzc2lvbldpdGhTY29yZUFzeW5jXzsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvblBhZGRlZF8oaGEsYWEseGEsYmE9LjUsU2E9TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLFRhPSExKXtjb25zdCB3YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYm94ZXMiLCJub25NYXhTdXBwcmVzc2lvbiIpLEVhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJzY29yZXMiLCJub25NYXhTdXBwcmVzc2lvbiIpLGthPW5vbk1heFN1cHBTYW5pdHlDaGVjayh3YSxFYSx4YSxiYSxTYSxudWxsKSxBYT1rYS5tYXhPdXRwdXRTaXplLEZhPWthLmlvdVRocmVzaG9sZCxMYT1rYS5zY29yZVRocmVzaG9sZCxlbD17Ym94ZXM6d2Esc2NvcmVzOkVhfSx0bD17bWF4T3V0cHV0U2l6ZTpBYSxpb3VUaHJlc2hvbGQ6RmEsc2NvcmVUaHJlc2hvbGQ6TGEscGFkVG9NYXhPdXRwdXRTaXplOlRhfSxubD1FTkdJTkUkMS5ydW5LZXJuZWwoTm9uTWF4U3VwcHJlc3Npb25WNCQxLGVsLHRsKTtyZXR1cm57c2VsZWN0ZWRJbmRpY2VzOm5sWzBdLHZhbGlkT3V0cHV0czpubFsxXX19Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25QYWRkZWQ9b3AkMSh7bm9uTWF4U3VwcHJlc3Npb25QYWRkZWRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovYXN5bmMgZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25QYWRkZWRBc3luY18oaGEsYWEseGEsYmE9LjUsU2E9TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLFRhPSExKXtjb25zdCB3YT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiYm94ZXMiLCJub25NYXhTdXBwcmVzc2lvbkFzeW5jIiksRWE9Y29udmVydFRvVGVuc29yJDEoYWEsInNjb3JlcyIsIm5vbk1heFN1cHByZXNzaW9uQXN5bmMiKSxrYT1ub25NYXhTdXBwU2FuaXR5Q2hlY2sod2EsRWEseGEsYmEsU2EsbnVsbCksQWE9a2EubWF4T3V0cHV0U2l6ZSxGYT1rYS5pb3VUaHJlc2hvbGQsTGE9a2Euc2NvcmVUaHJlc2hvbGQsW2VsLHRsXT1hd2FpdCBQcm9taXNlLmFsbChbd2EuZGF0YSgpLEVhLmRhdGEoKV0pLHtzZWxlY3RlZEluZGljZXM6bmwsdmFsaWRPdXRwdXRzOnNsfT1ub25NYXhTdXBwcmVzc2lvblY0SW1wbCQ0KGVsLHRsLEFhLEZhLExhLFRhKTtyZXR1cm4gd2EhPT1oYSYmd2EuZGlzcG9zZSgpLEVhIT09YWEmJkVhLmRpc3Bvc2UoKSx7c2VsZWN0ZWRJbmRpY2VzOnRlbnNvcjFkKG5sLCJpbnQzMiIpLHZhbGlkT3V0cHV0czpzY2FsYXIkMShzbCwiaW50MzIiKX19Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25QYWRkZWRBc3luYz1ub25NYXhTdXBwcmVzc2lvblBhZGRlZEFzeW5jXzsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNpemVCaWxpbmVhcl8oaGEsYWEseGE9ITEsYmE9ITEpe2NvbnN0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbWFnZXMiLCJyZXNpemVCaWxpbmVhciIpO2Fzc2VydCQyKFNhLnJhbms9PT0zfHxTYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIHJlc2l6ZUJpbGluZWFyOiB4IG11c3QgYmUgcmFuayAzIG9yIDQsIGJ1dCBnb3QgcmFuayAke1NhLnJhbmt9LmApLGFzc2VydCQyKGFhLmxlbmd0aD09PTIsKCk9PmBFcnJvciBpbiByZXNpemVCaWxpbmVhcjogbmV3IHNoYXBlIG11c3QgMkQsIGJ1dCBnb3Qgc2hhcGUgJHthYX0uYCksYXNzZXJ0JDIoYmE9PT0hMXx8eGE9PT0hMSwoKT0+IkVycm9yIGluIHJlc2l6ZUJpbGluZWFyOiBJZiBoYWxmUGl4ZWxDZW50ZXJzIGlzIHRydWUsIGFsaWduQ29ybmVycyBtdXN0IGJlIGZhbHNlLiIpO2xldCBUYT1TYSx3YT0hMTtTYS5yYW5rPT09MyYmKHdhPSEwLFRhPXJlc2hhcGUkNChTYSxbMSxTYS5zaGFwZVswXSxTYS5zaGFwZVsxXSxTYS5zaGFwZVsyXV0pKTtjb25zdCBFYT17aW1hZ2VzOlRhfSxrYT17YWxpZ25Db3JuZXJzOnhhLGhhbGZQaXhlbENlbnRlcnM6YmEsc2l6ZTphYX0sQWE9RU5HSU5FJDEucnVuS2VybmVsKFJlc2l6ZUJpbGluZWFyJDEsRWEsa2EpO3JldHVybiB3YT9yZXNoYXBlJDQoQWEsW0FhLnNoYXBlWzFdLEFhLnNoYXBlWzJdLEFhLnNoYXBlWzNdXSk6QWF9Y29uc3QgcmVzaXplQmlsaW5lYXIkND1vcCQxKHtyZXNpemVCaWxpbmVhcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNpemVOZWFyZXN0TmVpZ2hib3JfKGhhLGFhLHhhPSExLGJhPSExKXtjb25zdCBTYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiaW1hZ2VzIiwicmVzaXplTmVhcmVzdE5laWdoYm9yIik7YXNzZXJ0JDIoU2EucmFuaz09PTN8fFNhLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gcmVzaXplTmVhcmVzdE5laWdoYm9yOiB4IG11c3QgYmUgcmFuayAzIG9yIDQsIGJ1dCBnb3QgcmFuayAke1NhLnJhbmt9LmApLGFzc2VydCQyKGFhLmxlbmd0aD09PTIsKCk9PmBFcnJvciBpbiByZXNpemVOZWFyZXN0TmVpZ2hib3I6IG5ldyBzaGFwZSBtdXN0IDJELCBidXQgZ290IHNoYXBlICR7YWF9LmApLGFzc2VydCQyKFNhLmR0eXBlPT09ImZsb2F0MzIifHxTYS5kdHlwZT09PSJpbnQzMiIsKCk9PiJgaW1hZ2VzYCBtdXN0IGhhdmUgYGludDMyYCBvciBgZmxvYXQzMmAgYXMgZHR5cGUiKSxhc3NlcnQkMihiYT09PSExfHx4YT09PSExLCgpPT4iRXJyb3IgaW4gcmVzaXplTmVhcmVzdE5laWdoYm9yOiBJZiBoYWxmUGl4ZWxDZW50ZXJzIGlzIHRydWUsIGFsaWduQ29ybmVycyBtdXN0IGJlIGZhbHNlLiIpO2xldCBUYT1TYSx3YT0hMTtTYS5yYW5rPT09MyYmKHdhPSEwLFRhPXJlc2hhcGUkNChTYSxbMSxTYS5zaGFwZVswXSxTYS5zaGFwZVsxXSxTYS5zaGFwZVsyXV0pKTtjb25zdCBFYT17aW1hZ2VzOlRhfSxrYT17YWxpZ25Db3JuZXJzOnhhLGhhbGZQaXhlbENlbnRlcnM6YmEsc2l6ZTphYX0sQWE9RU5HSU5FJDEucnVuS2VybmVsKFJlc2l6ZU5lYXJlc3ROZWlnaGJvciQxLEVhLGthKTtyZXR1cm4gd2E/cmVzaGFwZSQ0KEFhLFtBYS5zaGFwZVsxXSxBYS5zaGFwZVsyXSxBYS5zaGFwZVszXV0pOkFhfWNvbnN0IHJlc2l6ZU5lYXJlc3ROZWlnaGJvciQzPW9wJDEoe3Jlc2l6ZU5lYXJlc3ROZWlnaGJvcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdGhyZXNob2xkXyhoYSxhYT0iYmluYXJ5Iix4YT0hMSxiYT0uNSl7Y29uc3QgU2E9Y29udmVydFRvVGVuc29yJDEoaGEsImltYWdlIiwidGhyZXNob2xkIiksVGE9LjI5ODksd2E9LjU4NyxFYT0uMTE0LGthPVNhLnNoYXBlWzBdKlNhLnNoYXBlWzFdO2xldCBBYT1tdWwkMSh0ZW5zb3IxZChbYmFdKSwyNTUpLEZhLExhLGVsLHRsO2lmKGFzc2VydCQyKFNhLnJhbms9PT0zLCgpPT5gRXJyb3IgaW4gdGhyZXNob2xkOiBpbWFnZSBtdXN0IGJlIHJhbmsgMyxidXQgZ290IHJhbmsgJHtTYS5yYW5rfS5gKSxhc3NlcnQkMihTYS5zaGFwZVsyXT09PTN8fFNhLnNoYXBlWzJdPT09MSwoKT0+YEVycm9yIGluIHRocmVzaG9sZDogaW1hZ2UgY29sb3IgY2hhbm5lbCBtdXN0IGJlIGVxdWFsIHRvIDMgb3IgMWJ1dCBnb3QgJHtTYS5zaGFwZVsyXX0uYCksYXNzZXJ0JDIoU2EuZHR5cGU9PT0iaW50MzIifHxTYS5kdHlwZT09PSJmbG9hdDMyIiwoKT0+YEVycm9yIGluIGR0eXBlOiBpbWFnZSBkdHlwZSBtdXN0IGJlIGludDMyIG9yIGZsb2F0MzIsYnV0IGdvdCBkdHlwZSAke1NhLmR0eXBlfS5gKSxhc3NlcnQkMihhYT09PSJvdHN1Inx8YWE9PT0iYmluYXJ5IiwoKT0+YE1ldGhvZCBtdXN0IGJlIGJpbmFyeSBvciBvdHN1LCBidXQgd2FzICR7YWF9YCksU2Euc2hhcGVbMl09PT0zKXtbRmEsTGEsZWxdPXNwbGl0JDMoU2EsWzEsMSwxXSwtMSk7Y29uc3Qgcmw9bXVsJDEoRmEsVGEpLG9sPW11bCQxKExhLHdhKSxhbD1tdWwkMShlbCxFYSk7dGw9YWRkJDMoYWRkJDMocmwsb2wpLGFsKX1lbHNlIHRsPWhhO2lmKGFhPT09Im90c3UiKXtjb25zdCBybD1iaW5jb3VudCQzKGNhc3QkNShyb3VuZCQ0KHRsKSwiaW50MzIiKSx0ZW5zb3IoW10pLDI1Nik7QWE9b3RzdShybCxrYSl9Y29uc3Qgbmw9eGE/bGVzc0VxdWFsJDModGwsQWEpOmdyZWF0ZXIkMyh0bCxBYSk7cmV0dXJuIGNhc3QkNShtdWwkMShubCwyNTUpLCJpbnQzMiIpfWZ1bmN0aW9uIG90c3UoaGEsYWEpe2xldCB4YT10ZW5zb3IxZChbLTFdKSxiYT10ZW5zb3IxZChbMF0pLFNhPXRlbnNvcjFkKFswXSksVGEsd2EsRWEsa2EsQWEsRmE7Zm9yKGxldCBMYT0wO0xhPGhhLnNpemUtMTtMYSsrKXtUYT1zbGljZSQzKGhhLDAsTGErMSksd2E9c2xpY2UkMyhoYSxMYSsxKSxBYT1kaXYkMihzdW0kNShUYSksYWEpLEZhPWRpdiQyKHN1bSQ1KHdhKSxhYSk7Y29uc3QgZWw9c3VtJDUobXVsJDEoVGEscmFuZ2UkNCgwLFRhLnNpemUpKSk7RWE9ZGl2JDIoZWwsc3VtJDUoVGEpKTtjb25zdCB0bD1maWxsJDQod2Euc2hhcGUsVGEuc2l6ZSksbmw9YWRkJDMocmFuZ2UkNCgwLHdhLnNpemUpLHRsKSxzbD1tdWwkMSh3YSxubCk7a2E9ZGl2JDIoc3VtJDUoc2wpLHN1bSQ1KHdhKSk7Y29uc3Qgcmw9c3ViJDQoRWEsa2EpLG9sPXN1YiQ0KEVhLGthKSxhbD1tdWwkMShBYSxGYSk7U2E9bXVsJDEobXVsJDEoYWwscmwpLG9sKTtjb25zdCBsbD1ncmVhdGVyJDMoU2EsYmEpO2JhPXdoZXJlKGxsLFNhLGJhKSx4YT13aGVyZShsbCx0ZW5zb3IxZChbTGFdKSx4YSl9cmV0dXJuIHhhfWNvbnN0IHRocmVzaG9sZCQxPW9wJDEoe3RocmVzaG9sZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0cmFuc2Zvcm1fKGhhLGFhLHhhPSJuZWFyZXN0IixiYT0iY29uc3RhbnQiLFNhPTAsVGEpe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbWFnZSIsInRyYW5zZm9ybSIsImZsb2F0MzIiKSxFYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwidHJhbnNmb3JtcyIsInRyYW5zZm9ybSIsImZsb2F0MzIiKTthc3NlcnQkMih3YS5yYW5rPT09NCwoKT0+YEVycm9yIGluIHRyYW5zZm9ybTogaW1hZ2UgbXVzdCBiZSByYW5rIDQsYnV0IGdvdCByYW5rICR7d2EucmFua30uYCksYXNzZXJ0JDIoRWEucmFuaz09PTImJihFYS5zaGFwZVswXT09PXdhLnNoYXBlWzBdfHxFYS5zaGFwZVswXT09PTEpJiZFYS5zaGFwZVsxXT09PTgsKCk9PiJFcnJvciBpbiB0cmFuc2Zvcm06IElucHV0IHRyYW5zZm9ybSBzaG91bGQgYmUgYmF0Y2ggeCA4IG9yIDEgeCA4IiksYXNzZXJ0JDIoVGE9PW51bGx8fFRhLmxlbmd0aD09PTIsKCk9PmBFcnJvciBpbiB0cmFuc2Zvcm06IG91dHB1dFNoYXBlIG11c3QgYmUgW2hlaWdodCwgd2lkdGhdIG9yIG51bGwsIGJ1dCBnb3QgJHtUYX0uYCk7Y29uc3Qga2E9e2ltYWdlOndhLHRyYW5zZm9ybXM6RWF9LEFhPXtpbnRlcnBvbGF0aW9uOnhhLGZpbGxNb2RlOmJhLGZpbGxWYWx1ZTpTYSxvdXRwdXRTaGFwZTpUYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChUcmFuc2Zvcm0kMSxrYSxBYSl9Y29uc3QgdHJhbnNmb3JtJDM9b3AkMSh7dHJhbnNmb3JtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJhbmRQYXJ0XyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsImEiLCJiYW5kUGFydCIpO2Fzc2VydCQyKGJhLnJhbms+PTIsKCk9PmBiYW5kUGFydCgpOiBSYW5rIG11c3QgYmUgYXQgbGVhc3QgMiwgZ290ICR7YmEucmFua30uYCk7Y29uc3QgU2E9YmEuc2hhcGUsW1RhLHdhXT1iYS5zaGFwZS5zbGljZSgtMik7bGV0IEVhLGthO3R5cGVvZiBhYT09Im51bWJlciI/KGFzc2VydCQyKGFhJTE9PT0wLCgpPT5gYmFuZFBhcnQoKTogbnVtTG93ZXIgbXVzdCBiZSBhbiBpbnRlZ2VyLCBnb3QgJHthYX0uYCksYXNzZXJ0JDIoYWE8PVRhLCgpPT5gYmFuZFBhcnQoKTogbnVtTG93ZXIgKCR7YWF9KSBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiByb3dzICgke1RhfSkuYCksRWE9Y29udmVydFRvVGVuc29yJDEoYWE8MD9UYTphYSwibnVtTG93ZXIiLCJiYW5kUGFydCIpKTooYXNzZXJ0JDIoYWEuZHR5cGU9PT0iaW50MzIiLCgpPT4iYmFuZFBhcnQoKTogbnVtTG93ZXIncyBkdHlwZSBtdXN0IGJlIGFuIGludDMyLiIpLEVhPXdoZXJlKGxlc3MkMyhhYSwwKSxUYSxtaW5pbXVtJDMoYWEsVGEpKSksdHlwZW9mIHhhPT0ibnVtYmVyIj8oYXNzZXJ0JDIoeGElMT09PTAsKCk9PmBiYW5kUGFydCgpOiBudW1VcHBlciBtdXN0IGJlIGFuIGludGVnZXIsIGdvdCAke3hhfS5gKSxhc3NlcnQkMih4YTw9d2EsKCk9PmBiYW5kUGFydCgpOiBudW1VcHBlciAoJHt4YX0pIG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgKCR7d2F9KS5gKSxrYT1jb252ZXJ0VG9UZW5zb3IkMSh4YTwwP3dhOnhhLCJudW1VcHBlciIsImJhbmRQYXJ0IikpOihhc3NlcnQkMih4YS5kdHlwZT09PSJpbnQzMiIsKCk9PiJiYW5kUGFydCgpOiBudW1VcHBlcidzIGR0eXBlIG11c3QgYmUgYW4gaW50MzIuIiksa2E9d2hlcmUobGVzcyQzKHhhLDApLHdhLG1pbmltdW0kMyh4YSx3YSkpKTtjb25zdCBBYT1yZXNoYXBlJDQocmFuZ2UkNCgwLFRhLDEsImludDMyIiksWy0xLDFdKSxGYT1yYW5nZSQ0KDAsd2EsMSwiaW50MzIiKSxMYT1zdWIkNChBYSxGYSksZWw9bG9naWNhbEFuZCQzKGxlc3NFcXVhbCQzKExhLEVhKSxncmVhdGVyRXF1YWwkMyhMYSxuZWckMyhrYSkpKSx0bD16ZXJvcyQyKFtUYSx3YV0sYmEuZHR5cGUpO3JldHVybiByZXNoYXBlJDQoc3RhY2sodW5zdGFjayhyZXNoYXBlJDQoYmEsWy0xLFRhLHdhXSkpLm1hcChubD0+d2hlcmUoZWwsbmwsdGwpKSksU2EpfWNvbnN0IGJhbmRQYXJ0PW9wJDEoe2JhbmRQYXJ0X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdyYW1TY2htaWR0XyhoYSl7bGV0IGFhO2lmKEFycmF5LmlzQXJyYXkoaGEpKXthYT0hMSxhc3NlcnQkMihoYSE9bnVsbCYmaGEubGVuZ3RoPjAsKCk9PiJHcmFtLVNjaG1pZHQgcHJvY2VzczogaW5wdXQgbXVzdCBub3QgYmUgbnVsbCwgdW5kZWZpbmVkLCBvciBlbXB0eSIpO2NvbnN0IFNhPWhhWzBdLnNoYXBlWzBdO2ZvcihsZXQgVGE9MTtUYTxoYS5sZW5ndGg7KytUYSlhc3NlcnQkMihoYVtUYV0uc2hhcGVbMF09PT1TYSwoKT0+YEdyYW0tU2NobWlkdDogTm9uLXVuaXF1ZSBsZW5ndGhzIGZvdW5kIGluIHRoZSBpbnB1dCB2ZWN0b3JzOiAoJHtoYVtUYV0uc2hhcGVbMF19IHZzLiAke1NhfSlgKX1lbHNlIGFhPSEwLGhhPXNwbGl0JDMoaGEsaGEuc2hhcGVbMF0sMCkubWFwKFNhPT5zcXVlZXplKFNhLFswXSkpO2Fzc2VydCQyKGhhLmxlbmd0aDw9aGFbMF0uc2hhcGVbMF0sKCk9PmBHcmFtLVNjaG1pZHQ6IE51bWJlciBvZiB2ZWN0b3JzICgke2hhLmxlbmd0aH0pIGV4Y2VlZHMgbnVtYmVyIG9mIGRpbWVuc2lvbnMgKCR7aGFbMF0uc2hhcGVbMF19KS5gKTtjb25zdCB4YT1bXSxiYT1oYTtmb3IobGV0IFNhPTA7U2E8aGEubGVuZ3RoOysrU2EpeGEucHVzaChFTkdJTkUkMS50aWR5KCgpPT57bGV0IFRhPWJhW1NhXTtpZihTYT4wKWZvcihsZXQgd2E9MDt3YTxTYTsrK3dhKXtjb25zdCBFYT1tdWwkMShzdW0kNShtdWwkMSh4YVt3YV0sVGEpKSx4YVt3YV0pO1RhPXN1YiQ0KFRhLEVhKX1yZXR1cm4gZGl2JDIoVGEsbm9ybShUYSwiZXVjbGlkZWFuIikpfSkpO3JldHVybiBhYT9zdGFjayh4YSwwKTp4YX1jb25zdCBncmFtU2NobWlkdD1vcCQxKHtncmFtU2NobWlkdF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBxcl8oaGEsYWE9ITEpe2lmKGFzc2VydCQyKGhhLnJhbms+PTIsKCk9PmBxcigpIHJlcXVpcmVzIGlucHV0IHRlbnNvciB0byBoYXZlIGEgcmFuayA+PSAyLCBidXQgZ290IHJhbmsgJHtoYS5yYW5rfWApLGhhLnJhbms9PT0yKXJldHVybiBxcjJkKGhhLGFhKTt7Y29uc3QgeGE9aGEuc2hhcGUuc2xpY2UoMCxoYS5zaGFwZS5sZW5ndGgtMikucmVkdWNlKChrYSxBYSk9PmthKkFhKSxiYT11bnN0YWNrKHJlc2hhcGUkNChoYSxbeGEsaGEuc2hhcGVbaGEuc2hhcGUubGVuZ3RoLTJdLGhhLnNoYXBlW2hhLnNoYXBlLmxlbmd0aC0xXV0pLDApLFNhPVtdLFRhPVtdO2JhLmZvckVhY2goa2E9Pntjb25zdFtBYSxGYV09cXIyZChrYSxhYSk7U2EucHVzaChBYSksVGEucHVzaChGYSl9KTtjb25zdCB3YT1yZXNoYXBlJDQoc3RhY2soU2EsMCksaGEuc2hhcGUpLEVhPXJlc2hhcGUkNChzdGFjayhUYSwwKSxoYS5zaGFwZSk7cmV0dXJuW3dhLEVhXX19ZnVuY3Rpb24gcXIyZChoYSxhYT0hMSl7cmV0dXJuIEVOR0lORSQxLnRpZHkoKCk9Pnthc3NlcnQkMihoYS5zaGFwZS5sZW5ndGg9PT0yLCgpPT5gcXIyZCgpIHJlcXVpcmVzIGEgMkQgVGVuc29yLCBidXQgZ290IGEgJHtoYS5zaGFwZS5sZW5ndGh9RCBUZW5zb3IuYCk7Y29uc3QgeGE9aGEuc2hhcGVbMF0sYmE9aGEuc2hhcGVbMV07bGV0IFNhPWV5ZSh4YSksVGE9Y2xvbmUkMShoYSk7Y29uc3Qgd2E9dGVuc29yMmQoW1sxXV0sWzEsMV0pO2xldCBFYT1jbG9uZSQxKHdhKTtjb25zdCBrYT14YT49YmE/YmE6eGE7Zm9yKGxldCBBYT0wO0FhPGthOysrQWEpe2NvbnN0IEZhPVRhLExhPUVhLGVsPVNhO1tFYSxUYSxTYV09RU5HSU5FJDEudGlkeSgoKT0+e2NvbnN0IHRsPXNsaWNlJDMoVGEsW0FhLEFhXSxbeGEtQWEsMV0pLG5sPW5vcm0odGwpLHNsPXNsaWNlJDMoVGEsW0FhLEFhXSxbMSwxXSkscmw9d2hlcmUoZ3JlYXRlciQzKHNsLDApLHRlbnNvcjJkKFtbLTFdXSksdGVuc29yMmQoW1sxXV0pKSxvbD1zdWIkNChzbCxtdWwkMShybCxubCkpLGFsPWRpdiQyKHRsLG9sKTthbC5zaGFwZVswXT09PTE/RWE9Y2xvbmUkMSh3YSk6RWE9Y29uY2F0JDMoW3dhLHNsaWNlJDMoYWwsWzEsMF0sW2FsLnNoYXBlWzBdLTEsYWwuc2hhcGVbMV1dKV0sMCk7Y29uc3QgbGw9bmVnJDMoZGl2JDIobWF0TXVsJDEocmwsb2wpLG5sKSksaWw9c2xpY2UkMyhUYSxbQWEsMF0sW3hhLUFhLGJhXSksY2w9bXVsJDEobGwsRWEpLHVsPXRyYW5zcG9zZSQzKEVhKTtpZihBYT09PTApVGE9c3ViJDQoaWwsbWF0TXVsJDEoY2wsbWF0TXVsJDEodWwsaWwpKSk7ZWxzZXtjb25zdCBwbD1zdWIkNChpbCxtYXRNdWwkMShjbCxtYXRNdWwkMSh1bCxpbCkpKTtUYT1jb25jYXQkMyhbc2xpY2UkMyhUYSxbMCwwXSxbQWEsYmFdKSxwbF0sMCl9Y29uc3QgZGw9dHJhbnNwb3NlJDMoY2wpLGhsPXNsaWNlJDMoU2EsWzAsQWFdLFt4YSxTYS5zaGFwZVsxXS1BYV0pO2lmKEFhPT09MClTYT1zdWIkNChobCxtYXRNdWwkMShtYXRNdWwkMShobCxFYSksZGwpKTtlbHNle2NvbnN0IHBsPXN1YiQ0KGhsLG1hdE11bCQxKG1hdE11bCQxKGhsLEVhKSxkbCkpO1NhPWNvbmNhdCQzKFtzbGljZSQzKFNhLFswLDBdLFt4YSxBYV0pLHBsXSwxKX1yZXR1cm5bRWEsVGEsU2FdfSksZGlzcG9zZSQxKFtGYSxMYSxlbF0pfXJldHVybiFhYSYmeGE+YmEmJihTYT1zbGljZSQzKFNhLFswLDBdLFt4YSxiYV0pLFRhPXNsaWNlJDMoVGEsWzAsMF0sW2JhLGJhXSkpLFtTYSxUYV19KX1jb25zdCBxciQxPW9wJDEoe3FyX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBSZWR1Y3Rpb247KGZ1bmN0aW9uKGhhKXtoYVtoYS5OT05FPTBdPSJOT05FIixoYVtoYS5NRUFOPTFdPSJNRUFOIixoYVtoYS5TVU09Ml09IlNVTSIsaGFbaGEuU1VNX0JZX05PTlpFUk9fV0VJR0hUUz0zXT0iU1VNX0JZX05PTlpFUk9fV0VJR0hUUyJ9KShSZWR1Y3Rpb258fChSZWR1Y3Rpb249e30pKTtmdW5jdGlvbiBjb21wdXRlV2VpZ2h0ZWRMb3NzXyhoYSxhYSx4YT1SZWR1Y3Rpb24uU1VNX0JZX05PTlpFUk9fV0VJR0hUUyl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsImxvc3NlcyIsImNvbXB1dGVXZWlnaHRlZExvc3MiKTtsZXQgU2E9bnVsbDthYSE9bnVsbCYmKFNhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJ3ZWlnaHRzIiwiY29tcHV0ZVdlaWdodGVkTG9zcyIpKTtjb25zdCBUYT1TYT09bnVsbD9iYTptdWwkMShiYSxTYSk7aWYoeGE9PT1SZWR1Y3Rpb24uTk9ORSlyZXR1cm4gVGE7aWYoeGE9PT1SZWR1Y3Rpb24uU1VNKXJldHVybiBzdW0kNShUYSk7aWYoeGE9PT1SZWR1Y3Rpb24uTUVBTil7aWYoU2E9PW51bGwpcmV0dXJuIG1lYW4kMShUYSk7e2NvbnN0IHdhPWJhLnNpemUvU2Euc2l6ZSxFYT1kaXYkMihzdW0kNShUYSksc3VtJDUoU2EpKTtyZXR1cm4gd2E+MT9kaXYkMihFYSxzY2FsYXIkMSh3YSkpOkVhfX1pZih4YT09PVJlZHVjdGlvbi5TVU1fQllfTk9OWkVST19XRUlHSFRTKXtpZihTYT09bnVsbClyZXR1cm4gZGl2JDIoc3VtJDUoVGEpLHNjYWxhciQxKGJhLnNpemUpKTt7Y29uc3Qgd2E9bXVsJDEoU2Esb25lcyQxKGJhLnNoYXBlKSksRWE9Y2FzdCQ1KHN1bSQ1KG5vdEVxdWFsJDMod2Esc2NhbGFyJDEoMCkpKSwiZmxvYXQzMiIpO3JldHVybiBkaXYkMihzdW0kNShUYSksRWEpfX10aHJvdyBFcnJvcihgVW5rbm93biByZWR1Y3Rpb246ICR7eGF9YCl9Y29uc3QgY29tcHV0ZVdlaWdodGVkTG9zcyQxPW9wJDEoe2NvbXB1dGVXZWlnaHRlZExvc3NffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYWJzb2x1dGVEaWZmZXJlbmNlXyhoYSxhYSx4YSxiYT1SZWR1Y3Rpb24uU1VNX0JZX05PTlpFUk9fV0VJR0hUUyl7Y29uc3QgU2E9Y29udmVydFRvVGVuc29yJDEoaGEsImxhYmVscyIsImFic29sdXRlRGlmZmVyZW5jZSIpLFRhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJwcmVkaWN0aW9ucyIsImFic29sdXRlRGlmZmVyZW5jZSIpO2xldCB3YT1udWxsO3hhIT1udWxsJiYod2E9Y29udmVydFRvVGVuc29yJDEoeGEsIndlaWdodHMiLCJhYnNvbHV0ZURpZmZlcmVuY2UiKSksYXNzZXJ0U2hhcGVzTWF0Y2gkMShTYS5zaGFwZSxUYS5zaGFwZSwiRXJyb3IgaW4gYWJzb2x1dGVEaWZmZXJlbmNlOiAiKTtjb25zdCBFYT1hYnMkNChzdWIkNChTYSxUYSkpO3JldHVybiBjb21wdXRlV2VpZ2h0ZWRMb3NzJDEoRWEsd2EsYmEpfWNvbnN0IGFic29sdXRlRGlmZmVyZW5jZT1vcCQxKHthYnNvbHV0ZURpZmZlcmVuY2VffSk7ZnVuY3Rpb24gY29zaW5lRGlzdGFuY2VfKGhhLGFhLHhhLGJhLFNhPVJlZHVjdGlvbi5TVU1fQllfTk9OWkVST19XRUlHSFRTKXtjb25zdCBUYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwibGFiZWxzIiwiY29zaW5lRGlzdGFuY2UiKSx3YT1jb252ZXJ0VG9UZW5zb3IkMShhYSwicHJlZGljdGlvbnMiLCJjb3NpbmVEaXN0YW5jZSIpO2xldCBFYT1udWxsO2JhIT1udWxsJiYoRWE9Y29udmVydFRvVGVuc29yJDEoYmEsIndlaWdodHMiLCJjb3NpbmVEaXN0YW5jZSIpKSxhc3NlcnRTaGFwZXNNYXRjaCQxKFRhLnNoYXBlLHdhLnNoYXBlLCJFcnJvciBpbiBjb3NpbmVEaXN0YW5jZTogIik7Y29uc3Qga2E9c2NhbGFyJDEoMSksQWE9c3ViJDQoa2Esc3VtJDUobXVsJDEoVGEsd2EpLHhhLCEwKSk7cmV0dXJuIGNvbXB1dGVXZWlnaHRlZExvc3MkMShBYSxFYSxTYSl9Y29uc3QgY29zaW5lRGlzdGFuY2U9b3AkMSh7Y29zaW5lRGlzdGFuY2VffSk7ZnVuY3Rpb24gaGluZ2VMb3NzXyhoYSxhYSx4YSxiYT1SZWR1Y3Rpb24uU1VNX0JZX05PTlpFUk9fV0VJR0hUUyl7bGV0IFNhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJsYWJlbHMiLCJoaW5nZUxvc3MiKTtjb25zdCBUYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwicHJlZGljdGlvbnMiLCJoaW5nZUxvc3MiKTtsZXQgd2E9bnVsbDt4YSE9bnVsbCYmKHdhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ3ZWlnaHRzIiwiaGluZ2VMb3NzIikpLGFzc2VydFNoYXBlc01hdGNoJDEoU2Euc2hhcGUsVGEuc2hhcGUsIkVycm9yIGluIGhpbmdlTG9zczogIik7Y29uc3QgRWE9c2NhbGFyJDEoMSk7U2E9c3ViJDQobXVsJDEoc2NhbGFyJDEoMiksU2EpLEVhKTtjb25zdCBrYT1yZWx1JDQoc3ViJDQoRWEsbXVsJDEoU2EsVGEpKSk7cmV0dXJuIGNvbXB1dGVXZWlnaHRlZExvc3MkMShrYSx3YSxiYSl9Y29uc3QgaGluZ2VMb3NzPW9wJDEoe2hpbmdlTG9zc199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBodWJlckxvc3NfKGhhLGFhLHhhLGJhPTEsU2E9UmVkdWN0aW9uLlNVTV9CWV9OT05aRVJPX1dFSUdIVFMpe2NvbnN0IFRhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJsYWJlbHMiLCJodWJlckxvc3MiKSx3YT1jb252ZXJ0VG9UZW5zb3IkMShhYSwicHJlZGljdGlvbnMiLCJodWJlckxvc3MiKTtsZXQgRWE9bnVsbDt4YSE9bnVsbCYmKEVhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ3ZWlnaHRzIiwiaHViZXJMb3NzIikpLGFzc2VydFNoYXBlc01hdGNoJDEoVGEuc2hhcGUsd2Euc2hhcGUsIkVycm9yIGluIGh1YmVyTG9zczogIik7Y29uc3Qga2E9c2NhbGFyJDEoYmEpLEFhPWFicyQ0KHN1YiQ0KHdhLFRhKSksRmE9bWluaW11bSQzKEFhLGthKSxMYT1zdWIkNChBYSxGYSksZWw9YWRkJDMobXVsJDEoc2NhbGFyJDEoLjUpLHNxdWFyZSQ0KEZhKSksbXVsJDEoa2EsTGEpKTtyZXR1cm4gY29tcHV0ZVdlaWdodGVkTG9zcyQxKGVsLEVhLFNhKX1jb25zdCBodWJlckxvc3M9b3AkMSh7aHViZXJMb3NzX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvZ0xvc3NfKGhhLGFhLHhhLGJhPTFlLTcsU2E9UmVkdWN0aW9uLlNVTV9CWV9OT05aRVJPX1dFSUdIVFMpe2NvbnN0IFRhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJsYWJlbHMiLCJsb2dMb3NzIiksd2E9Y29udmVydFRvVGVuc29yJDEoYWEsInByZWRpY3Rpb25zIiwibG9nTG9zcyIpO2xldCBFYT1udWxsO3hhIT1udWxsJiYoRWE9Y29udmVydFRvVGVuc29yJDEoeGEsIndlaWdodHMiLCJsb2dMb3NzIikpLGFzc2VydFNoYXBlc01hdGNoJDEoVGEuc2hhcGUsd2Euc2hhcGUsIkVycm9yIGluIGxvZ0xvc3M6ICIpO2NvbnN0IGthPXNjYWxhciQxKDEpLEFhPXNjYWxhciQxKGJhKSxGYT1uZWckMyhtdWwkMShUYSxsb2ckNChhZGQkMyh3YSxBYSkpKSksTGE9bXVsJDEoc3ViJDQoa2EsVGEpLGxvZyQ0KGFkZCQzKHN1YiQ0KGthLHdhKSxBYSkpKSxlbD1zdWIkNChGYSxMYSk7cmV0dXJuIGNvbXB1dGVXZWlnaHRlZExvc3MkMShlbCxFYSxTYSl9Y29uc3QgbG9nTG9zcz1vcCQxKHtsb2dMb3NzX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1lYW5TcXVhcmVkRXJyb3JfKGhhLGFhLHhhLGJhPVJlZHVjdGlvbi5TVU1fQllfTk9OWkVST19XRUlHSFRTKXtjb25zdCBTYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwibGFiZWxzIiwibWVhblNxdWFyZWRFcnJvciIpLFRhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJwcmVkaWN0aW9ucyIsIm1lYW5TcXVhcmVkRXJyb3IiKTtsZXQgd2E9bnVsbDt4YSE9bnVsbCYmKHdhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ3ZWlnaHRzIiwibWVhblNxdWFyZWRFcnJvciIpKSxhc3NlcnRTaGFwZXNNYXRjaCQxKFNhLnNoYXBlLFRhLnNoYXBlLCJFcnJvciBpbiBtZWFuU3F1YXJlZEVycm9yOiAiKTtjb25zdCBFYT1zcXVhcmVkRGlmZmVyZW5jZSQzKFNhLFRhKTtyZXR1cm4gY29tcHV0ZVdlaWdodGVkTG9zcyQxKEVhLHdhLGJhKX1jb25zdCBtZWFuU3F1YXJlZEVycm9yJDE9b3AkMSh7bWVhblNxdWFyZWRFcnJvcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzaWdtb2lkQ3Jvc3NFbnRyb3B5V2l0aExvZ2l0c18oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJsYWJlbHMiLCJzaWdtb2lkQ3Jvc3NFbnRyb3B5V2l0aExvZ2l0cyIpLGJhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJsb2dpdHMiLCJzaWdtb2lkQ3Jvc3NFbnRyb3B5V2l0aExvZ2l0cyIpO2Fzc2VydFNoYXBlc01hdGNoJDEoeGEuc2hhcGUsYmEuc2hhcGUsIkVycm9yIGluIHNpZ21vaWRDcm9zc0VudHJvcHlXaXRoTG9naXRzOiAiKTtjb25zdCBTYT1yZWx1JDQoYmEpLFRhPW11bCQxKGJhLHhhKSx3YT1sb2cxcCQzKGV4cCQzKG5lZyQzKGFicyQ0KGJhKSkpKTtyZXR1cm4gYWRkJDMoc3ViJDQoU2EsVGEpLHdhKX1mdW5jdGlvbiBzaWdtb2lkQ3Jvc3NFbnRyb3B5XyhoYSxhYSx4YSxiYT0wLFNhPVJlZHVjdGlvbi5TVU1fQllfTk9OWkVST19XRUlHSFRTKXtsZXQgVGE9Y29udmVydFRvVGVuc29yJDEoaGEsIm11bHRpQ2xhc3NMYWJlbHMiLCJzaWdtb2lkQ3Jvc3NFbnRyb3B5Iik7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoYWEsImxvZ2l0cyIsInNpZ21vaWRDcm9zc0VudHJvcHkiKTtsZXQgRWE9bnVsbDtpZih4YSE9bnVsbCYmKEVhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ3ZWlnaHRzIiwic2lnbW9pZENyb3NzRW50cm9weSIpKSxhc3NlcnRTaGFwZXNNYXRjaCQxKFRhLnNoYXBlLHdhLnNoYXBlLCJFcnJvciBpbiBzaWdtb2lkQ3Jvc3NFbnRyb3B5OiAiKSxiYT4wKXtjb25zdCBBYT1zY2FsYXIkMShiYSksRmE9c2NhbGFyJDEoMSksTGE9c2NhbGFyJDEoLjUpO1RhPWFkZCQzKG11bCQxKFRhLHN1YiQ0KEZhLEFhKSksbXVsJDEoTGEsQWEpKX1jb25zdCBrYT1zaWdtb2lkQ3Jvc3NFbnRyb3B5V2l0aExvZ2l0c18oVGEsd2EpO3JldHVybiBjb21wdXRlV2VpZ2h0ZWRMb3NzJDEoa2EsRWEsU2EpfWNvbnN0IHNpZ21vaWRDcm9zc0VudHJvcHk9b3AkMSh7c2lnbW9pZENyb3NzRW50cm9weV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzb2Z0bWF4Q3Jvc3NFbnRyb3B5V2l0aExvZ2l0c18oaGEsYWEseGE9LTEpe2lmKHhhPT09LTEmJih4YT1hYS5yYW5rLTEpLHhhIT09YWEucmFuay0xKXRocm93IEVycm9yKGBTb2Z0bWF4IGNyb3NzIGVudHJvcHkgYWxvbmcgYSBub24tbGFzdCBkaW1lbnNpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQuIExhYmVscyAvIGxvZ2l0cyB3YXMgcmFuayAke2FhLnJhbmt9IGFuZCBkaW0gd2FzICR7eGF9YCk7cmV0dXJuIGN1c3RvbUdyYWQoKFNhLFRhLHdhKT0+e2NvbnN0IGthPWxvZ1N1bUV4cChUYSxbeGFdLCEwKSxBYT1zdWIkNChjYXN0JDUoVGEsImZsb2F0MzIiKSxrYSk7d2EoW1NhLEFhXSk7Y29uc3QgRmE9bmVnJDMobXVsJDEoQWEsU2EpKTtyZXR1cm57dmFsdWU6c3VtJDUoRmEsW3hhXSksZ3JhZEZ1bmM6KHRsLG5sKT0+e2NvbnN0W3NsLHJsXT1ubCxvbD1leHBhbmRTaGFwZVRvS2VlcERpbSQxKHRsLnNoYXBlLFt4YV0pO3JldHVyblttdWwkMShyZXNoYXBlJDQodGwsb2wpLHN1YiQ0KGNhc3QkNShzbCwiZmxvYXQzMiIpLGV4cCQzKHJsKSkpLG11bCQxKHJlc2hhcGUkNCh0bCxvbCksc3ViJDQoZXhwJDMocmwpLGNhc3QkNShzbCwiZmxvYXQzMiIpKSldfX19KShoYSxhYSl9ZnVuY3Rpb24gc29mdG1heENyb3NzRW50cm9weV8oaGEsYWEseGEsYmE9MCxTYT1SZWR1Y3Rpb24uU1VNX0JZX05PTlpFUk9fV0VJR0hUUyl7bGV0IFRhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJvbmVob3RMYWJlbHMiLCJzb2Z0bWF4Q3Jvc3NFbnRyb3B5Iik7Y29uc3Qgd2E9Y29udmVydFRvVGVuc29yJDEoYWEsImxvZ2l0cyIsInNvZnRtYXhDcm9zc0VudHJvcHkiKTtsZXQgRWE9bnVsbDtpZih4YSE9bnVsbCYmKEVhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJ3ZWlnaHRzIiwic29mdG1heENyb3NzRW50cm9weSIpKSxhc3NlcnRTaGFwZXNNYXRjaCQxKFRhLnNoYXBlLHdhLnNoYXBlLCJFcnJvciBpbiBzb2Z0bWF4Q3Jvc3NFbnRyb3B5OiAiKSxiYT4wKXtjb25zdCBBYT1zY2FsYXIkMShiYSksRmE9c2NhbGFyJDEoMSksTGE9c2NhbGFyJDEoVGEuc2hhcGVbMV0pO1RhPWFkZCQzKG11bCQxKFRhLHN1YiQ0KEZhLEFhKSksZGl2JDIoQWEsTGEpKX1jb25zdCBrYT1zb2Z0bWF4Q3Jvc3NFbnRyb3B5V2l0aExvZ2l0c18oVGEsd2EpO3JldHVybiBjb21wdXRlV2VpZ2h0ZWRMb3NzJDEoa2EsRWEsU2EpfWNvbnN0IHNvZnRtYXhDcm9zc0VudHJvcHk9b3AkMSh7c29mdG1heENyb3NzRW50cm9weV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFyc2VGaWxsRW1wdHlSb3dzXyhoYSxhYSx4YSxiYSl7Y29uc3QgU2E9Y29udmVydFRvVGVuc29yJDEoaGEsImluZGljZXMiLCJzcGFyc2VGaWxsRW1wdHlSb3dzIiwiaW50MzIiKSxUYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwidmFsdWVzIiwic3BhcnNlRmlsbEVtcHR5Um93cyIpLHdhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJkZW5zZVNoYXBlIiwic3BhcnNlRmlsbEVtcHR5Um93cyIsImludDMyIiksRWE9Y29udmVydFRvVGVuc29yJDEoYmEsImRlZmF1bHRWYWx1ZSIsInNwYXJzZUZpbGxFbXB0eVJvd3MiLFRhLmR0eXBlKTtpZihTYS5yYW5rIT09Mil0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc2hvdWxkIGJlIFRlbnNvcjJEIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICR7U2Euc2hhcGV9YCk7aWYoVGEucmFuayE9PTEpdGhyb3cgbmV3IEVycm9yKGBWYWx1ZXMgc2hvdWxkIGJlIFRlbnNvcjFEIGJ1dCByZWNlaXZlZCBzaGFwZSAke1RhLnNoYXBlfWApO2lmKHdhLnJhbmshPT0xKXRocm93IG5ldyBFcnJvcihgRGVuc2Ugc2hhcGUgc2hvdWxkIGJlIFRlbnNvcjFEIGJ1dCByZWNlaXZlZCBzaGFwZSAke3dhLnNoYXBlfWApO2lmKEVhLnJhbmshPT0wKXRocm93IG5ldyBFcnJvcihgRGVmYXVsdCB2YWx1ZSBzaG91bGQgYmUgYSBzY2FsYXIgYnV0IHJlY2VpdmVkIHNoYXBlICR7RWEuc2hhcGV9YCk7Y29uc3Qga2E9e2luZGljZXM6U2EsdmFsdWVzOlRhLGRlbnNlU2hhcGU6d2EsZGVmYXVsdFZhbHVlOkVhfSxBYT1FTkdJTkUkMS5ydW5LZXJuZWwoU3BhcnNlRmlsbEVtcHR5Um93cyQxLGthKTtyZXR1cm57b3V0cHV0SW5kaWNlczpBYVswXSxvdXRwdXRWYWx1ZXM6QWFbMV0sZW1wdHlSb3dJbmRpY2F0b3I6QWFbMl0scmV2ZXJzZUluZGV4TWFwOkFhWzNdfX1jb25zdCBzcGFyc2VGaWxsRW1wdHlSb3dzJDM9b3AkMSh7c3BhcnNlRmlsbEVtcHR5Um93c199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFyc2VSZXNoYXBlXyhoYSxhYSx4YSl7Y29uc3QgYmE9Y29udmVydFRvVGVuc29yJDEoaGEsImlucHV0SW5kaWNlcyIsInNwYXJzZVJlc2hhcGUiLCJpbnQzMiIpLFNhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJpbnB1dFNoYXBlIiwic3BhcnNlUmVzaGFwZSIsImludDMyIiksVGE9Y29udmVydFRvVGVuc29yJDEoeGEsIm5ld1NoYXBlIiwic3BhcnNlUmVzaGFwZSIsImludDMyIik7aWYoYmEucmFuayE9PTIpdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBpbmRpY2VzIHNob3VsZCBiZSBUZW5zb3IyRCBidXQgcmVjZWl2ZWQgc2hhcGUKICAgICAgICAke2JhLnNoYXBlfWApO2lmKFNhLnJhbmshPT0xKXRocm93IG5ldyBFcnJvcihgSW5wdXQgc2hhcGUgc2hvdWxkIGJlIFRlbnNvcjFEIGJ1dCByZWNlaXZlZCBzaGFwZSAke1NhLnNoYXBlfWApO2lmKFRhLnJhbmshPT0xKXRocm93IG5ldyBFcnJvcihgTmV3IHNoYXBlIHNob3VsZCBiZSBUZW5zb3IxRCBidXQgcmVjZWl2ZWQgc2hhcGUgJHtUYS5zaGFwZX1gKTtjb25zdCB3YT17aW5wdXRJbmRpY2VzOmJhLGlucHV0U2hhcGU6U2EsbmV3U2hhcGU6VGF9LEVhPUVOR0lORSQxLnJ1bktlcm5lbChTcGFyc2VSZXNoYXBlJDEsd2EpO3JldHVybntvdXRwdXRJbmRpY2VzOkVhWzBdLG91dHB1dFNoYXBlOkVhWzFdfX1jb25zdCBzcGFyc2VSZXNoYXBlJDM9b3AkMSh7c3BhcnNlUmVzaGFwZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFyc2VTZWdtZW50TWVhbl8oaGEsYWEseGEpe2NvbnN0IGJhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJkYXRhIiwic3BhcnNlU2VnbWVudE1lYW4iKSxTYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiaW5kaWNlcyIsInNwYXJzZVNlZ21lbnRNZWFuIiwiaW50MzIiKSxUYT1jb252ZXJ0VG9UZW5zb3IkMSh4YSwic2VnbWVudElkcyIsInNwYXJzZVNlZ21lbnRNZWFuIiwiaW50MzIiKTtpZihiYS5yYW5rPDEpdGhyb3cgbmV3IEVycm9yKCJEYXRhIHNob3VsZCBiZSBhdCBsZWFzdCAxIGRpbWVuc2lvbmFsIGJ1dCByZWNlaXZlZCBzY2FsYXIiKTtpZihTYS5yYW5rIT09MSl0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc2hvdWxkIGJlIFRlbnNvcjFEIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgJHtTYS5zaGFwZX1gKTtpZihUYS5yYW5rIT09MSl0aHJvdyBuZXcgRXJyb3IoYFNlZ21lbnQgaWRzIHNob3VsZCBiZSBUZW5zb3IxRCBidXQgcmVjZWl2ZWQgc2hhcGUKICAgICAgICAgICR7VGEuc2hhcGV9YCk7Y29uc3Qgd2E9e2RhdGE6YmEsaW5kaWNlczpTYSxzZWdtZW50SWRzOlRhfTtyZXR1cm4gRU5HSU5FJDEucnVuS2VybmVsKFNwYXJzZVNlZ21lbnRNZWFuJDEsd2EpfWNvbnN0IHNwYXJzZVNlZ21lbnRNZWFuJDM9b3AkMSh7c3BhcnNlU2VnbWVudE1lYW5ffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlU2VnbWVudFN1bV8oaGEsYWEseGEpe2NvbnN0IGJhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJkYXRhIiwic3BhcnNlU2VnbWVudFN1bSIpLFNhPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJpbmRpY2VzIiwic3BhcnNlU2VnbWVudFN1bSIsImludDMyIiksVGE9Y29udmVydFRvVGVuc29yJDEoeGEsInNlZ21lbnRJZHMiLCJzcGFyc2VTZWdtZW50U3VtIiwiaW50MzIiKTtpZihiYS5yYW5rPDEpdGhyb3cgbmV3IEVycm9yKCJEYXRhIHNob3VsZCBiZSBhdCBsZWFzdCAxIGRpbWVuc2lvbmFsIGJ1dCByZWNlaXZlZCBzY2FsYXIiKTtpZihTYS5yYW5rIT09MSl0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc2hvdWxkIGJlIFRlbnNvcjFEIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAke1NhLnNoYXBlfWApO2lmKFRhLnJhbmshPT0xKXRocm93IG5ldyBFcnJvcihgU2VnbWVudCBpZHMgc2hvdWxkIGJlIFRlbnNvcjFEIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAke1RhLnNoYXBlfWApO2NvbnN0IHdhPXtkYXRhOmJhLGluZGljZXM6U2Esc2VnbWVudElkczpUYX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChTcGFyc2VTZWdtZW50U3VtJDEsd2EpfWNvbnN0IHNwYXJzZVNlZ21lbnRTdW0kMz1vcCQxKHtzcGFyc2VTZWdtZW50U3VtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0cmluZ05HcmFtc18oaGEsYWEseGEsYmEsU2EsVGEsd2EsRWEpe2NvbnN0IGthPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJkYXRhIiwic3RyaW5nTkdyYW1zIiwic3RyaW5nIik7aWYoa2EuZHR5cGUhPT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIkRhdGEgbXVzdCBiZSBvZiBkYXRhdHlwZSBzdHJpbmciKTtpZihrYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgRGF0YSBtdXN0IGJlIGEgdmVjdG9yLCBzYXc6ICR7a2Euc2hhcGV9YCk7Y29uc3QgQWE9Y29udmVydFRvVGVuc29yJDEoYWEsImRhdGFTcGxpdHMiLCJzdHJpbmdOR3JhbXMiKTtpZihBYS5kdHlwZSE9PSJpbnQzMiIpdGhyb3cgbmV3IEVycm9yKCJEYXRhIHNwbGl0cyBtdXN0IGJlIG9mIGRhdGF0eXBlIGludDMyIik7Y29uc3QgRmE9e3NlcGFyYXRvcjp4YSxuR3JhbVdpZHRoczpiYSxsZWZ0UGFkOlNhLHJpZ2h0UGFkOlRhLHBhZFdpZHRoOndhLHByZXNlcnZlU2hvcnRTZXF1ZW5jZXM6RWF9LExhPXtkYXRhOmthLGRhdGFTcGxpdHM6QWF9LGVsPUVOR0lORSQxLnJ1bktlcm5lbChTdHJpbmdOR3JhbXMkMSxMYSxGYSk7cmV0dXJue25HcmFtczplbFswXSxuR3JhbXNTcGxpdHM6ZWxbMV19fWNvbnN0IHN0cmluZ05HcmFtcyQzPW9wJDEoe3N0cmluZ05HcmFtc199KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdHJpbmdTcGxpdF8oaGEsYWEseGE9ITApe2NvbnN0IGJhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbnB1dCIsInN0cmluZ1NwbGl0Iiwic3RyaW5nIiksU2E9Y29udmVydFRvVGVuc29yJDEoYWEsImRlbGltaXRlciIsInN0cmluZ1NwbGl0Iiwic3RyaW5nIik7aWYoYmEucmFuayE9PTEpdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBzaG91bGQgYmUgVGVuc29yMUQgYnV0IHJlY2VpdmVkIHNoYXBlICR7YmEuc2hhcGV9YCk7aWYoU2EucmFuayE9PTApdGhyb3cgbmV3IEVycm9yKGBEZWxpbWl0ZXIgc2hvdWxkIGJlIGEgc2NhbGFyIGJ1dCByZWNlaXZlZCBzaGFwZSAke1NhLnNoYXBlfWApO2NvbnN0IFRhPXtza2lwRW1wdHk6eGF9LHdhPXtpbnB1dDpiYSxkZWxpbWl0ZXI6U2F9LEVhPUVOR0lORSQxLnJ1bktlcm5lbChTdHJpbmdTcGxpdCQxLHdhLFRhKTtyZXR1cm57aW5kaWNlczpFYVswXSx2YWx1ZXM6RWFbMV0sc2hhcGU6RWFbMl19fWNvbnN0IHN0cmluZ1NwbGl0JDM9b3AkMSh7c3RyaW5nU3BsaXRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nVG9IYXNoQnVja2V0RmFzdF8oaGEsYWEpe2NvbnN0IHhhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJpbnB1dCIsInN0cmluZ1RvSGFzaEJ1Y2tldEZhc3QiLCJzdHJpbmciKSxiYT17bnVtQnVja2V0czphYX07aWYoYWE8PTApdGhyb3cgbmV3IEVycm9yKCJOdW1iZXIgb2YgYnVja2V0cyBtdXN0IGJlIGF0IGxlYXN0IDEiKTtjb25zdCBTYT17aW5wdXQ6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU3RyaW5nVG9IYXNoQnVja2V0RmFzdCQxLFNhLGJhKX1jb25zdCBzdHJpbmdUb0hhc2hCdWNrZXRGYXN0JDM9b3AkMSh7c3RyaW5nVG9IYXNoQnVja2V0RmFzdF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdGF0aWNSZWdleFJlcGxhY2VfKGhhLGFhLHhhLGJhPSEwKXtjb25zdCBTYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiaW5wdXQiLCJzdGF0aWNSZWdleFJlcGxhY2UiLCJzdHJpbmciKSxUYT17cGF0dGVybjphYSxyZXdyaXRlOnhhLHJlcGxhY2VHbG9iYWw6YmF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoU3RhdGljUmVnZXhSZXBsYWNlJDEse3g6U2F9LFRhKX1jb25zdCBzdGF0aWNSZWdleFJlcGxhY2UkMz1vcCQxKHtzdGF0aWNSZWdleFJlcGxhY2VffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3BlY3RyYWwkMT17ZmZ0OmZmdCQzLGlmZnQ6aWZmdCQzLHJmZnQsaXJmZnR9LHNpZ25hbD17aGFtbWluZ1dpbmRvdyxoYW5uV2luZG93LGZyYW1lLHN0ZnR9LGltYWdlJDE9e2ZsaXBMZWZ0UmlnaHQsZ3JheXNjYWxlVG9SR0IscmVzaXplTmVhcmVzdE5laWdoYm9yOnJlc2l6ZU5lYXJlc3ROZWlnaGJvciQzLHJlc2l6ZUJpbGluZWFyOnJlc2l6ZUJpbGluZWFyJDQscmdiVG9HcmF5c2NhbGUscm90YXRlV2l0aE9mZnNldCxjcm9wQW5kUmVzaXplOmNyb3BBbmRSZXNpemUkNCxub25NYXhTdXBwcmVzc2lvbixub25NYXhTdXBwcmVzc2lvbkFzeW5jLG5vbk1heFN1cHByZXNzaW9uV2l0aFNjb3JlLG5vbk1heFN1cHByZXNzaW9uV2l0aFNjb3JlQXN5bmMsbm9uTWF4U3VwcHJlc3Npb25QYWRkZWQsbm9uTWF4U3VwcHJlc3Npb25QYWRkZWRBc3luYyx0aHJlc2hvbGQ6dGhyZXNob2xkJDEsdHJhbnNmb3JtOnRyYW5zZm9ybSQzfSxsaW5hbGc9e2JhbmRQYXJ0LGdyYW1TY2htaWR0LHFyOnFyJDF9LGxvc3Nlcz17YWJzb2x1dGVEaWZmZXJlbmNlLGNvbXB1dGVXZWlnaHRlZExvc3M6Y29tcHV0ZVdlaWdodGVkTG9zcyQxLGNvc2luZURpc3RhbmNlLGhpbmdlTG9zcyxodWJlckxvc3MsbG9nTG9zcyxtZWFuU3F1YXJlZEVycm9yOm1lYW5TcXVhcmVkRXJyb3IkMSxzaWdtb2lkQ3Jvc3NFbnRyb3B5LHNvZnRtYXhDcm9zc0VudHJvcHl9LHNwYXJzZSQxPXtzcGFyc2VGaWxsRW1wdHlSb3dzOnNwYXJzZUZpbGxFbXB0eVJvd3MkMyxzcGFyc2VSZXNoYXBlOnNwYXJzZVJlc2hhcGUkMyxzcGFyc2VTZWdtZW50TWVhbjpzcGFyc2VTZWdtZW50TWVhbiQzLHNwYXJzZVNlZ21lbnRTdW06c3BhcnNlU2VnbWVudFN1bSQzfSxzdHJpbmckMT17c3RyaW5nTkdyYW1zOnN0cmluZ05HcmFtcyQzLHN0cmluZ1NwbGl0OnN0cmluZ1NwbGl0JDMsc3RyaW5nVG9IYXNoQnVja2V0RmFzdDpzdHJpbmdUb0hhc2hCdWNrZXRGYXN0JDMsc3RhdGljUmVnZXhSZXBsYWNlOnN0YXRpY1JlZ2V4UmVwbGFjZSQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBHTE9CQUxfQ1VTVE9NX09CSkVDVCQxPW5ldyBNYXAsR0xPQkFMX0NVU1RPTV9OQU1FUyQxPW5ldyBNYXA7bGV0IFNlcmlhbGl6YWJsZSQxPWNsYXNze2dldENsYXNzTmFtZSgpe3JldHVybiB0aGlzLmNvbnN0cnVjdG9yLmNsYXNzTmFtZX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YSl9fSxTZXJpYWxpemF0aW9uTWFwJDE9Y2xhc3MgdGN7Y29uc3RydWN0b3IoKXt0aGlzLmNsYXNzTmFtZU1hcD17fX1zdGF0aWMgZ2V0TWFwKCl7cmV0dXJuIHRjLmluc3RhbmNlPT1udWxsJiYodGMuaW5zdGFuY2U9bmV3IHRjKSx0Yy5pbnN0YW5jZX1zdGF0aWMgcmVnaXN0ZXIoYWEpe3RjLmdldE1hcCgpLmNsYXNzTmFtZU1hcFthYS5jbGFzc05hbWVdPVthYSxhYS5mcm9tQ29uZmlnXX19O2Z1bmN0aW9uIHJlZ2lzdGVyQ2xhc3MkMShoYSxhYSx4YSl7YXNzZXJ0JDIoaGEuY2xhc3NOYW1lIT1udWxsLCgpPT4iQ2xhc3MgYmVpbmcgcmVnaXN0ZXJlZCBkb2VzIG5vdCBoYXZlIHRoZSBzdGF0aWMgY2xhc3NOYW1lIHByb3BlcnR5IGRlZmluZWQuIiksYXNzZXJ0JDIodHlwZW9mIGhhLmNsYXNzTmFtZT09InN0cmluZyIsKCk9PiJjbGFzc05hbWUgaXMgcmVxdWlyZWQgdG8gYmUgYSBzdHJpbmcsIGJ1dCBnb3QgdHlwZSAiK3R5cGVvZiBoYS5jbGFzc05hbWUpLGFzc2VydCQyKGhhLmNsYXNzTmFtZS5sZW5ndGg+MCwoKT0+IkNsYXNzIGJlaW5nIHJlZ2lzdGVyZWQgaGFzIGFuIGVtcHR5LXN0cmluZyBhcyBpdHMgY2xhc3NOYW1lLCB3aGljaCBpcyBkaXNhbGxvd2VkLiIpLHR5cGVvZiBhYT4idSImJihhYT0iQ3VzdG9tIiksdHlwZW9mIHhhPiJ1IiYmKHhhPWhhLmNsYXNzTmFtZSk7Y29uc3QgYmE9eGEsU2E9YWErIj4iK2JhO3JldHVybiBTZXJpYWxpemF0aW9uTWFwJDEucmVnaXN0ZXIoaGEpLEdMT0JBTF9DVVNUT01fT0JKRUNUJDEuc2V0KFNhLGhhKSxHTE9CQUxfQ1VTVE9NX05BTUVTJDEuc2V0KGhhLFNhKSxoYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgT3B0aW1pemVyJDE9Y2xhc3MgZXh0ZW5kcyBTZXJpYWxpemFibGUkMXttaW5pbWl6ZShhYSx4YT0hMSxiYSl7Y29uc3R7dmFsdWU6U2EsZ3JhZHM6VGF9PXRoaXMuY29tcHV0ZUdyYWRpZW50cyhhYSxiYSk7aWYoYmEhPW51bGwpe2NvbnN0IHdhPWJhLm1hcChFYT0+KHtuYW1lOkVhLm5hbWUsdGVuc29yOlRhW0VhLm5hbWVdfSkpO3RoaXMuYXBwbHlHcmFkaWVudHMod2EpfWVsc2UgdGhpcy5hcHBseUdyYWRpZW50cyhUYSk7cmV0dXJuIGRpc3Bvc2UkMShUYSkseGE/U2E6KFNhLmRpc3Bvc2UoKSxudWxsKX1nZXQgaXRlcmF0aW9ucygpe3JldHVybiB0aGlzLml0ZXJhdGlvbnNfPT1udWxsJiYodGhpcy5pdGVyYXRpb25zXz0wKSx0aGlzLml0ZXJhdGlvbnNffWluY3JlbWVudEl0ZXJhdGlvbnMoKXt0aGlzLml0ZXJhdGlvbnNfPXRoaXMuaXRlcmF0aW9ucysxfWNvbXB1dGVHcmFkaWVudHMoYWEseGEpe3JldHVybiB2YXJpYWJsZUdyYWRzJDEoYWEseGEpfWRpc3Bvc2UoKXt0aGlzLml0ZXJhdGlvbnNfIT1udWxsJiZkaXNwb3NlJDEodGhpcy5pdGVyYXRpb25zXyl9YXN5bmMgc2F2ZUl0ZXJhdGlvbnMoKXtyZXR1cm4gdGhpcy5pdGVyYXRpb25zXz09bnVsbCYmKHRoaXMuaXRlcmF0aW9uc189MCkse25hbWU6Iml0ZXIiLHRlbnNvcjpzY2FsYXIkMSh0aGlzLml0ZXJhdGlvbnNfLCJpbnQzMiIpfX1hc3luYyBnZXRXZWlnaHRzKCl7dGhyb3cgbmV3IEVycm9yKCJnZXRXZWlnaHRzKCkgaXMgbm90IGltcGxlbWVudGVkIGZvciB0aGlzIG9wdGltaXplciB5ZXQuIil9YXN5bmMgc2V0V2VpZ2h0cyhhYSl7dGhyb3cgbmV3IEVycm9yKGBzZXRXZWlnaHRzKCkgaXMgbm90IGltcGxlbWVudGVkIGZvciB0aGlzIG9wdGltaXplciBjbGFzcyAke3RoaXMuZ2V0Q2xhc3NOYW1lKCl9YCl9YXN5bmMgZXh0cmFjdEl0ZXJhdGlvbnMoYWEpe3JldHVybiB0aGlzLml0ZXJhdGlvbnNfPShhd2FpdCBhYVswXS50ZW5zb3IuZGF0YSgpKVswXSxhYS5zbGljZSgxKX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eShPcHRpbWl6ZXIkMSxTeW1ib2wuaGFzSW5zdGFuY2Use3ZhbHVlOmhhPT5oYS5taW5pbWl6ZSE9bnVsbCYmaGEuY29tcHV0ZUdyYWRpZW50cyE9bnVsbCYmaGEuYXBwbHlHcmFkaWVudHMhPW51bGx9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWRhZGVsdGFPcHRpbWl6ZXIkMT1jbGFzcyBleHRlbmRzIE9wdGltaXplciQxe3N0YXRpYyBnZXQgY2xhc3NOYW1lKCl7cmV0dXJuIkFkYWRlbHRhIn1jb25zdHJ1Y3RvcihhYSx4YSxiYT1udWxsKXtzdXBlcigpLHRoaXMubGVhcm5pbmdSYXRlPWFhLHRoaXMucmhvPXhhLHRoaXMuZXBzaWxvbj1iYSx0aGlzLmFjY3VtdWxhdGVkR3JhZHM9W10sdGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXM9W10sYmE9PW51bGwmJih0aGlzLmVwc2lsb249RU5HSU5FJDEuYmFja2VuZC5lcHNpbG9uKCkpfWFwcGx5R3JhZGllbnRzKGFhKXsoQXJyYXkuaXNBcnJheShhYSk/YWEubWFwKGJhPT5iYS5uYW1lKTpPYmplY3Qua2V5cyhhYSkpLmZvckVhY2goKGJhLFNhKT0+e2NvbnN0IFRhPUVOR0lORSQxLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYmFdLHdhPSExO3RoaXMuYWNjdW11bGF0ZWRHcmFkc1tTYV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkR3JhZHNbU2FdPXtvcmlnaW5hbE5hbWU6YCR7YmF9L2FjY3VtX2dyYWRgLHZhcmlhYmxlOnRpZHkkMSgoKT0+emVyb3NMaWtlJDQoVGEpLnZhcmlhYmxlKHdhKSl9KSx0aGlzLmFjY3VtdWxhdGVkVXBkYXRlc1tTYV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkVXBkYXRlc1tTYV09e29yaWdpbmFsTmFtZTpgJHtiYX0vYWNjdW1fdmFyYCx2YXJpYWJsZTp0aWR5JDEoKCk9Pnplcm9zTGlrZSQ0KFRhKS52YXJpYWJsZSh3YSkpfSk7Y29uc3QgRWE9QXJyYXkuaXNBcnJheShhYSk/YWFbU2FdLnRlbnNvcjphYVtiYV07aWYoRWE9PW51bGwpcmV0dXJuO2NvbnN0IGthPXRoaXMuYWNjdW11bGF0ZWRHcmFkc1tTYV0udmFyaWFibGUsQWE9dGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXNbU2FdLnZhcmlhYmxlO3RpZHkkMSgoKT0+e2NvbnN0IEZhPWFkZCQzKG11bCQxKGthLHRoaXMucmhvKSxtdWwkMShzcXVhcmUkNChFYSksMS10aGlzLnJobykpLExhPW11bCQxKGRpdiQyKHNxcnQkNChhZGQkMyhBYSx0aGlzLmVwc2lsb24pKSxzcXJ0JDQoYWRkJDMoa2EsdGhpcy5lcHNpbG9uKSkpLEVhKSxlbD1hZGQkMyhtdWwkMShBYSx0aGlzLnJobyksbXVsJDEoc3F1YXJlJDQoTGEpLDEtdGhpcy5yaG8pKTtrYS5hc3NpZ24oRmEpLEFhLmFzc2lnbihlbCk7Y29uc3QgdGw9YWRkJDMobXVsJDEoTGEsLXRoaXMubGVhcm5pbmdSYXRlKSxUYSk7VGEuYXNzaWduKHRsKX0pfSksdGhpcy5pbmNyZW1lbnRJdGVyYXRpb25zKCl9ZGlzcG9zZSgpe3RoaXMuYWNjdW11bGF0ZWRVcGRhdGVzIT1udWxsJiYoZGlzcG9zZSQxKHRoaXMuYWNjdW11bGF0ZWRHcmFkcy5tYXAoYWE9PmFhLnZhcmlhYmxlKSksZGlzcG9zZSQxKHRoaXMuYWNjdW11bGF0ZWRVcGRhdGVzLm1hcChhYT0+YWEudmFyaWFibGUpKSl9YXN5bmMgZ2V0V2VpZ2h0cygpe2NvbnN0IGFhPVsuLi50aGlzLmFjY3VtdWxhdGVkR3JhZHMsLi4udGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXNdO3JldHVyblthd2FpdCB0aGlzLnNhdmVJdGVyYXRpb25zKCldLmNvbmNhdChhYS5tYXAoeGE9Pih7bmFtZTp4YS5vcmlnaW5hbE5hbWUsdGVuc29yOnhhLnZhcmlhYmxlfSkpKX1hc3luYyBzZXRXZWlnaHRzKGFhKXthYT1hd2FpdCB0aGlzLmV4dHJhY3RJdGVyYXRpb25zKGFhKTtjb25zdCB4YT1hYS5sZW5ndGgvMixiYT0hMTt0aGlzLmFjY3VtdWxhdGVkR3JhZHM9YWEuc2xpY2UoMCx4YSkubWFwKFNhPT4oe29yaWdpbmFsTmFtZTpTYS5uYW1lLHZhcmlhYmxlOlNhLnRlbnNvci52YXJpYWJsZShiYSl9KSksdGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXM9YWEuc2xpY2UoeGEseGEqMikubWFwKFNhPT4oe29yaWdpbmFsTmFtZTpTYS5uYW1lLHZhcmlhYmxlOlNhLnRlbnNvci52YXJpYWJsZShiYSl9KSl9Z2V0Q29uZmlnKCl7cmV0dXJue2xlYXJuaW5nUmF0ZTp0aGlzLmxlYXJuaW5nUmF0ZSxyaG86dGhpcy5yaG8sZXBzaWxvbjp0aGlzLmVwc2lsb259fXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtyZXR1cm4gbmV3IGFhKHhhLmxlYXJuaW5nUmF0ZSx4YS5yaG8seGEuZXBzaWxvbil9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWRhZ3JhZE9wdGltaXplciQxPWNsYXNzIGV4dGVuZHMgT3B0aW1pemVyJDF7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iQWRhZ3JhZCJ9Y29uc3RydWN0b3IoYWEseGE9LjEpe3N1cGVyKCksdGhpcy5sZWFybmluZ1JhdGU9YWEsdGhpcy5pbml0aWFsQWNjdW11bGF0b3JWYWx1ZT14YSx0aGlzLmFjY3VtdWxhdGVkR3JhZHM9W119YXBwbHlHcmFkaWVudHMoYWEpeyhBcnJheS5pc0FycmF5KGFhKT9hYS5tYXAoYmE9PmJhLm5hbWUpOk9iamVjdC5rZXlzKGFhKSkuZm9yRWFjaCgoYmEsU2EpPT57Y29uc3QgVGE9RU5HSU5FJDEucmVnaXN0ZXJlZFZhcmlhYmxlc1tiYV07dGhpcy5hY2N1bXVsYXRlZEdyYWRzW1NhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRHcmFkc1tTYV09e29yaWdpbmFsTmFtZTpgJHtiYX0vYWNjdW11bGF0b3JgLHZhcmlhYmxlOnRpZHkkMSgoKT0+ZmlsbCQ0KFRhLnNoYXBlLHRoaXMuaW5pdGlhbEFjY3VtdWxhdG9yVmFsdWUpLnZhcmlhYmxlKCExKSl9KTtjb25zdCB3YT1BcnJheS5pc0FycmF5KGFhKT9hYVtTYV0udGVuc29yOmFhW2JhXTtpZih3YT09bnVsbClyZXR1cm47Y29uc3QgRWE9dGhpcy5hY2N1bXVsYXRlZEdyYWRzW1NhXS52YXJpYWJsZTt0aWR5JDEoKCk9Pntjb25zdCBrYT1hZGQkMyhFYSxzcXVhcmUkNCh3YSkpO0VhLmFzc2lnbihrYSk7Y29uc3QgQWE9YWRkJDMobXVsJDEoZGl2JDIod2Esc3FydCQ0KGFkZCQzKGthLEVOR0lORSQxLmJhY2tlbmQuZXBzaWxvbigpKSkpLC10aGlzLmxlYXJuaW5nUmF0ZSksVGEpO1RhLmFzc2lnbihBYSl9KX0pLHRoaXMuaW5jcmVtZW50SXRlcmF0aW9ucygpfWRpc3Bvc2UoKXt0aGlzLmFjY3VtdWxhdGVkR3JhZHMhPW51bGwmJmRpc3Bvc2UkMSh0aGlzLmFjY3VtdWxhdGVkR3JhZHMubWFwKGFhPT5hYS52YXJpYWJsZSkpfWFzeW5jIGdldFdlaWdodHMoKXtyZXR1cm5bYXdhaXQgdGhpcy5zYXZlSXRlcmF0aW9ucygpXS5jb25jYXQodGhpcy5hY2N1bXVsYXRlZEdyYWRzLm1hcChhYT0+KHtuYW1lOmFhLm9yaWdpbmFsTmFtZSx0ZW5zb3I6YWEudmFyaWFibGV9KSkpfWFzeW5jIHNldFdlaWdodHMoYWEpe2FhPWF3YWl0IHRoaXMuZXh0cmFjdEl0ZXJhdGlvbnMoYWEpO2NvbnN0IHhhPSExO3RoaXMuYWNjdW11bGF0ZWRHcmFkcz1hYS5tYXAoYmE9Pih7b3JpZ2luYWxOYW1lOmJhLm5hbWUsdmFyaWFibGU6YmEudGVuc29yLnZhcmlhYmxlKHhhKX0pKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlLGluaXRpYWxBY2N1bXVsYXRvclZhbHVlOnRoaXMuaW5pdGlhbEFjY3VtdWxhdG9yVmFsdWV9fXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtyZXR1cm4gbmV3IGFhKHhhLmxlYXJuaW5nUmF0ZSx4YS5pbml0aWFsQWNjdW11bGF0b3JWYWx1ZSl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWRhbU9wdGltaXplciQxPWNsYXNzIGV4dGVuZHMgT3B0aW1pemVyJDF7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iQWRhbSJ9Y29uc3RydWN0b3IoYWEseGEsYmEsU2E9bnVsbCl7c3VwZXIoKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLmJldGExPXhhLHRoaXMuYmV0YTI9YmEsdGhpcy5lcHNpbG9uPVNhLHRoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudD1bXSx0aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50PVtdLHRpZHkkMSgoKT0+e3RoaXMuYWNjQmV0YTE9c2NhbGFyJDEoeGEpLnZhcmlhYmxlKCksdGhpcy5hY2NCZXRhMj1zY2FsYXIkMShiYSkudmFyaWFibGUoKX0pLFNhPT1udWxsJiYodGhpcy5lcHNpbG9uPUVOR0lORSQxLmJhY2tlbmQuZXBzaWxvbigpKX1hcHBseUdyYWRpZW50cyhhYSl7Y29uc3QgeGE9QXJyYXkuaXNBcnJheShhYSk/YWEubWFwKGJhPT5iYS5uYW1lKTpPYmplY3Qua2V5cyhhYSk7dGlkeSQxKCgpPT57Y29uc3QgYmE9c3ViJDQoMSx0aGlzLmFjY0JldGExKSxTYT1zdWIkNCgxLHRoaXMuYWNjQmV0YTIpO3hhLmZvckVhY2goKFRhLHdhKT0+e2NvbnN0IEVhPUVOR0lORSQxLnJlZ2lzdGVyZWRWYXJpYWJsZXNbVGFdLGthPSExO3RoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudFt3YV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnRbd2FdPXtvcmlnaW5hbE5hbWU6YCR7VGF9L21gLHZhcmlhYmxlOnRpZHkkMSgoKT0+emVyb3NMaWtlJDQoRWEpLnZhcmlhYmxlKGthKSl9KSx0aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50W3dhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRTZWNvbmRNb21lbnRbd2FdPXtvcmlnaW5hbE5hbWU6YCR7VGF9L3ZgLHZhcmlhYmxlOnRpZHkkMSgoKT0+emVyb3NMaWtlJDQoRWEpLnZhcmlhYmxlKGthKSl9KTtjb25zdCBBYT1BcnJheS5pc0FycmF5KGFhKT9hYVt3YV0udGVuc29yOmFhW1RhXTtpZihBYT09bnVsbClyZXR1cm47Y29uc3QgRmE9dGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50W3dhXS52YXJpYWJsZSxMYT10aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50W3dhXS52YXJpYWJsZSxlbD1hZGQkMyhtdWwkMShGYSx0aGlzLmJldGExKSxtdWwkMShBYSwxLXRoaXMuYmV0YTEpKSx0bD1hZGQkMyhtdWwkMShMYSx0aGlzLmJldGEyKSxtdWwkMShzcXVhcmUkNChBYSksMS10aGlzLmJldGEyKSksbmw9ZGl2JDIoZWwsYmEpLHNsPWRpdiQyKHRsLFNhKTtGYS5hc3NpZ24oZWwpLExhLmFzc2lnbih0bCk7Y29uc3Qgcmw9YWRkJDMobXVsJDEoZGl2JDIobmwsYWRkJDMoc3FydCQ0KHNsKSx0aGlzLmVwc2lsb24pKSwtdGhpcy5sZWFybmluZ1JhdGUpLEVhKTtFYS5hc3NpZ24ocmwpfSksdGhpcy5hY2NCZXRhMS5hc3NpZ24obXVsJDEodGhpcy5hY2NCZXRhMSx0aGlzLmJldGExKSksdGhpcy5hY2NCZXRhMi5hc3NpZ24obXVsJDEodGhpcy5hY2NCZXRhMix0aGlzLmJldGEyKSl9KSx0aGlzLmluY3JlbWVudEl0ZXJhdGlvbnMoKX1kaXNwb3NlKCl7dGhpcy5hY2NCZXRhMS5kaXNwb3NlKCksdGhpcy5hY2NCZXRhMi5kaXNwb3NlKCksdGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50IT1udWxsJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50Lm1hcChhYT0+YWEudmFyaWFibGUpKSx0aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50IT1udWxsJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRlZFNlY29uZE1vbWVudC5tYXAoYWE9PmFhLnZhcmlhYmxlKSl9YXN5bmMgZ2V0V2VpZ2h0cygpe2NvbnN0IGFhPVsuLi50aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnQsLi4udGhpcy5hY2N1bXVsYXRlZFNlY29uZE1vbWVudF07cmV0dXJuW2F3YWl0IHRoaXMuc2F2ZUl0ZXJhdGlvbnMoKV0uY29uY2F0KGFhLm1hcCh4YT0+KHtuYW1lOnhhLm9yaWdpbmFsTmFtZSx0ZW5zb3I6eGEudmFyaWFibGV9KSkpfWFzeW5jIHNldFdlaWdodHMoYWEpe2FhPWF3YWl0IHRoaXMuZXh0cmFjdEl0ZXJhdGlvbnMoYWEpLHRpZHkkMSgoKT0+e3RoaXMuYWNjQmV0YTEuYXNzaWduKHBvdyQ0KHRoaXMuYmV0YTEsdGhpcy5pdGVyYXRpb25zXysxKSksdGhpcy5hY2NCZXRhMi5hc3NpZ24ocG93JDQodGhpcy5iZXRhMix0aGlzLml0ZXJhdGlvbnNfKzEpKX0pO2NvbnN0IHhhPWFhLmxlbmd0aC8yLGJhPSExO3RoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudD1hYS5zbGljZSgwLHhhKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKSx0aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50PWFhLnNsaWNlKHhhLHhhKjIpLm1hcChTYT0+KHtvcmlnaW5hbE5hbWU6U2EubmFtZSx2YXJpYWJsZTpTYS50ZW5zb3IudmFyaWFibGUoYmEpfSkpfWdldENvbmZpZygpe3JldHVybntsZWFybmluZ1JhdGU6dGhpcy5sZWFybmluZ1JhdGUsYmV0YTE6dGhpcy5iZXRhMSxiZXRhMjp0aGlzLmJldGEyLGVwc2lsb246dGhpcy5lcHNpbG9ufX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YS5sZWFybmluZ1JhdGUseGEuYmV0YTEseGEuYmV0YTIseGEuZXBzaWxvbil9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWRhbWF4T3B0aW1pemVyJDE9Y2xhc3MgZXh0ZW5kcyBPcHRpbWl6ZXIkMXtzdGF0aWMgZ2V0IGNsYXNzTmFtZSgpe3JldHVybiJBZGFtYXgifWNvbnN0cnVjdG9yKGFhLHhhLGJhLFNhPW51bGwsVGE9MCl7c3VwZXIoKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLmJldGExPXhhLHRoaXMuYmV0YTI9YmEsdGhpcy5lcHNpbG9uPVNhLHRoaXMuZGVjYXk9VGEsdGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50PVtdLHRoaXMuYWNjdW11bGF0ZWRXZWlnaHRlZEluZk5vcm09W10sdGlkeSQxKCgpPT57dGhpcy5pdGVyYXRpb249c2NhbGFyJDEoMCkudmFyaWFibGUoKSx0aGlzLmFjY0JldGExPXNjYWxhciQxKHhhKS52YXJpYWJsZSgpfSksU2E9PW51bGwmJih0aGlzLmVwc2lsb249RU5HSU5FJDEuYmFja2VuZC5lcHNpbG9uKCkpfWFwcGx5R3JhZGllbnRzKGFhKXtjb25zdCB4YT1BcnJheS5pc0FycmF5KGFhKT9hYS5tYXAoYmE9PmJhLm5hbWUpOk9iamVjdC5rZXlzKGFhKTt0aWR5JDEoKCk9Pntjb25zdCBiYT1zdWIkNCgxLHRoaXMuYWNjQmV0YTEpLFNhPWRpdiQyKC10aGlzLmxlYXJuaW5nUmF0ZSxhZGQkMyhtdWwkMSh0aGlzLml0ZXJhdGlvbix0aGlzLmRlY2F5KSwxKSk7eGEuZm9yRWFjaCgoVGEsd2EpPT57Y29uc3QgRWE9RU5HSU5FJDEucmVnaXN0ZXJlZFZhcmlhYmxlc1tUYV0sa2E9ITE7dGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50W3dhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudFt3YV09e29yaWdpbmFsTmFtZTpgJHtUYX0vbWAsdmFyaWFibGU6emVyb3NMaWtlJDQoRWEpLnZhcmlhYmxlKGthKX0pLHRoaXMuYWNjdW11bGF0ZWRXZWlnaHRlZEluZk5vcm1bd2FdPT1udWxsJiYodGhpcy5hY2N1bXVsYXRlZFdlaWdodGVkSW5mTm9ybVt3YV09e29yaWdpbmFsTmFtZTpgJHtUYX0vdmAsdmFyaWFibGU6emVyb3NMaWtlJDQoRWEpLnZhcmlhYmxlKGthKX0pO2NvbnN0IEFhPUFycmF5LmlzQXJyYXkoYWEpP2FhW3dhXS50ZW5zb3I6YWFbVGFdO2lmKEFhPT1udWxsKXJldHVybjtjb25zdCBGYT10aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnRbd2FdLnZhcmlhYmxlLExhPXRoaXMuYWNjdW11bGF0ZWRXZWlnaHRlZEluZk5vcm1bd2FdLnZhcmlhYmxlLGVsPWFkZCQzKG11bCQxKEZhLHRoaXMuYmV0YTEpLG11bCQxKEFhLDEtdGhpcy5iZXRhMSkpLHRsPW11bCQxKExhLHRoaXMuYmV0YTIpLG5sPWFicyQ0KEFhKSxzbD1tYXhpbXVtJDQodGwsbmwpO0ZhLmFzc2lnbihlbCksTGEuYXNzaWduKHNsKTtjb25zdCBybD1hZGQkMyhtdWwkMShkaXYkMihTYSxiYSksZGl2JDIoZWwsYWRkJDMoc2wsdGhpcy5lcHNpbG9uKSkpLEVhKTtFYS5hc3NpZ24ocmwpfSksdGhpcy5pdGVyYXRpb24uYXNzaWduKGFkZCQzKHRoaXMuaXRlcmF0aW9uLDEpKSx0aGlzLmFjY0JldGExLmFzc2lnbihtdWwkMSh0aGlzLmFjY0JldGExLHRoaXMuYmV0YTEpKX0pLHRoaXMuaW5jcmVtZW50SXRlcmF0aW9ucygpfWRpc3Bvc2UoKXt0aGlzLmFjY0JldGExLmRpc3Bvc2UoKSx0aGlzLml0ZXJhdGlvbi5kaXNwb3NlKCksdGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50IT1udWxsJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50Lm1hcChhYT0+YWEudmFyaWFibGUpKSx0aGlzLmFjY3VtdWxhdGVkV2VpZ2h0ZWRJbmZOb3JtIT1udWxsJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRlZFdlaWdodGVkSW5mTm9ybS5tYXAoYWE9PmFhLnZhcmlhYmxlKSl9YXN5bmMgZ2V0V2VpZ2h0cygpe3Rocm93IG5ldyBFcnJvcigiZ2V0V2VpZ2h0cygpIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgQWRhbWF4IHlldC4iKX1hc3luYyBzZXRXZWlnaHRzKGFhKXt0aHJvdyBuZXcgRXJyb3IoInNldFdlaWdodHMoKSBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIEFkYW1heCB5ZXQuIil9Z2V0Q29uZmlnKCl7cmV0dXJue2xlYXJuaW5nUmF0ZTp0aGlzLmxlYXJuaW5nUmF0ZSxiZXRhMTp0aGlzLmJldGExLGJldGEyOnRoaXMuYmV0YTIsZXBzaWxvbjp0aGlzLmVwc2lsb24sZGVjYXk6dGhpcy5kZWNheX19c3RhdGljIGZyb21Db25maWcoYWEseGEpe3JldHVybiBuZXcgYWEoeGEubGVhcm5pbmdSYXRlLHhhLmJldGExLHhhLmJldGEyLHhhLmVwc2lsb24seGEuZGVjYXkpfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFNHRE9wdGltaXplciQxPWNsYXNzIGV4dGVuZHMgT3B0aW1pemVyJDF7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iU0dEIn1jb25zdHJ1Y3RvcihhYSl7c3VwZXIoKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLnNldExlYXJuaW5nUmF0ZShhYSl9YXBwbHlHcmFkaWVudHMoYWEpeyhBcnJheS5pc0FycmF5KGFhKT9hYS5tYXAoYmE9PmJhLm5hbWUpOk9iamVjdC5rZXlzKGFhKSkuZm9yRWFjaCgoYmEsU2EpPT57Y29uc3QgVGE9QXJyYXkuaXNBcnJheShhYSk/YWFbU2FdLnRlbnNvcjphYVtiYV07aWYoVGE9PW51bGwpcmV0dXJuO2NvbnN0IHdhPUVOR0lORSQxLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYmFdO3RpZHkkMSgoKT0+e2NvbnN0IEVhPWFkZCQzKG11bCQxKHRoaXMuYyxUYSksd2EpO3dhLmFzc2lnbihFYSl9KX0pLHRoaXMuaW5jcmVtZW50SXRlcmF0aW9ucygpfXNldExlYXJuaW5nUmF0ZShhYSl7dGhpcy5sZWFybmluZ1JhdGU9YWEsdGhpcy5jIT1udWxsJiZ0aGlzLmMuZGlzcG9zZSgpLHRoaXMuYz1rZWVwJDEoc2NhbGFyJDEoLWFhKSl9ZGlzcG9zZSgpe3RoaXMuYy5kaXNwb3NlKCl9YXN5bmMgZ2V0V2VpZ2h0cygpe3JldHVyblthd2FpdCB0aGlzLnNhdmVJdGVyYXRpb25zKCldfWFzeW5jIHNldFdlaWdodHMoYWEpe2lmKGFhPWF3YWl0IHRoaXMuZXh0cmFjdEl0ZXJhdGlvbnMoYWEpLGFhLmxlbmd0aCE9PTApdGhyb3cgbmV3IEVycm9yKCJTR0Qgb3B0aW1pemVyIGRvZXMgbm90IGhhdmUgc2V0dGFibGUgd2VpZ2h0cy4iKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlfX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YS5sZWFybmluZ1JhdGUpfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IE1vbWVudHVtT3B0aW1pemVyJDE9Y2xhc3MgZXh0ZW5kcyBTR0RPcHRpbWl6ZXIkMXtzdGF0aWMgZ2V0IGNsYXNzTmFtZSgpe3JldHVybiJNb21lbnR1bSJ9Y29uc3RydWN0b3IoYWEseGEsYmE9ITEpe3N1cGVyKGFhKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLm1vbWVudHVtPXhhLHRoaXMudXNlTmVzdGVyb3Y9YmEsdGhpcy5hY2N1bXVsYXRpb25zPVtdLHRoaXMubT1zY2FsYXIkMSh0aGlzLm1vbWVudHVtKX1hcHBseUdyYWRpZW50cyhhYSl7KEFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpKS5mb3JFYWNoKChiYSxTYSk9Pntjb25zdCBUYT1FTkdJTkUkMS5yZWdpc3RlcmVkVmFyaWFibGVzW2JhXTt0aGlzLmFjY3VtdWxhdGlvbnNbU2FdPT1udWxsJiYodGhpcy5hY2N1bXVsYXRpb25zW1NhXT17b3JpZ2luYWxOYW1lOmAke2JhfS9tb21lbnR1bWAsdmFyaWFibGU6dGlkeSQxKCgpPT56ZXJvc0xpa2UkNChUYSkudmFyaWFibGUoITEpKX0pO2NvbnN0IHdhPXRoaXMuYWNjdW11bGF0aW9uc1tTYV0udmFyaWFibGUsRWE9QXJyYXkuaXNBcnJheShhYSk/YWFbU2FdLnRlbnNvcjphYVtiYV07RWEhPW51bGwmJnRpZHkkMSgoKT0+e2xldCBrYTtjb25zdCBBYT1hZGQkMyhtdWwkMSh0aGlzLm0sd2EpLEVhKTt0aGlzLnVzZU5lc3Rlcm92P2thPWFkZCQzKG11bCQxKHRoaXMuYyxhZGQkMyhFYSxtdWwkMShBYSx0aGlzLm0pKSksVGEpOmthPWFkZCQzKG11bCQxKHRoaXMuYyxBYSksVGEpLHdhLmFzc2lnbihBYSksVGEuYXNzaWduKGthKX0pfSksdGhpcy5pbmNyZW1lbnRJdGVyYXRpb25zKCl9ZGlzcG9zZSgpe3RoaXMubS5kaXNwb3NlKCksdGhpcy5hY2N1bXVsYXRpb25zIT1udWxsJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRpb25zLm1hcChhYT0+YWEudmFyaWFibGUpKX1zZXRNb21lbnR1bShhYSl7dGhpcy5tb21lbnR1bT1hYX1hc3luYyBnZXRXZWlnaHRzKCl7cmV0dXJuW2F3YWl0IHRoaXMuc2F2ZUl0ZXJhdGlvbnMoKV0uY29uY2F0KHRoaXMuYWNjdW11bGF0aW9ucy5tYXAoYWE9Pih7bmFtZTphYS5vcmlnaW5hbE5hbWUsdGVuc29yOmFhLnZhcmlhYmxlfSkpKX1hc3luYyBzZXRXZWlnaHRzKGFhKXthYT1hd2FpdCB0aGlzLmV4dHJhY3RJdGVyYXRpb25zKGFhKTtjb25zdCB4YT0hMTt0aGlzLmFjY3VtdWxhdGlvbnM9YWEubWFwKGJhPT4oe29yaWdpbmFsTmFtZTpiYS5uYW1lLHZhcmlhYmxlOmJhLnRlbnNvci52YXJpYWJsZSh4YSl9KSl9Z2V0Q29uZmlnKCl7cmV0dXJue2xlYXJuaW5nUmF0ZTp0aGlzLmxlYXJuaW5nUmF0ZSxtb21lbnR1bTp0aGlzLm1vbWVudHVtLHVzZU5lc3Rlcm92OnRoaXMudXNlTmVzdGVyb3Z9fXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtyZXR1cm4gbmV3IGFhKHhhLmxlYXJuaW5nUmF0ZSx4YS5tb21lbnR1bSx4YS51c2VOZXN0ZXJvdil9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUk1TUHJvcE9wdGltaXplciQxPWNsYXNzIGV4dGVuZHMgT3B0aW1pemVyJDF7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iUk1TUHJvcCJ9Y29uc3RydWN0b3IoYWEseGE9LjksYmE9MCxTYT1udWxsLFRhPSExKXtpZihzdXBlcigpLHRoaXMubGVhcm5pbmdSYXRlPWFhLHRoaXMuZGVjYXk9eGEsdGhpcy5tb21lbnR1bT1iYSx0aGlzLmVwc2lsb249U2EsdGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzPVtdLHRoaXMuYWNjdW11bGF0ZWRNb21lbnRzPVtdLHRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHM9W10sdGhpcy5jZW50ZXJlZD1UYSxTYT09bnVsbCYmKHRoaXMuZXBzaWxvbj1FTkdJTkUkMS5iYWNrZW5kLmVwc2lsb24oKSksYWE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJsZWFybmluZ1JhdGUgZm9yIFJNU1Byb3BPcHRpbWl6ZXIgbXVzdCBiZSBkZWZpbmVkLiIpfWFwcGx5R3JhZGllbnRzKGFhKXsoQXJyYXkuaXNBcnJheShhYSk/YWEubWFwKGJhPT5iYS5uYW1lKTpPYmplY3Qua2V5cyhhYSkpLmZvckVhY2goKGJhLFNhKT0+e2NvbnN0IFRhPUVOR0lORSQxLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYmFdLHdhPSExO3RoaXMuYWNjdW11bGF0ZWRNZWFuU3F1YXJlc1tTYV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkTWVhblNxdWFyZXNbU2FdPXtvcmlnaW5hbE5hbWU6YCR7YmF9L3Jtc2AsdmFyaWFibGU6dGlkeSQxKCgpPT56ZXJvc0xpa2UkNChUYSkudmFyaWFibGUod2EpKX0pLHRoaXMuYWNjdW11bGF0ZWRNb21lbnRzW1NhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRNb21lbnRzW1NhXT17b3JpZ2luYWxOYW1lOmAke2JhfS9tb21lbnR1bWAsdmFyaWFibGU6dGlkeSQxKCgpPT56ZXJvc0xpa2UkNChUYSkudmFyaWFibGUod2EpKX0pLHRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHNbU2FdPT1udWxsJiZ0aGlzLmNlbnRlcmVkJiYodGhpcy5hY2N1bXVsYXRlZE1lYW5HcmFkc1tTYV09e29yaWdpbmFsTmFtZTpgJHtiYX0vbWdgLHZhcmlhYmxlOnRpZHkkMSgoKT0+emVyb3NMaWtlJDQoVGEpLnZhcmlhYmxlKHdhKSl9KTtjb25zdCBFYT1BcnJheS5pc0FycmF5KGFhKT9hYVtTYV0udGVuc29yOmFhW2JhXTtpZihFYT09bnVsbClyZXR1cm47Y29uc3Qga2E9dGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzW1NhXS52YXJpYWJsZSxBYT10aGlzLmFjY3VtdWxhdGVkTW9tZW50c1tTYV0udmFyaWFibGU7dGlkeSQxKCgpPT57Y29uc3QgRmE9YWRkJDMobXVsJDEoa2EsdGhpcy5kZWNheSksbXVsJDEoc3F1YXJlJDQoRWEpLDEtdGhpcy5kZWNheSkpO2lmKHRoaXMuY2VudGVyZWQpe2NvbnN0IExhPXRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHNbU2FdLnZhcmlhYmxlLGVsPWFkZCQzKG11bCQxKExhLHRoaXMuZGVjYXkpLG11bCQxKEVhLDEtdGhpcy5kZWNheSkpLHRsPWRpdiQyKG11bCQxKEVhLHRoaXMubGVhcm5pbmdSYXRlKSxzcXJ0JDQoc3ViJDQoRmEsYWRkJDMoc3F1YXJlJDQoZWwpLHRoaXMuZXBzaWxvbikpKSksbmw9YWRkJDMobXVsJDEoQWEsdGhpcy5tb21lbnR1bSksdGwpO2thLmFzc2lnbihGYSksTGEuYXNzaWduKGVsKSxBYS5hc3NpZ24obmwpO2NvbnN0IHNsPXN1YiQ0KFRhLG5sKTtUYS5hc3NpZ24oc2wpfWVsc2V7Y29uc3QgTGE9YWRkJDMobXVsJDEoa2EsdGhpcy5kZWNheSksbXVsJDEoc3F1YXJlJDQoRWEpLDEtdGhpcy5kZWNheSkpLGVsPWFkZCQzKG11bCQxKEFhLHRoaXMubW9tZW50dW0pLGRpdiQyKG11bCQxKEVhLHRoaXMubGVhcm5pbmdSYXRlKSxzcXJ0JDQoYWRkJDMoTGEsdGhpcy5lcHNpbG9uKSkpKTtrYS5hc3NpZ24oTGEpLEFhLmFzc2lnbihlbCk7Y29uc3QgdGw9c3ViJDQoVGEsZWwpO1RhLmFzc2lnbih0bCl9fSl9KSx0aGlzLmluY3JlbWVudEl0ZXJhdGlvbnMoKX1kaXNwb3NlKCl7dGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzIT1udWxsJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzLm1hcChhYT0+YWEudmFyaWFibGUpKSx0aGlzLmFjY3VtdWxhdGVkTWVhbkdyYWRzIT1udWxsJiZ0aGlzLmNlbnRlcmVkJiZkaXNwb3NlJDEodGhpcy5hY2N1bXVsYXRlZE1lYW5HcmFkcy5tYXAoYWE9PmFhLnZhcmlhYmxlKSksdGhpcy5hY2N1bXVsYXRlZE1vbWVudHMhPW51bGwmJmRpc3Bvc2UkMSh0aGlzLmFjY3VtdWxhdGVkTW9tZW50cy5tYXAoYWE9PmFhLnZhcmlhYmxlKSl9YXN5bmMgZ2V0V2VpZ2h0cygpe2NvbnN0IGFhPVsuLi50aGlzLmFjY3VtdWxhdGVkTWVhblNxdWFyZXMsLi4udGhpcy5hY2N1bXVsYXRlZE1vbWVudHNdO3JldHVybiB0aGlzLmNlbnRlcmVkJiZhYS5wdXNoKC4uLnRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHMpLFthd2FpdCB0aGlzLnNhdmVJdGVyYXRpb25zKCldLmNvbmNhdChhYS5tYXAoeGE9Pih7bmFtZTp4YS5vcmlnaW5hbE5hbWUsdGVuc29yOnhhLnZhcmlhYmxlfSkpKX1hc3luYyBzZXRXZWlnaHRzKGFhKXthYT1hd2FpdCB0aGlzLmV4dHJhY3RJdGVyYXRpb25zKGFhKTtjb25zdCB4YT10aGlzLmNlbnRlcmVkP2FhLmxlbmd0aC8zOmFhLmxlbmd0aC8yLGJhPSExO3RoaXMuYWNjdW11bGF0ZWRNZWFuU3F1YXJlcz1hYS5zbGljZSgwLHhhKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKSx0aGlzLmFjY3VtdWxhdGVkTW9tZW50cz1hYS5zbGljZSh4YSx4YSoyKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKSx0aGlzLmNlbnRlcmVkJiYodGhpcy5hY2N1bXVsYXRlZE1lYW5HcmFkcz1hYS5zbGljZSh4YSoyLHhhKjMpLm1hcChTYT0+KHtvcmlnaW5hbE5hbWU6U2EubmFtZSx2YXJpYWJsZTpTYS50ZW5zb3IudmFyaWFibGUoYmEpfSkpKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlLGRlY2F5OnRoaXMuZGVjYXksbW9tZW50dW06dGhpcy5tb21lbnR1bSxlcHNpbG9uOnRoaXMuZXBzaWxvbixjZW50ZXJlZDp0aGlzLmNlbnRlcmVkfX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YS5sZWFybmluZ1JhdGUseGEuZGVjYXkseGEubW9tZW50dW0seGEuZXBzaWxvbix4YS5jZW50ZXJlZCl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBPUFRJTUlaRVJTJDE9W0FkYWRlbHRhT3B0aW1pemVyJDEsQWRhZ3JhZE9wdGltaXplciQxLEFkYW1PcHRpbWl6ZXIkMSxBZGFtYXhPcHRpbWl6ZXIkMSxNb21lbnR1bU9wdGltaXplciQxLFJNU1Byb3BPcHRpbWl6ZXIkMSxTR0RPcHRpbWl6ZXIkMV07ZnVuY3Rpb24gcmVnaXN0ZXJPcHRpbWl6ZXJzJDEoKXtmb3IoY29uc3QgaGEgb2YgT1BUSU1JWkVSUyQxKXJlZ2lzdGVyQ2xhc3MkMShoYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgREVGQVVMVF9GSUxFX05BTUVfUFJFRklYJDE9Im1vZGVsIixERUZBVUxUX0pTT05fRVhURU5TSU9OX05BTUUkMT0iLmpzb24iLERFRkFVTFRfV0VJR0hUX0RBVEFfRVhURU5TSU9OX05BTUUkMT0iLndlaWdodHMuYmluIjtmdW5jdGlvbiBkZWZlciQxKGhhKXtyZXR1cm4gbmV3IFByb21pc2UoYWE9PnNldFRpbWVvdXQoYWEpKS50aGVuKGhhKX1sZXQgQnJvd3NlckRvd25sb2FkcyQxPWNsYXNzIGlje2NvbnN0cnVjdG9yKGFhKXtpZighZW52JDEoKS5nZXRCb29sKCJJU19CUk9XU0VSIikpdGhyb3cgbmV3IEVycm9yKCJicm93c2VyRG93bmxvYWRzKCkgY2Fubm90IHByb2NlZWQgYmVjYXVzZSB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBub3QgYSBicm93c2VyLiIpO2FhLnN0YXJ0c1dpdGgoaWMuVVJMX1NDSEVNRSkmJihhYT1hYS5zbGljZShpYy5VUkxfU0NIRU1FLmxlbmd0aCkpLChhYT09bnVsbHx8YWEubGVuZ3RoPT09MCkmJihhYT1ERUZBVUxUX0ZJTEVfTkFNRV9QUkVGSVgkMSksdGhpcy5tb2RlbEpzb25GaWxlTmFtZT1hYStERUZBVUxUX0pTT05fRVhURU5TSU9OX05BTUUkMSx0aGlzLndlaWdodERhdGFGaWxlTmFtZT1hYStERUZBVUxUX1dFSUdIVF9EQVRBX0VYVEVOU0lPTl9OQU1FJDF9YXN5bmMgc2F2ZShhYSl7aWYodHlwZW9mIGRvY3VtZW50PiJ1Iil0aHJvdyBuZXcgRXJyb3IoIkJyb3dzZXIgZG93bmxvYWRzIGFyZSBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQgc2luY2UgYGRvY3VtZW50YCBpcyBub3QgcHJlc2VudCIpO2NvbnN0IHhhPUNvbXBvc2l0ZUFycmF5QnVmZmVyJDEuam9pbihhYS53ZWlnaHREYXRhKSxiYT13aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbeGFdLHt0eXBlOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0ifSkpO2lmKGFhLm1vZGVsVG9wb2xvZ3kgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil0aHJvdyBuZXcgRXJyb3IoIkJyb3dzZXJEb3dubG9hZHMuc2F2ZSgpIGRvZXMgbm90IHN1cHBvcnQgc2F2aW5nIG1vZGVsIHRvcG9sb2d5IGluIGJpbmFyeSBmb3JtYXRzIHlldC4iKTt7Y29uc3QgU2E9W3twYXRoczpbIi4vIit0aGlzLndlaWdodERhdGFGaWxlTmFtZV0sd2VpZ2h0czphYS53ZWlnaHRTcGVjc31dLFRhPWdldE1vZGVsSlNPTkZvck1vZGVsQXJ0aWZhY3RzJDEoYWEsU2EpLHdhPXdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFtKU09OLnN0cmluZ2lmeShUYSldLHt0eXBlOiJhcHBsaWNhdGlvbi9qc29uIn0pKSxFYT10aGlzLm1vZGVsSnNvbkFuY2hvcj09bnVsbD9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik6dGhpcy5tb2RlbEpzb25BbmNob3I7aWYoRWEuZG93bmxvYWQ9dGhpcy5tb2RlbEpzb25GaWxlTmFtZSxFYS5ocmVmPXdhLGF3YWl0IGRlZmVyJDEoKCk9PkVhLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoImNsaWNrIikpKSxhYS53ZWlnaHREYXRhIT1udWxsKXtjb25zdCBrYT10aGlzLndlaWdodERhdGFBbmNob3I9PW51bGw/ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOnRoaXMud2VpZ2h0RGF0YUFuY2hvcjtrYS5kb3dubG9hZD10aGlzLndlaWdodERhdGFGaWxlTmFtZSxrYS5ocmVmPWJhLGF3YWl0IGRlZmVyJDEoKCk9PmthLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoImNsaWNrIikpKX1yZXR1cm57bW9kZWxBcnRpZmFjdHNJbmZvOmdldE1vZGVsQXJ0aWZhY3RzSW5mb0ZvckpTT04kMShhYSl9fX19O0Jyb3dzZXJEb3dubG9hZHMkMS5VUkxfU0NIRU1FPSJkb3dubG9hZHM6Ly8iO2NsYXNzIEJyb3dzZXJGaWxlc3tjb25zdHJ1Y3RvcihhYSl7aWYoYWE9PW51bGx8fGFhLmxlbmd0aDwxKXRocm93IG5ldyBFcnJvcihgV2hlbiBjYWxsaW5nIGJyb3dzZXJGaWxlcywgYXQgbGVhc3QgMSBmaWxlIGlzIHJlcXVpcmVkLCBidXQgcmVjZWl2ZWQgJHthYX1gKTt0aGlzLmpzb25GaWxlPWFhWzBdLHRoaXMud2VpZ2h0c0ZpbGVzPWFhLnNsaWNlKDEpfWFzeW5jIGxvYWQoKXtyZXR1cm4gbmV3IFByb21pc2UoKGFhLHhhKT0+e2NvbnN0IGJhPW5ldyBGaWxlUmVhZGVyO2JhLm9ubG9hZD1TYT0+e2NvbnN0IFRhPUpTT04ucGFyc2UoU2EudGFyZ2V0LnJlc3VsdCksd2E9VGEubW9kZWxUb3BvbG9neTtpZih3YT09bnVsbCl7eGEobmV3IEVycm9yKGBtb2RlbFRvcG9sb2d5IGZpZWxkIGlzIG1pc3NpbmcgZnJvbSBmaWxlICR7dGhpcy5qc29uRmlsZS5uYW1lfWApKTtyZXR1cm59aWYoVGEud2VpZ2h0c01hbmlmZXN0PT1udWxsKXt4YShuZXcgRXJyb3IoYHdlaWdodE1hbmlmZXN0IGZpZWxkIGlzIG1pc3NpbmcgZnJvbSBmaWxlICR7dGhpcy5qc29uRmlsZS5uYW1lfWApKTtyZXR1cm59aWYodGhpcy53ZWlnaHRzRmlsZXMubGVuZ3RoPT09MCl7YWEoe21vZGVsVG9wb2xvZ3k6d2F9KTtyZXR1cm59Y29uc3Qga2E9Z2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OJDEoVGEsQWE9PnRoaXMubG9hZFdlaWdodHMoQWEpKTthYShrYSl9LGJhLm9uZXJyb3I9U2E9PnhhKGBGYWlsZWQgdG8gcmVhZCBtb2RlbCB0b3BvbG9neSBhbmQgd2VpZ2h0cyBtYW5pZmVzdCBKU09OIGZyb20gZmlsZSAnJHt0aGlzLmpzb25GaWxlLm5hbWV9Jy4gQnJvd3NlckZpbGVzIHN1cHBvcnRzIGxvYWRpbmcgS2VyYXMtc3R5bGUgdGYuTW9kZWwgYXJ0aWZhY3RzIG9ubHkuYCksYmEucmVhZEFzVGV4dCh0aGlzLmpzb25GaWxlKX0pfWxvYWRXZWlnaHRzKGFhKXtjb25zdCB4YT1bXSxiYT1bXTtmb3IoY29uc3Qgd2Egb2YgYWEpeGEucHVzaCguLi53YS53ZWlnaHRzKSxiYS5wdXNoKC4uLndhLnBhdGhzKTtjb25zdCBTYT10aGlzLmNoZWNrTWFuaWZlc3RBbmRXZWlnaHRGaWxlcyhhYSksVGE9YmEubWFwKHdhPT50aGlzLmxvYWRXZWlnaHRzRmlsZSh3YSxTYVt3YV0pKTtyZXR1cm4gUHJvbWlzZS5hbGwoVGEpLnRoZW4od2E9Plt4YSx3YV0pfWxvYWRXZWlnaHRzRmlsZShhYSx4YSl7cmV0dXJuIG5ldyBQcm9taXNlKChiYSxTYSk9Pntjb25zdCBUYT1uZXcgRmlsZVJlYWRlcjtUYS5vbmxvYWQ9d2E9Pntjb25zdCBFYT13YS50YXJnZXQucmVzdWx0O2JhKEVhKX0sVGEub25lcnJvcj13YT0+U2EoYEZhaWxlZCB0byB3ZWlnaHRzIGRhdGEgZnJvbSBmaWxlIG9mIHBhdGggJyR7YWF9Jy5gKSxUYS5yZWFkQXNBcnJheUJ1ZmZlcih4YSl9KX1jaGVja01hbmlmZXN0QW5kV2VpZ2h0RmlsZXMoYWEpe2NvbnN0IHhhPVtdLGJhPXRoaXMud2VpZ2h0c0ZpbGVzLm1hcChUYT0+YmFzZW5hbWUoVGEubmFtZSkpLFNhPXt9O2Zvcihjb25zdCBUYSBvZiBhYSlUYS5wYXRocy5mb3JFYWNoKHdhPT57Y29uc3QgRWE9YmFzZW5hbWUod2EpO2lmKHhhLmluZGV4T2YoRWEpIT09LTEpdGhyb3cgbmV3IEVycm9yKGBEdXBsaWNhdGUgZmlsZSBiYXNlbmFtZSBmb3VuZCBpbiB3ZWlnaHRzIG1hbmlmZXN0OiAnJHtFYX0nYCk7aWYoeGEucHVzaChFYSksYmEuaW5kZXhPZihFYSk9PT0tMSl0aHJvdyBuZXcgRXJyb3IoYFdlaWdodCBmaWxlIHdpdGggYmFzZW5hbWUgJyR7RWF9JyBpcyBub3QgcHJvdmlkZWQuYCk7U2Fbd2FdPXRoaXMud2VpZ2h0c0ZpbGVzW2JhLmluZGV4T2YoRWEpXX0pO2lmKHhhLmxlbmd0aCE9PXRoaXMud2VpZ2h0c0ZpbGVzLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYE1pc21hdGNoIGluIHRoZSBudW1iZXIgb2YgZmlsZXMgaW4gd2VpZ2h0cyBtYW5pZmVzdCAoJHt4YS5sZW5ndGh9KSBhbmQgdGhlIG51bWJlciBvZiB3ZWlnaHQgZmlsZXMgcHJvdmlkZWQgKCR7dGhpcy53ZWlnaHRzRmlsZXMubGVuZ3RofSkuYCk7cmV0dXJuIFNhfX1jb25zdCBicm93c2VyRG93bmxvYWRzUm91dGVyJDE9aGE9PmVudiQxKCkuZ2V0Qm9vbCgiSVNfQlJPV1NFUiIpJiYhQXJyYXkuaXNBcnJheShoYSkmJmhhLnN0YXJ0c1dpdGgoQnJvd3NlckRvd25sb2FkcyQxLlVSTF9TQ0hFTUUpP2Jyb3dzZXJEb3dubG9hZHMkMShoYS5zbGljZShCcm93c2VyRG93bmxvYWRzJDEuVVJMX1NDSEVNRS5sZW5ndGgpKTpudWxsO0lPUm91dGVyUmVnaXN0cnkkMS5yZWdpc3RlclNhdmVSb3V0ZXIoYnJvd3NlckRvd25sb2Fkc1JvdXRlciQxKTtmdW5jdGlvbiBicm93c2VyRG93bmxvYWRzJDEoaGE9Im1vZGVsIil7cmV0dXJuIG5ldyBCcm93c2VyRG93bmxvYWRzJDEoaGEpfWZ1bmN0aW9uIGJyb3dzZXJGaWxlcyhoYSl7cmV0dXJuIG5ldyBCcm93c2VyRmlsZXMoaGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1vbml0b3JQcm9taXNlc1Byb2dyZXNzJDEoaGEsYWEseGEsYmEpe3dhKGhhKSx4YT14YT8/MCxiYT1iYT8/MSxFYSh4YSxiYSk7bGV0IFNhPTA7Y29uc3QgVGE9a2E9PihrYS50aGVuKEFhPT57Y29uc3QgRmE9eGErICsrU2EvaGEubGVuZ3RoKihiYS14YSk7cmV0dXJuIGFhKEZhKSxBYX0pLGthKTtmdW5jdGlvbiB3YShrYSl7YXNzZXJ0JDIoa2EhPW51bGwmJkFycmF5LmlzQXJyYXkoa2EpJiZrYS5sZW5ndGg+MCwoKT0+InByb21pc2VzIG11c3QgYmUgYSBub25lIGVtcHR5IGFycmF5Iil9ZnVuY3Rpb24gRWEoa2EsQWEpe2Fzc2VydCQyKGthPj0wJiZrYTw9MSwoKT0+YFByb2dyZXNzIGZyYWN0aW9uIG11c3QgYmUgaW4gcmFuZ2UgWzAsIDFdLCBidXQgZ290IHN0YXJ0RnJhY3Rpb24gJHtrYX1gKSxhc3NlcnQkMihBYT49MCYmQWE8PTEsKCk9PmBQcm9ncmVzcyBmcmFjdGlvbiBtdXN0IGJlIGluIHJhbmdlIFswLCAxXSwgYnV0IGdvdCBlbmRGcmFjdGlvbiAke0FhfWApLGFzc2VydCQyKEFhPj1rYSwoKT0+YHN0YXJ0RnJhY3Rpb24gbXVzdCBiZSBubyBtb3JlIHRoYW4gZW5kRnJhY3Rpb24sIGJ1dCBnb3Qgc3RhcnRGcmFjdGlvbiAke2thfSBhbmQgZW5kRnJhY3Rpb24gJHtBYX1gKX1yZXR1cm4gUHJvbWlzZS5hbGwoaGEubWFwKFRhKSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovYXN5bmMgZnVuY3Rpb24gbG9hZFdlaWdodHNBc0FycmF5QnVmZmVyJDIoaGEsYWEpe2FhPT1udWxsJiYoYWE9e30pO2NvbnN0IHhhPWFhLmZldGNoRnVuYz09bnVsbD9lbnYkMSgpLnBsYXRmb3JtLmZldGNoOmFhLmZldGNoRnVuYyxiYT1oYS5tYXAoTGE9PnhhKExhLGFhLnJlcXVlc3RJbml0LHtpc0JpbmFyeTohMH0pKSxFYT0oYWEub25Qcm9ncmVzcz09bnVsbD9hd2FpdCBQcm9taXNlLmFsbChiYSk6YXdhaXQgbW9uaXRvclByb21pc2VzUHJvZ3Jlc3MkMShiYSxhYS5vblByb2dyZXNzLDAsLjUpKS5tYXAoTGE9PkxhLmFycmF5QnVmZmVyKCkpO3JldHVybiBhYS5vblByb2dyZXNzPT1udWxsP2F3YWl0IFByb21pc2UuYWxsKEVhKTphd2FpdCBtb25pdG9yUHJvbWlzZXNQcm9ncmVzcyQxKEVhLGFhLm9uUHJvZ3Jlc3MsLjUsMSl9ZnVuY3Rpb24gc3RyZWFtV2VpZ2h0cyQxKGhhLGFhKXt2YXIgeGE7Y29uc3QgYmE9YWEuZmV0Y2hGdW5jPT1udWxsP2VudiQxKCkucGxhdGZvcm0uZmV0Y2g6YWEuZmV0Y2hGdW5jO2xldCBTYT0wLFRhO3JldHVybih4YT1hYS5vblByb2dyZXNzKT09PW51bGx8fHhhPT09dm9pZCAwfHx4YS5jYWxsKGFhLDApLG5ldyBSZWFkYWJsZVN0cmVhbSh7cHVsbDphc3luYyB3YT0+e2Zvcih2YXIgRWE7U2E8aGEubGVuZ3RoOyl7VGF8fChUYT0oYXdhaXQgYmEoaGFbU2FdLGFhLnJlcXVlc3RJbml0LHtpc0JpbmFyeTohMH0pKS5ib2R5LmdldFJlYWRlcigpKTtjb25zdHtkb25lOmthLHZhbHVlOkFhfT1hd2FpdCBUYS5yZWFkKCk7aWYoa2Epe1NhKyssVGE9dm9pZCAwLChFYT1hYS5vblByb2dyZXNzKT09PW51bGx8fEVhPT09dm9pZCAwfHxFYS5jYWxsKGFhLFNhL2hhLmxlbmd0aCk7Y29udGludWV9d2EuZW5xdWV1ZShBYSk7cmV0dXJufXdhLmNsb3NlKCl9fSl9YXN5bmMgZnVuY3Rpb24gbG9hZFdlaWdodHMoaGEsYWE9IiIseGEsYmEpe3JldHVybiB3ZWlnaHRzTG9hZGVyRmFjdG9yeSh3YT0+bG9hZFdlaWdodHNBc0FycmF5QnVmZmVyJDIod2Ese3JlcXVlc3RJbml0OmJhfSkpKGhhLGFhLHhhKX1mdW5jdGlvbiB3ZWlnaHRzTG9hZGVyRmFjdG9yeShoYSl7cmV0dXJuIGFzeW5jKGFhLHhhPSIiLGJhKT0+e2NvbnN0IFNhPWFhLm1hcCgoKT0+ITEpLFRhPXt9LHdhPWJhIT1udWxsP2JhLm1hcCgoKT0+ITEpOltdLEVhPVtdO2lmKGFhLmZvckVhY2goKHRsLG5sKT0+e2xldCBzbD0wO3RsLndlaWdodHMuZm9yRWFjaChybD0+e2NvbnN0IG9sPSJxdWFudGl6YXRpb24iaW4gcmw/cmwucXVhbnRpemF0aW9uLmR0eXBlOnJsLmR0eXBlLGFsPURUWVBFX1ZBTFVFX1NJWkVfTUFQW29sXSpzaXplRnJvbVNoYXBlJDEocmwuc2hhcGUpLGxsPSgpPT57U2FbbmxdPSEwLFRhW25sXT09bnVsbCYmKFRhW25sXT1bXSksVGFbbmxdLnB1c2goe21hbmlmZXN0RW50cnk6cmwsZ3JvdXBPZmZzZXQ6c2wsc2l6ZUJ5dGVzOmFsfSl9O2JhIT1udWxsP2JhLmZvckVhY2goKGlsLGNsKT0+e2lsPT09cmwubmFtZSYmKGxsKCksd2FbY2xdPSEwKX0pOmxsKCksRWEucHVzaChybC5uYW1lKSxzbCs9YWx9KX0pLCF3YS5ldmVyeSh0bD0+dGwpKXtjb25zdCB0bD1iYS5maWx0ZXIoKG5sLHNsKT0+IXdhW3NsXSk7dGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZmluZCB3ZWlnaHRzIGluIG1hbmlmZXN0IHdpdGggbmFtZXM6ICR7dGwuam9pbigiLCAiKX0uIApNYW5pZmVzdCBKU09OIGhhcyB3ZWlnaHRzIHdpdGggbmFtZXM6ICR7RWEuam9pbigiLCAiKX0uYCl9Y29uc3Qga2E9U2EucmVkdWNlKCh0bCxubCxzbCk9PihubCYmdGwucHVzaChzbCksdGwpLFtdKSxBYT1bXTtrYS5mb3JFYWNoKHRsPT57YWFbdGxdLnBhdGhzLmZvckVhY2gobmw9Pntjb25zdCBzbD14YSsoeGEuZW5kc1dpdGgoIi8iKT8iIjoiLyIpK25sO0FhLnB1c2goc2wpfSl9KTtjb25zdCBGYT1hd2FpdCBoYShBYSksTGE9e307bGV0IGVsPTA7cmV0dXJuIGthLmZvckVhY2godGw9Pntjb25zdCBubD1hYVt0bF0ucGF0aHMubGVuZ3RoLHNsPW5ldyBDb21wb3NpdGVBcnJheUJ1ZmZlciQxKEZhLnNsaWNlKGVsLGVsK25sKSk7VGFbdGxdLmZvckVhY2gob2w9Pntjb25zdCBhbD1zbC5zbGljZShvbC5ncm91cE9mZnNldCxvbC5ncm91cE9mZnNldCtvbC5zaXplQnl0ZXMpLGxsPWRlY29kZVdlaWdodHMoYWwsW29sLm1hbmlmZXN0RW50cnldKTtmb3IoY29uc3QgaWwgaW4gbGwpTGFbaWxdPWxsW2lsXX0pLGVsKz1ubH0pLExhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBPQ1RFVF9TVFJFQU1fTUlNRV9UWVBFJDE9ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsSlNPTl9UWVBFJDE9ImFwcGxpY2F0aW9uL2pzb24iO2xldCBIVFRQUmVxdWVzdCQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhKXtpZih0aGlzLkRFRkFVTFRfTUVUSE9EPSJQT1NUIix4YT09bnVsbCYmKHhhPXt9KSx0aGlzLndlaWdodFBhdGhQcmVmaXg9eGEud2VpZ2h0UGF0aFByZWZpeCx0aGlzLndlaWdodFVybENvbnZlcnRlcj14YS53ZWlnaHRVcmxDb252ZXJ0ZXIseGEuZmV0Y2hGdW5jIT1udWxsPyhhc3NlcnQkMih0eXBlb2YgeGEuZmV0Y2hGdW5jPT0iZnVuY3Rpb24iLCgpPT4iTXVzdCBwYXNzIGEgZnVuY3Rpb24gdGhhdCBtYXRjaGVzIHRoZSBzaWduYXR1cmUgb2YgYGZldGNoYCAoc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9GZXRjaF9BUEkpIiksdGhpcy5mZXRjaD14YS5mZXRjaEZ1bmMpOnRoaXMuZmV0Y2g9ZW52JDEoKS5wbGF0Zm9ybS5mZXRjaCxhc3NlcnQkMihhYSE9bnVsbCYmYWEubGVuZ3RoPjAsKCk9PiJVUkwgcGF0aCBmb3IgaHR0cCBtdXN0IG5vdCBiZSBudWxsLCB1bmRlZmluZWQgb3IgZW1wdHkuIiksQXJyYXkuaXNBcnJheShhYSkmJmFzc2VydCQyKGFhLmxlbmd0aD09PTIsKCk9PmBVUkwgcGF0aHMgZm9yIGh0dHAgbXVzdCBoYXZlIGEgbGVuZ3RoIG9mIDIsIChhY3R1YWwgbGVuZ3RoIGlzICR7YWEubGVuZ3RofSkuYCksdGhpcy5wYXRoPWFhLHhhLnJlcXVlc3RJbml0IT1udWxsJiZ4YS5yZXF1ZXN0SW5pdC5ib2R5IT1udWxsKXRocm93IG5ldyBFcnJvcigicmVxdWVzdEluaXQgaXMgZXhwZWN0ZWQgdG8gaGF2ZSBubyBwcmUtZXhpc3RpbmcgYm9keSwgYnV0IGhhcyBvbmUuIik7dGhpcy5yZXF1ZXN0SW5pdD14YS5yZXF1ZXN0SW5pdHx8e30sdGhpcy5sb2FkT3B0aW9ucz14YX1hc3luYyBzYXZlKGFhKXtpZihhYS5tb2RlbFRvcG9sb2d5IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpdGhyb3cgbmV3IEVycm9yKCJCcm93c2VySFRUUFJlcXVlc3Quc2F2ZSgpIGRvZXMgbm90IHN1cHBvcnQgc2F2aW5nIG1vZGVsIHRvcG9sb2d5IGluIGJpbmFyeSBmb3JtYXRzIHlldC4iKTtjb25zdCB4YT1PYmplY3QuYXNzaWduKHttZXRob2Q6dGhpcy5ERUZBVUxUX01FVEhPRH0sdGhpcy5yZXF1ZXN0SW5pdCk7eGEuYm9keT1uZXcgRm9ybURhdGE7Y29uc3QgYmE9W3twYXRoczpbIi4vbW9kZWwud2VpZ2h0cy5iaW4iXSx3ZWlnaHRzOmFhLndlaWdodFNwZWNzfV0sU2E9Z2V0TW9kZWxKU09ORm9yTW9kZWxBcnRpZmFjdHMkMShhYSxiYSk7aWYoeGEuYm9keS5hcHBlbmQoIm1vZGVsLmpzb24iLG5ldyBCbG9iKFtKU09OLnN0cmluZ2lmeShTYSldLHt0eXBlOkpTT05fVFlQRSQxfSksIm1vZGVsLmpzb24iKSxhYS53ZWlnaHREYXRhIT1udWxsKXtjb25zdCB3YT1Db21wb3NpdGVBcnJheUJ1ZmZlciQxLmpvaW4oYWEud2VpZ2h0RGF0YSk7eGEuYm9keS5hcHBlbmQoIm1vZGVsLndlaWdodHMuYmluIixuZXcgQmxvYihbd2FdLHt0eXBlOk9DVEVUX1NUUkVBTV9NSU1FX1RZUEUkMX0pLCJtb2RlbC53ZWlnaHRzLmJpbiIpfWNvbnN0IFRhPWF3YWl0IHRoaXMuZmV0Y2godGhpcy5wYXRoLHhhKTtpZihUYS5vaylyZXR1cm57bW9kZWxBcnRpZmFjdHNJbmZvOmdldE1vZGVsQXJ0aWZhY3RzSW5mb0ZvckpTT04kMShhYSkscmVzcG9uc2VzOltUYV19O3Rocm93IG5ldyBFcnJvcihgQnJvd3NlckhUVFBSZXF1ZXN0LnNhdmUoKSBmYWlsZWQgZHVlIHRvIEhUVFAgcmVzcG9uc2Ugc3RhdHVzICR7VGEuc3RhdHVzfS5gKX1hc3luYyBsb2FkTW9kZWxKU09OKCl7Y29uc3QgYWE9YXdhaXQgdGhpcy5mZXRjaCh0aGlzLnBhdGgsdGhpcy5yZXF1ZXN0SW5pdCk7aWYoIWFhLm9rKXRocm93IG5ldyBFcnJvcihgUmVxdWVzdCB0byAke3RoaXMucGF0aH0gZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJHthYS5zdGF0dXN9LiBQbGVhc2UgdmVyaWZ5IHRoaXMgVVJMIHBvaW50cyB0byB0aGUgbW9kZWwgSlNPTiBvZiB0aGUgbW9kZWwgdG8gbG9hZC5gKTtsZXQgeGE7dHJ5e3hhPWF3YWl0IGFhLmpzb24oKX1jYXRjaHtsZXQgd2E9YEZhaWxlZCB0byBwYXJzZSBtb2RlbCBKU09OIG9mIHJlc3BvbnNlIGZyb20gJHt0aGlzLnBhdGh9LmA7dGhyb3cgdGhpcy5wYXRoLmVuZHNXaXRoKCIucGIiKT93YSs9IiBZb3VyIHBhdGggY29udGFpbnMgYSAucGIgZmlsZSBleHRlbnNpb24uIFN1cHBvcnQgZm9yIC5wYiBtb2RlbHMgaGF2ZSBiZWVuIHJlbW92ZWQgaW4gVGVuc29yRmxvdy5qcyAxLjAgaW4gZmF2b3Igb2YgLmpzb24gbW9kZWxzLiBZb3UgY2FuIHJlLWNvbnZlcnQgeW91ciBQeXRob24gVGVuc29yRmxvdyBtb2RlbCB1c2luZyB0aGUgVGVuc29yRmxvdy5qcyAxLjAgY29udmVyc2lvbiBzY3JpcHRzIG9yIHlvdSBjYW4gY29udmVydCB5b3VyLnBiIG1vZGVscyB3aXRoIHRoZSAncGIyanNvbidOUE0gc2NyaXB0IGluIHRoZSB0ZW5zb3JmbG93L3RmanMtY29udmVydGVyIHJlcG9zaXRvcnkuIjp3YSs9IiBQbGVhc2UgbWFrZSBzdXJlIHRoZSBzZXJ2ZXIgaXMgc2VydmluZyB2YWxpZCBKU09OIGZvciB0aGlzIHJlcXVlc3QuIixuZXcgRXJyb3Iod2EpfWNvbnN0IGJhPXhhLm1vZGVsVG9wb2xvZ3ksU2E9eGEud2VpZ2h0c01hbmlmZXN0O2lmKGJhPT1udWxsJiZTYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYFRoZSBKU09OIGZyb20gSFRUUCBwYXRoICR7dGhpcy5wYXRofSBjb250YWlucyBuZWl0aGVyIG1vZGVsIHRvcG9sb2d5IG9yIG1hbmlmZXN0IGZvciB3ZWlnaHRzLmApO3JldHVybiB4YX1hc3luYyBsb2FkKCl7aWYodGhpcy5sb2FkT3B0aW9ucy5zdHJlYW1XZWlnaHRzKXJldHVybiB0aGlzLmxvYWRTdHJlYW0oKTtjb25zdCBhYT1hd2FpdCB0aGlzLmxvYWRNb2RlbEpTT04oKTtyZXR1cm4gZ2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OJDEoYWEseGE9PnRoaXMubG9hZFdlaWdodHMoeGEpKX1hc3luYyBsb2FkU3RyZWFtKCl7Y29uc3QgYWE9YXdhaXQgdGhpcy5sb2FkTW9kZWxKU09OKCkseGE9YXdhaXQgdGhpcy5nZXRXZWlnaHRVcmxzKGFhLndlaWdodHNNYW5pZmVzdCksYmE9Z2V0V2VpZ2h0U3BlY3MkMShhYS53ZWlnaHRzTWFuaWZlc3QpLFNhPSgpPT5zdHJlYW1XZWlnaHRzJDEoeGEsdGhpcy5sb2FkT3B0aW9ucyk7cmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxhYSkse3dlaWdodFNwZWNzOmJhLGdldFdlaWdodFN0cmVhbTpTYX0pfWFzeW5jIGdldFdlaWdodFVybHMoYWEpe2NvbnN0IHhhPUFycmF5LmlzQXJyYXkodGhpcy5wYXRoKT90aGlzLnBhdGhbMV06dGhpcy5wYXRoLFtiYSxTYV09cGFyc2VVcmwkMSh4YSksVGE9dGhpcy53ZWlnaHRQYXRoUHJlZml4fHxiYSx3YT1bXSxFYT1bXTtmb3IoY29uc3Qga2Egb2YgYWEpZm9yKGNvbnN0IEFhIG9mIGthLnBhdGhzKXRoaXMud2VpZ2h0VXJsQ29udmVydGVyIT1udWxsP0VhLnB1c2godGhpcy53ZWlnaHRVcmxDb252ZXJ0ZXIoQWEpKTp3YS5wdXNoKFRhK0FhK1NhKTtyZXR1cm4gdGhpcy53ZWlnaHRVcmxDb252ZXJ0ZXImJndhLnB1c2goLi4uYXdhaXQgUHJvbWlzZS5hbGwoRWEpKSx3YX1hc3luYyBsb2FkV2VpZ2h0cyhhYSl7Y29uc3QgeGE9YXdhaXQgdGhpcy5nZXRXZWlnaHRVcmxzKGFhKSxiYT1nZXRXZWlnaHRTcGVjcyQxKGFhKSxTYT1hd2FpdCBsb2FkV2VpZ2h0c0FzQXJyYXlCdWZmZXIkMih4YSx0aGlzLmxvYWRPcHRpb25zKTtyZXR1cm5bYmEsU2FdfX07SFRUUFJlcXVlc3QkMS5VUkxfU0NIRU1FX1JFR0VYPS9eaHR0cHM/OlwvXC8vO2Z1bmN0aW9uIHBhcnNlVXJsJDEoaGEpe2NvbnN0IGFhPWhhLmxhc3RJbmRleE9mKCIvIikseGE9aGEubGFzdEluZGV4T2YoIj8iKSxiYT1oYS5zdWJzdHJpbmcoMCxhYSksU2E9eGE+YWE/aGEuc3Vic3RyaW5nKHhhKToiIjtyZXR1cm5bYmErIi8iLFNhXX1mdW5jdGlvbiBpc0hUVFBTY2hlbWUkMShoYSl7cmV0dXJuIGhhLm1hdGNoKEhUVFBSZXF1ZXN0JDEuVVJMX1NDSEVNRV9SRUdFWCkhPW51bGx9Y29uc3QgaHR0cFJvdXRlciQxPShoYSxhYSk9PntpZih0eXBlb2YgZmV0Y2g+InUiJiYoYWE9PW51bGx8fGFhLmZldGNoRnVuYz09bnVsbCkpcmV0dXJuIG51bGw7e2xldCB4YT0hMDtpZihBcnJheS5pc0FycmF5KGhhKT94YT1oYS5ldmVyeShiYT0+aXNIVFRQU2NoZW1lJDEoYmEpKTp4YT1pc0hUVFBTY2hlbWUkMShoYSkseGEpcmV0dXJuIGh0dHAkMShoYSxhYSl9cmV0dXJuIG51bGx9O0lPUm91dGVyUmVnaXN0cnkkMS5yZWdpc3RlclNhdmVSb3V0ZXIoaHR0cFJvdXRlciQxKSxJT1JvdXRlclJlZ2lzdHJ5JDEucmVnaXN0ZXJMb2FkUm91dGVyKGh0dHBSb3V0ZXIkMSk7ZnVuY3Rpb24gaHR0cCQxKGhhLGFhKXtyZXR1cm4gbmV3IEhUVFBSZXF1ZXN0JDEoaGEsYWEpfWZ1bmN0aW9uIGJyb3dzZXJIVFRQUmVxdWVzdChoYSxhYSl7cmV0dXJuIGh0dHAkMShoYSxhYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUGFzc3Rocm91Z2hMb2FkZXJ7Y29uc3RydWN0b3IoYWEpe3RoaXMubW9kZWxBcnRpZmFjdHM9YWF9bG9hZCgpe3JldHVybiB0aGlzLm1vZGVsQXJ0aWZhY3RzfX1jbGFzcyBQYXNzdGhyb3VnaFNhdmVye2NvbnN0cnVjdG9yKGFhKXt0aGlzLnNhdmVIYW5kbGVyPWFhfXNhdmUoYWEpe3JldHVybiB0aGlzLnNhdmVIYW5kbGVyKGFhKX19Y2xhc3MgUGFzc3Rocm91Z2hBc3luY3tjb25zdHJ1Y3RvcihhYSl7YWEubG9hZCYmKHRoaXMubG9hZD0oKT0+UHJvbWlzZS5yZXNvbHZlKGFhLmxvYWQoKSkpLGFhLnNhdmUmJih0aGlzLnNhdmU9eGE9PlByb21pc2UucmVzb2x2ZShhYS5zYXZlKHhhKSkpfX1mdW5jdGlvbiBmcm9tTWVtb3J5KGhhLGFhLHhhLGJhKXtjb25zdCBTYT1hcmd1bWVudHM7cmV0dXJuIG5ldyBQYXNzdGhyb3VnaEFzeW5jKGZyb21NZW1vcnlTeW5jKC4uLlNhKSl9ZnVuY3Rpb24gZnJvbU1lbW9yeVN5bmMoaGEsYWEseGEsYmEpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPT09MT9oYS5tb2RlbFRvcG9sb2d5IT1udWxsfHxoYS53ZWlnaHRTcGVjcyE9bnVsbD9uZXcgUGFzc3Rocm91Z2hMb2FkZXIoaGEpOihjb25zb2xlLndhcm4oIlBsZWFzZSBjYWxsIHRmLmlvLmZyb21NZW1vcnkoKSB3aXRoIG9ubHkgb25lIGFyZ3VtZW50LiBUaGUgYXJndW1lbnQgc2hvdWxkIGJlIG9mIHR5cGUgTW9kZWxBcnRpZmFjdHMuIFRoZSBtdWx0aS1hcmd1bWVudCBzaWduYXR1cmUgb2YgdGYuaW8uZnJvbU1lbW9yeSgpIGhhcyBiZWVuIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSByZWxlYXNlLiIpLG5ldyBQYXNzdGhyb3VnaExvYWRlcih7bW9kZWxUb3BvbG9neTpoYX0pKTooY29uc29sZS53YXJuKCJQbGVhc2UgY2FsbCB0Zi5pby5mcm9tTWVtb3J5KCkgd2l0aCBvbmx5IG9uZSBhcmd1bWVudC4gVGhlIGFyZ3VtZW50IHNob3VsZCBiZSBvZiB0eXBlIE1vZGVsQXJ0aWZhY3RzLiBUaGUgbXVsdGktYXJndW1lbnQgc2lnbmF0dXJlIG9mIHRmLmlvLmZyb21NZW1vcnkoKSBoYXMgYmVlbiBkZXByZWNhdGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZS4iKSxuZXcgUGFzc3Rocm91Z2hMb2FkZXIoe21vZGVsVG9wb2xvZ3k6aGEsd2VpZ2h0U3BlY3M6YWEsd2VpZ2h0RGF0YTp4YSx0cmFpbmluZ0NvbmZpZzpiYX0pKX1mdW5jdGlvbiB3aXRoU2F2ZUhhbmRsZXIoaGEpe3JldHVybiBuZXcgUGFzc3Rocm91Z2hTYXZlcihoYSl9ZnVuY3Rpb24gd2l0aFNhdmVIYW5kbGVyU3luYyhoYSl7cmV0dXJuIG5ldyBQYXNzdGhyb3VnaFNhdmVyKGhhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi92YXIgaW8kMT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxDb21wb3NpdGVBcnJheUJ1ZmZlcjpDb21wb3NpdGVBcnJheUJ1ZmZlciQxLGJyb3dzZXJGaWxlcyxicm93c2VySFRUUFJlcXVlc3QsY29uY2F0ZW5hdGVBcnJheUJ1ZmZlcnM6Y29uY2F0ZW5hdGVBcnJheUJ1ZmZlcnMkMSxjb3B5TW9kZWwsZGVjb2RlV2VpZ2h0cyxkZWNvZGVXZWlnaHRzU3RyZWFtLGVuY29kZVdlaWdodHMsZnJvbU1lbW9yeSxmcm9tTWVtb3J5U3luYyxnZXRMb2FkSGFuZGxlcnMsZ2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OOmdldE1vZGVsQXJ0aWZhY3RzRm9ySlNPTiQxLGdldE1vZGVsQXJ0aWZhY3RzRm9ySlNPTlN5bmM6Z2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OU3luYyQxLGdldE1vZGVsQXJ0aWZhY3RzSW5mb0ZvckpTT046Z2V0TW9kZWxBcnRpZmFjdHNJbmZvRm9ySlNPTiQxLGdldFNhdmVIYW5kbGVycyxnZXRXZWlnaHRTcGVjczpnZXRXZWlnaHRTcGVjcyQxLGh0dHA6aHR0cCQxLGlzSFRUUFNjaGVtZTppc0hUVFBTY2hlbWUkMSxsaXN0TW9kZWxzLGxvYWRXZWlnaHRzLG1vdmVNb2RlbCxyZWdpc3RlckxvYWRSb3V0ZXIscmVnaXN0ZXJTYXZlUm91dGVyLHJlbW92ZU1vZGVsLHdlaWdodHNMb2FkZXJGYWN0b3J5LHdpdGhTYXZlSGFuZGxlcix3aXRoU2F2ZUhhbmRsZXJTeW5jfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IGZyb21QaXhlbHMyRENvbnRleHQkMjtmdW5jdGlvbiBmcm9tUGl4ZWxzXyhoYSxhYT0zKXtpZihhYT40KXRocm93IG5ldyBFcnJvcigiQ2Fubm90IGNvbnN0cnVjdCBUZW5zb3Igd2l0aCBtb3JlIHRoYW4gNCBjaGFubmVscyBmcm9tIHBpeGVscy4iKTtpZihoYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoInBpeGVscyBwYXNzZWQgdG8gdGYuYnJvd3Nlci5mcm9tUGl4ZWxzKCkgY2FuIG5vdCBiZSBudWxsIik7bGV0IHhhPSExLGJhPSExLFNhPSExLFRhPSExLHdhPSExLEVhPSExO2lmKGhhLmRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KXhhPSEwO2Vsc2UgaWYodHlwZW9mIEltYWdlRGF0YTwidSImJmhhIGluc3RhbmNlb2YgSW1hZ2VEYXRhKWJhPSEwO2Vsc2UgaWYodHlwZW9mIEhUTUxWaWRlb0VsZW1lbnQ8InUiJiZoYSBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQpU2E9ITA7ZWxzZSBpZih0eXBlb2YgSFRNTEltYWdlRWxlbWVudDwidSImJmhhIGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudClUYT0hMDtlbHNlIGlmKGhhLmdldENvbnRleHQhPW51bGwpd2E9ITA7ZWxzZSBpZih0eXBlb2YgSW1hZ2VCaXRtYXA8InUiJiZoYSBpbnN0YW5jZW9mIEltYWdlQml0bWFwKUVhPSEwO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBwaXhlbHMgcGFzc2VkIHRvIHRmLmJyb3dzZXIuZnJvbVBpeGVscygpIG11c3QgYmUgZWl0aGVyIGFuIEhUTUxWaWRlb0VsZW1lbnQsIEhUTUxJbWFnZUVsZW1lbnQsIEhUTUxDYW52YXNFbGVtZW50LCBJbWFnZURhdGEgaW4gYnJvd3Nlciwgb3IgT2Zmc2NyZWVuQ2FudmFzLCBJbWFnZURhdGEgaW4gd2Vid29ya2VyIG9yIHtkYXRhOiBVaW50MzJBcnJheSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXJ9LCBidXQgd2FzICR7aGEuY29uc3RydWN0b3IubmFtZX1gKTtpZihnZXRLZXJuZWwkMShGcm9tUGl4ZWxzJDEsRU5HSU5FJDEuYmFja2VuZE5hbWUpIT1udWxsKXtjb25zdCBubD17cGl4ZWxzOmhhfSxzbD17bnVtQ2hhbm5lbHM6YWF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoRnJvbVBpeGVscyQxLG5sLHNsKX1jb25zdFtBYSxGYV09U2E/W2hhLnZpZGVvV2lkdGgsaGEudmlkZW9IZWlnaHRdOltoYS53aWR0aCxoYS5oZWlnaHRdO2xldCBMYTtpZih3YSlMYT1oYS5nZXRDb250ZXh0KCIyZCIpLmdldEltYWdlRGF0YSgwLDAsQWEsRmEpLmRhdGE7ZWxzZSBpZihiYXx8eGEpTGE9aGEuZGF0YTtlbHNlIGlmKFRhfHxTYXx8RWEpe2lmKGZyb21QaXhlbHMyRENvbnRleHQkMj09bnVsbClpZih0eXBlb2YgZG9jdW1lbnQ+InUiKWlmKHR5cGVvZiBPZmZzY3JlZW5DYW52YXM8InUiJiZ0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEPCJ1Iilmcm9tUGl4ZWxzMkRDb250ZXh0JDI9bmV3IE9mZnNjcmVlbkNhbnZhcygxLDEpLmdldENvbnRleHQoIjJkIik7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBwYXJzZSBpbnB1dCBpbiBjdXJyZW50IGNvbnRleHQuIFJlYXNvbjogT2Zmc2NyZWVuQ2FudmFzIENvbnRleHQyRCByZW5kZXJpbmcgaXMgbm90IHN1cHBvcnRlZC4iKTtlbHNlIGZyb21QaXhlbHMyRENvbnRleHQkMj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKS5nZXRDb250ZXh0KCIyZCIse3dpbGxSZWFkRnJlcXVlbnRseTohMH0pO2Zyb21QaXhlbHMyRENvbnRleHQkMi5jYW52YXMud2lkdGg9QWEsZnJvbVBpeGVsczJEQ29udGV4dCQyLmNhbnZhcy5oZWlnaHQ9RmEsZnJvbVBpeGVsczJEQ29udGV4dCQyLmRyYXdJbWFnZShoYSwwLDAsQWEsRmEpLExhPWZyb21QaXhlbHMyRENvbnRleHQkMi5nZXRJbWFnZURhdGEoMCwwLEFhLEZhKS5kYXRhfWxldCBlbDtpZihhYT09PTQpZWw9bmV3IEludDMyQXJyYXkoTGEpO2Vsc2V7Y29uc3Qgbmw9QWEqRmE7ZWw9bmV3IEludDMyQXJyYXkobmwqYWEpO2ZvcihsZXQgc2w9MDtzbDxubDtzbCsrKWZvcihsZXQgcmw9MDtybDxhYTsrK3JsKWVsW3NsKmFhK3JsXT1MYVtzbCo0K3JsXX1yZXR1cm4gdGVuc29yM2QoZWwsW0ZhLEFhLGFhXSwiaW50MzIiKX1jb25zdCBmcm9tUGl4ZWxzJDI9b3AkMSh7ZnJvbVBpeGVsc199KTtmdW5jdGlvbiBwcmVwYXJlQW5kVmFsaWRhdGUkMShoYSxhYSl7Y29uc3QgeGE9aGEuc2hhcGUubGVuZ3RoLGJhPWFhLnNoYXBlLmxlbmd0aDtpZih4YTwxKXRocm93IG5ldyBFcnJvcihgdGYuZ2F0aGVyTkQoKSBleHBlY3RzIHRoZSBpbnB1dCB0byBiZSByYW5rIDEgb3IgaGlnaGVyLCBidXQgdGhlIHJhbmsgd2FzICR7eGF9LmApO2lmKGJhPDEpdGhyb3cgbmV3IEVycm9yKGB0Zi5nYXRoZXJORCgpIGV4cGVjdHMgdGhlIGluZGljZXMgdG8gYmUgcmFuayAxIG9yIGhpZ2hlciwgYnV0IHRoZSByYW5rIHdhcyAke2JhfS5gKTtpZihhYS5kdHlwZSE9PSJpbnQzMiIpdGhyb3cgbmV3IEVycm9yKGB0Zi5nYXRoZXJORCgpIGV4cGVjdHMgdGhlIGluZGljZXMgdG8gYmUgaW50MzIgdHlwZSwgYnV0IHRoZSBkdHlwZSB3YXMgJHthYS5kdHlwZX0uYCk7aWYoYWEuc2hhcGVbYmEtMV0+eGEpdGhyb3cgbmV3IEVycm9yKGBpbmRleCBpbm5lcm1vc3QgZGltZW5zaW9uIGxlbmd0aCBtdXN0IGJlIDw9IHRlbnNvciByYW5rOyBzYXc6ICR7YWEuc2hhcGVbYmEtMV19IHZzLiAke3hhfWApO2lmKHNpemVGcm9tU2hhcGUkMShoYS5zaGFwZSk9PT0wKXRocm93IG5ldyBFcnJvcihgUmVxdWVzdGVkIG1vcmUgdGhhbiAwIGVudHJpZXMsIGJ1dCBpbnB1dCBpcyBlbXB0eS4gSW5wdXQgc2hhcGU6ICR7aGEuc2hhcGV9LmApO2NvbnN0IFNhPWFhLnNoYXBlLFRhPVNhW1NhLmxlbmd0aC0xXTtsZXQgd2E9MTtmb3IobGV0IExhPTA7TGE8U2EubGVuZ3RoLTE7KytMYSl3YSo9U2FbTGFdO2NvbnN0IEVhPWhhLnNoYXBlLGthPVNhLnNsaWNlKCk7a2EucG9wKCk7bGV0IEFhPTE7Zm9yKGxldCBMYT1UYTtMYTx4YTsrK0xhKUFhKj1FYVtMYV0sa2EucHVzaChFYVtMYV0pO2NvbnN0IEZhPVsuLi5jb21wdXRlU3RyaWRlcyQxKGhhLnNoYXBlKS5tYXAoTGE9PkxhL0FhKSwxXS5zbGljZSgwLFRhKTtyZXR1cm5ba2Esd2EsQWEsRmFdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE5FV19BWElTJDE9LTIsU0hSSU5LX0FYSVMkMT0tMTtmdW5jdGlvbiBhc3NlcnRQYXJhbXNWYWxpZCQxKGhhLGFhLHhhKXtjb25zdCBiYT1oYS5zaGFwZS5sZW5ndGg7YXNzZXJ0JDIoYmE9PT1hYS5sZW5ndGgsKCk9PmBFcnJvciBpbiBzbGljZSR7YmF9RDogTGVuZ3RoIG9mIGJlZ2luICR7YWF9IG11c3QgbWF0Y2ggdGhlIHJhbmsgb2YgdGhlIGFycmF5ICgke2JhfSkuYCksYXNzZXJ0JDIoYmE9PT14YS5sZW5ndGgsKCk9PmBFcnJvciBpbiBzbGljZSR7YmF9RDogTGVuZ3RoIG9mIHNpemUgJHt4YX0gbXVzdCBtYXRjaCB0aGUgcmFuayBvZiB0aGUgYXJyYXkgKCR7YmF9KS5gKTtmb3IobGV0IFNhPTA7U2E8YmE7KytTYSlhc3NlcnQkMihhYVtTYV0reGFbU2FdPD1oYS5zaGFwZVtTYV0sKCk9PmBFcnJvciBpbiBzbGljZSR7YmF9RDogYmVnaW5bJHtTYX1dICsgc2l6ZVske1NhfV0gKCR7YWFbU2FdK3hhW1NhXX0pIHdvdWxkIG92ZXJmbG93IGlucHV0LnNoYXBlWyR7U2F9XSAoJHtoYS5zaGFwZVtTYV19KWApfWZ1bmN0aW9uIG1hc2tUb0F4ZXMkMShoYSl7Y29uc3QgYWE9W107bGV0IHhhPTA7Zm9yKDtoYT4wOyloYSYxJiZhYS5wdXNoKHhhKSxoYS89Mix4YSsrO3JldHVybiBhYX1mdW5jdGlvbiBjb21wdXRlT3V0U2hhcGUkNShoYSxhYSx4YSl7Y29uc3QgYmE9W107Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aDtTYSsrKWJhW1NhXT1NYXRoLmNlaWwoKGFhW1NhXS1oYVtTYV0pL3hhW1NhXSk7cmV0dXJuIGJhfWZ1bmN0aW9uIHN0cmlkZXNXaXRoRWxpZGVkRGltcyQxKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1bLi4uaGFdO2ZvcihsZXQgVGE9U2EubGVuZ3RoO1RhPGJhLmxlbmd0aDtUYSsrKVNhLnB1c2goMSk7Zm9yKGxldCBUYT0wO1RhPHhhO1RhKyspVGE9PT0wP1NhW2FhXT0xOihTYS5zcGxpY2UoYWEsMCwxKSxTYS5wb3AoKSk7cmV0dXJuIFNhfWZ1bmN0aW9uIHVubm9ybWFsaXplQXhpcyQxKGhhLGFhLHhhKXtyZXR1cm4geGE8PWhhP3hhOnhhLShhYS0xKX1mdW5jdGlvbiBnZXRFbGlkZWRBeGVzJDEoaGEsYWEpe2NvbnN0IHhhPVtdO2ZvcihsZXQgYmE9MDtiYTxoYTtiYSsrKXhhLnB1c2goYWErYmEpO3JldHVybiB4YX1mdW5jdGlvbiBnZXROb3JtYWxpemVkQXhlcyQxKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthKXtjb25zdCBBYT1oYS5sZW5ndGg7bGV0IEZhPW5ldyBBcnJheShBYSksTGE9bmV3IEFycmF5KEFhKSxlbD1uZXcgQXJyYXkoQWEpO2lmKGFhLmxlbmd0aCYmeGE+MCl7Y29uc3QgdGw9YWFbMF0sbmw9eGErMTtGYT1zdGFydEluZGljZXNXaXRoRWxpZGVkRGltcyQxKHdhLHRsLG5sLGJhLGhhKSxMYT1zdG9wSW5kaWNlc1dpdGhFbGlkZWREaW1zJDEoRWEsdGwsbmwsU2EsaGEpLGVsPXN0cmlkZXNXaXRoRWxpZGVkRGltcyQxKFRhLHRsLG5sLGhhKX1lbHNlIGZvcihsZXQgdGw9MDt0bDxBYTt0bCsrKUZhW3RsXT1zdGFydEZvckF4aXMkMSh3YSxiYSxUYSxoYSx0bCxrYSksTGFbdGxdPXN0b3BGb3JBeGlzJDEoRWEsU2EsVGEsaGEsdGwsa2EpLGVsW3RsXT1zdHJpZGVzRm9yQXhpcyQxKFRhLHRsLGthKTtyZXR1cm57YmVnaW46RmEsZW5kOkxhLHN0cmlkZXM6ZWx9fWZ1bmN0aW9uIHN0YXJ0SW5kaWNlc1dpdGhFbGlkZWREaW1zJDEoaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPVsuLi5TYV0sd2E9Z2V0RWxpZGVkQXhlcyQxKHhhLGFhKTtmb3IobGV0IEVhPTA7RWE8VGEubGVuZ3RoO0VhKyspaWYod2EuaW5kZXhPZihFYSk+LTEpVGFbRWFdPTA7ZWxzZXtjb25zdCBrYT11bm5vcm1hbGl6ZUF4aXMkMShhYSx4YSxFYSk7bGV0IEFhPWJhW2thXTtoYSYxPDxrYSYmKEFhPTApLFRhW0VhXT1BYX1yZXR1cm4gVGF9ZnVuY3Rpb24gc3RvcEluZGljZXNXaXRoRWxpZGVkRGltcyQxKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1bLi4uU2FdLHdhPWdldEVsaWRlZEF4ZXMkMSh4YSxhYSk7Zm9yKGxldCBFYT0wO0VhPFRhLmxlbmd0aDtFYSsrKWlmKHdhLmluZGV4T2YoRWEpPi0xKVRhW0VhXT1OdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtlbHNle2NvbnN0IGthPXVubm9ybWFsaXplQXhpcyQxKGFhLHhhLEVhKTtsZXQgQWE9YmFba2FdO2hhJjE8PGthJiYoQWE9TnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLFRhW0VhXT1BYX1mb3IobGV0IEVhPTA7RWE8VGEubGVuZ3RoO0VhKyspe2NvbnN0IGthPVNhW0VhXTtUYVtFYV08MCYmKFRhW0VhXSs9a2EpLFRhW0VhXT1jbGFtcCQxKDAsVGFbRWFdLFNhW0VhXSl9cmV0dXJuIFRhfWZ1bmN0aW9uIHN0cmlkZXNGb3JBeGlzJDEoaGEsYWEseGEpe2xldCBiYT1oYVthYV07cmV0dXJuKHhhJjE8PGFhfHxiYT09bnVsbCkmJihiYT0xKSxiYX1mdW5jdGlvbiBzdGFydEZvckF4aXMkMShoYSxhYSx4YSxiYSxTYSxUYSl7bGV0IHdhPWFhW1NhXTtjb25zdCBFYT14YVtTYV18fDE7KGhhJjE8PFNhfHxUYSYxPDxTYXx8d2E9PW51bGwpJiYoRWE+MD93YT1OdW1iZXIuTUlOX1NBRkVfSU5URUdFUjp3YT1OdW1iZXIuTUFYX1NBRkVfSU5URUdFUik7Y29uc3Qga2E9YmFbU2FdO3JldHVybiB3YTwwJiYod2ErPWthKSx3YT1jbGFtcCQxKDAsd2Esa2EtMSksd2F9ZnVuY3Rpb24gc3RvcEZvckF4aXMkMShoYSxhYSx4YSxiYSxTYSxUYSl7bGV0IHdhPWFhW1NhXTtjb25zdCBFYT14YVtTYV18fDE7KGhhJjE8PFNhfHxUYSYxPDxTYXx8d2E9PW51bGwpJiYoRWE+MD93YT1OdW1iZXIuTUFYX1NBRkVfSU5URUdFUjp3YT1OdW1iZXIuTUlOX1NBRkVfSU5URUdFUik7Y29uc3Qga2E9YmFbU2FdO3JldHVybiB3YTwwJiYod2ErPWthKSxFYT4wP3dhPWNsYW1wJDEoMCx3YSxrYSk6d2E9Y2xhbXAkMSgtMSx3YSxrYS0xKSx3YX1mdW5jdGlvbiBpc1NsaWNlQ29udGlub3VzJDEoaGEsYWEseGEpe2xldCBiYT14YS5sZW5ndGg7Zm9yKGxldCBTYT0wO1NhPHhhLmxlbmd0aDtTYSsrKWlmKHhhW1NhXT4xKXtiYT1TYTticmVha31mb3IobGV0IFNhPWJhKzE7U2E8eGEubGVuZ3RoO1NhKyspaWYoYWFbU2FdPjB8fHhhW1NhXSE9PWhhW1NhXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBjb21wdXRlRmxhdE9mZnNldCQxKGhhLGFhKXtsZXQgeGE9aGEubGVuZ3RoPjA/aGFbaGEubGVuZ3RoLTFdOjE7Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aC0xO2JhKyspeGErPWhhW2JhXSphYVtiYV07cmV0dXJuIHhhfWZ1bmN0aW9uIHBhcnNlU2xpY2VQYXJhbXMkMShoYSxhYSx4YSl7bGV0IGJhO2NvbnN0IFNhPWhhLnNoYXBlLmxlbmd0aDt0eXBlb2YgYWE9PSJudW1iZXIiP2JhPVthYSwuLi5uZXcgQXJyYXkoU2EtMSkuZmlsbCgwKV06YWEubGVuZ3RoPFNhP2JhPWFhLmNvbmNhdChuZXcgQXJyYXkoU2EtYWEubGVuZ3RoKS5maWxsKDApKTpiYT1hYS5zbGljZSgpLGJhLmZvckVhY2god2E9Pnthc3NlcnQkMih3YSE9PS0xLCgpPT4ic2xpY2UoKSBkb2VzIG5vdCBzdXBwb3J0IG5lZ2F0aXZlIGJlZ2luIGluZGV4aW5nLiIpfSk7bGV0IFRhO3JldHVybiB4YT09bnVsbD9UYT1uZXcgQXJyYXkoU2EpLmZpbGwoLTEpOnR5cGVvZiB4YT09Im51bWJlciI/VGE9W3hhLC4uLm5ldyBBcnJheShTYS0xKS5maWxsKC0xKV06eGEubGVuZ3RoPFNhP1RhPXhhLmNvbmNhdChuZXcgQXJyYXkoU2EteGEubGVuZ3RoKS5maWxsKC0xKSk6VGE9eGEsVGE9VGEubWFwKCh3YSxFYSk9PndhPj0wP3dhOihhc3NlcnQkMih3YT09PS0xLCgpPT5gTmVnYXRpdmUgc2l6ZSB2YWx1ZXMgc2hvdWxkIGJlIGV4YWN0bHkgLTEgYnV0IGdvdCAke3dhfSBmb3IgdGhlIHNsaWNlKCkgc2l6ZSBhdCBpbmRleCAke0VhfS5gKSxoYS5zaGFwZVtFYV0tYmFbRWFdKSksW2JhLFRhXX1mdW5jdGlvbiBzbGljZUluZm8kMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSl7bGV0IEFhO2lmKGJhPT1udWxsPyhBYT1uZXcgQXJyYXkoYWEubGVuZ3RoKSxBYS5maWxsKDEpKTpBYT1iYSx3YSE9bnVsbCYmd2Emd2EtMSl0aHJvdyBuZXcgRXJyb3IoIk11bHRpcGxlIGVsbGlwc2VzIGluIHNsaWNlIGlzIG5vdCBhbGxvd2VkLiIpO2xldCBGYT0hMTtjb25zdCBMYT17ZGltczpBYS5sZW5ndGgsbnVtQWRkQXhpc0FmdGVyRWxsaXBzaXM6MCxiZWdpbjphYS5zbGljZSgpLGVuZDp4YS5zbGljZSgpLHN0cmlkZXM6QWEuc2xpY2UoKSxiZWdpbk1hc2s6U2EsZW5kTWFzazpUYSxlbGxpcHNpc01hc2s6d2EsbmV3QXhpc01hc2s6RWEsc2hyaW5rQXhpc01hc2s6a2F9O2ZvcihsZXQgbGw9MDtsbDxMYS5kaW1zO2xsKyspRmEmJjE8PGxsJkVhJiZMYS5udW1BZGRBeGlzQWZ0ZXJFbGxpcHNpcysrLDE8PGxsJndhJiYoRmE9ITApO0ZhfHwoTGEuZWxsaXBzaXNNYXNrfD0xPDxMYS5kaW1zLExhLmRpbXMrKyk7Y29uc3QgZWw9e2RpbXM6aGEubGVuZ3RoLGJlZ2luTWFzazowLGVuZE1hc2s6MCxiZWdpblZhbGlkOiExLGVuZFZhbGlkOiExfTtidWlsZERlbnNlU3BlYyQxKExhLGVsKTtsZXQgdGw9ITAsbmw9ITAsc2w9ITA7Y29uc3Qgcmw9W10sb2w9W107Zm9yKGxldCBsbD0wO2xsPGhhLmxlbmd0aDsrK2xsKXtpZihlbC5zdHJpZGVzW2xsXT09PTApdGhyb3cgRXJyb3IoYHN0cmlkZXNbJHtsbH1dIG11c3QgYmUgbm9uLXplcm9gKTtjb25zdCBpbD0hIShlbC5zaHJpbmtBeGlzTWFzayYxPDxsbCksY2w9aGFbbGxdO2lmKGNsPT09LTEpe3JsLnB1c2goaWw/MTotMSk7Y29udGludWV9Y29uc3QgdWw9W2VsLmJlZ2luTWFzayYxPDxsbCxlbC5lbmRNYXNrJjE8PGxsXSxkbD1bZWwuc3RyaWRlc1tsbF0+MD8wOi0xLGVsLnN0cmlkZXNbbGxdPjA/Y2w6Y2wtMV07aWYoaWwmJmVsLnN0cmlkZXNbbGxdPD0wKXRocm93IEVycm9yKCJvbmx5IHN0cmlkZSAxIGFsbG93ZWQgb24gbm9uLXJhbmdlIGluZGV4aW5nLiIpO3NsPXNsJiZlbC5zdHJpZGVzW2xsXT09PTE7Y29uc3QgaGw9ISEoZWwuYmVnaW5NYXNrJjE8PGxsJiZlbC5lbmRNYXNrJjE8PGxsKTtpZihlbC5iZWdpblZhbGlkJiZlbC5lbmRWYWxpZCl7aWYoaWwpe2NvbnN0IGdsPWVsLmJlZ2luW2xsXTwwP2NsK2VsLmJlZ2luW2xsXTplbC5iZWdpbltsbF07aWYoZWwuYmVnaW5bbGxdPWdsLGVsLmVuZFtsbF09ZWwuYmVnaW5bbGxdKzEsZ2w8MHx8Z2w+PWNsKXRocm93IEVycm9yKGBzbGljZSBpbmRleCAke2VsLmJlZ2luW2xsXX0gb2YgZGltZW5zaW9uICR7bGx9IG91dCBvZiBib3VuZHMuYCl9ZWxzZSBlbC5iZWdpbltsbF09Y2Fub25pY2FsJDEoZWwuYmVnaW5bbGxdLDAsZWwuc3RyaWRlc1tsbF0sY2wsdWwsZGwpLGVsLmVuZFtsbF09Y2Fub25pY2FsJDEoZWwuZW5kW2xsXSwxLGVsLnN0cmlkZXNbbGxdLGNsLHVsLGRsKTtjb25zdCBtbD1lbC5zdHJpZGVzW2xsXT09PTEmJmVsLmJlZ2luW2xsXT09PTAmJmVsLmVuZFtsbF09PT1jbDt0bD10bCYmbWwsbmw9bmwmJihsbD09PTAmJmVsLnN0cmlkZXNbbGxdPT09MXx8bWwpfWVsc2UgdGw9dGwmJmVsLnN0cmlkZXNbbGxdPT09MSYmaGwsbmw9bmwmJihsbD09PTAmJmVsLnN0cmlkZXNbbGxdPT09MXx8aGwpO2xldCBwbCxmbD0hMTtpZihlbC5iZWdpblZhbGlkJiZlbC5lbmRWYWxpZD8ocGw9ZWwuZW5kW2xsXS1lbC5iZWdpbltsbF0sZmw9ITApOmlsPyhwbD0xLGZsPSEwKTpobCYmY2w+PTAmJihlbC5zdHJpZGVzW2xsXTwwP3BsPS1jbDpwbD1jbCxmbD0hMCksZmwpe2xldCBtbDtwbD09PTB8fHBsPDAhPWVsLnN0cmlkZXNbbGxdPDA/bWw9MDptbD1NYXRoLnRydW5jKHBsL2VsLnN0cmlkZXNbbGxdKSsocGwlZWwuc3RyaWRlc1tsbF0hPT0wPzE6MCkscmwucHVzaChtbCl9ZWxzZSBybC5wdXNoKC0xKX1mb3IobGV0IGxsPTA7bGw8ZWwuZmluYWxTaGFwZUdhdGhlckluZGljZXMubGVuZ3RoOysrbGwpe2NvbnN0IGlsPWVsLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzW2xsXTtpbD49MD9vbC5wdXNoKHJsW2lsXSk6aWw9PT1ORVdfQVhJUyQxJiZvbC5wdXNoKDEpfXJldHVybntmaW5hbFNoYXBlU3BhcnNlOm9sLmZpbHRlcigobGwsaWwpPT5lbC5maW5hbFNoYXBlR2F0aGVySW5kaWNlc1tpbF0hPT1ORVdfQVhJUyQxKSxmaW5hbFNoYXBlOm9sLGlzSWRlbnRpdHk6dGwsc2xpY2VEaW0wOm5sLGlzU2ltcGxlU2xpY2U6c2wsYmVnaW46ZWwuYmVnaW4sZW5kOmVsLmVuZCxzdHJpZGVzOmVsLnN0cmlkZXN9fWZ1bmN0aW9uIGJ1aWxkRGVuc2VTcGVjJDEoaGEsYWEpe2FhLmJlZ2luTWFzaz0wLGFhLmVuZE1hc2s9MCxhYS5zaHJpbmtBeGlzTWFzaz0wO2xldCB4YT0wO2FhLmJlZ2luVmFsaWQ9aGEuYmVnaW4hPW51bGwsYWEuZW5kVmFsaWQ9aGEuZW5kIT1udWxsLGFhLmJlZ2luPW5ldyBBcnJheShhYS5kaW1zKSxhYS5lbmQ9bmV3IEFycmF5KGFhLmRpbXMpLGFhLnN0cmlkZXM9bmV3IEFycmF5KGFhLmRpbXMpLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzPVtdLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlPVtdLGFhLmlucHV0U2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlPW5ldyBBcnJheShhYS5kaW1zKTtmb3IobGV0IGJhPTA7YmE8aGEuZGltcztiYSsrKWlmKDE8PGJhJmhhLmVsbGlwc2lzTWFzayl7Y29uc3QgU2E9TWF0aC5taW4oYWEuZGltcy0oaGEuZGltcy1iYSkrMStoYS5udW1BZGRBeGlzQWZ0ZXJFbGxpcHNpcyxhYS5kaW1zKTtmb3IoO3hhPFNhO3hhKyspYWEuYmVnaW5beGFdPTAsYWEuZW5kW3hhXT0wLGFhLnN0cmlkZXNbeGFdPTEsYWEuYmVnaW5NYXNrfD0xPDx4YSxhYS5lbmRNYXNrfD0xPDx4YSxhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlcy5wdXNoKHhhKSxhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlc1NwYXJzZS5wdXNoKC0xKSxhYS5pbnB1dFNoYXBlR2F0aGVySW5kaWNlc1NwYXJzZVt4YV09YmF9ZWxzZSBpZigxPDxiYSZoYS5uZXdBeGlzTWFzaylhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlcy5wdXNoKE5FV19BWElTJDEpLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlLnB1c2goLTEpO2Vsc2V7aWYoeGE9PT1hYS5iZWdpbi5sZW5ndGgpdGhyb3cgRXJyb3IoYEluZGV4IG91dCBvZiByYW5nZSB1c2luZyBpbnB1dCBkaW0gJHt4YX07IGlucHV0IGhhcyBvbmx5ICR7YWEuZGltc30gZGltcywgJHthYS5iZWdpbi5sZW5ndGh9LmApO2hhLmJlZ2luIT1udWxsJiYoYWEuYmVnaW5beGFdPWhhLmJlZ2luW2JhXSksaGEuZW5kIT1udWxsJiYoYWEuZW5kW3hhXT1oYS5lbmRbYmFdKSxhYS5zdHJpZGVzW3hhXT1oYS5zdHJpZGVzW2JhXSxoYS5iZWdpbk1hc2smMTw8YmEmJihhYS5iZWdpbk1hc2t8PTE8PHhhKSxoYS5lbmRNYXNrJjE8PGJhJiYoYWEuZW5kTWFza3w9MTw8eGEpLGhhLnNocmlua0F4aXNNYXNrJjE8PGJhPyhhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlcy5wdXNoKFNIUklOS19BWElTJDEpLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlLnB1c2goLTEpLGFhLnNocmlua0F4aXNNYXNrfD0xPDx4YSk6KGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzLnB1c2goeGEpLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlLnB1c2goYmEpKSxhYS5pbnB1dFNoYXBlR2F0aGVySW5kaWNlc1NwYXJzZVt4YV09YmEseGErK319ZnVuY3Rpb24gY2Fub25pY2FsJDEoaGEsYWEseGEsYmEsU2EsVGEpe2lmKFNhW2FhXSlyZXR1cm4geGE+MD9UYVthYV06VGFbYWErMSYxXTt7Y29uc3Qgd2E9aGE8MD9iYStoYTpoYTtyZXR1cm4gd2E8VGFbMF0/VGFbMF06d2E+VGFbMV0/VGFbMV06d2F9fXZhciBzbGljZV91dGlsJDE9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsYXNzZXJ0UGFyYW1zVmFsaWQ6YXNzZXJ0UGFyYW1zVmFsaWQkMSxjb21wdXRlRmxhdE9mZnNldDpjb21wdXRlRmxhdE9mZnNldCQxLGNvbXB1dGVPdXRTaGFwZTpjb21wdXRlT3V0U2hhcGUkNSxnZXROb3JtYWxpemVkQXhlczpnZXROb3JtYWxpemVkQXhlcyQxLGlzU2xpY2VDb250aW5vdXM6aXNTbGljZUNvbnRpbm91cyQxLG1hc2tUb0F4ZXM6bWFza1RvQXhlcyQxLHBhcnNlU2xpY2VQYXJhbXM6cGFyc2VTbGljZVBhcmFtcyQxLHNsaWNlSW5mbzpzbGljZUluZm8kMSxzdGFydEZvckF4aXM6c3RhcnRGb3JBeGlzJDEsc3RhcnRJbmRpY2VzV2l0aEVsaWRlZERpbXM6c3RhcnRJbmRpY2VzV2l0aEVsaWRlZERpbXMkMSxzdG9wRm9yQXhpczpzdG9wRm9yQXhpcyQxLHN0b3BJbmRpY2VzV2l0aEVsaWRlZERpbXM6c3RvcEluZGljZXNXaXRoRWxpZGVkRGltcyQxLHN0cmlkZXNGb3JBeGlzOnN0cmlkZXNGb3JBeGlzJDEsc3RyaWRlc1dpdGhFbGlkZWREaW1zOnN0cmlkZXNXaXRoRWxpZGVkRGltcyQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgT3B0aW1pemVyQ29uc3RydWN0b3Jze3N0YXRpYyBzZ2QoYWEpe3JldHVybiBuZXcgU0dET3B0aW1pemVyJDEoYWEpfXN0YXRpYyBtb21lbnR1bShhYSx4YSxiYT0hMSl7cmV0dXJuIG5ldyBNb21lbnR1bU9wdGltaXplciQxKGFhLHhhLGJhKX1zdGF0aWMgcm1zcHJvcChhYSx4YT0uOSxiYT0wLFNhPW51bGwsVGE9ITEpe3JldHVybiBuZXcgUk1TUHJvcE9wdGltaXplciQxKGFhLHhhLGJhLFNhLFRhKX1zdGF0aWMgYWRhbShhYT0uMDAxLHhhPS45LGJhPS45OTksU2E9bnVsbCl7cmV0dXJuIG5ldyBBZGFtT3B0aW1pemVyJDEoYWEseGEsYmEsU2EpfXN0YXRpYyBhZGFkZWx0YShhYT0uMDAxLHhhPS45NSxiYT1udWxsKXtyZXR1cm4gbmV3IEFkYWRlbHRhT3B0aW1pemVyJDEoYWEseGEsYmEpfXN0YXRpYyBhZGFtYXgoYWE9LjAwMix4YT0uOSxiYT0uOTk5LFNhPW51bGwsVGE9MCl7cmV0dXJuIG5ldyBBZGFtYXhPcHRpbWl6ZXIkMShhYSx4YSxiYSxTYSxUYSl9c3RhdGljIGFkYWdyYWQoYWEseGE9LjEpe3JldHVybiBuZXcgQWRhZ3JhZE9wdGltaXplciQxKGFhLHhhKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgdHJhaW49T3B0aW1pemVyQ29uc3RydWN0b3JzOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGRlbGF5Q2FsbGJhY2skMT10eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lPCJ1Ij9yZXF1ZXN0QW5pbWF0aW9uRnJhbWU6dHlwZW9mIHNldEltbWVkaWF0ZTwidSI/c2V0SW1tZWRpYXRlOmhhPT5oYSgpO2Z1bmN0aW9uIG5leHRGcmFtZSQxKCl7cmV0dXJuIG5ldyBQcm9taXNlKGhhPT5kZWxheUNhbGxiYWNrJDEoKCk9PmhhKCkpKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhc3NlcnRQYXJhbXNDb25zaXN0ZW50JDEoaGEsYWEpe2NvbnN0IHhhPWhhWzBdLmxlbmd0aDtoYS5mb3JFYWNoKChTYSxUYSk9Pnthc3NlcnQkMihTYS5sZW5ndGg9PT14YSwoKT0+YEVycm9yIGluIGNvbmNhdCR7eGF9RDogcmFuayBvZiB0ZW5zb3JzWyR7VGF9XSBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSByYW5rIG9mIHRoZSByZXN0ICgke3hhfSlgKX0pLGFzc2VydCQyKGFhPj0wJiZhYTx4YSwoKT0+YEVycm9yIGluIGNvbmNhdCR7eGF9RDogYXhpcyBtdXN0IGJlIGJldHdlZW4gMCBhbmQgJHt4YS0xfS5gKTtjb25zdCBiYT1oYVswXTtoYS5mb3JFYWNoKChTYSxUYSk9Pntmb3IobGV0IHdhPTA7d2E8eGE7d2ErKylhc3NlcnQkMih3YT09PWFhfHxTYVt3YV09PT1iYVt3YV0sKCk9PmBFcnJvciBpbiBjb25jYXQke3hhfUQ6IFNoYXBlIG9mIHRlbnNvcnNbJHtUYX1dICgke1NhfSkgZG9lcyBub3QgbWF0Y2ggdGhlIHNoYXBlIG9mIHRoZSByZXN0ICgke2JhfSkgYWxvbmcgdGhlIG5vbi1jb25jYXRlbmF0ZWQgYXhpcyAke1RhfS5gKX0pfWZ1bmN0aW9uIGNvbXB1dGVPdXRTaGFwZSQ0KGhhLGFhKXtjb25zdCB4YT1oYVswXS5zbGljZSgpO2ZvcihsZXQgYmE9MTtiYTxoYS5sZW5ndGg7YmErKyl4YVthYV0rPWhhW2JhXVthYV07cmV0dXJuIHhhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBSb3dQYXJ0aXRpb25UeXBlJDM7KGZ1bmN0aW9uKGhhKXtoYVtoYS5GSVJTVF9ESU1fU0laRT0wXT0iRklSU1RfRElNX1NJWkUiLGhhW2hhLlZBTFVFX1JPV0lEUz0xXT0iVkFMVUVfUk9XSURTIixoYVtoYS5ST1dfTEVOR1RIUz0yXT0iUk9XX0xFTkdUSFMiLGhhW2hhLlJPV19TUExJVFM9M109IlJPV19TUExJVFMiLGhhW2hhLlJPV19MSU1JVFM9NF09IlJPV19MSU1JVFMiLGhhW2hhLlJPV19TVEFSVFM9NV09IlJPV19TVEFSVFMifSkoUm93UGFydGl0aW9uVHlwZSQzfHwoUm93UGFydGl0aW9uVHlwZSQzPXt9KSk7ZnVuY3Rpb24gY29tYmluZVJhZ2dlZFRlbnNvclRvVGVuc29yU2hhcGVzJDEoaGEsYWEseGEpe2xldCBiYT1uZXcgQXJyYXk7aWYoeGE9PW51bGwmJmFhPT1udWxsKXJldHVybiBiYTtpZihhYT09bnVsbClmb3IoO2JhLmxlbmd0aDxoYSt4YS5sZW5ndGg7KWJhLnB1c2goLTEpO2Vsc2UgYmE9YWEuc2xpY2UoKTtpZih4YT09bnVsbClyZXR1cm4gYmE7aWYoaGEreGEubGVuZ3RoIT09YmEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgcnQgaW5wdXQuc2hhcGUgYW5kIHNoYXBlPSR7YWF9IGFyZSBpbmNvbXBhdGlibGU6IHJ0IGlucHV0LnJhbmsgPSAke2hhK3hhLmxlbmd0aH0sIGJ1dCBzaGFwZS5yYW5rID0gJHtiYS5sZW5ndGh9YCk7Zm9yKGxldCBTYT0xO1NhPHhhLmxlbmd0aDsrK1NhKXtjb25zdCBUYT14YVtTYV0sd2E9YmFbYmEubGVuZ3RoLXhhLmxlbmd0aCtTYV0sRWE9YmFbd2FdO2lmKFRhPj0wKWlmKEVhPj0wKXtpZihFYSE9PVRhKXRocm93IG5ldyBFcnJvcihgcnQgaW5wdXQuc2hhcGUgYW5kIHNoYXBlPSR7YWF9IGFyZSBpbmNvbXBhdGlibGU6IHJ0IGlucHV0LnNoYXBlWyR7U2EraGF9XSA9ICR7VGF9IGJ1dCBzaGFwZVske1NhK2hhfV0gPSAke0VhfWApfWVsc2UgYmFbd2FdPVRhfXJldHVybiBiYX1mdW5jdGlvbiBnZXRSb3dQYXJ0aXRpb25UeXBlc0hlbHBlciQxKGhhKXtjb25zdCBhYT17RklSU1RfRElNX1NJWkU6Um93UGFydGl0aW9uVHlwZSQzLkZJUlNUX0RJTV9TSVpFLFZBTFVFX1JPV0lEUzpSb3dQYXJ0aXRpb25UeXBlJDMuVkFMVUVfUk9XSURTLFJPV19MRU5HVEhTOlJvd1BhcnRpdGlvblR5cGUkMy5ST1dfTEVOR1RIUyxST1dfU1BMSVRTOlJvd1BhcnRpdGlvblR5cGUkMy5ST1dfU1BMSVRTLFJPV19MSU1JVFM6Um93UGFydGl0aW9uVHlwZSQzLlJPV19MSU1JVFMsUk9XX1NUQVJUUzpSb3dQYXJ0aXRpb25UeXBlJDMuUk9XX1NUQVJUU30seGE9W107Zm9yKGNvbnN0IGJhIG9mIGhhKWlmKGJhIGluIGFhKXhhLnB1c2goYWFbYmFdKTtlbHNlIGJyZWFrO3JldHVybiB4YX1mdW5jdGlvbiBnZXRSYWdnZWRSYW5rJDEoaGEpe3JldHVybiBoYS5sZW5ndGg9PT0wPzA6aGFbMF09PT1Sb3dQYXJ0aXRpb25UeXBlJDMuRklSU1RfRElNX1NJWkU/aGEubGVuZ3RoLTE6aGEubGVuZ3RofWZ1bmN0aW9uIHZhbGlkYXRlRGVmYXVsdFZhbHVlU2hhcGUkMShoYSxhYSl7aWYoaGE9PW51bGx8fGFhPT1udWxsKXJldHVybjtjb25zdCB4YT1oYS5sZW5ndGgsYmE9YWEubGVuZ3RoO2lmKHhhPj1iYSl0aHJvdyBuZXcgRXJyb3IoYGRlZmF1bHRWYWx1ZS5zaGFwZT0ke2hhfSBhbmQgcmFnZ2VkIHRlbnNvciBmbGF0VmFsdWVzLnNoYXBlPSR7YWF9LCBhcmUgaW5jb21wYXRpYmxlOiBkZWZhdWx0VmFsdWUucmFuayA9ICR7eGF9IG11c3QgYmUgbGVzcyB0aGFuIHJhZ2dlZCB0ZW5zb3IgaW5wdXQgZmxhdFZhbHVlcy5yYW5rID0gJHtiYX0pYCk7Zm9yKGxldCBTYT0wO1NhPE1hdGgubWluKHhhLGJhLTEpOysrU2Epe2NvbnN0IFRhPWhhW1NhXSx3YT1hYVtTYSsxXTtpZihUYT49MCYmd2E+PTAmJlRhIT09MSYmVGEhPT13YSl0aHJvdyBuZXcgRXJyb3IoYGRlZmF1bHRWYWx1ZS5zaGFwZT0ke2hhfSwgYW5kIHJhZ2dlZCB0ZW5zb3IgaW5wdXQgZmxhdFZhbHVlcy5zaGFwZT0ke2FhfSBhcmUgaW5jb21wYXRpYmxlOiBkZWZhdWx0VmFsdWUuc2hhcGVbJHtTYS1oYS5sZW5ndGh9XSA9ICR7VGF9IGJ1dCByYWdnZWQgdGVuc29yIGlucHV0LmZsYXRWYWx1ZXMuc2hhcGVbJHtTYS1oYS5sZW5ndGh9XSA9ICR7d2F9YCl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFBBUkFMTEVMSVpFX1RIUkVTSE9MRCQxPTMwO2Z1bmN0aW9uIGNvbXB1dGVPcHRpbWFsV2luZG93U2l6ZSQxKGhhKXtyZXR1cm4gaGE8PVBBUkFMTEVMSVpFX1RIUkVTSE9MRCQxP2hhOm5lYXJlc3REaXZpc29yJDEoaGEsTWF0aC5mbG9vcihNYXRoLnNxcnQoaGEpKSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0SW1hZ2VDZW50ZXIkMShoYSxhYSx4YSl7Y29uc3QgYmE9eGEqKHR5cGVvZiBoYT09Im51bWJlciI/aGE6aGFbMF0pLFNhPWFhKih0eXBlb2YgaGE9PSJudW1iZXIiP2hhOmhhWzFdKTtyZXR1cm5bYmEsU2FdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdldFJlc2hhcGVkJDEoaGEsYWEseGEsYmE9ITApe2xldCBTYT1bXTtpZihiYSlTYT1TYS5jb25jYXQoYWEuc2xpY2UoMCkpLFNhLnB1c2goaGFbMF0veGEpLFNhPVNhLmNvbmNhdChoYS5zbGljZSgxKSk7ZWxzZXtTYT1TYS5jb25jYXQoaGFbMF0pO2NvbnN0IFRhPWFhLmxlbmd0aDtmb3IobGV0IHdhPTA7d2E8VGE7Kyt3YSlTYT1TYS5jb25jYXQoW2hhW3dhKzFdL2FhW3dhXSxhYVt3YV1dKTtTYT1TYS5jb25jYXQoaGEuc2xpY2UoVGErMSkpfXJldHVybiBTYX1mdW5jdGlvbiBnZXRQZXJtdXRlZCQxKGhhLGFhLHhhPSEwKXtjb25zdCBiYT1bXTtpZih4YSl7YmEucHVzaChhYSk7Zm9yKGxldCBTYT1hYSsxO1NhPGhhOysrU2EpU2E8PTIqYWE/KGJhLnB1c2goU2EpLGJhLnB1c2goU2EtKGFhKzEpKSk6YmEucHVzaChTYSl9ZWxzZXtjb25zdCBTYT1bXSxUYT1bXTtmb3IobGV0IHdhPTE7d2E8aGE7Kyt3YSl3YT49YWEqMisxfHx3YSUyPT09MT9UYS5wdXNoKHdhKTpTYS5wdXNoKHdhKTtiYS5wdXNoKC4uLlNhKSxiYS5wdXNoKDApLGJhLnB1c2goLi4uVGEpfXJldHVybiBiYX1mdW5jdGlvbiBnZXRSZXNoYXBlZFBlcm11dGVkJDEoaGEsYWEseGEsYmE9ITApe2NvbnN0IFNhPVtdO2JhP1NhLnB1c2goaGFbMF0veGEpOlNhLnB1c2goaGFbMF0qeGEpO2ZvcihsZXQgVGE9MTtUYTxoYS5sZW5ndGg7KytUYSlUYTw9YWEubGVuZ3RoP2JhP1NhLnB1c2goYWFbVGEtMV0qaGFbVGFdKTpTYS5wdXNoKGhhW1RhXS9hYVtUYS0xXSk6U2EucHVzaChoYVtUYV0pO3JldHVybiBTYX1mdW5jdGlvbiBnZXRTbGljZUJlZ2luQ29vcmRzJDEoaGEsYWEpe2NvbnN0IHhhPVswXTtmb3IobGV0IGJhPTA7YmE8YWE7KytiYSl4YS5wdXNoKGhhW2JhXVswXSk7cmV0dXJuIHhhfWZ1bmN0aW9uIGdldFNsaWNlU2l6ZSQxKGhhLGFhLHhhKXtjb25zdCBiYT1oYS5zbGljZSgwLDEpO2ZvcihsZXQgU2E9MDtTYTx4YTsrK1NhKWJhLnB1c2goaGFbU2ErMV0tYWFbU2FdWzBdLWFhW1NhXVsxXSk7cmV0dXJuIGJhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNFTFVfU0NBTEVBTFBIQSQxPTEuNzU4MDk5MzQwODQ3Mzc2OCxTRUxVX1NDQUxFJDE9MS4wNTA3MDA5ODczNTU0ODA1Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVSRl9QJDE9LjMyNzU5MTEsRVJGX0ExJDE9LjI1NDgyOTU5MixFUkZfQTIkMT0tLjI4NDQ5NjczNixFUkZfQTMkMT0xLjQyMTQxMzc0MSxFUkZfQTQkMT0tMS40NTMxNTIwMjcsRVJGX0E1JDE9MS4wNjE0MDU0Mjk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWVyZ2VSZWFsQW5kSW1hZ0FycmF5cyQxKGhhLGFhKXtpZihoYS5sZW5ndGghPT1hYS5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgbWVyZ2UgcmVhbCBhbmQgaW1hZyBhcnJheXMgb2YgZGlmZmVyZW50IGxlbmd0aHMuIHJlYWw6JHtoYS5sZW5ndGh9LCBpbWFnOiAke2FhLmxlbmd0aH0uYCk7Y29uc3QgeGE9bmV3IEZsb2F0MzJBcnJheShoYS5sZW5ndGgqMik7Zm9yKGxldCBiYT0wO2JhPHhhLmxlbmd0aDtiYSs9Mil4YVtiYV09aGFbYmEvMl0seGFbYmErMV09YWFbYmEvMl07cmV0dXJuIHhhfWZ1bmN0aW9uIHNwbGl0UmVhbEFuZEltYWdBcnJheXMkMShoYSl7Y29uc3QgYWE9bmV3IEZsb2F0MzJBcnJheShoYS5sZW5ndGgvMikseGE9bmV3IEZsb2F0MzJBcnJheShoYS5sZW5ndGgvMik7Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDtiYSs9MilhYVtiYS8yXT1oYVtiYV0seGFbYmEvMl09aGFbYmErMV07cmV0dXJue3JlYWw6YWEsaW1hZzp4YX19ZnVuY3Rpb24gY29tcGxleFdpdGhFdmVuSW5kZXgkMShoYSl7Y29uc3QgYWE9TWF0aC5jZWlsKGhhLmxlbmd0aC80KSx4YT1uZXcgRmxvYXQzMkFycmF5KGFhKSxiYT1uZXcgRmxvYXQzMkFycmF5KGFhKTtmb3IobGV0IFNhPTA7U2E8aGEubGVuZ3RoO1NhKz00KXhhW01hdGguZmxvb3IoU2EvNCldPWhhW1NhXSxiYVtNYXRoLmZsb29yKFNhLzQpXT1oYVtTYSsxXTtyZXR1cm57cmVhbDp4YSxpbWFnOmJhfX1mdW5jdGlvbiBjb21wbGV4V2l0aE9kZEluZGV4JDEoaGEpe2NvbnN0IGFhPU1hdGguZmxvb3IoaGEubGVuZ3RoLzQpLHhhPW5ldyBGbG9hdDMyQXJyYXkoYWEpLGJhPW5ldyBGbG9hdDMyQXJyYXkoYWEpO2ZvcihsZXQgU2E9MjtTYTxoYS5sZW5ndGg7U2ErPTQpeGFbTWF0aC5mbG9vcihTYS80KV09aGFbU2FdLGJhW01hdGguZmxvb3IoU2EvNCldPWhhW1NhKzFdO3JldHVybntyZWFsOnhhLGltYWc6YmF9fWZ1bmN0aW9uIGdldENvbXBsZXhXaXRoSW5kZXgkMShoYSxhYSl7Y29uc3QgeGE9aGFbYWEqMl0sYmE9aGFbYWEqMisxXTtyZXR1cm57cmVhbDp4YSxpbWFnOmJhfX1mdW5jdGlvbiBhc3NpZ25Ub1R5cGVkQXJyYXkkMShoYSxhYSx4YSxiYSl7aGFbYmEqMl09YWEsaGFbYmEqMisxXT14YX1mdW5jdGlvbiBleHBvbmVudHMkMShoYSxhYSl7Y29uc3QgeGE9bmV3IEZsb2F0MzJBcnJheShoYS8yKSxiYT1uZXcgRmxvYXQzMkFycmF5KGhhLzIpO2ZvcihsZXQgU2E9MDtTYTxNYXRoLmNlaWwoaGEvMik7U2ErKyl7Y29uc3QgVGE9KGFhPzI6LTIpKk1hdGguUEkqKFNhL2hhKTt4YVtTYV09TWF0aC5jb3MoVGEpLGJhW1NhXT1NYXRoLnNpbihUYSl9cmV0dXJue3JlYWw6eGEsaW1hZzpiYX19ZnVuY3Rpb24gZXhwb25lbnQkMShoYSxhYSx4YSl7Y29uc3QgYmE9KHhhPzI6LTIpKk1hdGguUEkqKGhhL2FhKSxTYT1NYXRoLmNvcyhiYSksVGE9TWF0aC5zaW4oYmEpO3JldHVybntyZWFsOlNhLGltYWc6VGF9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFSUk9XJDE9Ii0+IixBUlJPV19SRUdFWCQxPS8tPi9nLENPTU1BJDE9IiwiLEVMTElQU0lTJDE9Ii4uLiI7ZnVuY3Rpb24gZGVjb2RlRWluc3VtRXF1YXRpb24kMShoYSxhYSl7aGE9aGEucmVwbGFjZSgvXHMvZywiIik7Y29uc3QgeGE9KGhhLmxlbmd0aC1oYS5yZXBsYWNlKEFSUk9XX1JFR0VYJDEsIiIpLmxlbmd0aCkvQVJST1ckMS5sZW5ndGg7aWYoeGE8MSl0aHJvdyBuZXcgRXJyb3IoIkVxdWF0aW9ucyB3aXRob3V0IGFuIGFycm93IGFyZSBub3Qgc3VwcG9ydGVkLiIpO2lmKHhhPjEpdGhyb3cgbmV3IEVycm9yKGBFcXVhdGlvbiBtdXN0IGNvbnRhaW4gZXhhY3RseSBvbmUgYXJyb3cgKCIke0FSUk9XJDF9IikuYCk7Y29uc3RbYmEsU2FdPWhhLnNwbGl0KEFSUk9XJDEpO2Fzc2VydCQyKGJhLmluZGV4T2YoRUxMSVBTSVMkMSk9PT0tMSwoKT0+YFRoZSBlbGxpcHNpcyBub3RhdGlvbiAoIiR7RUxMSVBTSVMkMX0iKSBpcyBub3Qgc3VwcG9ydGVkIHlldC5gKTtjb25zdCBUYT1iYS5zcGxpdChDT01NQSQxKSx3YT1UYS5sZW5ndGg7aWYoYWEhPT13YSl0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7d2F9IGlucHV0IHRlbnNvcnMsIHJlY2VpdmVkICR7YWF9YCk7aWYod2E+Mil0aHJvdyBuZXcgRXJyb3IoIlN1cHBvcnQgZm9yIG1vcmUgdGhhbiAyIGlucHV0IHRlbnNvcnMgaXMgbm90IGltcGxlbWVudGVkIHlldC4iKTtjb25zdCBFYT1bXTtmb3IobGV0IGVsPTA7ZWw8U2EubGVuZ3RoOysrZWwpe2NvbnN0IHRsPVNhW2VsXTtpZighVGEuc29tZShubD0+bmwuaW5kZXhPZih0bCkhPT0tMSkpdGhyb3cgbmV3IEVycm9yKGBPdXRwdXQgc3Vic2NyaXB0cyBjb250YWluIHRoZSBsYWJlbCAke3RsfSBub3QgcHJlc2VudCBpbiB0aGUgaW5wdXQgc3Vic2NyaXB0cy5gKTtFYS5pbmRleE9mKHRsKT09PS0xJiZFYS5wdXNoKHRsKX1mb3IobGV0IGVsPTA7ZWw8YmEubGVuZ3RoOysrZWwpe2NvbnN0IHRsPWJhW2VsXTtFYS5pbmRleE9mKHRsKT09PS0xJiZ0bCE9PUNPTU1BJDEmJkVhLnB1c2godGwpfWNvbnN0IGthPW5ldyBBcnJheShUYS5sZW5ndGgpO2ZvcihsZXQgZWw9MDtlbDx3YTsrK2VsKXtpZihuZXcgU2V0KFRhW2VsXS5zcGxpdCgiIikpLnNpemUhPT1UYVtlbF0ubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgRm91bmQgZHVwbGljYXRlIGF4ZXMgaW4gaW5wdXQgY29tcG9uZW50ICR7VGFbZWxdfS4gU3VwcG9ydCBmb3IgZHVwbGljYXRlIGF4ZXMgaW4gaW5wdXQgaXMgbm90IGltcGxlbWVudGVkIHlldC5gKTtrYVtlbF09W107Zm9yKGxldCB0bD0wO3RsPFRhW2VsXS5sZW5ndGg7Kyt0bClrYVtlbF0ucHVzaChFYS5pbmRleE9mKFRhW2VsXVt0bF0pKX1jb25zdCBBYT1FYS5sZW5ndGgsRmE9U2EubGVuZ3RoLExhPVtdO2ZvcihsZXQgZWw9RmE7ZWw8QWE7KytlbClMYS5wdXNoKGVsKTtyZXR1cm57YWxsRGltczpFYSxzdW1tZWREaW1zOkxhLGlkRGltczprYX19ZnVuY3Rpb24gZ2V0RWluc3VtUGVybXV0YXRpb24kMShoYSxhYSl7bGV0IHhhPW5ldyBBcnJheShoYSk7eGEuZmlsbCgtMSk7Zm9yKGxldCBTYT0wO1NhPGFhLmxlbmd0aDsrK1NhKXhhW2FhW1NhXV09U2E7Y29uc3QgYmE9W107Zm9yKGxldCBTYT0wO1NhPGhhOysrU2EpeGFbU2FdPT09LTEmJmJhLnB1c2goU2EpO3JldHVybiB4YT14YS5maWx0ZXIoU2E9PlNhIT09LTEpLHtwZXJtdXRhdGlvbkluZGljZXM6eGEsZXhwYW5kRGltczpiYX19ZnVuY3Rpb24gY2hlY2tFaW5zdW1EaW1TaXplcyQxKGhhLGFhLHhhKXtjb25zdCBiYT1uZXcgQXJyYXkoaGEpO2ZvcihsZXQgU2E9MDtTYTx4YS5sZW5ndGg7KytTYSl7Y29uc3QgVGE9eGFbU2FdLnNoYXBlO2ZvcihsZXQgd2E9MDt3YTxhYVtTYV0ubGVuZ3RoOysrd2EpYmFbYWFbU2FdW3dhXV09PT12b2lkIDA/YmFbYWFbU2FdW3dhXV09VGFbd2FdOmFzc2VydCQyKGJhW2FhW1NhXVt3YV1dPT09VGFbd2FdLCgpPT5gRXhwZWN0ZWQgZGltZW5zaW9uICR7YmFbYWFbU2FdW3dhXV19IGF0IGF4aXMgJHt3YX0gb2YgaW5wdXQgc2hhcGVkICR7SlNPTi5zdHJpbmdpZnkoVGEpfSwgYnV0IGdvdCBkaW1lbnNpb24gJHtUYVt3YV19YCl9fWZ1bmN0aW9uIGdldEVpbnN1bUNvbXB1dGVQYXRoJDEoaGEsYWEpe2NvbnN0IHhhPWhhLGJhPVtdO2xldCBTYT0wO2hhLmxlbmd0aD09PTAmJnhhLnB1c2goLTEpLFNhPWhhLmxlbmd0aCsxO2ZvcihsZXQgd2E9MDt3YTxTYTsrK3dhKWJhLnB1c2goW10pO2NvbnN0IFRhPVtdO2ZvcihsZXQgd2E9MDt3YTx4YS5sZW5ndGg7Kyt3YSl7Y29uc3QgRWE9eGFbd2FdLGthPWZpbmRUZXJtc1dpdGhEaW0kMShhYSxFYSk7Zm9yKGNvbnN0IEFhIG9mIGthKVRhLmluZGV4T2YoQWEpPT09LTEmJihiYVt3YV0ucHVzaChBYSksVGEucHVzaChBYSkpfXJldHVybntwYXRoOnhhLHN0ZXBzOmJhfX1mdW5jdGlvbiBpc0lkZW50aXR5UGVybXV0YXRpb24kMShoYSl7cmV0dXJuIGhhLmV2ZXJ5KChhYSx4YSk9PmFhPT09eGEpfWZ1bmN0aW9uIGZpbmRUZXJtc1dpdGhEaW0kMShoYSxhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDsrK2JhKShoYVtiYV0ubGVuZ3RoPT09MHx8aGFbYmFdLmluZGV4T2YoYWEpIT09LTF8fGFhPT09LTEpJiZ4YS5wdXNoKGJhKTtyZXR1cm4geGF9ZnVuY3Rpb24gcHJlcGFyZVNwbGl0U2l6ZSQxKGhhLGFhLHhhPTApe2xldCBiYT1bXTtpZih0eXBlb2YgYWE9PSJudW1iZXIiKWFzc2VydCQyKGhhLnNoYXBlW3hhXSVhYT09PTAsKCk9PiJOdW1iZXIgb2Ygc3BsaXRzIG11c3QgZXZlbmx5IGRpdmlkZSB0aGUgYXhpcy4iKSxiYT1uZXcgQXJyYXkoYWEpLmZpbGwoaGEuc2hhcGVbeGFdL2FhKTtlbHNle2NvbnN0IFNhPWFhLnJlZHVjZSgod2EsRWEpPT4oRWE9PT0tMSYmKHdhKz0xKSx3YSksMCk7YXNzZXJ0JDIoU2E8PTEsKCk9PiJUaGVyZSBzaG91bGQgYmUgb25seSBvbmUgbmVnYXRpdmUgdmFsdWUgaW4gc3BsaXQgYXJyYXkuIik7Y29uc3QgVGE9YWEuaW5kZXhPZigtMSk7aWYoVGEhPT0tMSl7Y29uc3Qgd2E9YWEucmVkdWNlKChFYSxrYSk9PmthPjA/RWEra2E6RWEpO2FhW1RhXT1oYS5zaGFwZVt4YV0td2F9YXNzZXJ0JDIoaGEuc2hhcGVbeGFdPT09YWEucmVkdWNlKCh3YSxFYSk9PndhK0VhKSwoKT0+IlRoZSBzdW0gb2Ygc2l6ZXMgbXVzdCBtYXRjaCB0aGUgc2l6ZSBvZiB0aGUgYXhpcyBkaW1lbnNpb24uIiksYmE9YWF9cmV0dXJuIGJhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdldFNwYXJzZUZpbGxFbXB0eVJvd3NJbmRpY2VzRGVuc2VTaGFwZU1pc21hdGNoJDEoaGEpe3JldHVybmBSZWNlaXZlZCBTcGFyc2VUZW5zb3Igd2l0aCBkZW5zZVNoYXBlWzBdID0gMCBidXQKICBpbmRpY2VzLnNoYXBlWzBdID0gJHtoYX1gfWZ1bmN0aW9uIGdldFNwYXJzZUZpbGxFbXB0eVJvd3NOZWdhdGl2ZUluZGV4RXJyb3JNZXNzYWdlJDEoaGEsYWEpe3JldHVybmBpbmRpY2VzKCR7aGF9LCAwKSBpcyBpbnZhbGlkOiAke2FhfSA8IDBgfWZ1bmN0aW9uIGdldFNwYXJzZUZpbGxFbXB0eVJvd3NPdXRPZlJhbmdlSW5kZXhFcnJvck1lc3NhZ2UkMShoYSxhYSx4YSl7cmV0dXJuYGluZGljZXMoJHtoYX0sIDApIGlzIGludmFsaWQ6ICR7YWF9ID49ICR7eGF9YH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRTcGFyc2VSZXNoYXBlTXVsdGlwbGVOZWdhdGl2ZU9uZU91dHB1dERpbUVycm9yTWVzc2FnZSQxKGhhLGFhKXtyZXR1cm5gb25seSBvbmUgb3V0cHV0IGRpbWVuc2lvbiBtYXkgYmUgLTEsIG5vdCBib3RoICR7aGF9IGFuZCAke2FhfWB9ZnVuY3Rpb24gZ2V0U3BhcnNlUmVzaGFwZU5lZ2F0aXZlT3V0cHV0RGltRXJyb3JNZXNzYWdlJDEoaGEsYWEpe3JldHVybmBzaXplICR7aGF9IG11c3QgYmUgbm9uLW5lZ2F0aXZlLCBub3QgJHthYX1gfWZ1bmN0aW9uIGdldFNwYXJzZVJlc2hhcGVFbXB0eVRlbnNvclplcm9PdXRwdXREaW1FcnJvck1lc3NhZ2UkMSgpe3JldHVybiJyZXNoYXBlIGNhbm5vdCBpbmZlciB0aGUgbWlzc2luZyBpbnB1dCBzaXplIGZvciBhbiBlbXB0eSB0ZW5zb3IgdW5sZXNzIGFsbCBzcGVjaWZpZWQgaW5wdXQgc2l6ZXMgYXJlIG5vbi16ZXJvIn1mdW5jdGlvbiBnZXRTcGFyc2VSZXNoYXBlSW5wdXRPdXRwdXRNdWx0aXBsZUVycm9yTWVzc2FnZSQxKGhhLGFhKXtjb25zdCB4YT1zaXplRnJvbVNoYXBlJDEoaGEpLGJhPXNpemVGcm9tU2hhcGUkMShhYSk7cmV0dXJuYElucHV0IHRvIHJlc2hhcGUgaXMgYSBTcGFyc2VUZW5zb3Igd2l0aCAke3hhfQogIGRlbnNlIHZhbHVlcywgYnV0IHRoZSByZXF1ZXN0ZWQgc2hhcGUgcmVxdWlyZXMgYSBtdWx0aXBsZSBvZiAke2JhfS4gaW5wdXRTaGFwZT0ke2hhfSBvdXRwdXRTaGFwZT0gJHthYX1gfWZ1bmN0aW9uIGdldFNwYXJzZVJlc2hhcGVJbnB1dE91dHB1dE1pc21hdGNoRXJyb3JNZXNzYWdlJDEoaGEsYWEpe2NvbnN0IHhhPXNpemVGcm9tU2hhcGUkMShoYSksYmE9c2l6ZUZyb21TaGFwZSQxKGFhKTtyZXR1cm5gSW5wdXQgdG8gcmVzaGFwZSBpcyBhIHRlbnNvciB3aXRoICR7eGF9IGRlbnNlIHZhbHVlcywgYnV0IHRoZSByZXF1ZXN0ZWQgc2hhcGUgaGFzICR7YmF9LiBpbnB1dFNoYXBlPSR7aGF9IG91dHB1dFNoYXBlPSR7YWF9YH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uTmVnYXRpdmVTZWdtZW50SWRzRXJyb3JNZXNzYWdlJDEoKXtyZXR1cm4ic2VnbWVudCBpZHMgbXVzdCBiZSA+PSAwIn1mdW5jdGlvbiBnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uTm9uSW5jcmVhc2luZ1NlZ21lbnRJZHNFcnJvck1lc3NhZ2UkMSgpe3JldHVybiJzZWdtZW50IGlkcyBhcmUgbm90IGluY3JlYXNpbmcifWZ1bmN0aW9uIGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25TZWdtZW50SWRPdXRPZlJhbmdlRXJyb3JNZXNzYWdlJDEoaGEsYWEpe3JldHVybmBTZWdtZW50IGlkICR7aGF9IG91dCBvZiByYW5nZSBbMCwgJHthYX0pLCBwb3NzaWJseSBiZWNhdXNlIHNlZ21lbnRJZHMgaW5wdXQgaXMgbm90IHNvcnRlZC5gfWZ1bmN0aW9uIGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25JbmRpY2VzT3V0T2ZSYW5nZUVycm9yTWVzc2FnZSQxKGhhLGFhLHhhKXtyZXR1cm5gQmFkOiBpbmRpY2VzWyR7aGF9XSA9PSAke2FhfSBvdXQgb2YgcmFuZ2UgWzAsICR7eGF9KWB9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2VnT3BDb21wdXRlT3B0aW1hbFdpbmRvd1NpemUkMShoYSxhYSl7bGV0IHhhPSExLGJhO2ZvcihoYTw9UEFSQUxMRUxJWkVfVEhSRVNIT0xEJDE/KGJhPWhhLHhhPSEwKTpiYT1uZWFyZXN0RGl2aXNvciQxKGhhLE1hdGguZmxvb3IoTWF0aC5zcXJ0KGhhKSkpOyF4YTspYmE+YWF8fGJhPT09aGE/eGE9ITA6YmE9bmVhcmVzdERpdmlzb3IkMShoYSxiYSsxKTtyZXR1cm4gYmF9ZnVuY3Rpb24gY29tcHV0ZU91dFNoYXBlJDMoaGEsYWEseGEpe2NvbnN0IGJhPVtdLFNhPWhhLmxlbmd0aDtmb3IobGV0IFRhPTA7VGE8U2E7VGErKylUYSE9PWFhP2JhLnB1c2goaGFbVGFdKTpiYS5wdXNoKHhhKTtyZXR1cm4gYmF9ZnVuY3Rpb24gY29sbGVjdEdhdGhlck9wU2hhcGVJbmZvJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWFhLnNoYXBlLmxlbmd0aCxUYT1oYS5zaGFwZS5sZW5ndGg7aWYoYmEhPT0wJiYoYmE8LVNhfHxiYT5TYSkpdGhyb3cgbmV3IEVycm9yKGBFeHBlY3QgYmF0Y2hEaW1zIGluIHRoZSByYW5nZSBvZiBbLSR7U2F9LCAke1NhfV0sIGJ1dCBnb3QgJHtiYX1gKTtpZihiYTwwJiYoYmErPVNhKSxiYT5UYSl0aHJvdyBuZXcgRXJyb3IoYGJhdGNoRGltcyAoJHtiYX0pIG11c3QgYmUgbGVzcyB0aGFuIHJhbmsoeCkgKAogICAgJHtUYX0pLmApO2lmKHhhPGJhKXRocm93IG5ldyBFcnJvcihgYmF0Y2hEaW1zICgke2JhfSkgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYXhpcyAoJHt4YX0pLmApO2ZvcihsZXQgTGE9MDtMYTxiYTsrK0xhKWlmKGhhLnNoYXBlW0xhXSE9PWFhLnNoYXBlW0xhXSl0aHJvdyBuZXcgRXJyb3IoYHguc2hhcGVbJHtMYX1dOiAke2hhLnNoYXBlW0xhXX0gc2hvdWxkIGJlIGVxdWFsIHRvIGluZGljZXMuc2hhcGVbJHtMYX1dOiAke2FhLnNoYXBlW0xhXX0uYCk7Y29uc3Qgd2E9aGEuc2hhcGVbeGFdLEVhPVtdO2xldCBrYT0xLEFhPTEsRmE9MTtmb3IobGV0IExhPTA7TGE8YmE7KytMYSlFYS5wdXNoKGhhLnNoYXBlW0xhXSksa2EqPWhhLnNoYXBlW0xhXTtmb3IobGV0IExhPWJhO0xhPHhhO0xhKyspRWEucHVzaChoYS5zaGFwZVtMYV0pLEFhKj1oYS5zaGFwZVtMYV07Zm9yKGxldCBMYT1iYTtMYTxTYTtMYSsrKUVhLnB1c2goYWEuc2hhcGVbTGFdKTtmb3IobGV0IExhPXhhKzE7TGE8VGE7TGErKylFYS5wdXNoKGhhLnNoYXBlW0xhXSksRmEqPWhhLnNoYXBlW0xhXTtyZXR1cm57YmF0Y2hTaXplOmthLHNsaWNlU2l6ZTpGYSxvdXRlclNpemU6QWEsZGltU2l6ZTp3YSxvdXRwdXRTaGFwZTpFYX19dmFyIHNlZ21lbnRfdXRpbCQxPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGNvbGxlY3RHYXRoZXJPcFNoYXBlSW5mbzpjb2xsZWN0R2F0aGVyT3BTaGFwZUluZm8kMSxjb21wdXRlT3V0U2hhcGU6Y29tcHV0ZU91dFNoYXBlJDMsc2VnT3BDb21wdXRlT3B0aW1hbFdpbmRvd1NpemU6c2VnT3BDb21wdXRlT3B0aW1hbFdpbmRvd1NpemUkMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZyb21VaW50OFRvU3RyaW5nQXJyYXkkMShoYSl7dHJ5e3JldHVybiBoYS5tYXAoYWE9PmRlY29kZVN0cmluZyQxKGFhKSl9Y2F0Y2goYWEpe3Rocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlY29kZSBlbmNvZGVkIHN0cmluZyBieXRlcyBpbnRvIHV0Zi04LCBlcnJvcjogJHthYX1gKX19ZnVuY3Rpb24gZnJvbVN0cmluZ0FycmF5VG9VaW50OCQxKGhhKXtyZXR1cm4gaGEubWFwKGFhPT5lbmNvZGVTdHJpbmckMShhYSkpfXZhciBiYWNrZW5kX3V0aWwkMT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxFUkZfQTE6RVJGX0ExJDEsRVJGX0EyOkVSRl9BMiQxLEVSRl9BMzpFUkZfQTMkMSxFUkZfQTQ6RVJGX0E0JDEsRVJGX0E1OkVSRl9BNSQxLEVSRl9QOkVSRl9QJDEsUEFSQUxMRUxJWkVfVEhSRVNIT0xEOlBBUkFMTEVMSVpFX1RIUkVTSE9MRCQxLGdldCBSb3dQYXJ0aXRpb25UeXBlKCl7cmV0dXJuIFJvd1BhcnRpdGlvblR5cGUkM30sU0VMVV9TQ0FMRTpTRUxVX1NDQUxFJDEsU0VMVV9TQ0FMRUFMUEhBOlNFTFVfU0NBTEVBTFBIQSQxLGFwcGx5QWN0aXZhdGlvbjphcHBseUFjdGl2YXRpb24kMixhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZTphc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxLGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zOmFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zJDEsYXNzZXJ0UGFyYW1zQ29uc2lzdGVudDphc3NlcnRQYXJhbXNDb25zaXN0ZW50JDEsYXNzaWduVG9UeXBlZEFycmF5OmFzc2lnblRvVHlwZWRBcnJheSQxLGF4ZXNBcmVJbm5lck1vc3REaW1zOmF4ZXNBcmVJbm5lck1vc3REaW1zJDEsY2FsY3VsYXRlU2hhcGVzOmNhbGN1bGF0ZVNoYXBlcyQxLGNoZWNrRWluc3VtRGltU2l6ZXM6Y2hlY2tFaW5zdW1EaW1TaXplcyQxLGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGU6Y2hlY2tQYWRPbkRpbVJvdW5kaW5nTW9kZSQxLGNvbWJpbmVMb2NhdGlvbnM6Y29tYmluZUxvY2F0aW9ucyQxLGNvbWJpbmVSYWdnZWRUZW5zb3JUb1RlbnNvclNoYXBlczpjb21iaW5lUmFnZ2VkVGVuc29yVG9UZW5zb3JTaGFwZXMkMSxjb21wbGV4V2l0aEV2ZW5JbmRleDpjb21wbGV4V2l0aEV2ZW5JbmRleCQxLGNvbXBsZXhXaXRoT2RkSW5kZXg6Y29tcGxleFdpdGhPZGRJbmRleCQxLGNvbXB1dGVDb252MkRJbmZvOmNvbXB1dGVDb252MkRJbmZvJDEsY29tcHV0ZUNvbnYzREluZm86Y29tcHV0ZUNvbnYzREluZm8kMSxjb21wdXRlRGVmYXVsdFBhZDpjb21wdXRlRGVmYXVsdFBhZCQxLGNvbXB1dGVEaWxhdGlvbjJESW5mbzpjb21wdXRlRGlsYXRpb24yREluZm8kMSxjb21wdXRlT3B0aW1hbFdpbmRvd1NpemU6Y29tcHV0ZU9wdGltYWxXaW5kb3dTaXplJDEsY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlczpjb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEsY29tcHV0ZU91dFNoYXBlOmNvbXB1dGVPdXRTaGFwZSQ0LGNvbXB1dGVQb29sMkRJbmZvOmNvbXB1dGVQb29sMkRJbmZvJDEsY29tcHV0ZVBvb2wzREluZm86Y29tcHV0ZVBvb2wzREluZm8kMSxjb252ZXJ0Q29udjJERGF0YUZvcm1hdDpjb252ZXJ0Q29udjJERGF0YUZvcm1hdCQxLGRlY29kZUVpbnN1bUVxdWF0aW9uOmRlY29kZUVpbnN1bUVxdWF0aW9uJDEsZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lOmVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZSQxLGV4cGFuZFNoYXBlVG9LZWVwRGltOmV4cGFuZFNoYXBlVG9LZWVwRGltJDEsZXhwb25lbnQ6ZXhwb25lbnQkMSxleHBvbmVudHM6ZXhwb25lbnRzJDEsZnJvbVN0cmluZ0FycmF5VG9VaW50ODpmcm9tU3RyaW5nQXJyYXlUb1VpbnQ4JDEsZnJvbVVpbnQ4VG9TdHJpbmdBcnJheTpmcm9tVWludDhUb1N0cmluZ0FycmF5JDEsZ2V0QXhlc1Blcm11dGF0aW9uOmdldEF4ZXNQZXJtdXRhdGlvbiQxLGdldEJyb2FkY2FzdERpbXM6Z2V0QnJvYWRjYXN0RGltcyQzLGdldENvbXBsZXhXaXRoSW5kZXg6Z2V0Q29tcGxleFdpdGhJbmRleCQxLGdldEVpbnN1bUNvbXB1dGVQYXRoOmdldEVpbnN1bUNvbXB1dGVQYXRoJDEsZ2V0RWluc3VtUGVybXV0YXRpb246Z2V0RWluc3VtUGVybXV0YXRpb24kMSxnZXRGdXNlZEJpYXNHcmFkaWVudDpnZXRGdXNlZEJpYXNHcmFkaWVudCQxLGdldEZ1c2VkRHlBY3RpdmF0aW9uOmdldEZ1c2VkRHlBY3RpdmF0aW9uJDEsZ2V0SW1hZ2VDZW50ZXI6Z2V0SW1hZ2VDZW50ZXIkMSxnZXRJbm5lck1vc3RBeGVzOmdldElubmVyTW9zdEF4ZXMkMSxnZXRQZXJtdXRlZDpnZXRQZXJtdXRlZCQxLGdldFJhZ2dlZFJhbms6Z2V0UmFnZ2VkUmFuayQxLGdldFJlZHVjdGlvbkF4ZXM6Z2V0UmVkdWN0aW9uQXhlcyQxLGdldFJlc2hhcGVkOmdldFJlc2hhcGVkJDEsZ2V0UmVzaGFwZWRQZXJtdXRlZDpnZXRSZXNoYXBlZFBlcm11dGVkJDEsZ2V0Um93UGFydGl0aW9uVHlwZXNIZWxwZXI6Z2V0Um93UGFydGl0aW9uVHlwZXNIZWxwZXIkMSxnZXRTbGljZUJlZ2luQ29vcmRzOmdldFNsaWNlQmVnaW5Db29yZHMkMSxnZXRTbGljZVNpemU6Z2V0U2xpY2VTaXplJDEsZ2V0U3BhcnNlRmlsbEVtcHR5Um93c0luZGljZXNEZW5zZVNoYXBlTWlzbWF0Y2g6Z2V0U3BhcnNlRmlsbEVtcHR5Um93c0luZGljZXNEZW5zZVNoYXBlTWlzbWF0Y2gkMSxnZXRTcGFyc2VGaWxsRW1wdHlSb3dzTmVnYXRpdmVJbmRleEVycm9yTWVzc2FnZTpnZXRTcGFyc2VGaWxsRW1wdHlSb3dzTmVnYXRpdmVJbmRleEVycm9yTWVzc2FnZSQxLGdldFNwYXJzZUZpbGxFbXB0eVJvd3NPdXRPZlJhbmdlSW5kZXhFcnJvck1lc3NhZ2U6Z2V0U3BhcnNlRmlsbEVtcHR5Um93c091dE9mUmFuZ2VJbmRleEVycm9yTWVzc2FnZSQxLGdldFNwYXJzZVJlc2hhcGVFbXB0eVRlbnNvclplcm9PdXRwdXREaW1FcnJvck1lc3NhZ2U6Z2V0U3BhcnNlUmVzaGFwZUVtcHR5VGVuc29yWmVyb091dHB1dERpbUVycm9yTWVzc2FnZSQxLGdldFNwYXJzZVJlc2hhcGVJbnB1dE91dHB1dE1pc21hdGNoRXJyb3JNZXNzYWdlOmdldFNwYXJzZVJlc2hhcGVJbnB1dE91dHB1dE1pc21hdGNoRXJyb3JNZXNzYWdlJDEsZ2V0U3BhcnNlUmVzaGFwZUlucHV0T3V0cHV0TXVsdGlwbGVFcnJvck1lc3NhZ2U6Z2V0U3BhcnNlUmVzaGFwZUlucHV0T3V0cHV0TXVsdGlwbGVFcnJvck1lc3NhZ2UkMSxnZXRTcGFyc2VSZXNoYXBlTXVsdGlwbGVOZWdhdGl2ZU9uZU91dHB1dERpbUVycm9yTWVzc2FnZTpnZXRTcGFyc2VSZXNoYXBlTXVsdGlwbGVOZWdhdGl2ZU9uZU91dHB1dERpbUVycm9yTWVzc2FnZSQxLGdldFNwYXJzZVJlc2hhcGVOZWdhdGl2ZU91dHB1dERpbUVycm9yTWVzc2FnZTpnZXRTcGFyc2VSZXNoYXBlTmVnYXRpdmVPdXRwdXREaW1FcnJvck1lc3NhZ2UkMSxnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uSW5kaWNlc091dE9mUmFuZ2VFcnJvck1lc3NhZ2U6Z2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbkluZGljZXNPdXRPZlJhbmdlRXJyb3JNZXNzYWdlJDEsZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbk5lZ2F0aXZlU2VnbWVudElkc0Vycm9yTWVzc2FnZTpnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uTmVnYXRpdmVTZWdtZW50SWRzRXJyb3JNZXNzYWdlJDEsZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbk5vbkluY3JlYXNpbmdTZWdtZW50SWRzRXJyb3JNZXNzYWdlOmdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25Ob25JbmNyZWFzaW5nU2VnbWVudElkc0Vycm9yTWVzc2FnZSQxLGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25TZWdtZW50SWRPdXRPZlJhbmdlRXJyb3JNZXNzYWdlOmdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25TZWdtZW50SWRPdXRPZlJhbmdlRXJyb3JNZXNzYWdlJDEsZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbjpnZXRVbmRvQXhlc1Blcm11dGF0aW9uJDEsaXNJZGVudGl0eVBlcm11dGF0aW9uOmlzSWRlbnRpdHlQZXJtdXRhdGlvbiQxLGxvZzpsb2ckNSxtZXJnZVJlYWxBbmRJbWFnQXJyYXlzOm1lcmdlUmVhbEFuZEltYWdBcnJheXMkMSxwcmVwYXJlQW5kVmFsaWRhdGU6cHJlcGFyZUFuZFZhbGlkYXRlJDEscHJlcGFyZVNwbGl0U2l6ZTpwcmVwYXJlU3BsaXRTaXplJDEsc2VnbWVudF91dGlsOnNlZ21lbnRfdXRpbCQxLHNob3VsZEZ1c2U6c2hvdWxkRnVzZSQxLHNsaWNlX3V0aWw6c2xpY2VfdXRpbCQxLHNwbGl0UmVhbEFuZEltYWdBcnJheXM6c3BsaXRSZWFsQW5kSW1hZ0FycmF5cyQxLHN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlOnN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlJDEsdHVwbGVWYWx1ZXNBcmVPbmU6dHVwbGVWYWx1ZXNBcmVPbmUkMSx1cGNhc3RUeXBlOnVwY2FzdFR5cGUkMSx2YWxpZGF0ZURlZmF1bHRWYWx1ZVNoYXBlOnZhbGlkYXRlRGVmYXVsdFZhbHVlU2hhcGUkMSx2YWxpZGF0ZUlucHV0OnZhbGlkYXRlSW5wdXQkMix2YWxpZGF0ZVVwZGF0ZVNoYXBlOnZhbGlkYXRlVXBkYXRlU2hhcGUkMSx3YXJuOndhcm4kMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3JlZ2lzdGVyT3B0aW1pemVycyQxKCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYWJzR3JhZENvbmZpZz17a2VybmVsTmFtZTpBYnMkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoaGEsc3RlcCQ0KGNhc3QkNSh4YSwiZmxvYXQzMiIpLC0xKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYWNvc0dyYWRDb25maWc9e2tlcm5lbE5hbWU6QWNvcyQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybnt4OigpPT57Y29uc3QgYmE9c3F1YXJlJDQoY2FzdCQ1KHhhLCJmbG9hdDMyIikpLFNhPXNxcnQkNChzdWIkNChzY2FsYXIkMSgxKSxiYSkpO3JldHVybiBuZWckMyhkaXYkMihoYSxTYSkpfX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhY29zaEdyYWRDb25maWc9e2tlcm5lbE5hbWU6QWNvc2gkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+e2NvbnN0IGJhPXNxcnQkNChzdWIkNChzcXVhcmUkNChjYXN0JDUoeGEsImZsb2F0MzIiKSksMSkpO3JldHVybiBkaXYkMihoYSxiYSl9fX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGFkZEdyYWRDb25maWc9e2tlcm5lbE5hbWU6QWRkJDIsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhLFNhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO3JldHVybnthOigpPT57bGV0IEVhPWhhO2NvbnN0IGthPWdldFJlZHVjdGlvbkF4ZXMkMSh4YS5zaGFwZSxTYSk7cmV0dXJuIGthLmxlbmd0aD4wJiYoRWE9c3VtJDUoRWEsa2EpKSxyZXNoYXBlJDQoRWEseGEuc2hhcGUpfSxiOigpPT57bGV0IEVhPWhhO2NvbnN0IGthPWdldFJlZHVjdGlvbkF4ZXMkMShiYS5zaGFwZSxTYSk7cmV0dXJuIGthLmxlbmd0aD4wJiYoRWE9c3VtJDUoRWEsa2EpKSxyZXNoYXBlJDQoRWEsYmEuc2hhcGUpfX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhZGROR3JhZENvbmZpZz17a2VybmVsTmFtZTpBZGROJDEsc2F2ZUFsbElucHV0czohMCxncmFkRnVuYzooaGEsYWEpPT57Y29uc3QgeGE9e307cmV0dXJuIGFhLmZvckVhY2goKGJhLFNhKT0+e3hhW1NhXT0oKT0+aGEuY2xvbmUoKX0pLHhhfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYXJnTWF4R3JhZENvbmZpZz17a2VybmVsTmFtZTpBcmdNYXgkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+emVyb3NMaWtlJDQoeGEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGFyZ01pbkdyYWRDb25maWc9e2tlcm5lbE5hbWU6QXJnTWluJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWE7cmV0dXJue3g6KCk9Pnplcm9zTGlrZSQ0KHhhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhc2luR3JhZENvbmZpZz17a2VybmVsTmFtZTpBc2luJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWE7cmV0dXJue3g6KCk9PmRpdiQyKGhhLHNxcnQkNChzdWIkNChzY2FsYXIkMSgxKSxzcXVhcmUkNChjYXN0JDUoeGEsImZsb2F0MzIiKSkpKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYXNpbmhHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkFzaW5oJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWE7cmV0dXJue3g6KCk9Pntjb25zdCBiYT1zcXJ0JDQoYWRkJDMoc2NhbGFyJDEoMSksc3F1YXJlJDQoY2FzdCQ1KHhhLCJmbG9hdDMyIikpKSk7cmV0dXJuIGRpdiQyKGhhLGJhKX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYXRhbjJHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkF0YW4yJDEsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhLFNhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO3JldHVybnthOigpPT57Y29uc3QgRWE9YWRkJDMoc3F1YXJlJDQoeGEpLHNxdWFyZSQ0KGJhKSk7bGV0IGthPW11bCQxKGhhLGRpdiQyKGJhLEVhKSk7Y29uc3QgQWE9Z2V0UmVkdWN0aW9uQXhlcyQxKHhhLnNoYXBlLFNhKTtyZXR1cm4gQWEubGVuZ3RoPjAmJihrYT1zdW0kNShrYSxBYSkpLHJlc2hhcGUkNChrYSx4YS5zaGFwZSl9LGI6KCk9Pntjb25zdCBFYT1hZGQkMyhzcXVhcmUkNCh4YSksc3F1YXJlJDQoYmEpKTtsZXQga2E9bmVnJDMobXVsJDEoaGEsZGl2JDIoeGEsRWEpKSk7Y29uc3QgQWE9Z2V0UmVkdWN0aW9uQXhlcyQxKGJhLnNoYXBlLFNhKTtyZXR1cm4gQWEubGVuZ3RoPjAmJihrYT1zdW0kNShrYSxBYSkpLHJlc2hhcGUkNChrYSxiYS5zaGFwZSl9fX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGF0YW5HcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkF0YW4kMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+ZGl2JDIoaGEsYWRkJDMoc3F1YXJlJDQoY2FzdCQ1KHhhLCJmbG9hdDMyIikpLDEpKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhdGFuaEdyYWRDb25maWc9e2tlcm5lbE5hbWU6QXRhbmgkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+ZGl2JDIoaGEsc3ViJDQoc2NhbGFyJDEoMSksc3F1YXJlJDQoY2FzdCQ1KHhhLCJmbG9hdDMyIikpKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXZnUG9vbDNkR3JhZF8oaGEsYWEseGEsYmEsU2EsVGEpe2NvbnN0IHdhPWNvbnZlcnRUb1RlbnNvciQxKGhhLCJkeSIsImF2Z1Bvb2wzZEdyYWQiKSxFYT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiaW5wdXQiLCJhdmdQb29sM2RHcmFkIik7bGV0IGthPXdhLEFhPUVhLEZhPSExO0VhLnJhbms9PT00JiYoRmE9ITAsa2E9cmVzaGFwZSQ0KHdhLFsxLHdhLnNoYXBlWzBdLHdhLnNoYXBlWzFdLHdhLnNoYXBlWzJdLHdhLnNoYXBlWzNdXSksQWE9cmVzaGFwZSQ0KEVhLFsxLEVhLnNoYXBlWzBdLEVhLnNoYXBlWzFdLEVhLnNoYXBlWzJdLEVhLnNoYXBlWzNdXSkpLGFzc2VydCQyKGthLnJhbms9PT01LCgpPT5gRXJyb3IgaW4gYXZnUG9vbDNkR3JhZDogZHkgbXVzdCBiZSByYW5rIDUgYnV0IGdvdCByYW5rICR7a2EucmFua30uYCksYXNzZXJ0JDIoQWEucmFuaz09PTUsKCk9PmBFcnJvciBpbiBhdmdQb29sM2RHcmFkOiBpbnB1dCBtdXN0IGJlIHJhbmsgNSBidXQgZ290IHJhbmsgJHtBYS5yYW5rfS5gKSxjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlJDEoImF2Z1Bvb2wzZEdyYWQiLFNhLFRhKTtjb25zdCBMYT17ZHk6a2EsaW5wdXQ6QWF9LGVsPXtmaWx0ZXJTaXplOnhhLHN0cmlkZXM6YmEscGFkOlNhLGRpbVJvdW5kaW5nTW9kZTpUYX0sdGw9RU5HSU5FJDEucnVuS2VybmVsKEF2Z1Bvb2wzREdyYWQkMSxMYSxlbCk7cmV0dXJuIEZhP3Jlc2hhcGUkNCh0bCxbdGwuc2hhcGVbMV0sdGwuc2hhcGVbMl0sdGwuc2hhcGVbM10sdGwuc2hhcGVbNF1dKTp0bH1jb25zdCBhdmdQb29sM2RHcmFkPW9wJDEoe2F2Z1Bvb2wzZEdyYWRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYXZnUG9vbDNER3JhZENvbmZpZyQzPXtrZXJuZWxOYW1lOkF2Z1Bvb2wzRCQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3RbYmFdPWFhLHtmaWx0ZXJTaXplOlNhLHN0cmlkZXM6VGEscGFkOndhLGRpbVJvdW5kaW5nTW9kZTpFYX09eGE7cmV0dXJue3g6KCk9PmF2Z1Bvb2wzZEdyYWQoaGEsYmEsU2EsVGEsd2EsRWEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2xHcmFkXyhoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9Y29udmVydFRvVGVuc29yJDEoaGEsImR5IiwiYXZnUG9vbEdyYWQiKSx3YT1jb252ZXJ0VG9UZW5zb3IkMShhYSwiaW5wdXQiLCJhdmdQb29sR3JhZCIpO2Fzc2VydCQyKHdhLnJhbms9PT1UYS5yYW5rLCgpPT5gUmFuayBvZiBpbnB1dCAoJHt3YS5yYW5rfSkgZG9lcyBub3QgbWF0Y2ggcmFuayBvZiBkeSAoJHtUYS5yYW5rfSlgKTtsZXQgRWE9d2Esa2E9VGEsQWE9ITE7d2EucmFuaz09PTMmJihBYT0hMCxFYT1yZXNoYXBlJDQod2EsWzEsd2Euc2hhcGVbMF0sd2Euc2hhcGVbMV0sd2Euc2hhcGVbMl1dKSxrYT1yZXNoYXBlJDQoVGEsWzEsVGEuc2hhcGVbMF0sVGEuc2hhcGVbMV0sVGEuc2hhcGVbMl1dKSksYXNzZXJ0JDIoa2EucmFuaz09PTQsKCk9PmBFcnJvciBpbiBhdmdQb29sR3JhZDogZHkgbXVzdCBiZSByYW5rIDQgYnV0IGdvdCByYW5rICR7a2EucmFua30uYCksYXNzZXJ0JDIoRWEucmFuaz09PTQsKCk9PmBFcnJvciBpbiBhdmdQb29sR3JhZDogaW5wdXQgbXVzdCBiZSByYW5rIDQgYnV0IGdvdCByYW5rICR7RWEucmFua30uYCk7Y29uc3QgRmE9e2R5OmthLGlucHV0OkVhfSxMYT17ZmlsdGVyU2l6ZTp4YSxzdHJpZGVzOmJhLHBhZDpTYX0sZWw9RU5HSU5FJDEucnVuS2VybmVsKEF2Z1Bvb2xHcmFkJDEsRmEsTGEpO3JldHVybiBBYT9yZXNoYXBlJDQoZWwsW2VsLnNoYXBlWzFdLGVsLnNoYXBlWzJdLGVsLnNoYXBlWzNdXSk6ZWx9Y29uc3QgYXZnUG9vbEdyYWQkMz1vcCQxKHthdmdQb29sR3JhZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhdmdQb29sR3JhZENvbmZpZyQzPXtrZXJuZWxOYW1lOkF2Z1Bvb2wkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhXT1hYSx7ZmlsdGVyU2l6ZTpTYSxzdHJpZGVzOlRhLHBhZDp3YX09eGE7cmV0dXJue3g6KCk9PmF2Z1Bvb2xHcmFkJDMoaGEsYmEsU2EsVGEsd2EpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGJhdGNoTWF0TXVsR3JhZENvbmZpZz17a2VybmVsTmFtZTpCYXRjaE1hdE11bCQxLGlucHV0c1RvU2F2ZTpbImEiLCJiIl0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhLFNhXT1hYSx7dHJhbnNwb3NlQTpUYSx0cmFuc3Bvc2VCOndhfT14YTtyZXR1cm4hVGEmJiF3YT97YTooKT0+bWF0TXVsJDEoaGEsU2EsITEsITApLGI6KCk9Pm1hdE11bCQxKGJhLGhhLCEwLCExKX06IVRhJiZ3YT97YTooKT0+bWF0TXVsJDEoaGEsU2EsITEsITEpLGI6KCk9Pm1hdE11bCQxKGhhLGJhLCEwLCExKX06VGEmJiF3YT97YTooKT0+bWF0TXVsJDEoU2EsaGEsITEsITApLGI6KCk9Pm1hdE11bCQxKGJhLGhhLCExLCExKX06e2E6KCk9Pm1hdE11bCQxKFNhLGhhLCEwLCEwKSxiOigpPT5tYXRNdWwkMShoYSxiYSwhMCwhMCl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYmF0Y2hUb1NwYWNlTkRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkJhdGNoVG9TcGFjZU5EJDEsZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0e2Jsb2NrU2hhcGU6YmEsY3JvcHM6U2F9PXhhO3JldHVybnt4OigpPT5zcGFjZVRvQmF0Y2hORCQzKGhhLGJhLFNhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBicm9hZGNhc3RUb0dyYWRDb25maWc9e2tlcm5lbE5hbWU6QnJvYWRjYXN0VG8sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0IGJhPXhhLFNhPWJhLmlucHV0U2hhcGUsVGE9YmEuc2hhcGUsd2E9QXJyYXkuZnJvbShUYSk7Zm9yKGxldCBrYT1TYS5sZW5ndGgtMTtrYT49MDtrYS0tKWlmKFNhW2thXT09PVRhW2thXSl3YVtrYV09MTtlbHNlIGlmKFNhW2thXSE9PTEpdGhyb3cgbmV3IEVycm9yKGBicm9hZGNhc3RUbygpOiBbJHtTYX1dIGNhbm5vdCBiZSBicm9hZGNhc3QgdG8gWyR7VGF9XS5gKTtjb25zdCBFYT1bXTtmb3IobGV0IGthPTA7a2E8d2EubGVuZ3RoO2thKyspd2Fba2FdPjEmJkVhLnB1c2goa2EpO3JldHVybnt4OigpPT5zdW0kNShoYSxFYSwhMCl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgY2FzdEdyYWRDb25maWc9e2tlcm5lbE5hbWU6Q2FzdCQxLGdyYWRGdW5jOmhhPT4oe3g6KCk9PmhhLmNsb25lKCl9KX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgY2VpbEdyYWRDb25maWc9e2tlcm5lbE5hbWU6Q2VpbCQxLGdyYWRGdW5jOmhhPT4oe3g6KCk9Pnplcm9zTGlrZSQ0KGhhKX0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjbGlwQnlWYWx1ZUdyYWRDb25maWc9e2tlcm5lbE5hbWU6Q2xpcEJ5VmFsdWUkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhXT1hYSx7Y2xpcFZhbHVlTWluOlNhLGNsaXBWYWx1ZU1heDpUYX09eGE7cmV0dXJue3g6KCk9PndoZXJlKGxvZ2ljYWxBbmQkMyhncmVhdGVyRXF1YWwkMyhiYSxTYSksbGVzc0VxdWFsJDMoYmEsVGEpKSxoYSx6ZXJvc0xpa2UkNChoYSkpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNvbXBsZXhBYnNHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkNvbXBsZXhBYnMkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6YWJzR3JhZENvbmZpZy5ncmFkRnVuY307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgY29uY2F0R3JhZENvbmZpZz17a2VybmVsTmFtZTpDb25jYXQkMSxzYXZlQWxsSW5wdXRzOiEwLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdCBiYT1hYS5tYXAoa2E9PmthLnNoYXBlKSx7YXhpczpTYX09eGEsVGE9cGFyc2VBeGlzUGFyYW0kMShTYSxhYVswXS5zaGFwZSlbMF0sd2E9YmEubWFwKGthPT5rYVtUYV0pO3JldHVybiBzcGxpdCQzKGhhLHdhLFRhKS5tYXAoa2E9PigpPT5rYSl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjb252MkRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkNvbnYyRCQyLGlucHV0c1RvU2F2ZTpbIngiLCJmaWx0ZXIiXSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3RbYmEsU2FdPWFhLHtkaWxhdGlvbnM6VGEsc3RyaWRlczp3YSxwYWQ6RWEsZGF0YUZvcm1hdDprYX09eGE7cmV0dXJuIGFzc2VydCQyKHR1cGxlVmFsdWVzQXJlT25lJDEoVGEpLCgpPT5gRXJyb3IgaW4gZ3JhZGllbnQgb2YgY29udjJEOiBkaWxhdGlvbiByYXRlcyBncmVhdGVyIHRoYW4gMSBhcmUgbm90IHlldCBzdXBwb3J0ZWQgaW4gZ3JhZGllbnRzLiBHb3QgZGlsYXRpb25zICcke1RhfSdgKSx7eDooKT0+Y29udjJEQmFja3Byb3BJbnB1dCQzKGJhLnNoYXBlLGhhLFNhLHdhLEVhLGthKSxmaWx0ZXI6KCk9PmNvbnYyREJhY2twcm9wRmlsdGVyJDMoYmEsaGEsU2Euc2hhcGUsd2EsRWEsa2EpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNvbnYyREJhY2twcm9wSW5wdXRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkNvbnYyREJhY2twcm9wSW5wdXQkMSxpbnB1dHNUb1NhdmU6WyJkeSIsImZpbHRlciJdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYSxTYV09YWEse3N0cmlkZXM6VGEscGFkOndhLGRhdGFGb3JtYXQ6RWEsZGltUm91bmRpbmdNb2RlOmthfT14YTtyZXR1cm57ZHk6KCk9PmNvbnYyZCQzKGhhLFNhLFRhLHdhLEVhLDEsa2EpLGZpbHRlcjooKT0+Y29udjJEQmFja3Byb3BGaWx0ZXIkMyhoYSxiYSxTYS5zaGFwZSxUYSx3YSxFYSxrYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjNEQmFja3Byb3BGaWx0ZXJfKGhhLGFhLHhhLGJhLFNhKXtsZXQgVGE9aGE7aGEucmFuaz09PTQmJihUYT1yZXNoYXBlJDQoaGEsWzEsaGEuc2hhcGVbMF0saGEuc2hhcGVbMV0saGEuc2hhcGVbMl0saGEuc2hhcGVbM11dKSk7bGV0IHdhPWFhO3dhLnJhbms9PT00JiYod2E9cmVzaGFwZSQ0KGFhLFsxLGFhLnNoYXBlWzBdLGFhLnNoYXBlWzFdLGFhLnNoYXBlWzJdLGFhLnNoYXBlWzNdXSkpLGFzc2VydCQyKFRhLnJhbms9PT01LCgpPT5gRXJyb3IgaW4gY29udjNkRGVyRmlsdGVyOiBpbnB1dCBtdXN0IGJlIHJhbmsgNSwgYnV0IGdvdCBzaGFwZSAke1RhLnNoYXBlfS5gKSxhc3NlcnQkMih3YS5yYW5rPT09NSwoKT0+YEVycm9yIGluIGNvbnYzZERlckZpbHRlcjogZHkgbXVzdCBiZSByYW5rIDUsIGJ1dCBnb3Qgc2hhcGUgJHt3YS5zaGFwZX0uYCksYXNzZXJ0JDIoeGEubGVuZ3RoPT09NSwoKT0+YEVycm9yIGluIGNvbnYzZERlckZpbHRlcjogZmlsdGVyU2hhcGUgbXVzdCBiZSBsZW5ndGggNSwgYnV0IGdvdCAke3hhfS5gKSxhc3NlcnQkMihUYS5zaGFwZVs0XT09PXhhWzNdLCgpPT5gRXJyb3IgaW4gY29udjNkRGVyRmlsdGVyOiBkZXB0aCBvZiBpbnB1dCAke1RhLnNoYXBlWzRdfSkgbXVzdCBtYXRjaCBpbnB1dCBkZXB0aCBpbiBmaWx0ZXIgKCR7eGFbM119LmApLGFzc2VydCQyKHdhLnNoYXBlWzRdPT09eGFbNF0sKCk9PmBFcnJvciBpbiBjb252M2REZXJGaWx0ZXI6IGRlcHRoIG9mIGR5ICgke3dhLnNoYXBlWzRdfSkgbXVzdCBtYXRjaCBvdXRwdXQgZGVwdGggZm9yIGZpbHRlciAoJHt4YVs0XX0pLmApO2NvbnN0IEVhPXt4OlRhLGR5OndhfSxrYT17c3RyaWRlczpiYSxwYWQ6U2EsZmlsdGVyU2hhcGU6eGF9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoQ29udjNEQmFja3Byb3BGaWx0ZXJWMiQxLEVhLGthKX1jb25zdCBjb252M0RCYWNrcHJvcEZpbHRlcj1vcCQxKHtjb252M0RCYWNrcHJvcEZpbHRlcl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjb252M0RHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkNvbnYzRCQyLGlucHV0c1RvU2F2ZTpbIngiLCJmaWx0ZXIiXSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3R7ZGlsYXRpb25zOmJhLHN0cmlkZXM6U2EscGFkOlRhfT14YTthc3NlcnQkMih0dXBsZVZhbHVlc0FyZU9uZSQxKGJhKSwoKT0+YEVycm9yIGluIGdyYWRpZW50IG9mIGNvbnYzRDogZGlsYXRpb24gcmF0ZXMgZ3JlYXRlciB0aGFuIDEgYXJlIG5vdCB5ZXQgc3VwcG9ydGVkIGluIGdyYWRpZW50cy4gR290IGRpbGF0aW9ucyAnJHtiYX0nYCk7Y29uc3Rbd2EsRWFdPWFhO3JldHVybnt4OigpPT5jb252M0RCYWNrcHJvcElucHV0JDIod2Euc2hhcGUsaGEsRWEsU2EsVGEpLGZpbHRlcjooKT0+Y29udjNEQmFja3Byb3BGaWx0ZXIod2EsaGEsRWEuc2hhcGUsU2EsVGEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNvc0dyYWRDb25maWc9e2tlcm5lbE5hbWU6Q29zJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWE7cmV0dXJue3g6KCk9Pm11bCQxKG5lZyQzKHNpbiQzKGNhc3QkNSh4YSwiZmxvYXQzMiIpKSksaGEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNvc2hHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkNvc2gkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoc2luaCQzKGNhc3QkNSh4YSwiZmxvYXQzMiIpKSxoYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgY3Vtc3VtR3JhZENvbmZpZz17a2VybmVsTmFtZTpDdW1zdW0kMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhXT1hYSx7YXhpczpTYSxleGNsdXNpdmU6VGEscmV2ZXJzZTp3YX09eGE7cmV0dXJue3g6KCk9Pntjb25zdCBFYT1nZXRBeGVzUGVybXV0YXRpb24kMShbU2FdLGJhLnJhbmspO2xldCBrYT1jdW1zdW0kMyhoYSxTYSxUYSwhd2EpO3JldHVybiBFYSE9bnVsbCYmKGthPXRyYW5zcG9zZSQzKGthLEVhKSksa2F9fX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGRlcHRod2lzZUNvbnYyZE5hdGl2ZUdyYWRDb25maWc9e2tlcm5lbE5hbWU6RGVwdGh3aXNlQ29udjJkTmF0aXZlJDEsaW5wdXRzVG9TYXZlOlsieCIsImZpbHRlciJdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdHtkaWxhdGlvbnM6YmEsc3RyaWRlczpTYSxwYWQ6VGEsZGltUm91bmRpbmdNb2RlOndhfT14YSxFYT1iYT8/WzEsMV07YXNzZXJ0JDIodHVwbGVWYWx1ZXNBcmVPbmUkMShFYSksKCk9PmBFcnJvciBpbiBncmFkaWVudCBvZiBkZXB0aHdpc2VDb252MmROYXRpdmU6IGRpbGF0aW9uIHJhdGVzIGdyZWF0ZXIgdGhhbiAxIGFyZSBub3QgeWV0IHN1cHBvcnRlZC4gR290IGRpbGF0aW9ucyAnJHtFYX0nYCk7Y29uc3Rba2EsQWFdPWFhO3JldHVybiBhc3NlcnQkMihrYS5yYW5rPT09NCwoKT0+YEVycm9yIGluIGdyYWRpZW50IG9mIGRlcHRod2lzZUNvbnYyZE5hdGl2ZTogaW5wdXQgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke2thLnJhbmt9LmApLGFzc2VydCQyKEFhLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gZ3JhZGllbnQgb2YgZGVwdGh3aXNlQ29udjJkTmF0aXZlOiBmaWx0ZXIgbXVzdCBiZSByYW5rIDQsIGJ1dCBnb3QgcmFuayAke0FhLnJhbmt9LmApLGFzc2VydCQyKGthLnNoYXBlWzNdPT09QWEuc2hhcGVbMl0sKCk9PmBFcnJvciBpbiBncmFkaWVudCBvZiBkZXB0aHdpc2VDb252MmQ6IG51bWJlciBvZiBpbnB1dCBjaGFubmVscyAoJHtrYS5zaGFwZVszXX0pIG11c3QgbWF0Y2ggdGhlIGluQ2hhbm5lbHMgZGltZW5zaW9uIGluIGZpbHRlciAke0FhLnNoYXBlWzJdfS5gKSxhc3NlcnQkMihlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUkMShTYSxFYSksKCk9PmBFcnJvciBpbiBncmFkaWVudCBvZiBkZXB0aHdpc2VDb252MmQ6IEVpdGhlciBzdHJpZGVzIG9yIGRpbGF0aW9ucyBtdXN0IGJlICAxLiBHb3Qgc3RyaWRlcyAke1NhfSBhbmQgZGlsYXRpb25zICcke0VhfScuYCksY2hlY2tQYWRPbkRpbVJvdW5kaW5nTW9kZSQxKCJkZXB0aHdpc2VDb252MmQiLFRhLHdhKSx7eDooKT0+ZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dCQzKGthLnNoYXBlLGhhLEFhLFNhLFRhLEVhLHdhKSxmaWx0ZXI6KCk9PmRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDMoa2EsaGEsQWEuc2hhcGUsU2EsVGEsRWEsd2EpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGRpbGF0aW9uMmRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkRpbGF0aW9uMkQkMSxpbnB1dHNUb1NhdmU6WyJ4IiwiZmlsdGVyIl0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhLFNhXT1hYSxUYT17eDpiYSxmaWx0ZXI6U2EsZHk6aGF9LHdhPXt4OmJhLGZpbHRlcjpTYSxkeTpoYX07cmV0dXJue3g6KCk9PkVOR0lORSQxLnJ1bktlcm5lbChEaWxhdGlvbjJEQmFja3Byb3BJbnB1dCxUYSx4YSksZmlsdGVyOigpPT5FTkdJTkUkMS5ydW5LZXJuZWwoRGlsYXRpb24yREJhY2twcm9wRmlsdGVyLHdhLHhhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBlbHVHcmFkQ29uZmlnJDM9e2tlcm5lbE5hbWU6RWx1JDIsb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWEsYmE9e2R5OmhhLHk6eGF9O3JldHVybnt4OigpPT5FTkdJTkUkMS5ydW5LZXJuZWwoRWx1R3JhZCQxLGJhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBlcmZHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkVyZiQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhLGJhPW11bCQxKGV4cCQzKG5lZyQzKHNxdWFyZSQ0KHhhKSkpLDIvTWF0aC5zcXJ0KE1hdGguUEkpKTtyZXR1cm57eDooKT0+bXVsJDEoaGEsYmEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4cEdyYWRDb25maWc9e2tlcm5lbE5hbWU6RXhwJDEsb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWE7cmV0dXJue3g6KCk9Pm11bCQxKGhhLHhhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleHBhbmREaW1zR3JhZENvbmZpZz17a2VybmVsTmFtZTpFeHBhbmREaW1zJDEsaW5wdXRzVG9TYXZlOlsiaW5wdXQiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybntpbnB1dDooKT0+cmVzaGFwZSQ0KGhhLHhhLnNoYXBlKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleHBtMUdyYWRDb25maWc9e2tlcm5lbE5hbWU6RXhwbTEkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoaGEsZXhwJDMoeGEpKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBmbG9vckdyYWRDb25maWc9e2tlcm5lbE5hbWU6Rmxvb3IkMSxncmFkRnVuYzpoYT0+KHt4OigpPT56ZXJvc0xpa2UkNChoYSl9KX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZmxvb3JEaXZHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkZsb29yRGl2JDEsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhLFNhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO3JldHVybnthOigpPT57Y29uc3QgRWE9ZGl2JDIoaGEsY2FzdCQ1KGJhLCJmbG9hdDMyIikpLGthPWdldFJlZHVjdGlvbkF4ZXMkMSh4YS5zaGFwZSxTYSk7cmV0dXJuIGthLmxlbmd0aD4wP3Jlc2hhcGUkNChzdW0kNShFYSxrYSkseGEuc2hhcGUpOkVhfSxiOigpPT57bGV0IEVhPW11bCQxKGhhLGNhc3QkNSh4YSwiZmxvYXQzMiIpKTtjb25zdCBrYT1nZXRSZWR1Y3Rpb25BeGVzJDEoYmEuc2hhcGUsU2EpO2thLmxlbmd0aD4wJiYoRWE9cmVzaGFwZSQ0KHN1bSQ1KEVhLGthKSxiYS5zaGFwZSkpO2NvbnN0IEFhPXNxdWFyZSQ0KGJhKTtyZXR1cm4gbmVnJDMoZGl2JDIoRWEsY2FzdCQ1KEFhLCJmbG9hdDMyIikpKX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZnVzZWRCYXRjaE5vcm1HcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkZ1c2VkQmF0Y2hOb3JtJDEsaW5wdXRzVG9TYXZlOlsieCIsIm1lYW4iLCJ2YXJpYW5jZSIsInNjYWxlIl0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0e3ZhcmlhbmNlRXBzaWxvbjpiYX09eGEsW1NhLFRhLHdhLEVhXT1hYSxrYT1FYT8/c2NhbGFyJDEoMSksQWE9Z2V0UmVkdWN0aW9uQXhlcyQxKFRhLnNoYXBlLFNhLnNoYXBlKSxGYT1bXTtpZihUYS5yYW5rPT09MSl7Zm9yKGxldCBpbD0wO2lsPFNhLnNoYXBlLmxlbmd0aC0xOysraWwpRmEucHVzaChTYS5zaGFwZVtpbF0pO0ZhLnB1c2goMSl9Y29uc3QgTGE9c3ViJDQoU2EsVGEpLGVsPW11bCQxKGhhLGthKSx0bD1yc3FydCQzKGFkZCQzKHdhLHNjYWxhciQxKGJhKSkpLG5sPW11bCQxKG11bCQxKG11bCQxKHRsLHRsKSx0bCksc2NhbGFyJDEoLS41KSk7cmV0dXJue3g6KCk9PlRhLnJhbms9PT0xP3Jlc2hhcGUkNChtdWwkMShtdWwkMShoYSx0aWxlJDQocmVzaGFwZSQ0KHRsLFsxLDEsMSxUYS5zaGFwZVswXV0pLEZhKSksa2EpLFNhLnNoYXBlKTpyZXNoYXBlJDQobXVsJDEobXVsJDEoaGEsdGwpLGthKSxTYS5zaGFwZSksbWVhbjooKT0+e2xldCBpbD1tdWwkMShtdWwkMSh0bCxzY2FsYXIkMSgtMSkpLGVsKTtyZXR1cm4gVGEucmFuaz09PTEmJihpbD1zdW0kNShpbCxBYSkpLHJlc2hhcGUkNChpbCxUYS5zaGFwZSl9LHZhcmlhbmNlOigpPT57bGV0IGlsPW11bCQxKG11bCQxKG5sLExhKSxlbCk7cmV0dXJuIFRhLnJhbms9PT0xJiYoaWw9c3VtJDUoaWwsQWEpKSxyZXNoYXBlJDQoaWwsVGEuc2hhcGUpfSxzY2FsZTooKT0+e2NvbnN0IGlsPW11bCQxKExhLHRsKTtsZXQgY2w9bXVsJDEoaGEsaWwpO3JldHVybiBUYS5yYW5rPT09MSYmKGNsPXN1bSQ1KGNsLEFhKSkscmVzaGFwZSQ0KGNsLFRhLnNoYXBlKX0sb2Zmc2V0OigpPT57bGV0IGlsPWhhO3JldHVybiBUYS5yYW5rPT09MSYmKGlsPXN1bSQ1KGlsLEFhKSkscmVzaGFwZSQ0KGlsLFRhLnNoYXBlKX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZ2F0aGVyR3JhZENvbmZpZz17a2VybmVsTmFtZTpHYXRoZXJWMiQxLGlucHV0c1RvU2F2ZTpbIngiLCJpbmRpY2VzIl0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhLFNhXT1hYSx7YXhpczpUYSxiYXRjaERpbXM6d2F9PXhhLEVhPXBhcnNlQXhpc1BhcmFtJDEoVGEsYmEuc2hhcGUpWzBdLGthPShBYSxGYSxMYSk9PigpPT57Y29uc3QgZWw9QWEuc2hhcGUsdGw9RmEuc2l6ZSxubD1lbC5zbGljZSgwLEVhKSxzbD1ubC5sZW5ndGgscmw9ZWwuc2xpY2UoVGEsZWwubGVuZ3RoKS5zbGljZSgxKSxvbD1ybC5sZW5ndGgsYWw9YXJyYXlSYW5nZSgwLHNsKSxsbD1hcnJheVJhbmdlKHNsKzEsc2wrMStvbCksaWw9YXJyYXlDb25jYXQoW25sLFt0bF0scmxdKSxjbD1yZXNoYXBlJDQoTGEsaWwpLHVsPXJlc2hhcGUkNChGYSxbdGxdKSxkbD1hcnJheUNvbmNhdChbW3NsXSxhbCxsbF0pLGhsPXRyYW5zcG9zZSQzKGNsLGRsKTtsZXQgcGw9dW5zb3J0ZWRTZWdtZW50U3VtJDMoaGwsdWwsQWEuc2hhcGVbRWFdKTtjb25zdCBmbD1nZXRVbmRvQXhlc1Blcm11dGF0aW9uJDEoZGwpO3JldHVybiBwbD10cmFuc3Bvc2UkMyhwbCxmbCkscGx9O2lmKHdhPT09MSl7Y29uc3QgQWE9YmEuc2hhcGVbMF0sRmE9YmEuc3BsaXQoQWEsMCk7cmV0dXJue3g6KCk9PnN0YWNrKEZhLm1hcCgodGwsbmwpPT5rYSh0bCxTYS5zbGljZShubCwxKSxoYS5zbGljZShubCwxKSkoKSkpLnJlc2hhcGUoYmEuc2hhcGUpLGluZGljZXM6KCk9PlNhfX1lbHNlIHJldHVybnt4OmthKGJhLFNhLGhhKSxpbmRpY2VzOigpPT5TYX19fTtmdW5jdGlvbiBhcnJheVJhbmdlKGhhLGFhKXtjb25zdCB4YT1bXTtmb3IobGV0IGJhPWhhO2JhPGFhOysrYmEpeGEucHVzaChiYSk7cmV0dXJuIHhhfWZ1bmN0aW9uIGFycmF5Q29uY2F0KGhhKXtjb25zdCBhYT1bXTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoOysreGEpZm9yKGxldCBiYT0wO2JhPGhhW3hhXS5sZW5ndGg7KytiYSlhYS5wdXNoKGhhW3hhXVtiYV0pO3JldHVybiBhYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBncmVhdGVyRXF1YWxHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkdyZWF0ZXJFcXVhbCQxLGlucHV0c1RvU2F2ZTpbImEiLCJiIl0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhLGJhXT1hYTtyZXR1cm57YTooKT0+emVyb3NMaWtlJDQoeGEpLGI6KCk9Pnplcm9zTGlrZSQ0KGJhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBpZGVudGl0eUdyYWRDb25maWc9e2tlcm5lbE5hbWU6SWRlbnRpdHkkMixncmFkRnVuYzpoYT0+KHt4OigpPT5jYXN0JDUoaGEsImZsb2F0MzIiKX0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBpc0Zpbml0ZUdyYWRDb25maWc9e2tlcm5lbE5hbWU6SXNGaW5pdGUkMSxncmFkRnVuYzpoYT0+KHt4OigpPT56ZXJvc0xpa2UkNChoYSl9KX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgaXNJbmZHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOklzSW5mJDEsZ3JhZEZ1bmM6aGE9Pih7eDooKT0+emVyb3NMaWtlJDQoaGEpfSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGlzTmFuR3JhZENvbmZpZz17a2VybmVsTmFtZTpJc05hbiQxLGdyYWRGdW5jOmhhPT4oe3g6KCk9Pnplcm9zTGlrZSQ0KGhhKX0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsZWFreVJlbHVHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkxlYWt5UmVsdSQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3RbYmFdPWFhLHthbHBoYTpTYX09eGEsVGE9Z3JlYXRlciQzKGJhLDApO3JldHVybnt4OigpPT53aGVyZShUYSxoYSxtdWwkMShoYSxTYSkpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGxvZzFwR3JhZENvbmZpZz17a2VybmVsTmFtZTpMb2cxcCQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybnt4OigpPT5kaXYkMihoYSxhZGQkMyh4YSwxKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbG9nR3JhZENvbmZpZz17a2VybmVsTmFtZTpMb2ckMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+ZGl2JDIoaGEsY2FzdCQ1KHhhLCJmbG9hdDMyIikpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGxvZ1NvZnRtYXhHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkxvZ1NvZnRtYXgkMSxpbnB1dHNUb1NhdmU6W10sb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYV09YWEse2F4aXM6U2F9PXhhO3JldHVybntsb2dpdHM6KCk9Pntjb25zdCB3YT1leHAkMyhiYSk7cmV0dXJuIHN1YiQ0KGhhLG11bCQxKHN1bSQ1KGhhLFNhLCEwKSx3YSkpfX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsb2NhbFJlc3BvbnNlTm9ybWFsaXphdGlvbkJhY2twcm9wXyhoYSxhYSx4YSxiYT01LFNhPTEsVGE9MSx3YT0uNSl7Y29uc3QgRWE9e3g6aGEseTphYSxkeTp4YX0sa2E9e2RlcHRoUmFkaXVzOmJhLGJpYXM6U2EsYWxwaGE6VGEsYmV0YTp3YX07cmV0dXJuIEVOR0lORSQxLnJ1bktlcm5lbChMUk5HcmFkJDEsRWEsa2EpfWNvbnN0IGxvY2FsUmVzcG9uc2VOb3JtYWxpemF0aW9uQmFja3Byb3A9b3AkMSh7bG9jYWxSZXNwb25zZU5vcm1hbGl6YXRpb25CYWNrcHJvcF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBscm5HcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkxSTiQxLGlucHV0c1RvU2F2ZTpbIngiXSxvdXRwdXRzVG9TYXZlOlshMF0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhLFNhXT1hYSx7ZGVwdGhSYWRpdXM6VGEsYmlhczp3YSxhbHBoYTpFYSxiZXRhOmthfT14YTtyZXR1cm57eDooKT0+bG9jYWxSZXNwb25zZU5vcm1hbGl6YXRpb25CYWNrcHJvcChiYSxTYSxoYSxUYSx3YSxFYSxrYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ3JhZEZvck1pbkFuZE1heChoYSxhYSx4YSxiYSl7cmV0dXJuIGFhLnJhbms8eGEucmFuayYmKGFhPXJlc2hhcGUkNChhYSxleHBhbmRTaGFwZVRvS2VlcERpbSQxKGFhLnNoYXBlLGJhKSkpLGhhLnJhbms8eGEucmFuayYmKGhhPXJlc2hhcGUkNChoYSxleHBhbmRTaGFwZVRvS2VlcERpbSQxKGhhLnNoYXBlLGJhKSkpLHt4OigpPT5tdWwkMShoYSxjYXN0JDUoZXF1YWwkMyh4YSxhYSksaGEuZHR5cGUpKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWF4R3JhZENvbmZpZz17a2VybmVsTmFtZTpNYXgkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdCBiYT14YSx7cmVkdWN0aW9uSW5kaWNlczpTYX09YmEsVGE9YWFbMF0sd2E9YWFbMV0sRWE9cGFyc2VBeGlzUGFyYW0kMShTYSxUYS5zaGFwZSksa2E9Z3JhZEZvck1pbkFuZE1heChoYSx3YSxUYSxFYSk7cmV0dXJue3g6KCk9PmthLngoKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBtYXhpbXVtR3JhZENvbmZpZz17a2VybmVsTmFtZTpNYXhpbXVtJDIsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhO3JldHVybnthOigpPT5tdWwkMShoYSxjYXN0JDUoZ3JlYXRlckVxdWFsJDMoeGEsYmEpLCJmbG9hdDMyIikpLGI6KCk9Pm11bCQxKGhhLGNhc3QkNShsZXNzJDMoeGEsYmEpLCJmbG9hdDMyIikpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2wzZEdyYWRfKGhhLGFhLHhhLGJhLFNhLFRhLHdhKXtjb25zdCBFYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiZHkiLCJtYXhQb29sM2RHcmFkIiksa2E9Y29udmVydFRvVGVuc29yJDEoYWEsImlucHV0IiwibWF4UG9vbDNkR3JhZCIpLEFhPWNvbnZlcnRUb1RlbnNvciQxKHhhLCJvdXRwdXQiLCJtYXhQb29sM2RHcmFkIik7bGV0IEZhPUVhLExhPWthLGVsPUFhLHRsPSExO2thLnJhbms9PT00JiYodGw9ITAsRmE9cmVzaGFwZSQ0KEVhLFsxLEVhLnNoYXBlWzBdLEVhLnNoYXBlWzFdLEVhLnNoYXBlWzJdLEVhLnNoYXBlWzNdXSksTGE9cmVzaGFwZSQ0KGthLFsxLGthLnNoYXBlWzBdLGthLnNoYXBlWzFdLGthLnNoYXBlWzJdLGthLnNoYXBlWzNdXSksZWw9cmVzaGFwZSQ0KEFhLFsxLEFhLnNoYXBlWzBdLEFhLnNoYXBlWzFdLEFhLnNoYXBlWzJdLEFhLnNoYXBlWzNdXSkpLGFzc2VydCQyKEZhLnJhbms9PT01LCgpPT5gRXJyb3IgaW4gbWF4UG9vbDNkR3JhZDogZHkgbXVzdCBiZSByYW5rIDUgYnV0IGdvdCByYW5rICR7RmEucmFua30uYCksYXNzZXJ0JDIoTGEucmFuaz09PTUsKCk9PmBFcnJvciBpbiBtYXhQb29sM2RHcmFkOiBpbnB1dCBtdXN0IGJlIHJhbmsgNSBidXQgZ290IHJhbmsgJHtMYS5yYW5rfS5gKSxhc3NlcnQkMihlbC5yYW5rPT09NSwoKT0+YEVycm9yIGluIG1heFBvb2wzZEdyYWQ6IG91dHB1dCBtdXN0IGJlIHJhbmsgNSBidXQgZ290IHJhbmsgJHtlbC5yYW5rfS5gKSxjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlJDEoIm1heFBvb2wzZEdyYWQiLFRhLHdhKTtjb25zdCBubD17ZHk6RmEsaW5wdXQ6TGEsb3V0cHV0OmVsfSxzbD17ZmlsdGVyU2l6ZTpiYSxzdHJpZGVzOlNhLHBhZDpUYSxkaW1Sb3VuZGluZ01vZGU6d2F9LHJsPUVOR0lORSQxLnJ1bktlcm5lbChNYXhQb29sM0RHcmFkJDEsbmwsc2wpO3JldHVybiB0bD9yZXNoYXBlJDQocmwsW3JsLnNoYXBlWzFdLHJsLnNoYXBlWzJdLHJsLnNoYXBlWzNdLHJsLnNoYXBlWzRdXSk6cmx9Y29uc3QgbWF4UG9vbDNkR3JhZD1vcCQxKHttYXhQb29sM2RHcmFkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG1heFBvb2wzREdyYWRDb25maWckMz17a2VybmVsTmFtZTpNYXhQb29sM0QkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYSxTYV09YWEse2ZpbHRlclNpemU6VGEsc3RyaWRlczp3YSxwYWQ6RWEsZGltUm91bmRpbmdNb2RlOmthfT14YTtyZXR1cm57eDooKT0+bWF4UG9vbDNkR3JhZChoYSxiYSxTYSxUYSx3YSxFYSxrYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4UG9vbEdyYWRfKGhhLGFhLHhhLGJhLFNhLFRhLHdhKXtjb25zdCBFYT1jb252ZXJ0VG9UZW5zb3IkMShoYSwiZHkiLCJtYXhQb29sR3JhZCIpLGthPWNvbnZlcnRUb1RlbnNvciQxKGFhLCJpbnB1dCIsIm1heFBvb2xHcmFkIiksQWE9Y29udmVydFRvVGVuc29yJDEoeGEsIm91dHB1dCIsIm1heFBvb2xHcmFkIik7YXNzZXJ0JDIoa2EucmFuaz09PUVhLnJhbmssKCk9PmBSYW5rIG9mIGlucHV0ICgke2thLnJhbmt9KSBkb2VzIG5vdCBtYXRjaCByYW5rIG9mIGR5ICgke0VhLnJhbmt9KWApLGFzc2VydCQyKEVhLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gbWF4UG9vbEdyYWQ6IGR5IG11c3QgYmUgcmFuayA0IGJ1dCBnb3QgcmFuayAke0VhLnJhbmt9LmApLGFzc2VydCQyKGthLnJhbms9PT00LCgpPT5gRXJyb3IgaW4gbWF4UG9vbEdyYWQ6IGlucHV0IG11c3QgYmUgcmFuayA0IGJ1dCBnb3QgcmFuayAke2thLnJhbmt9LmApLGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGUkMSgibWF4UG9vbEdyYWQiLFRhLHdhKTtjb25zdCBGYT17ZHk6RWEsaW5wdXQ6a2Esb3V0cHV0OkFhfSxMYT17ZmlsdGVyU2l6ZTpiYSxzdHJpZGVzOlNhLHBhZDpUYSxkaW1Sb3VuZGluZ01vZGU6d2F9O3JldHVybiBFTkdJTkUkMS5ydW5LZXJuZWwoTWF4UG9vbEdyYWQkMSxGYSxMYSl9Y29uc3QgbWF4UG9vbEdyYWQkMz1vcCQxKHttYXhQb29sR3JhZF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBtYXhQb29sR3JhZENvbmZpZyQzPXtrZXJuZWxOYW1lOk1heFBvb2wkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYSxTYV09YWEse2ZpbHRlclNpemU6VGEsc3RyaWRlczp3YSxwYWQ6RWF9PXhhO3JldHVybnt4OigpPT5tYXhQb29sR3JhZCQzKGhhLGJhLFNhLFRhLHdhLEVhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBtZWFuR3JhZENvbmZpZz17a2VybmVsTmFtZTpNZWFuJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYV09YWEse2F4aXM6U2F9PXhhLFRhPXBhcnNlQXhpc1BhcmFtJDEoU2EsYmEuc2hhcGUpLEVhPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShiYS5zaGFwZSxUYSlbMV0sa2E9c2l6ZUZyb21TaGFwZSQxKEVhKTtyZXR1cm57eDooKT0+e2NvbnN0IEZhPWJhLnNoYXBlLnNsaWNlKCk7VGEuZm9yRWFjaCh0bD0+e0ZhW3RsXT0xfSk7Y29uc3QgTGE9cmVzaGFwZSQ0KGhhLEZhKTtyZXR1cm4gZGl2JDIobXVsJDEoTGEsb25lcyQxKGJhLnNoYXBlLCJmbG9hdDMyIikpLGthKX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWluR3JhZENvbmZpZz17a2VybmVsTmFtZTpNaW4kMSxpbnB1dHNUb1NhdmU6WyJ4Il0sb3V0cHV0c1RvU2F2ZTpbITBdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdCBiYT14YSx7YXhpczpTYX09YmEsW1RhLHdhXT1hYSxFYT1wYXJzZUF4aXNQYXJhbSQxKFNhLFRhLnNoYXBlKSxrYT1ncmFkRm9yTWluQW5kTWF4KGhhLHdhLFRhLEVhKTtyZXR1cm57eDooKT0+a2EueCgpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG1pbmltdW1HcmFkQ29uZmlnPXtrZXJuZWxOYW1lOk1pbmltdW0kMixpbnB1dHNUb1NhdmU6WyJhIiwiYiJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YSxiYV09YWE7cmV0dXJue2E6KCk9Pm11bCQxKGhhLGNhc3QkNShsZXNzRXF1YWwkMyh4YSxiYSksImZsb2F0MzIiKSksYjooKT0+bXVsJDEoaGEsY2FzdCQ1KGdyZWF0ZXIkMyh4YSxiYSksImZsb2F0MzIiKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWlycm9yUGFkR3JhZENvbmZpZz17a2VybmVsTmFtZTpNaXJyb3JQYWQkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0IGJhPWFhWzBdLHtwYWRkaW5nczpTYX09eGEsVGE9U2EubWFwKHdhPT53YVswXSk7cmV0dXJue3g6KCk9PnNsaWNlJDMoaGEsVGEsYmEuc2hhcGUpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG1vZEdyYWRDb25maWc9e2tlcm5lbE5hbWU6TW9kJDEsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhLFNhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO3JldHVybnthOigpPT57Y29uc3QgRWE9Z2V0UmVkdWN0aW9uQXhlcyQxKHhhLnNoYXBlLFNhKTtyZXR1cm4gRWEubGVuZ3RoPjA/cmVzaGFwZSQ0KHN1bSQ1KGhhLEVhKSx4YS5zaGFwZSk6aGF9LGI6KCk9Pntjb25zdCBFYT1tdWwkMShoYSxuZWckMyhmbG9vciQzKGRpdiQyKHhhLGJhKSkpKSxrYT1nZXRSZWR1Y3Rpb25BeGVzJDEoYmEuc2hhcGUsU2EpO3JldHVybiBrYS5sZW5ndGg+MD9yZXNoYXBlJDQoc3VtJDUoRWEsa2EpLGJhLnNoYXBlKTpFYX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbXVsdGlwbHlHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOk11bHRpcGx5JDIsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhLFNhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO3JldHVybnthOigpPT57Y29uc3QgRWE9bXVsJDEoaGEsY2FzdCQ1KGJhLCJmbG9hdDMyIikpLGthPWdldFJlZHVjdGlvbkF4ZXMkMSh4YS5zaGFwZSxTYSk7cmV0dXJuIGthLmxlbmd0aD4wP3Jlc2hhcGUkNChzdW0kNShFYSxrYSkseGEuc2hhcGUpOkVhfSxiOigpPT57Y29uc3QgRWE9bXVsJDEoaGEsY2FzdCQ1KHhhLCJmbG9hdDMyIikpLGthPWdldFJlZHVjdGlvbkF4ZXMkMShiYS5zaGFwZSxTYSk7cmV0dXJuIGthLmxlbmd0aD4wP3Jlc2hhcGUkNChzdW0kNShFYSxrYSksYmEuc2hhcGUpOkVhfX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBuZWdHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOk5lZyQxLGdyYWRGdW5jOmhhPT4oe3g6KCk9Pm5lZyQzKGhhKX0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBvbmVIb3RHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOk9uZUhvdCQxLGlucHV0c1RvU2F2ZTpbImluZGljZXMiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3QgeGE9YWFbMF07cmV0dXJue2luZGljZXM6KCk9Pnplcm9zJDIoeGEuc2hhcGUsImZsb2F0MzIiKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBvbmVzTGlrZUdyYWRDb25maWc9e2tlcm5lbE5hbWU6T25lc0xpa2UkMSxncmFkRnVuYzpoYT0+KHt4OigpPT56ZXJvc0xpa2UkNChoYSl9KX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcGFja0dyYWRDb25maWc9e2tlcm5lbE5hbWU6UGFjayQxLHNhdmVBbGxJbnB1dHM6ITAsZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0e2F4aXM6YmF9PXhhO3JldHVybiB1bnN0YWNrKGhhLGJhKS5tYXAoVGE9PigpPT5UYSl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBwYWRWMkdyYWRDb25maWc9e2tlcm5lbE5hbWU6UGFkVjIkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0IGJhPWFhWzBdLHtwYWRkaW5nczpTYX09eGEsVGE9U2EubWFwKHdhPT53YVswXSk7cmV0dXJue3g6KCk9PnNsaWNlJDMoaGEsVGEsYmEuc2hhcGUpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHBvd0dyYWRDb25maWc9e2tlcm5lbE5hbWU6UG93JDEsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxvdXRwdXRzVG9TYXZlOlshMF0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhLGJhLFNhXT1hYSxUYT14YSx3YT1iYSxFYT1hc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKFRhLnNoYXBlLHdhLnNoYXBlKTtyZXR1cm57YTooKT0+e2NvbnN0IEZhPWNhc3QkNSh3YSwiZmxvYXQzMiIpO2xldCBMYT1tdWwkMShoYSxtdWwkMShGYSxwb3ckNChUYSxzdWIkNChGYSxzY2FsYXIkMSgxKSkpKSk7Y29uc3QgZWw9Z2V0UmVkdWN0aW9uQXhlcyQxKFRhLnNoYXBlLEVhKTtyZXR1cm4gZWwubGVuZ3RoPjAmJihMYT1zdW0kNShMYSxlbCkpLHJlc2hhcGUkNChMYSxUYS5zaGFwZSl9LGI6KCk9Pntjb25zdCBGYT1ncmVhdGVyJDMoVGEsMCksTGE9d2hlcmUoRmEsbG9nJDQoVGEpLHplcm9zTGlrZSQ0KFRhKSk7bGV0IGVsPW11bCQxKGhhLG11bCQxKFNhLExhKSk7Y29uc3QgdGw9Z2V0UmVkdWN0aW9uQXhlcyQxKHdhLnNoYXBlLEVhKTtyZXR1cm4gdGwubGVuZ3RoPjAmJihlbD1zdW0kNShlbCx0bCkpLHJlc2hhcGUkNChlbCx3YS5zaGFwZSl9fX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHByZWx1R3JhZENvbmZpZz17a2VybmVsTmFtZTpQcmVsdSQxLGlucHV0c1RvU2F2ZTpbIngiLCJhbHBoYSJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YSxiYV09YWEsU2E9Z3JlYXRlciQzKHhhLDApO3JldHVybnt4OigpPT53aGVyZShTYSxoYSxtdWwkMShoYSxiYSkpLGFscGhhOigpPT57bGV0IFRhPXdoZXJlKFNhLHplcm9zTGlrZSQ0KGhhKSxtdWwkMShoYSx4YSkpO2NvbnN0IHdhPWdldFJlZHVjdGlvbkF4ZXMkMShiYS5zaGFwZSxoYS5zaGFwZSk7cmV0dXJuIHdhLmxlbmd0aD4wJiYoVGE9c3VtJDUoVGEsd2EpKSxyZXNoYXBlJDQoVGEsYmEuc2hhcGUpfX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwcm9kR3JhZEZuXyhoYSxhYSx4YSl7Y29uc3QgYmE9aGEuc2hhcGUuc2xpY2UoKTtiYVt4YV09MTtjb25zdCBTYT1yZXNoYXBlJDQoYWEsYmEpLFRhPWN1bXByb2QkMyhoYSx4YSwhMCwhMSksd2E9Y3VtcHJvZCQzKGhhLHhhLCEwLCEwKSxFYT1tdWwkMShUYSx3YSk7cmV0dXJuIG11bCQxKFNhLEVhKX1mdW5jdGlvbiBwcm9kc0dyYWRGbl8oaGEsYWEseGEpe2NvbnN0IGJhPWhhLnNoYXBlLmxlbmd0aCxTYT1iYS14YS5sZW5ndGgsVGE9Z2V0QXhlc1Blcm11dGF0aW9uJDEoeGEsYmEpO2xldCB3YT1oYTtUYSE9bnVsbCYmKHdhPXRyYW5zcG9zZSQzKGhhLFRhKSk7Y29uc3QgRWE9d2Euc2hhcGUuc2xpY2UoKSxBYT1FYS5zcGxpY2UoYmEteGEubGVuZ3RoLHhhLmxlbmd0aCkucmVkdWNlKChlbCx0bCk9PmVsKnRsLDEpO0VhLnB1c2goQWEpO2NvbnN0IEZhPXdhLnJlc2hhcGUoRWEpO2xldCBMYT1wcm9kR3JhZEZuXyhGYSxhYSxTYSk7aWYoTGE9TGEucmVzaGFwZSh3YS5zaGFwZSksVGEhPW51bGwpe2NvbnN0IGVsPWdldFVuZG9BeGVzUGVybXV0YXRpb24kMShUYSk7TGE9dHJhbnNwb3NlJDMoTGEsZWwpfXJldHVybiBMYX1jb25zdCBwcm9kR3JhZENvbmZpZz17a2VybmVsTmFtZTpQcm9kJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYV09YWEse2F4aXM6U2F9PXhhO2xldCBUYT1bXTtyZXR1cm4gU2E9PW51bGw/VGE9YmEuc2hhcGUubWFwKCh3YSxFYSk9PkVhKTp0eXBlb2YgU2E9PSJudW1iZXIiP1RhPVtTYV06VGE9U2Ese3g6KCk9PnByb2RzR3JhZEZuXyhiYSxoYSxUYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZGl2R3JhZENvbmZpZz17a2VybmVsTmFtZTpSZWFsRGl2JDEsaW5wdXRzVG9TYXZlOlsiYSIsImIiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGEsYmFdPWFhLFNhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoeGEuc2hhcGUsYmEuc2hhcGUpO3JldHVybnthOigpPT57Y29uc3QgRWE9ZGl2JDIoaGEsY2FzdCQ1KGJhLCJmbG9hdDMyIikpLGthPWdldFJlZHVjdGlvbkF4ZXMkMSh4YS5zaGFwZSxTYSk7cmV0dXJuIGthLmxlbmd0aD4wP3Jlc2hhcGUkNChzdW0kNShFYSxrYSkseGEuc2hhcGUpOkVhfSxiOigpPT57bGV0IEVhPW11bCQxKGhhLGNhc3QkNSh4YSwiZmxvYXQzMiIpKTtjb25zdCBrYT1nZXRSZWR1Y3Rpb25BeGVzJDEoYmEuc2hhcGUsU2EpO2thLmxlbmd0aD4wJiYoRWE9cmVzaGFwZSQ0KHN1bSQ1KEVhLGthKSxiYS5zaGFwZSkpO2NvbnN0IEFhPXNxdWFyZSQ0KGJhKTtyZXR1cm4gbmVnJDMoZGl2JDIoRWEsY2FzdCQ1KEFhLCJmbG9hdDMyIikpKX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcmVjaXByb2NhbEdyYWRDb25maWc9e2tlcm5lbE5hbWU6UmVjaXByb2NhbCQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybnt4OigpPT5kaXYkMihoYSxuZWckMyhzcXVhcmUkNCh4YSkpKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCByZWx1NkdyYWRDb25maWc9e2tlcm5lbE5hbWU6UmVsdTYkMixpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYSxiYT1tdWwkMShsZXNzRXF1YWwkMyh4YSw2KSxzdGVwJDQoeGEpKTtyZXR1cm57eDooKT0+bXVsJDEoaGEsY2FzdCQ1KGJhLCJmbG9hdDMyIikpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJlbHVHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlJlbHUkMixpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoaGEsY2FzdCQ1KHN0ZXAkNCh4YSksImZsb2F0MzIiKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcmVzaGFwZUdyYWRDb25maWc9e2tlcm5lbE5hbWU6UmVzaGFwZSQyLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybnt4OigpPT5yZXNoYXBlJDQoaGEseGEuc2hhcGUpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJlc2l6ZUJpbGluZWFyR3JhZENvbmZpZyQzPXtrZXJuZWxOYW1lOlJlc2l6ZUJpbGluZWFyJDEsaW5wdXRzVG9TYXZlOlsiaW1hZ2VzIl0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhXT1hYSxTYT17ZHk6aGEsaW1hZ2VzOmJhfTtyZXR1cm57aW1hZ2VzOigpPT5FTkdJTkUkMS5ydW5LZXJuZWwoUmVzaXplQmlsaW5lYXJHcmFkJDEsU2EseGEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWRDb25maWckMz17a2VybmVsTmFtZTpSZXNpemVOZWFyZXN0TmVpZ2hib3IkMSxpbnB1dHNUb1NhdmU6WyJpbWFnZXMiXSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3RbYmFdPWFhLFNhPXtkeTpoYSxpbWFnZXM6YmF9O3JldHVybntpbWFnZXM6KCk9PkVOR0lORSQxLnJ1bktlcm5lbChSZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkJDEsU2EseGEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJldmVyc2VHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlJldmVyc2UkMSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3R7ZGltczpiYX09eGEsU2E9cGFyc2VBeGlzUGFyYW0kMShiYSxoYS5zaGFwZSk7cmV0dXJue3g6KCk9PnJldmVyc2UkMyhoYSxTYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgcm91bmRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlJvdW5kJDEsZ3JhZEZ1bmM6aGE9Pih7eDooKT0+emVyb3NMaWtlJDQoaGEpfSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJzcXJ0R3JhZENvbmZpZz17a2VybmVsTmFtZTpSc3FydCQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybnt4OigpPT5uZWckMyhkaXYkMihoYSxtdWwkMShwb3ckNCh4YSwxLjUpLDIpKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc2VsZWN0R3JhZENvbmZpZz17a2VybmVsTmFtZTpTZWxlY3QkMSxpbnB1dHNUb1NhdmU6WyJjb25kaXRpb24iXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybntjb25kaXRpb246KCk9PmNhc3QkNSh6ZXJvc0xpa2UkNCh4YSksImZsb2F0MzIiKSx0OigpPT5tdWwkMShoYSxjYXN0JDUoeGEsaGEuZHR5cGUpKSxlOigpPT5tdWwkMShoYSxjYXN0JDUobG9naWNhbE5vdCQzKHhhKSxoYS5kdHlwZSkpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNlbHVHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNlbHUkMixpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+e2NvbnN0IGJhPWdyZWF0ZXIkMyh4YSxzY2FsYXIkMSgwKSksU2E9c2NhbGFyJDEoU0VMVV9TQ0FMRUFMUEhBJDEpLFRhPXNjYWxhciQxKFNFTFVfU0NBTEUkMSksd2E9bXVsJDEoaGEsVGEpLEVhPW11bCQxKG11bCQxKGhhLFNhKSxleHAkMyhjYXN0JDUoeGEsImZsb2F0MzIiKSkpO3JldHVybiB3aGVyZShiYSx3YSxFYSl9fX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNpZ21vaWRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNpZ21vaWQkMixvdXRwdXRzVG9TYXZlOlshMF0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoaGEsbXVsJDEoeGEsc3ViJDQoc2NhbGFyJDEoMSkseGEpKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc2lnbkdyYWRDb25maWc9e2tlcm5lbE5hbWU6U2lnbiQxLGdyYWRGdW5jOmhhPT4oe3g6KCk9Pnplcm9zTGlrZSQ0KGhhKX0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzaW5HcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNpbiQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEpPT57Y29uc3RbeGFdPWFhO3JldHVybnt4OigpPT5tdWwkMShjb3MkMyhjYXN0JDUoeGEsImZsb2F0MzIiKSksaGEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNpbmhHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNpbmgkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoY29zaCQzKGNhc3QkNSh4YSwiZmxvYXQzMiIpKSxoYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc2xpY2VHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNsaWNlJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYV09YWEse2JlZ2luOlNhLHNpemU6VGF9PXhhLHdhPWJhLnNoYXBlLFtFYSxrYV09cGFyc2VTbGljZVBhcmFtcyQxKGJhLFNhLFRhKSxBYT1bXTtmb3IobGV0IEZhPTA7RmE8aGEucmFuaztGYSsrKUFhLnB1c2goW0VhW0ZhXSx3YVtGYV0tRWFbRmFdLWthW0ZhXV0pO3JldHVybnt4OigpPT5wYWQoaGEsQWEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNvZnRtYXhHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNvZnRtYXgkMyxvdXRwdXRzVG9TYXZlOlshMF0sZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0W2JhXT1hYSx7ZGltOlNhfT14YSxUYT0hMCx3YT1tdWwkMShoYSxiYSk7cmV0dXJue2xvZ2l0czooKT0+c3ViJDQod2EsbXVsJDEoc3VtJDUod2EsW1NhXSxUYSksYmEpKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzb2Z0cGx1c0dyYWRDb25maWc9e2tlcm5lbE5hbWU6U29mdHBsdXMkMixpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoaGEsc2lnbW9pZCQ0KHhhKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3BhY2VUb0JhdGNoTkRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNwYWNlVG9CYXRjaE5EJDEsZ3JhZEZ1bmM6KGhhLGFhLHhhKT0+e2NvbnN0e2Jsb2NrU2hhcGU6YmEscGFkZGluZ3M6U2F9PXhhO3JldHVybnt4OigpPT5iYXRjaFRvU3BhY2VORCQzKGhhLGJhLFNhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzcGxpdFZHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNwbGl0ViQxLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdHtheGlzOmJhfT14YTtyZXR1cm57eDooKT0+Y29uY2F0JDMoaGEsYmEpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNxcnRHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlNxcnQkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+ZGl2JDIoaGEsbXVsJDEoc3FydCQ0KGNhc3QkNSh4YSwiZmxvYXQzMiIpKSwyKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3F1YXJlR3JhZENvbmZpZz17a2VybmVsTmFtZTpTcXVhcmUkMSxpbnB1dHNUb1NhdmU6WyJ4Il0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoaGEsbXVsJDEoY2FzdCQ1KHhhLCJmbG9hdDMyIiksMikpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNxdWFyZWREaWZmZXJlbmNlR3JhZENvbmZpZz17a2VybmVsTmFtZTpTcXVhcmVkRGlmZmVyZW5jZSQxLGlucHV0c1RvU2F2ZTpbImEiLCJiIl0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhLGJhXT1hYSxTYT1zY2FsYXIkMSgyKTtyZXR1cm57YTooKT0+bXVsJDEoaGEsbXVsJDEoU2Esc3ViJDQoeGEsYmEpKSksYjooKT0+bXVsJDEoaGEsbXVsJDEoU2Esc3ViJDQoYmEseGEpKSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3RlcEdyYWRDb25maWc9e2tlcm5lbE5hbWU6U3RlcCQxLGdyYWRGdW5jOmhhPT4oe3g6KCk9Pnplcm9zTGlrZSQ0KGhhKX0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzdWJHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlN1YiQxLGlucHV0c1RvU2F2ZTpbImEiLCJiIl0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhLGJhXT1hYSxTYT1hc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLnNoYXBlLGJhLnNoYXBlKTtyZXR1cm57YTooKT0+e2xldCBFYT1oYTtjb25zdCBrYT1nZXRSZWR1Y3Rpb25BeGVzJDEoeGEuc2hhcGUsU2EpO3JldHVybiBrYS5sZW5ndGg+MCYmKEVhPXN1bSQ1KEVhLGthKSkscmVzaGFwZSQ0KEVhLHhhLnNoYXBlKX0sYjooKT0+e2xldCBFYT1oYTtjb25zdCBrYT1nZXRSZWR1Y3Rpb25BeGVzJDEoYmEuc2hhcGUsU2EpO3JldHVybiBrYS5sZW5ndGg+MCYmKEVhPXN1bSQ1KEVhLGthKSkscmVzaGFwZSQ0KG5lZyQzKEVhKSxiYS5zaGFwZSl9fX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHN1bUdyYWRDb25maWc9e2tlcm5lbE5hbWU6U3VtJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdFtiYV09YWEsU2E9YmEuc2hhcGUuc2xpY2UoKSx7YXhpczpUYX09eGE7cGFyc2VBeGlzUGFyYW0kMShUYSxiYS5zaGFwZSkuZm9yRWFjaChBYT0+e1NhW0FhXT0xfSk7Y29uc3QgRWE9cmVzaGFwZSQ0KGhhLFNhKSxrYT1tdWwkMShFYSxvbmVzJDEoYmEuc2hhcGUsImZsb2F0MzIiKSk7cmV0dXJue3g6KCk9PmthfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHRhbkdyYWRDb25maWc9e2tlcm5lbE5hbWU6VGFuJDEsaW5wdXRzVG9TYXZlOlsieCJdLGdyYWRGdW5jOihoYSxhYSk9Pntjb25zdFt4YV09YWE7cmV0dXJue3g6KCk9PmRpdiQyKGhhLHNxdWFyZSQ0KGNvcyQzKHhhKSkpfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHRhbmhHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlRhbmgkMixvdXRwdXRzVG9TYXZlOlshMF0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+bXVsJDEoc3ViJDQoc2NhbGFyJDEoMSksc3F1YXJlJDQoeGEpKSxoYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgdGlsZUdyYWRDb25maWc9e2tlcm5lbE5hbWU6VGlsZSQxLGlucHV0c1RvU2F2ZTpbIngiXSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3RbYmFdPWFhLHtyZXBzOlNhfT14YTtyZXR1cm57eDooKT0+e2xldCB3YT16ZXJvc0xpa2UkNChiYSk7aWYoYmEucmFuaz09PTEpZm9yKGxldCBFYT0wO0VhPFNhWzBdOysrRWEpd2E9YWRkJDMod2Esc2xpY2UkMyhoYSxbRWEqYmEuc2hhcGVbMF1dLFtiYS5zaGFwZVswXV0pKTtlbHNlIGlmKGJhLnJhbms9PT0yKWZvcihsZXQgRWE9MDtFYTxTYVswXTsrK0VhKWZvcihsZXQga2E9MDtrYTxTYVsxXTsrK2thKXdhPWFkZCQzKHdhLHNsaWNlJDMoaGEsW0VhKmJhLnNoYXBlWzBdLGthKmJhLnNoYXBlWzFdXSxbYmEuc2hhcGVbMF0sYmEuc2hhcGVbMV1dKSk7ZWxzZSBpZihiYS5yYW5rPT09Mylmb3IobGV0IEVhPTA7RWE8U2FbMF07KytFYSlmb3IobGV0IGthPTA7a2E8U2FbMV07KytrYSlmb3IobGV0IEFhPTA7QWE8U2FbMl07KytBYSl3YT1hZGQkMyh3YSxzbGljZSQzKGhhLFtFYSpiYS5zaGFwZVswXSxrYSpiYS5zaGFwZVsxXSxBYSpiYS5zaGFwZVsyXV0sW2JhLnNoYXBlWzBdLGJhLnNoYXBlWzFdLGJhLnNoYXBlWzJdXSkpO2Vsc2UgaWYoYmEucmFuaz09PTQpZm9yKGxldCBFYT0wO0VhPFNhWzBdOysrRWEpZm9yKGxldCBrYT0wO2thPFNhWzFdOysra2EpZm9yKGxldCBBYT0wO0FhPFNhWzJdOysrQWEpZm9yKGxldCBGYT0wO0ZhPFNhWzNdOysrRmEpd2E9YWRkJDMod2Esc2xpY2UkMyhoYSxbRWEqYmEuc2hhcGVbMF0sa2EqYmEuc2hhcGVbMV0sQWEqYmEuc2hhcGVbMl0sRmEqYmEuc2hhcGVbM11dLFtiYS5zaGFwZVswXSxiYS5zaGFwZVsxXSxiYS5zaGFwZVsyXSxiYS5zaGFwZVszXV0pKTtlbHNlIHRocm93IG5ldyBFcnJvcihgR3JhZGllbnQgZm9yIHRpbGUgb3BlcmF0aW9uIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgcmFuay0ke2JhLnJhbmt9IHRlbnNvcnMgeWV0LmApO3JldHVybiB3YX19fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgdHJhbnNwb3NlR3JhZENvbmZpZz17a2VybmVsTmFtZTpUcmFuc3Bvc2UkMSxncmFkRnVuYzooaGEsYWEseGEpPT57Y29uc3QgYmE9eGEse3Blcm06U2F9PWJhLFRhPWdldFVuZG9BeGVzUGVybXV0YXRpb24kMShTYSk7cmV0dXJue3g6KCk9PnRyYW5zcG9zZSQzKGhhLFRhKX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCB1bnBhY2tHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOlVucGFjayQxLGdyYWRGdW5jOihoYSxhYSx4YSk9Pntjb25zdCBiYT14YSx7YXhpczpTYX09YmE7cmV0dXJue3ZhbHVlOigpPT5zdGFjayhoYSxTYSl9fX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgdW5zb3J0ZWRTZWdtZW50U3VtR3JhZENvbmZpZz17a2VybmVsTmFtZTpVbnNvcnRlZFNlZ21lbnRTdW0kMSxpbnB1dHNUb1NhdmU6WyJzZWdtZW50SWRzIl0sZ3JhZEZ1bmM6KGhhLGFhKT0+e2NvbnN0W3hhXT1hYTtyZXR1cm57eDooKT0+Z2F0aGVyRHJvcE5lZ2F0aXZlcyhoYSx4YSl9fX07ZnVuY3Rpb24gZ2F0aGVyRHJvcE5lZ2F0aXZlcyhoYSxhYSl7Y29uc3QgeGE9bWF4aW11bSQ0KGFhLHplcm9zTGlrZSQ0KGFhKSksYmE9Z2F0aGVyJDEoaGEseGEpO2xldCBTYT1ncmVhdGVyRXF1YWwkMyhhYSxzY2FsYXIkMSgwLCJpbnQzMiIpKTtjb25zdCBUYT1iYS5yYW5rLVNhLnJhbms7Zm9yKGxldCBFYT0wO0VhPFRhOysrRWEpU2E9ZXhwYW5kRGltcyQ0KFNhLEVhKzEpO1NhPWxvZ2ljYWxBbmQkMyhTYSxvbmVzJDEoYmEuc2hhcGUsImJvb2wiKSk7Y29uc3Qgd2E9emVyb3NMaWtlJDQoYmEpO3JldHVybiB3aGVyZShTYSxiYSx3YSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgemVyb3NMaWtlR3JhZENvbmZpZz17a2VybmVsTmFtZTpaZXJvc0xpa2UkMSxncmFkRnVuYzpoYT0+KHt4OigpPT56ZXJvc0xpa2UkNChoYSl9KX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZ3JhZENvbmZpZ3M9W2Fic0dyYWRDb25maWcsYWNvc0dyYWRDb25maWcsYWNvc2hHcmFkQ29uZmlnLGFkZEdyYWRDb25maWcsYWRkTkdyYWRDb25maWcsYXJnTWF4R3JhZENvbmZpZyxhcmdNaW5HcmFkQ29uZmlnLGFzaW5HcmFkQ29uZmlnLGFzaW5oR3JhZENvbmZpZyxhdGFuMkdyYWRDb25maWcsYXRhbkdyYWRDb25maWcsYXRhbmhHcmFkQ29uZmlnLGF2Z1Bvb2wzREdyYWRDb25maWckMyxhdmdQb29sR3JhZENvbmZpZyQzLGJhdGNoTWF0TXVsR3JhZENvbmZpZyxiYXRjaFRvU3BhY2VOREdyYWRDb25maWcsYnJvYWRjYXN0VG9HcmFkQ29uZmlnLGNhc3RHcmFkQ29uZmlnLGNlaWxHcmFkQ29uZmlnLGNsaXBCeVZhbHVlR3JhZENvbmZpZyxjb21wbGV4QWJzR3JhZENvbmZpZyxjb25jYXRHcmFkQ29uZmlnLGNvbnYyREJhY2twcm9wSW5wdXRHcmFkQ29uZmlnLGNvbnYyREdyYWRDb25maWcsY29udjNER3JhZENvbmZpZyxjb3NHcmFkQ29uZmlnLGNvc2hHcmFkQ29uZmlnLGN1bXN1bUdyYWRDb25maWcsZGVwdGh3aXNlQ29udjJkTmF0aXZlR3JhZENvbmZpZyxkaWxhdGlvbjJkR3JhZENvbmZpZyxkaXZHcmFkQ29uZmlnLGVsdUdyYWRDb25maWckMyxlcmZHcmFkQ29uZmlnLGV4cEdyYWRDb25maWcsZXhwYW5kRGltc0dyYWRDb25maWcsZXhwbTFHcmFkQ29uZmlnLGZsb29yRGl2R3JhZENvbmZpZyxmbG9vckdyYWRDb25maWcsZnVzZWRCYXRjaE5vcm1HcmFkQ29uZmlnLGdhdGhlckdyYWRDb25maWcsZ3JlYXRlckVxdWFsR3JhZENvbmZpZyxpZGVudGl0eUdyYWRDb25maWcsaXNGaW5pdGVHcmFkQ29uZmlnLGlzSW5mR3JhZENvbmZpZyxpc05hbkdyYWRDb25maWcsbGVha3lSZWx1R3JhZENvbmZpZyxsb2cxcEdyYWRDb25maWcsbG9nR3JhZENvbmZpZyxsb2dTb2Z0bWF4R3JhZENvbmZpZyxscm5HcmFkQ29uZmlnLG1heEdyYWRDb25maWcsbWF4R3JhZENvbmZpZyxtYXhpbXVtR3JhZENvbmZpZyxtYXhQb29sM0RHcmFkQ29uZmlnJDMsbWF4UG9vbEdyYWRDb25maWckMyxtZWFuR3JhZENvbmZpZyxtaW5HcmFkQ29uZmlnLG1pbmltdW1HcmFkQ29uZmlnLG1pcnJvclBhZEdyYWRDb25maWcsbW9kR3JhZENvbmZpZyxtdWx0aXBseUdyYWRDb25maWcsbmVnR3JhZENvbmZpZyxvbmVIb3RHcmFkQ29uZmlnLG9uZXNMaWtlR3JhZENvbmZpZyxwYWNrR3JhZENvbmZpZyxwYWRWMkdyYWRDb25maWcscGFkVjJHcmFkQ29uZmlnLHBvd0dyYWRDb25maWcscHJlbHVHcmFkQ29uZmlnLHByb2RHcmFkQ29uZmlnLHJlY2lwcm9jYWxHcmFkQ29uZmlnLHJlbHU2R3JhZENvbmZpZyxyZWx1R3JhZENvbmZpZyxyZXNoYXBlR3JhZENvbmZpZyxyZXNpemVCaWxpbmVhckdyYWRDb25maWckMyxyZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkQ29uZmlnJDMscmV2ZXJzZUdyYWRDb25maWcscm91bmRHcmFkQ29uZmlnLHJzcXJ0R3JhZENvbmZpZyxzZWxlY3RHcmFkQ29uZmlnLHNlbHVHcmFkQ29uZmlnLHNpZ21vaWRHcmFkQ29uZmlnLHNpZ25HcmFkQ29uZmlnLHNpbkdyYWRDb25maWcsc2luaEdyYWRDb25maWcsc2xpY2VHcmFkQ29uZmlnLHNvZnRtYXhHcmFkQ29uZmlnLHNvZnRwbHVzR3JhZENvbmZpZyxzcGFjZVRvQmF0Y2hOREdyYWRDb25maWcsc3BhY2VUb0JhdGNoTkRHcmFkQ29uZmlnLHNwbGl0VkdyYWRDb25maWcsc3BsaXRWR3JhZENvbmZpZyxzcXJ0R3JhZENvbmZpZyxzcXVhcmVkRGlmZmVyZW5jZUdyYWRDb25maWcsc3F1YXJlR3JhZENvbmZpZyxzdGVwR3JhZENvbmZpZyxzdWJHcmFkQ29uZmlnLHN1bUdyYWRDb25maWcsdGFuR3JhZENvbmZpZyx0YW5oR3JhZENvbmZpZyx0aWxlR3JhZENvbmZpZyx0cmFuc3Bvc2VHcmFkQ29uZmlnLHVucGFja0dyYWRDb25maWcsdW5zb3J0ZWRTZWdtZW50U3VtR3JhZENvbmZpZyx6ZXJvc0xpa2VHcmFkQ29uZmlnXTtmb3IoY29uc3QgaGEgb2YgZ3JhZENvbmZpZ3MpcmVnaXN0ZXJHcmFkaWVudChoYSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hYnM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxhYnMkNCh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hY29zPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYWNvcyQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmFjb3NoPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYWNvc2gkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGFkZCQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmFsbD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYWxsJDModGhpcyxoYSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuYW55PWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxhbnkkMyh0aGlzLGhhLGFhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hcmdNYXg9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGFyZ01heCQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmFyZ01pbj1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYXJnTWluJDModGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuYXNTY2FsYXI9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxhc3NlcnQkMih0aGlzLnNpemU9PT0xLCgpPT4iVGhlIGFycmF5IG11c3QgaGF2ZSBvbmx5IDEgZWxlbWVudC4iKSxyZXNoYXBlJDQodGhpcyxbXSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuYXNUeXBlPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjYXN0JDUodGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuYXMxRD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHJlc2hhcGUkNCh0aGlzLFt0aGlzLnNpemVdKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hczJEPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyZXNoYXBlJDQodGhpcyxbaGEsYWFdKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hczNEPWZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyZXNoYXBlJDQodGhpcyxbaGEsYWEseGFdKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hczREPWZ1bmN0aW9uKGhhLGFhLHhhLGJhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyZXNoYXBlJDQodGhpcyxbaGEsYWEseGEsYmFdKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hczVEPWZ1bmN0aW9uKGhhLGFhLHhhLGJhLFNhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyZXNoYXBlJDQodGhpcyxbaGEsYWEseGEsYmEsU2FdKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hc2luPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYXNpbiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmFzaW5oPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYXNpbmgkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hdGFuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYXRhbiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmF0YW4yPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxhdGFuMiQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmF0YW5oPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYXRhbmgkMyh0aGlzKX0sZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5hdmdQb29sPWZ1bmN0aW9uKGhhLGFhLHhhLGJhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxhdmdQb29sJDModGhpcyxoYSxhYSx4YSxiYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuYmF0Y2hUb1NwYWNlTkQ9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGJhdGNoVG9TcGFjZU5EJDModGhpcyxoYSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuYmF0Y2hOb3JtPWZ1bmN0aW9uKGhhLGFhLHhhLGJhLFNhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxiYXRjaE5vcm0kMyh0aGlzLGhhLGFhLHhhLGJhLFNhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5icm9hZGNhc3RUbz1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYnJvYWRjYXN0VG8kMSh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5jYXN0PWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjYXN0JDUodGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuY2VpbD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNlaWwkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5jbGlwQnlWYWx1ZT1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY2xpcEJ5VmFsdWUkMyh0aGlzLGhhLGFhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5jb25jYXQ9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGhhIGluc3RhbmNlb2YgVGVuc29yJDEmJihoYT1baGFdKSxjb25jYXQkMyhbdGhpcywuLi5oYV0sYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmNvbnYxZD1mdW5jdGlvbihoYSxhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY29udjFkKHRoaXMsaGEsYWEseGEsYmEsU2EsVGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmNvbnYyZFRyYW5zcG9zZT1mdW5jdGlvbihoYSxhYSx4YSxiYSxTYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY29udjJkVHJhbnNwb3NlKHRoaXMsaGEsYWEseGEsYmEsU2EpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmNvbnYyZD1mdW5jdGlvbihoYSxhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY29udjJkJDModGhpcyxoYSxhYSx4YSxiYSxTYSxUYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuY29zPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY29zJDModGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuY29zaD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNvc2gkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAnTGljZW5zZScpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAnQVMgSVMnIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5jdW1wcm9kPWZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjdW1wcm9kJDModGhpcyxoYSxhYSx4YSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuY3Vtc3VtPWZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjdW1zdW0kMyh0aGlzLGhhLGFhLHhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5kZXB0aFRvU3BhY2U9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGRlcHRoVG9TcGFjZSQzKHRoaXMsaGEsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmRlcHRod2lzZUNvbnYyZD1mdW5jdGlvbihoYSxhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZGVwdGh3aXNlQ29udjJkJDIodGhpcyxoYSxhYSx4YSxiYSxTYSxUYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuZGlsYXRpb24yZD1mdW5jdGlvbihoYSxhYSx4YSxiYSxTYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZGlsYXRpb24yZCh0aGlzLGhhLGFhLHhhLGJhLFNhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5kaXZOb05hbj1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZGl2Tm9OYW4odGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuZGl2PWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxkaXYkMih0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5kb3Q9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGRvdCQxKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmVsdT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGVsdSQ1KHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmVxdWFsPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxlcXVhbCQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmVyZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGVyZiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmV1Y2xpZGVhbk5vcm09ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGV1Y2xpZGVhbk5vcm0odGhpcyxoYSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuZXhwPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZXhwJDModGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuZXhwYW5kRGltcz1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZXhwYW5kRGltcyQ0KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmV4cG0xPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZXhwbTEkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5mZnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxmZnQkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5mbGF0dGVuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCkscmVzaGFwZSQ0KHRoaXMsW3RoaXMuc2l6ZV0pfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmZsb29yPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZmxvb3IkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5mbG9vckRpdj1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZmxvb3JEaXYkNCh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5nYXRoZXI9ZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGdhdGhlciQxKHRoaXMsaGEsYWEseGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmdyZWF0ZXJFcXVhbD1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZ3JlYXRlckVxdWFsJDModGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuZ3JlYXRlcj1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksZ3JlYXRlciQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmlmZnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxpZmZ0JDModGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuaXJmZnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxpcmZmdCh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5pc0Zpbml0ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGlzRmluaXRlJDQodGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuaXNJbmY9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxpc0luZiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmlzTmFOPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksaXNOYU4kNCh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5sZWFreVJlbHU9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGxlYWt5UmVsdSQ0KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmxlc3NFcXVhbD1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbGVzc0VxdWFsJDModGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubGVzcz1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbGVzcyQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmxvY2FsUmVzcG9uc2VOb3JtYWxpemF0aW9uPWZ1bmN0aW9uKGhhLGFhLHhhLGJhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxsb2NhbFJlc3BvbnNlTm9ybWFsaXphdGlvbih0aGlzLGhhLGFhLHhhLGJhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5sb2dTaWdtb2lkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbG9nU2lnbW9pZCh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5sb2dTb2Z0bWF4PWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxsb2dTb2Z0bWF4KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmxvZ1N1bUV4cD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbG9nU3VtRXhwKHRoaXMsaGEsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmxvZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGxvZyQ0KHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmxvZzFwPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbG9nMXAkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5sb2dpY2FsQW5kPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxsb2dpY2FsQW5kJDModGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubG9naWNhbE5vdD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGxvZ2ljYWxOb3QkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5sb2dpY2FsT3I9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGxvZ2ljYWxPciQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLmxvZ2ljYWxYb3I9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGxvZ2ljYWxYb3IodGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubWF0TXVsPWZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxtYXRNdWwkMSh0aGlzLGhhLGFhLHhhKX0sZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5tYXhQb29sPWZ1bmN0aW9uKGhhLGFhLHhhLGJhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxtYXhQb29sJDModGhpcyxoYSxhYSx4YSxiYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubWF4PWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxtYXgkNCh0aGlzLGhhLGFhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5tYXhpbXVtPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxtYXhpbXVtJDQodGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubWVhbj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbWVhbiQxKHRoaXMsaGEsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLm1pbj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbWluJDQodGhpcyxoYSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubWluaW11bT1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbWluaW11bSQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLm1pcnJvclBhZD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksbWlycm9yUGFkJDEodGhpcyxoYSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubW9kPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxtb2QkMyh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5tdWw9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLG11bCQxKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLm5lZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLG5lZyQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLm5vcm09ZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLG5vcm0odGhpcyxoYSxhYSx4YSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUubm90RXF1YWw9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLG5vdEVxdWFsJDModGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUub25lSG90PWZ1bmN0aW9uKGhhLGFhPTEseGE9MCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksb25lSG90JDModGhpcyxoYSxhYSx4YSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUub25lc0xpa2U9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxvbmVzTGlrZSQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnBhZD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCkscGFkKHRoaXMsaGEsYWEpfSxnZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnBvb2w9ZnVuY3Rpb24oaGEsYWEseGEsYmEsU2EsVGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHBvb2wkMSh0aGlzLGhhLGFhLHhhLGJhLFNhLFRhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5wb3c9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHBvdyQ0KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnByZWx1PWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxwcmVsdSQ0KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnByb2Q9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHByb2QkMyh0aGlzLGhhLGFhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5yZWNpcHJvY2FsPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCkscmVjaXByb2NhbCQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnJlbHU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyZWx1JDQodGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUucmVsdTY9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyZWx1NiQ0KHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnJlc2hhcGVBcz1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCkscmVzaGFwZSQ0KHRoaXMsaGEuc2hhcGUpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnJlc2hhcGU9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHJlc2hhcGUkNCh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5yZXNpemVCaWxpbmVhcj1mdW5jdGlvbihoYSxhYSx4YSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCkscmVzaXplQmlsaW5lYXIkNCh0aGlzLGhhLGFhLHhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5yZXNpemVOZWFyZXN0TmVpZ2hib3I9ZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHJlc2l6ZU5lYXJlc3ROZWlnaGJvciQzKHRoaXMsaGEsYWEseGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnJldmVyc2U9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHJldmVyc2UkMyh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5yZmZ0PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCkscmZmdCh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5yb3VuZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHJvdW5kJDQodGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUucnNxcnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxyc3FydCQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNlbHU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxzZWx1JDModGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc2VwYXJhYmxlQ29udjJkPWZ1bmN0aW9uKGhhLGFhLHhhLGJhLFNhLFRhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxzZXBhcmFibGVDb252MmQodGhpcyxoYSxhYSx4YSxiYSxTYSxUYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc2lnbW9pZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHNpZ21vaWQkNCh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5zaWduPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc2lnbiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNpbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHNpbiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNpbmg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxzaW5oJDModGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc2xpY2U9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHNsaWNlJDModGhpcyxoYSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc29mdG1heD1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc29mdG1heCQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNvZnRwbHVzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc29mdHBsdXMkMyh0aGlzKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5zcGFjZVRvQmF0Y2hORD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc3BhY2VUb0JhdGNoTkQkMyh0aGlzLGhhLGFhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5zcGxpdD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc3BsaXQkMyh0aGlzLGhhLGFhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5zcXJ0PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc3FydCQ0KHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNxdWFyZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHNxdWFyZSQ0KHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNxdWFyZWREaWZmZXJlbmNlPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxzcXVhcmVkRGlmZmVyZW5jZSQzKHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnNxdWVlemU9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHNxdWVlemUodGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc3RhY2s9ZnVuY3Rpb24oaGEsYWEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCk7Y29uc3QgeGE9aGEgaW5zdGFuY2VvZiBUZW5zb3IkMT9bdGhpcyxoYV06W3RoaXMsLi4uaGFdO3JldHVybiBzdGFjayh4YSxhYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc3RlcD1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc3RlcCQ0KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnN0cmlkZWRTbGljZT1mdW5jdGlvbihoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksc3RyaWRlZFNsaWNlJDModGhpcyxoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUuc3ViPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxzdWIkNCh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS5zdW09ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHN1bSQ1KHRoaXMsaGEsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnRhbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRhbiQzKHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnRhbmg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0YW5oJDModGhpcyl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUudGlsZT1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksdGlsZSQ0KHRoaXMsaGEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnRvQm9vbD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNhc3QkNSh0aGlzLCJib29sIil9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUudG9GbG9hdD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNhc3QkNSh0aGlzLCJmbG9hdDMyIil9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUudG9JbnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjYXN0JDUodGhpcywiaW50MzIiKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS50b3BrPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0b3BrKHRoaXMsaGEsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnRyYW5zcG9zZT1mdW5jdGlvbihoYSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksdHJhbnNwb3NlJDModGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUudW5pcXVlPWZ1bmN0aW9uKGhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSx1bmlxdWUkNCh0aGlzLGhhKX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0R2xvYmFsVGVuc29yQ2xhc3MkMSgpLnByb3RvdHlwZS51bnNvcnRlZFNlZ21lbnRTdW09ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHVuc29ydGVkU2VnbWVudFN1bSQzKHRoaXMsaGEsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnVuc3RhY2s9ZnVuY3Rpb24oaGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHVuc3RhY2sodGhpcyxoYSl9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2dldEdsb2JhbFRlbnNvckNsYXNzJDEoKS5wcm90b3R5cGUud2hlcmU9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHdoZXJlKGhhLHRoaXMsYWEpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9nZXRHbG9iYWxUZW5zb3JDbGFzcyQxKCkucHJvdG90eXBlLnplcm9zTGlrZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHplcm9zTGlrZSQ0KHRoaXMpfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBBdHRyaWJ1dGVFcnJvciBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsQXR0cmlidXRlRXJyb3IucHJvdG90eXBlKX19Y2xhc3MgUnVudGltZUVycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSxPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxSdW50aW1lRXJyb3IucHJvdG90eXBlKX19Y2xhc3MgVmFsdWVFcnJvciBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsVmFsdWVFcnJvci5wcm90b3R5cGUpfX1jbGFzcyBOb3RJbXBsZW1lbnRlZEVycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSxPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxOb3RJbXBsZW1lbnRlZEVycm9yLnByb3RvdHlwZSl9fWNsYXNzIEFzc2VydGlvbkVycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSxPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxBc3NlcnRpb25FcnJvci5wcm90b3R5cGUpfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBMcnVDYWNoZXtjb25zdHJ1Y3RvcihhYSl7dGhpcy5tYXhFbnRyaWVzPWFhfHwxMDAsdGhpcy5jYWNoZT1uZXcgTWFwfWdldChhYSl7bGV0IHhhO3JldHVybiB0aGlzLmNhY2hlLmhhcyhhYSkmJih4YT10aGlzLmNhY2hlLmdldChhYSksdGhpcy5jYWNoZS5kZWxldGUoYWEpLHRoaXMuY2FjaGUuc2V0KGFhLHhhKSkseGF9cHV0KGFhLHhhKXtpZih0aGlzLmNhY2hlLmhhcyhhYSkpdGhpcy5jYWNoZS5kZWxldGUoYWEpO2Vsc2UgaWYodGhpcy5jYWNoZS5zaXplPj10aGlzLm1heEVudHJpZXMpe2NvbnN0IGJhPXRoaXMuY2FjaGUua2V5cygpLm5leHQoKS52YWx1ZTt0aGlzLmNhY2hlLmRlbGV0ZShiYSl9dGhpcy5jYWNoZS5zZXQoYWEseGEpfWdldE1heEVudHJpZXMoKXtyZXR1cm4gdGhpcy5tYXhFbnRyaWVzfXNldE1heEVudHJpZXMoYWEpe2lmKGFhPDApdGhyb3cgbmV3IEVycm9yKGBUaGUgbWF4RW50cmllcyBvZiBMUlUgY2FjaGVzIG11c3QgYmUgYXQgbGVhc3QgMCwgYnV0IGdvdCAke2FhfS5gKTtpZih0aGlzLm1heEVudHJpZXM+YWEpZm9yKGxldCB4YT0wO3hhPHRoaXMubWF4RW50cmllcy1hYTt4YSsrKXtjb25zdCBiYT10aGlzLmNhY2hlLmtleXMoKS5uZXh0KCkudmFsdWU7dGhpcy5jYWNoZS5kZWxldGUoYmEpfXRoaXMubWF4RW50cmllcz1hYX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcHlMaXN0UmVwZWF0KGhhLGFhKXtpZihBcnJheS5pc0FycmF5KGhhKSl7bGV0IHhhPVtdO2ZvcihsZXQgYmE9MDtiYTxhYTtiYSsrKXhhPXhhLmNvbmNhdChoYSk7cmV0dXJuIHhhfWVsc2V7Y29uc3QgeGE9bmV3IEFycmF5KGFhKTtyZXR1cm4geGEuZmlsbChoYSkseGF9fWZ1bmN0aW9uIGFzc2VydCQxKGhhLGFhKXtpZighaGEpdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGFhKX1mdW5jdGlvbiBjb3VudChoYSxhYSl7bGV0IHhhPTA7Zm9yKGNvbnN0IGJhIG9mIGhhKWJhPT09YWEmJnhhKys7cmV0dXJuIHhhfWZ1bmN0aW9uIHNpbmdsZXRvbk9yQXJyYXkoaGEpe3JldHVybiBoYS5sZW5ndGg9PT0xP2hhWzBdOmhhfWZ1bmN0aW9uIHRvTGlzdChoYSl7cmV0dXJuIEFycmF5LmlzQXJyYXkoaGEpP2hhOltoYV19ZnVuY3Rpb24gdG9TbmFrZUNhc2UoaGEpe2NvbnN0IHhhPWhhLnJlcGxhY2UoLyguKShbQS1aXVthLXowLTldKykvZywiJDFfJDIiKS5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCIkMV8kMiIpLnRvTG93ZXJDYXNlKCk7cmV0dXJuIHhhWzBdIT09Il8iP3hhOiJwcml2YXRlIit4YX1mdW5jdGlvbiB0b0NhbWVsQ2FzZShoYSl7cmV0dXJuIGhhLmxlbmd0aDw9MXx8aGEuaW5kZXhPZigiXyIpPT09LTE/aGE6aGEucmVwbGFjZSgvW19dKyhcd3wkKS9nLChhYSx4YSk9PnhhLnRvVXBwZXJDYXNlKCkpfWxldCBfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTPXt9O2Z1bmN0aW9uIHNlcmlhbGl6ZUtlcmFzT2JqZWN0KGhhKXtpZihoYT09bnVsbClyZXR1cm4gbnVsbDtjb25zdCBhYT17fTtyZXR1cm4gYWEuY2xhc3NOYW1lPWhhLmdldENsYXNzTmFtZSgpLGFhLmNvbmZpZz1oYS5nZXRDb25maWcoKSxhYX1mdW5jdGlvbiBjb252ZXJ0TkRBcnJheVNjYWxhcnNJbkNvbmZpZyhoYSl7aWYoIShoYT09bnVsbHx8dHlwZW9mIGhhIT0ib2JqZWN0IikpaWYoQXJyYXkuaXNBcnJheShoYSkpaGEuZm9yRWFjaChhYT0+Y29udmVydE5EQXJyYXlTY2FsYXJzSW5Db25maWcoYWEpKTtlbHNle2NvbnN0IGFhPU9iamVjdC5rZXlzKGhhKTtmb3IoY29uc3QgeGEgb2YgYWEpe2NvbnN0IGJhPWhhW3hhXTtiYSE9bnVsbCYmdHlwZW9mIGJhPT0ib2JqZWN0IiYmKCFBcnJheS5pc0FycmF5KGJhKSYmYmEudHlwZT09PSJuZGFycmF5IiYmdHlwZW9mIGJhLnZhbHVlPT0ibnVtYmVyIj9oYVt4YV09YmEudmFsdWU6Y29udmVydE5EQXJyYXlTY2FsYXJzSW5Db25maWcoYmEpKX19fWZ1bmN0aW9uIGRlc2VyaWFsaXplS2VyYXNPYmplY3QoaGEsYWE9e30seGE9e30sYmE9Im9iamVjdCIsU2E9ITEpe2lmKHR5cGVvZiBoYT09InN0cmluZyIpe2NvbnN0IFRhPWhhO2xldCB3YTtpZihUYSBpbiB4YSl3YT14YVtUYV07ZWxzZSBpZihUYSBpbiBfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTKXdhPV9HTE9CQUxfQ1VTVE9NX09CSkVDVFNbVGFdO2Vsc2UgaWYod2E9YWFbVGFdLHdhPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKGBVbmtub3duICR7YmF9OiAke2hhfS4gVGhpcyBtYXkgYmUgZHVlIHRvIG9uZSBvZiB0aGUgZm9sbG93aW5nIHJlYXNvbnM6CjEuIFRoZSAke2JhfSBpcyBkZWZpbmVkIGluIFB5dGhvbiwgaW4gd2hpY2ggY2FzZSBpdCBuZWVkcyB0byBiZSBwb3J0ZWQgdG8gVGVuc29yRmxvdy5qcyBvciB5b3VyIEphdmFTY3JpcHQgY29kZS4KMi4gVGhlIGN1c3RvbSAke2JhfSBpcyBkZWZpbmVkIGluIEphdmFTY3JpcHQsIGJ1dCBpcyBub3QgcmVnaXN0ZXJlZCBwcm9wZXJseSB3aXRoIHRmLnNlcmlhbGl6YXRpb24ucmVnaXN0ZXJDbGFzcygpLmApO3JldHVybiB3YX1lbHNle2NvbnN0IFRhPWhhO2lmKFRhLmNsYXNzTmFtZT09bnVsbHx8VGEuY29uZmlnPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKGAke2JhfTogSW1wcm9wZXIgY29uZmlnIGZvcm1hdDogJHtKU09OLnN0cmluZ2lmeShUYSl9LgonY2xhc3NOYW1lJyBhbmQgJ2NvbmZpZycgbXVzdCBzZXQuYCk7Y29uc3Qgd2E9VGEuY2xhc3NOYW1lO2xldCBFYSxrYTtpZih3YSBpbiB4YT9bRWEsa2FdPXhhW3dhXTp3YSBpbiBfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTP1tFYSxrYV09X0dMT0JBTF9DVVNUT01fT0JKRUNUUy5jbGFzc05hbWU6d2EgaW4gYWEmJihbRWEsa2FdPWFhW3dhXSksRWE9PW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFVua25vd24gJHtiYX06ICR7d2F9LiBUaGlzIG1heSBiZSBkdWUgdG8gb25lIG9mIHRoZSBmb2xsb3dpbmcgcmVhc29uczoKMS4gVGhlICR7YmF9IGlzIGRlZmluZWQgaW4gUHl0aG9uLCBpbiB3aGljaCBjYXNlIGl0IG5lZWRzIHRvIGJlIHBvcnRlZCB0byBUZW5zb3JGbG93LmpzIG9yIHlvdXIgSmF2YVNjcmlwdCBjb2RlLgoyLiBUaGUgY3VzdG9tICR7YmF9IGlzIGRlZmluZWQgaW4gSmF2YVNjcmlwdCwgYnV0IGlzIG5vdCByZWdpc3RlcmVkIHByb3Blcmx5IHdpdGggdGYuc2VyaWFsaXphdGlvbi5yZWdpc3RlckNsYXNzKCkuYCk7aWYoa2EhPW51bGwpe2NvbnN0IEFhPXt9O2Zvcihjb25zdCB0bCBvZiBPYmplY3Qua2V5cyhfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTKSlBYVt0bF09X0dMT0JBTF9DVVNUT01fT0JKRUNUU1t0bF07Zm9yKGNvbnN0IHRsIG9mIE9iamVjdC5rZXlzKHhhKSlBYVt0bF09eGFbdGxdO2NvbnN0IEZhPVRhLmNvbmZpZztGYS5jdXN0b21PYmplY3RzPUFhO2NvbnN0IExhPU9iamVjdC5hc3NpZ24oe30sX0dMT0JBTF9DVVNUT01fT0JKRUNUUyk7Zm9yKGNvbnN0IHRsIG9mIE9iamVjdC5rZXlzKHhhKSlfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTW3RsXT14YVt0bF07Y29udmVydE5EQXJyYXlTY2FsYXJzSW5Db25maWcoVGEuY29uZmlnKTtjb25zdCBlbD1rYShFYSxUYS5jb25maWcseGEsU2EpO3JldHVybiBfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTPU9iamVjdC5hc3NpZ24oe30sTGEpLGVsfWVsc2V7Y29uc3QgQWE9T2JqZWN0LmFzc2lnbih7fSxfR0xPQkFMX0NVU1RPTV9PQkpFQ1RTKTtmb3IoY29uc3QgTGEgb2YgT2JqZWN0LmtleXMoeGEpKV9HTE9CQUxfQ1VTVE9NX09CSkVDVFNbTGFdPXhhW0xhXTtjb25zdCBGYT1uZXcgRWEoVGEuY29uZmlnKTtyZXR1cm4gX0dMT0JBTF9DVVNUT01fT0JKRUNUUz1PYmplY3QuYXNzaWduKHt9LEFhKSxGYX19fWZ1bmN0aW9uIG51bWJlckNvbXBhcmUoaGEsYWEpe3JldHVybiBoYTxhYT8tMTpoYT5hYT8xOjB9ZnVuY3Rpb24gcmV2ZXJzZU51bWJlckNvbXBhcmUoaGEsYWEpe3JldHVybi0xKm51bWJlckNvbXBhcmUoaGEsYWEpfWZ1bmN0aW9uIHVuaXF1ZSQzKGhhKXtpZihoYT09bnVsbClyZXR1cm4gaGE7Y29uc3QgYWE9W107Zm9yKGNvbnN0IHhhIG9mIGhhKWFhLmluZGV4T2YoeGEpPT09LTEmJmFhLnB1c2goeGEpO3JldHVybiBhYX1mdW5jdGlvbiBpc09iamVjdEVtcHR5KGhhKXtpZihoYT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW52YWxpZCB2YWx1ZSBpbiBvYmo6ICR7SlNPTi5zdHJpbmdpZnkoaGEpfWApO2Zvcihjb25zdCBhYSBpbiBoYSlpZihoYS5oYXNPd25Qcm9wZXJ0eShhYSkpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gY2hlY2tTdHJpbmdUeXBlVW5pb25WYWx1ZShoYSxhYSx4YSl7aWYoeGEhPW51bGwmJmhhLmluZGV4T2YoeGEpPDApdGhyb3cgbmV3IFZhbHVlRXJyb3IoYCR7eGF9IGlzIG5vdCBhIHZhbGlkICR7YWF9LiAgVmFsaWQgdmFsdWVzIGFyZSAke2hhfSBvciBudWxsL3VuZGVmaW5lZC5gKX1mdW5jdGlvbiBjaGVja0FycmF5VHlwZUFuZExlbmd0aChoYSxhYSx4YT0wLGJhPTEvMCl7cmV0dXJuIGFzc2VydCQxKHhhPj0wKSxhc3NlcnQkMShiYT49eGEpLEFycmF5LmlzQXJyYXkoaGEpJiZoYS5sZW5ndGg+PXhhJiZoYS5sZW5ndGg8PWJhJiZoYS5ldmVyeShTYT0+dHlwZW9mIFNhPT09YWEpfWZ1bmN0aW9uIGFzc2VydFBvc2l0aXZlSW50ZWdlcihoYSxhYSl7QXJyYXkuaXNBcnJheShoYSk/KGFzc2VydCQyKGhhLmxlbmd0aD4wLCgpPT5gJHthYX0gaXMgdW5leHBlY3RlZGx5IGFuIGVtcHR5IGFycmF5LmApLGhhLmZvckVhY2goKHhhLGJhKT0+YXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHhhLGBlbGVtZW50ICR7YmErMX0gb2YgJHthYX1gKSkpOmFzc2VydCQyKE51bWJlci5pc0ludGVnZXIoaGEpJiZoYT4wLCgpPT5gRXhwZWN0ZWQgJHthYX0gdG8gYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBidXQgZ290ICR7Zm9ybWF0QXNGcmllbmRseVN0cmluZyhoYSl9LmApfWZ1bmN0aW9uIGZvcm1hdEFzRnJpZW5kbHlTdHJpbmcoaGEpe3JldHVybiBoYT09PW51bGw/Im51bGwiOkFycmF5LmlzQXJyYXkoaGEpPyJbIitoYS5tYXAoYWE9PmZvcm1hdEFzRnJpZW5kbHlTdHJpbmcoYWEpKS5qb2luKCIsIikrIl0iOnR5cGVvZiBoYT09InN0cmluZyI/YCIke2hhfSJgOmAke2hhfWB9ZnVuY3Rpb24gZGVib3VuY2UoaGEsYWEseGEpe2xldCBiYT14YSE9bnVsbD94YSgpOm5vdyQxKCksU2E7cmV0dXJuKC4uLndhKT0+e2NvbnN0IEVhPXhhIT1udWxsP3hhKCk6bm93JDEoKTtyZXR1cm4gRWEtYmE8YWF8fChiYT1FYSxTYT1oYSguLi53YSkpLFNhfX1mdW5jdGlvbiBtYXBBY3RpdmF0aW9uVG9GdXNlZEtlcm5lbChoYSl7cmV0dXJuIGhhPT09InJlbHUiPyJyZWx1IjpoYT09PSJsaW5lYXIiPyJsaW5lYXIiOmhhPT09ImVsdSI/ImVsdSI6bnVsbH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgX25leHRVbmlxdWVUZW5zb3JJZD0wO2Z1bmN0aW9uIGdldE5leHRVbmlxdWVUZW5zb3JJZCgpe3JldHVybiBfbmV4dFVuaXF1ZVRlbnNvcklkKyt9Y29uc3QgX3VpZFByZWZpeGVzPXt9O2Z1bmN0aW9uIGdldFVpZChoYT0iIil7cmV0dXJuIGhhIGluIF91aWRQcmVmaXhlc3x8KF91aWRQcmVmaXhlc1toYV09MCksX3VpZFByZWZpeGVzW2hhXSs9MSxoYStfdWlkUHJlZml4ZXNbaGFdLnRvU3RyaW5nKCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgVkFMSURfREFUQV9GT1JNQVRfVkFMVUVTPVsiY2hhbm5lbHNGaXJzdCIsImNoYW5uZWxzTGFzdCJdLFZBTElEX0lOVEVSUE9MQVRJT05fRk9STUFUX1ZBTFVFUz1bIm5lYXJlc3QiLCJiaWxpbmVhciJdLFZBTElEX1BBRERJTkdfTU9ERV9WQUxVRVM9WyJ2YWxpZCIsInNhbWUiLCJjYXVzYWwiXSxWQUxJRF9QT09MX01PREVfVkFMVUVTPVsibWF4IiwiYXZnIl0sVkFMSURfQklESVJFQ1RJT05BTF9NRVJHRV9NT0RFUz1bInN1bSIsIm11bCIsImNvbmNhdCIsImF2ZSJdOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG5hbWVNYXA9bmV3IE1hcDtmdW5jdGlvbiBjaGVja0RhdGFGb3JtYXQoaGEpe2NoZWNrU3RyaW5nVHlwZVVuaW9uVmFsdWUoVkFMSURfREFUQV9GT1JNQVRfVkFMVUVTLCJEYXRhRm9ybWF0IixoYSl9ZnVuY3Rpb24gY2hlY2tJbnRlcnBvbGF0aW9uRm9ybWF0KGhhKXtjaGVja1N0cmluZ1R5cGVVbmlvblZhbHVlKFZBTElEX0lOVEVSUE9MQVRJT05fRk9STUFUX1ZBTFVFUywiSW50ZXJwb2xhdGlvbkZvcm1hdCIsaGEpfWZ1bmN0aW9uIGNoZWNrUGFkZGluZ01vZGUoaGEpe2NoZWNrU3RyaW5nVHlwZVVuaW9uVmFsdWUoVkFMSURfUEFERElOR19NT0RFX1ZBTFVFUywiUGFkZGluZ01vZGUiLGhhKX1mdW5jdGlvbiBjaGVja1Bvb2xNb2RlKGhhKXtjaGVja1N0cmluZ1R5cGVVbmlvblZhbHVlKFZBTElEX1BPT0xfTU9ERV9WQUxVRVMsIlBvb2xNb2RlIixoYSl9Y29uc3QgX25hbWVTY29wZVN0YWNrPVtdLF9uYW1lU2NvcGVEaXZpZGVyPSIvIjtmdW5jdGlvbiBuYW1lU2NvcGUoaGEsYWEpe19uYW1lU2NvcGVTdGFjay5wdXNoKGhhKTt0cnl7Y29uc3QgeGE9YWEoKTtyZXR1cm4gX25hbWVTY29wZVN0YWNrLnBvcCgpLHhhfWNhdGNoKHhhKXt0aHJvdyBfbmFtZVNjb3BlU3RhY2sucG9wKCkseGF9fWZ1bmN0aW9uIGN1cnJlbnROYW1lU2NvcGVQcmVmaXgoKXtyZXR1cm4gX25hbWVTY29wZVN0YWNrLmxlbmd0aD09PTA/IiI6X25hbWVTY29wZVN0YWNrLmpvaW4oX25hbWVTY29wZURpdmlkZXIpK19uYW1lU2NvcGVEaXZpZGVyfWZ1bmN0aW9uIGdldFNjb3BlZFRlbnNvck5hbWUoaGEpe2lmKCFpc1ZhbGlkVGVuc29yTmFtZShoYSkpdGhyb3cgbmV3IEVycm9yKCJOb3QgYSB2YWxpZCB0ZW5zb3IgbmFtZTogJyIraGErIiciKTtyZXR1cm4gY3VycmVudE5hbWVTY29wZVByZWZpeCgpK2hhfWZ1bmN0aW9uIGdldFVuaXF1ZVRlbnNvck5hbWUoaGEpe2lmKCFpc1ZhbGlkVGVuc29yTmFtZShoYSkpdGhyb3cgbmV3IEVycm9yKCJOb3QgYSB2YWxpZCB0ZW5zb3IgbmFtZTogJyIraGErIiciKTtuYW1lTWFwLmhhcyhoYSl8fG5hbWVNYXAuc2V0KGhhLDApO2NvbnN0IGFhPW5hbWVNYXAuZ2V0KGhhKTtpZihuYW1lTWFwLnNldChoYSxuYW1lTWFwLmdldChoYSkrMSksYWE+MCl7Y29uc3QgeGE9YCR7aGF9XyR7YWF9YDtyZXR1cm4gbmFtZU1hcC5zZXQoeGEsMSkseGF9ZWxzZSByZXR1cm4gaGF9Y29uc3QgdGVuc29yTmFtZVJlZ2V4PW5ldyBSZWdFeHAoL15bQS1aYS16MC05XVstQS1aYS16MC05XC5fXC9dKiQvKTtmdW5jdGlvbiBpc1ZhbGlkVGVuc29yTmFtZShoYSl7cmV0dXJuISFoYS5tYXRjaCh0ZW5zb3JOYW1lUmVnZXgpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlzSW50ZWdlcihoYSl7cmV0dXJuIGhhPT09cGFyc2VJbnQoaGEudG9TdHJpbmcoKSwxMCl9ZnVuY3Rpb24gYXJyYXlQcm9kKGhhLGFhLHhhKXthYT09bnVsbCYmKGFhPTApLHhhPT1udWxsJiYoeGE9aGEubGVuZ3RoKTtsZXQgYmE9MTtmb3IobGV0IFNhPWFhO1NhPHhhOysrU2EpYmEqPWhhW1NhXTtyZXR1cm4gYmF9ZnVuY3Rpb24gbWluJDMoaGEpe2lmKGhhLmxlbmd0aD09PTApcmV0dXJuIE51bWJlci5OYU47bGV0IGFhPU51bWJlci5QT1NJVElWRV9JTkZJTklUWTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoO3hhKyspe2NvbnN0IGJhPWhhW3hhXTtiYTxhYSYmKGFhPWJhKX1yZXR1cm4gYWF9ZnVuY3Rpb24gbWF4JDMoaGEpe2lmKGhhLmxlbmd0aD09PTApcmV0dXJuIE51bWJlci5OYU47bGV0IGFhPU51bWJlci5ORUdBVElWRV9JTkZJTklUWTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoO3hhKyspe2NvbnN0IGJhPWhhW3hhXTtiYT5hYSYmKGFhPWJhKX1yZXR1cm4gYWF9ZnVuY3Rpb24gcmFuZ2UkMyhoYSxhYSl7aWYoYWE8aGEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYGVuZCAoJHthYX0pIDwgYmVnaW4gKCR7aGF9KSBpcyBmb3JiaWRkZW4uYCk7Y29uc3QgeGE9W107Zm9yKGxldCBiYT1oYTtiYTxhYTsrK2JhKXhhLnB1c2goYmEpO3JldHVybiB4YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgX2Vwc2lsb247ZnVuY3Rpb24gZXBzaWxvbiQxKCl7cmV0dXJuIF9lcHNpbG9uPT1udWxsJiYoX2Vwc2lsb249YmFja2VuZCgpLmVwc2lsb24oKSksX2Vwc2lsb259ZnVuY3Rpb24gaW1hZ2VEYXRhRm9ybWF0KCl7cmV0dXJuImNoYW5uZWxzTGFzdCJ9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2FzdCQ0KGhhLGFhKXtyZXR1cm4gY2FzdCQ1KGhhLGFhKX1mdW5jdGlvbiBleHBhbmREaW1zJDMoaGEsYWE9LTEpe2NvbnN0IHhhPWhhLnNoYXBlLnNsaWNlKCk7cmV0dXJuIGFhPDAmJihhYT14YS5sZW5ndGgrYWErMSkseGEuc3BsaWNlKGFhLDAsMSkscmVzaGFwZSQ0KGhhLHhhKX1mdW5jdGlvbiByZXBlYXQoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9PntpZihoYS5zaGFwZS5sZW5ndGghPT0yKXRocm93IG5ldyBWYWx1ZUVycm9yKGByZXBlYXQoKSBleHBlY3RzIGEgcmFuay0yIHRlbnNvciwgYnV0IHJlY2VpdmVkIGEgcmFuay0ke2hhLnNoYXBlLmxlbmd0aH0gdGVuc29yLmApO2NvbnN0IHhhPWV4cGFuZERpbXMkMyhoYSwxKTtyZXR1cm4gdGlsZSQzKHhhLFsxLGFhLDFdKX0pfWZ1bmN0aW9uIGZsYXR0ZW4kMShoYSl7Y29uc3QgYWE9W2FycmF5UHJvZChoYS5zaGFwZSldO3JldHVybiByZXNoYXBlJDQoaGEsYWEpfWZ1bmN0aW9uIGJhdGNoRmxhdHRlbihoYSl7aWYoaGEucmFuazw9MSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgYmF0Y2hGbGF0dGVuIHJlcXVpcmVzIGEgbWluaW11bSByYW5rIG9mIDIuIEdvdCByYW5rOiAke2hhLnJhbmt9LmApO2NvbnN0IGFhPVtoYS5zaGFwZVswXSxhcnJheVByb2QoaGEuc2hhcGUsMSldO3JldHVybiByZXNoYXBlJDQoaGEsYWEpfWZ1bmN0aW9uIHNsaWNlQWxvbmdGaXJzdEF4aXMoaGEsYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntzd2l0Y2goaGEucmFuayl7Y2FzZSAxOnJldHVybiBzbGljZTFkKGhhLGFhLHhhKTtjYXNlIDI6cmV0dXJuIHNsaWNlMmQoaGEsW2FhLDBdLFt4YSxoYS5zaGFwZVsxXV0pO2Nhc2UgMzpyZXR1cm4gc2xpY2UzZChoYSxbYWEsMCwwXSxbeGEsaGEuc2hhcGVbMV0saGEuc2hhcGVbMl1dKTtjYXNlIDQ6cmV0dXJuIHNsaWNlNGQoaGEsW2FhLDAsMCwwXSxbeGEsaGEuc2hhcGVbMV0saGEuc2hhcGVbMl0saGEuc2hhcGVbM11dKTtjYXNlIDU6cmV0dXJuIHNsaWNlJDMoaGEsW2FhLDAsMCwwLDBdLFt4YSxoYS5zaGFwZVsxXSxoYS5zaGFwZVsyXSxoYS5zaGFwZVszXSxoYS5zaGFwZVs0XV0pO2Nhc2UgNjpyZXR1cm4gc2xpY2UkMyhoYSxbYWEsMCwwLDAsMCwwXSxbeGEsaGEuc2hhcGVbMV0saGEuc2hhcGVbMl0saGEuc2hhcGVbM10saGEuc2hhcGVbNF0saGEuc2hhcGVbNV1dKTtkZWZhdWx0OnRocm93IG5ldyBWYWx1ZUVycm9yKGBzbGljZUFsb25nRmlyc3RBeGlzKCkgcmVjZWl2ZWQgYW4gdW5zdXBwb3J0ZWQgdGVuc29yIHJhbms6ICR7aGEucmFua31gKX19KX1mdW5jdGlvbiBzbGljZUFsb25nTGFzdEF4aXMoaGEsYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntzd2l0Y2goaGEucmFuayl7Y2FzZSAxOnJldHVybiBzbGljZTFkKGhhLGFhLHhhKTtjYXNlIDI6cmV0dXJuIHNsaWNlMmQoaGEsWzAsYWFdLFtoYS5zaGFwZVswXSx4YV0pO2Nhc2UgMzpyZXR1cm4gc2xpY2UzZChoYSxbMCwwLGFhXSxbaGEuc2hhcGVbMF0saGEuc2hhcGVbMV0seGFdKTtjYXNlIDQ6cmV0dXJuIHNsaWNlNGQoaGEsWzAsMCwwLGFhXSxbaGEuc2hhcGVbMF0saGEuc2hhcGVbMV0saGEuc2hhcGVbMl0seGFdKTtkZWZhdWx0OnRocm93IG5ldyBWYWx1ZUVycm9yKGBzbGljZUFsb25nTGFzdEF4aXMoKSByZWNlaXZlZCBhbiB1bnN1cHBvcnRlZCB0ZW5zb3IgcmFuazogJHtoYS5yYW5rfWApfX0pfWZ1bmN0aW9uIHNsaWNlQWxvbmdBeGlzKGhhLGFhLHhhLGJhKXtyZXR1cm4gdGlkeSQxKCgpPT57c3dpdGNoKGhhLnJhbmspe2Nhc2UgMTpyZXR1cm4gc2xpY2UxZChoYSxhYSx4YSk7Y2FzZSAyOnN3aXRjaChiYSl7Y2FzZSAxOnJldHVybiBzbGljZUFsb25nRmlyc3RBeGlzKGhhLGFhLHhhKTtjYXNlIDI6cmV0dXJuIHNsaWNlQWxvbmdMYXN0QXhpcyhoYSxhYSx4YSk7ZGVmYXVsdDp0aHJvdyBuZXcgVmFsdWVFcnJvcihgVGhlIGF4aXMgaXMgbm90IHdpdGhpbiB0aGUgcmFuayBvZiB0aGUgdGVuc29yICR7YmF9YCl9Y2FzZSAzOnN3aXRjaChiYSl7Y2FzZSAxOnJldHVybiBzbGljZUFsb25nRmlyc3RBeGlzKGhhLGFhLHhhKTtjYXNlIDI6cmV0dXJuIHNsaWNlM2QoaGEsWzAsYWEsMF0sW2hhLnNoYXBlWzBdLHhhLGhhLnNoYXBlWzJdXSk7Y2FzZSAzOnJldHVybiBzbGljZUFsb25nTGFzdEF4aXMoaGEsYWEseGEpO2RlZmF1bHQ6dGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBheGlzIGlzIG5vdCB3aXRoaW4gdGhlIHJhbmsgb2YgdGhlIHRlbnNvciAke2JhfWApfWNhc2UgNDpzd2l0Y2goYmEpe2Nhc2UgMTpyZXR1cm4gc2xpY2VBbG9uZ0ZpcnN0QXhpcyhoYSxhYSx4YSk7Y2FzZSAyOnJldHVybiBzbGljZTRkKGhhLFswLGFhLDAsMF0sW2hhLnNoYXBlWzBdLHhhLGhhLnNoYXBlWzJdLGhhLnNoYXBlWzNdXSk7Y2FzZSAzOnJldHVybiBzbGljZTRkKGhhLFswLDAsYWEsMF0sW2hhLnNoYXBlWzBdLGhhLnNoYXBlWzFdLHhhLGhhLnNoYXBlWzNdXSk7Y2FzZSA0OnJldHVybiBzbGljZUFsb25nTGFzdEF4aXMoaGEsYWEseGEpO2RlZmF1bHQ6dGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBheGlzIGlzIG5vdCB3aXRoaW4gdGhlIHJhbmsgb2YgdGhlIHRlbnNvciAke2JhfWApfWRlZmF1bHQ6dGhyb3cgbmV3IFZhbHVlRXJyb3IoYHNsaWNlQWxvbmdMYXN0QXhpcygpIHJlY2VpdmVkIGFuIHVuc3VwcG9ydGVkIHRlbnNvciByYW5rOiAke2hhLnJhbmt9YCl9fSl9ZnVuY3Rpb24gY29uY2F0ZW5hdGUoaGEsYWE9LTEpe2xldCB4YTtyZXR1cm4gYWE8MCYmKHhhPWhhWzBdLnJhbmsseGEhPT0wP2FhPXhhOmFhPTApLGFhPT09aGFbMF0ucmFuayYmKGFhPS0xKSxjb25jYXQkMyhoYSxhYSl9ZnVuY3Rpb24gY29uY2F0QWxvbmdGaXJzdEF4aXMoaGEsYWEpe3N3aXRjaChoYS5yYW5rKXtjYXNlIDE6cmV0dXJuIGNvbmNhdDFkKFtoYSxhYV0pO2Nhc2UgMjpyZXR1cm4gY29uY2F0MmQoW2hhLGFhXSwwKTtjYXNlIDM6cmV0dXJuIGNvbmNhdDNkKFtoYSxhYV0sMCk7Y2FzZSA0OnJldHVybiBjb25jYXQ0ZChbaGEsYWFdLDApO2RlZmF1bHQ6dGhyb3cgbmV3IFZhbHVlRXJyb3IoYGNvbmNhdEFsb25nRmlyc3RBeGlzKCkgcmVjZWl2ZWQgYW4gdW5zdXBwb3J0ZWQgdGVuc29yIHJhbms6ICR7aGEucmFua31gKX19ZnVuY3Rpb24gdGlsZSQzKGhhLGFhKXtpZihBcnJheS5pc0FycmF5KGFhKXx8KGFhPVthYV0pLGhhLnJhbmshPT1hYS5sZW5ndGgpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBsZW5ndGggb2YgaW5wdXQgbiAoJHthYS5sZW5ndGh9KSBkb2VzIG5vdCBtYXRjaCB0aGUgbnVtYmVyIG9mIGRpbWVuc2lvbnMgaW4gaW5wdXQgeCAoJHtoYS5yYW5rfSlgKTtyZXR1cm4gdGlsZSQ0KGhhLGFhKX1mdW5jdGlvbiByYW5kb21Ob3JtYWwoaGEsYWE9MCx4YT0xLGJhLFNhKXtyZXR1cm4gcmFuZG9tTm9ybWFsJDEoaGEsYWEseGEsYmEsU2EpfWZ1bmN0aW9uIGRvdChoYSxhYSx4YSxiYSl7aWYoaGEucmFuazwyfHxhYS5yYW5rPDIpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYGRvdCByZXF1aXJlcyBib3RoIGlucHV0cyB0byBiZSByYW5rID49IDIgYnV0IGdvdCB4IHNoYXBlID0gJHtoYS5zaGFwZX0gYW5kIHkgc2hhcGUgPSAke2FhLnNoYXBlfWApO2lmKGFhLnJhbms+PTMpe2NvbnN0IFNhPWhhLnNoYXBlLnNsaWNlKC0xKVswXSxUYT1hYS5zaGFwZS5zbGljZSgtMilbMF07aWYoU2EhPT1UYSl0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcihgSWYgcmFuayB5ID49IDMsIHRoZW4gdGhlIHNlY29uZCBsYXN0IGRpbSBvZiB5IG11c3QgZXF1YWwgdGhlIGxhc3QgZGltIG9mIHggYnV0IGdvdCB4IHNoYXBlID0gJHtoYS5zaGFwZX0gYW5kICB5IHNoYXBlID0gJHthYS5zaGFwZX1gKX1pZihoYS5yYW5rPT09MiYmYWEucmFuaz09PTIpcmV0dXJuIG1hdE11bCh7YTpoYSxiOmFhLHRyYW5zcG9zZUE6ITEsdHJhbnNwb3NlQjohMSxiaWFzOmJhP3Jlc2hhcGVCaWFzKGhhLnJhbmssYmEsaW1hZ2VEYXRhRm9ybWF0KCkpOm51bGwsYWN0aXZhdGlvbjp4YX0pO3tjb25zdCBTYT1oYS5zaGFwZS5zbGljZSgpLFRhPVNhLnBvcCgpO2hhPXJlc2hhcGUkNChoYSxbLTEsVGFdKTtjb25zdCB3YT1hYS5zaGFwZS5zbGljZSgpLEVhPXdhLnBvcCgpLGthPXdhLnBvcCgpLEFhPVsuLi53YSxFYV0sRmE9QXJyYXkuZnJvbSh7bGVuZ3RoOmFhLnJhbmt9LChubCxzbCk9PnNsPT09MD9hYS5yYW5rLTI6c2w8PWFhLnJhbmstMj9zbC0xOnNsKTthYT1yZXNoYXBlJDQodHJhbnNwb3NlJDMoYWEsRmEpLFtrYSwtMV0pO2NvbnN0IExhPVsuLi5TYSwuLi5BYV07cmV0dXJuIHJlc2hhcGUkNChtYXRNdWwoe2E6aGEsYjphYSx0cmFuc3Bvc2VBOiExLHRyYW5zcG9zZUI6ITEsYmlhczpiYT9yZXNoYXBlQmlhcyhoYS5yYW5rLGJhLGltYWdlRGF0YUZvcm1hdCgpKTpudWxsLGFjdGl2YXRpb246eGF9KSxMYSl9fWZ1bmN0aW9uIGdhdGhlcihoYSxhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+KEFycmF5LmlzQXJyYXkoYWEpP2FhPXRlbnNvcjFkKGFhLCJpbnQzMiIpOmFhPWNhc3QkNShhYSwiaW50MzIiKSxnYXRoZXIkMShoYSxhYSx4YSkpKX1mdW5jdGlvbiBzcXVhcmUkMyhoYSl7cmV0dXJuIG11bCQxKGhhLGhhKX1mdW5jdGlvbiByZXNoYXBlQmlhcyhoYSxhYSx4YSl7Y29uc3QgYmE9YWEuc2hhcGU7aWYoYWEucmFuayE9PTEmJmFhLnJhbmshPT1oYSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgVW5leHBlY3RlZCBiaWFzIGRpbWVuc2lvbnM6ICR7YWEucmFua307IGV4cGVjdGVkIGl0IHRvIGJlIDEgb3IgJHtoYX1gKTtpZihoYT09PTUpe2lmKHhhPT09ImNoYW5uZWxzRmlyc3QiKXJldHVybiBiYS5sZW5ndGg9PT0xP3Jlc2hhcGUkNChhYSxbMSxiYVswXSwxLDEsMV0pOnJlc2hhcGUkNChhYSxbMSxiYVszXSxiYVswXSxiYVsxXSxiYVsyXV0pO2lmKHhhPT09ImNoYW5uZWxzTGFzdCIpcmV0dXJuIGJhLmxlbmd0aD09PTE/cmVzaGFwZSQ0KGFhLFsxLDEsMSwxLGJhWzBdXSk6cmVzaGFwZSQ0KGFhLFsxXS5jb25jYXQoYmEpKX1lbHNlIGlmKGhhPT09NCl7aWYoeGE9PT0iY2hhbm5lbHNGaXJzdCIpcmV0dXJuIGJhLmxlbmd0aD09PTE/cmVzaGFwZSQ0KGFhLFsxLGJhWzBdLDEsMV0pOnJlc2hhcGUkNChhYSxbMSxiYVsyXSxiYVswXSxiYVsxXV0pO2lmKHhhPT09ImNoYW5uZWxzTGFzdCIpcmV0dXJuIGJhLmxlbmd0aD09PTE/cmVzaGFwZSQ0KGFhLFsxLDEsMSxiYVswXV0pOnJlc2hhcGUkNChhYSxbMV0uY29uY2F0KGJhKSl9ZWxzZSBpZihoYT09PTMpe2lmKHhhPT09ImNoYW5uZWxzRmlyc3QiKXJldHVybiBiYS5sZW5ndGg9PT0xP3Jlc2hhcGUkNChhYSxbMSxiYVswXSwxXSk6cmVzaGFwZSQ0KGFhLFsxLGJhWzFdLGJhWzBdXSk7aWYoeGE9PT0iY2hhbm5lbHNMYXN0IilyZXR1cm4gYmEubGVuZ3RoPT09MT9yZXNoYXBlJDQoYWEsWzEsMSxiYVswXV0pOnJlc2hhcGUkNChhYSxbMV0uY29uY2F0KGJhKSl9ZWxzZSBpZihoYTwzKXJldHVybiBhYTt0aHJvdyBuZXcgVmFsdWVFcnJvcihgVW5zdXBwb3J0ZWQgaW5wdXQgcmFuayBieSBiaWFzQWRkOiAke2FhLnJhbmt9YCl9ZnVuY3Rpb24gYmlhc0FkZChoYSxhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+KHhhPT1udWxsJiYoeGE9aW1hZ2VEYXRhRm9ybWF0KCkpLGNoZWNrRGF0YUZvcm1hdCh4YSksYWRkJDMoaGEscmVzaGFwZUJpYXMoaGEucmFuayxhYSx4YSkpKSl9ZnVuY3Rpb24gZWx1JDQoaGEsYWE9MSl7aWYoYWEhPT0xKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKGBTdXBwb3J0IGZvciBhbHBoYSB2YWx1ZXMgb3RoZXIgdGhhbiAxICgke2FhfSkgaXMgbm90IGltcGxlbWVudGVkIHlldC5gKTtyZXR1cm4gZWx1JDUoaGEpfWZ1bmN0aW9uIHNvZnRzaWduKGhhKXtyZXR1cm4gdGlkeSQxKCgpPT5kaXYkMihoYSxhZGQkMyhhYnMkNChoYSksMSkpKX1mdW5jdGlvbiBkcm9wb3V0KGhhLGFhLHhhLGJhKXtyZXR1cm4gdGlkeSQxKCgpPT5kcm9wb3V0JDEoaGEsYWEseGEsYmEpKX1mdW5jdGlvbiBoYXJkU2lnbW9pZChoYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IGFhPWFkZCQzKC41LG11bCQxKC4yLGhhKSk7cmV0dXJuIGNsaXBCeVZhbHVlJDMoYWEsMCwxKX0pfWZ1bmN0aW9uIGluVHJhaW5QaGFzZShoYSxhYSx4YT0hMSl7cmV0dXJuIHhhP2hhKCk6YWEoKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBWQUxJRF9GQU5fTU9ERV9WQUxVRVM9WyJmYW5JbiIsImZhbk91dCIsImZhbkF2ZyJdLFZBTElEX0RJU1RSSUJVVElPTl9WQUxVRVM9WyJub3JtYWwiLCJ1bmlmb3JtIiwidHJ1bmNhdGVkTm9ybWFsIl07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2hlY2tGYW5Nb2RlKGhhKXtjaGVja1N0cmluZ1R5cGVVbmlvblZhbHVlKFZBTElEX0ZBTl9NT0RFX1ZBTFVFUywiRmFuTW9kZSIsaGEpfWZ1bmN0aW9uIGNoZWNrRGlzdHJpYnV0aW9uKGhhKXtjaGVja1N0cmluZ1R5cGVVbmlvblZhbHVlKFZBTElEX0RJU1RSSUJVVElPTl9WQUxVRVMsIkRpc3RyaWJ1dGlvbiIsaGEpfWNsYXNzIEluaXRpYWxpemVyIGV4dGVuZHMgU2VyaWFsaXphYmxlJDF7ZnJvbUNvbmZpZ1VzZXNDdXN0b21PYmplY3RzKCl7cmV0dXJuITF9Z2V0Q29uZmlnKCl7cmV0dXJue319fWNsYXNzIFplcm9zIGV4dGVuZHMgSW5pdGlhbGl6ZXJ7YXBwbHkoYWEseGEpe3JldHVybiB6ZXJvcyQyKGFhLHhhKX19WmVyb3MuY2xhc3NOYW1lPSJaZXJvcyIscmVnaXN0ZXJDbGFzcyQxKFplcm9zKTtjbGFzcyBPbmVzIGV4dGVuZHMgSW5pdGlhbGl6ZXJ7YXBwbHkoYWEseGEpe3JldHVybiBvbmVzJDEoYWEseGEpfX1PbmVzLmNsYXNzTmFtZT0iT25lcyIscmVnaXN0ZXJDbGFzcyQxKE9uZXMpO2NsYXNzIENvbnN0YW50IGV4dGVuZHMgSW5pdGlhbGl6ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKHN1cGVyKCksdHlwZW9mIGFhIT0ib2JqZWN0Iil0aHJvdyBuZXcgVmFsdWVFcnJvcihgRXhwZWN0ZWQgYXJndW1lbnQgb2YgdHlwZSBDb25zdGFudENvbmZpZyBidXQgZ290ICR7YWF9YCk7aWYoYWEudmFsdWU9PT12b2lkIDApdGhyb3cgbmV3IFZhbHVlRXJyb3IoYGNvbmZpZyBtdXN0IGhhdmUgdmFsdWUgc2V0IGJ1dCBnb3QgJHthYX1gKTt0aGlzLnZhbHVlPWFhLnZhbHVlfWFwcGx5KGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT5tdWwkMShzY2FsYXIkMSh0aGlzLnZhbHVlKSxvbmVzJDEoYWEseGEpKSl9Z2V0Q29uZmlnKCl7cmV0dXJue3ZhbHVlOnRoaXMudmFsdWV9fX1Db25zdGFudC5jbGFzc05hbWU9IkNvbnN0YW50IixyZWdpc3RlckNsYXNzJDEoQ29uc3RhbnQpO2NsYXNzIFJhbmRvbVVuaWZvcm0gZXh0ZW5kcyBJbml0aWFsaXplcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoKSx0aGlzLkRFRkFVTFRfTUlOVkFMPS0uMDUsdGhpcy5ERUZBVUxUX01BWFZBTD0uMDUsdGhpcy5taW52YWw9YWEubWludmFsfHx0aGlzLkRFRkFVTFRfTUlOVkFMLHRoaXMubWF4dmFsPWFhLm1heHZhbHx8dGhpcy5ERUZBVUxUX01BWFZBTCx0aGlzLnNlZWQ9YWEuc2VlZH1hcHBseShhYSx4YSl7cmV0dXJuIHJhbmRvbVVuaWZvcm0oYWEsdGhpcy5taW52YWwsdGhpcy5tYXh2YWwseGEsdGhpcy5zZWVkKX1nZXRDb25maWcoKXtyZXR1cm57bWludmFsOnRoaXMubWludmFsLG1heHZhbDp0aGlzLm1heHZhbCxzZWVkOnRoaXMuc2VlZH19fVJhbmRvbVVuaWZvcm0uY2xhc3NOYW1lPSJSYW5kb21Vbmlmb3JtIixyZWdpc3RlckNsYXNzJDEoUmFuZG9tVW5pZm9ybSk7Y2xhc3MgUmFuZG9tTm9ybWFsIGV4dGVuZHMgSW5pdGlhbGl6ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKCksdGhpcy5ERUZBVUxUX01FQU49MCx0aGlzLkRFRkFVTFRfU1REREVWPS4wNSx0aGlzLm1lYW49YWEubWVhbnx8dGhpcy5ERUZBVUxUX01FQU4sdGhpcy5zdGRkZXY9YWEuc3RkZGV2fHx0aGlzLkRFRkFVTFRfU1REREVWLHRoaXMuc2VlZD1hYS5zZWVkfWFwcGx5KGFhLHhhKXtpZih4YT14YXx8ImZsb2F0MzIiLHhhIT09ImZsb2F0MzIiJiZ4YSE9PSJpbnQzMiIpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYHJhbmRvbU5vcm1hbCBkb2VzIG5vdCBzdXBwb3J0IGRUeXBlICR7eGF9LmApO3JldHVybiByYW5kb21Ob3JtYWwoYWEsdGhpcy5tZWFuLHRoaXMuc3RkZGV2LHhhLHRoaXMuc2VlZCl9Z2V0Q29uZmlnKCl7cmV0dXJue21lYW46dGhpcy5tZWFuLHN0ZGRldjp0aGlzLnN0ZGRldixzZWVkOnRoaXMuc2VlZH19fVJhbmRvbU5vcm1hbC5jbGFzc05hbWU9IlJhbmRvbU5vcm1hbCIscmVnaXN0ZXJDbGFzcyQxKFJhbmRvbU5vcm1hbCk7Y2xhc3MgVHJ1bmNhdGVkTm9ybWFsIGV4dGVuZHMgSW5pdGlhbGl6ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKCksdGhpcy5ERUZBVUxUX01FQU49MCx0aGlzLkRFRkFVTFRfU1REREVWPS4wNSx0aGlzLm1lYW49YWEubWVhbnx8dGhpcy5ERUZBVUxUX01FQU4sdGhpcy5zdGRkZXY9YWEuc3RkZGV2fHx0aGlzLkRFRkFVTFRfU1REREVWLHRoaXMuc2VlZD1hYS5zZWVkfWFwcGx5KGFhLHhhKXtpZih4YT14YXx8ImZsb2F0MzIiLHhhIT09ImZsb2F0MzIiJiZ4YSE9PSJpbnQzMiIpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYHRydW5jYXRlZE5vcm1hbCBkb2VzIG5vdCBzdXBwb3J0IGRUeXBlICR7eGF9LmApO3JldHVybiB0cnVuY2F0ZWROb3JtYWwoYWEsdGhpcy5tZWFuLHRoaXMuc3RkZGV2LHhhLHRoaXMuc2VlZCl9Z2V0Q29uZmlnKCl7cmV0dXJue21lYW46dGhpcy5tZWFuLHN0ZGRldjp0aGlzLnN0ZGRldixzZWVkOnRoaXMuc2VlZH19fVRydW5jYXRlZE5vcm1hbC5jbGFzc05hbWU9IlRydW5jYXRlZE5vcm1hbCIscmVnaXN0ZXJDbGFzcyQxKFRydW5jYXRlZE5vcm1hbCk7bGV0IElkZW50aXR5JDE9Y2xhc3MgZXh0ZW5kcyBJbml0aWFsaXplcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoKSx0aGlzLmdhaW49YWEuZ2FpbiE9bnVsbD9hYS5nYWluOjF9YXBwbHkoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PntpZihhYS5sZW5ndGghPT0yfHxhYVswXSE9PWFhWzFdKXRocm93IG5ldyBWYWx1ZUVycm9yKCJJZGVudGl0eSBtYXRyaXggaW5pdGlhbGl6ZXIgY2FuIG9ubHkgYmUgdXNlZCBmb3IgMkQgc3F1YXJlIG1hdHJpY2VzLiIpO3JldHVybiBtdWwkMSh0aGlzLmdhaW4sZXllKGFhWzBdKSl9KX1nZXRDb25maWcoKXtyZXR1cm57Z2Fpbjp0aGlzLmdhaW59fX07SWRlbnRpdHkkMS5jbGFzc05hbWU9IklkZW50aXR5IixyZWdpc3RlckNsYXNzJDEoSWRlbnRpdHkkMSk7ZnVuY3Rpb24gY29tcHV0ZUZhbnMoaGEsYWE9ImNoYW5uZWxzTGFzdCIpe2xldCB4YSxiYTtpZihjaGVja0RhdGFGb3JtYXQoYWEpLGhhLmxlbmd0aD09PTIpeGE9aGFbMF0sYmE9aGFbMV07ZWxzZSBpZihbMyw0LDVdLmluZGV4T2YoaGEubGVuZ3RoKSE9PS0xKXtpZihhYT09PSJjaGFubmVsc0ZpcnN0Iil7Y29uc3QgU2E9YXJyYXlQcm9kKGhhLDIpO3hhPWhhWzFdKlNhLGJhPWhhWzBdKlNhfWVsc2UgaWYoYWE9PT0iY2hhbm5lbHNMYXN0Iil7Y29uc3QgU2E9YXJyYXlQcm9kKGhhLDAsaGEubGVuZ3RoLTIpO3hhPWhhW2hhLmxlbmd0aC0yXSpTYSxiYT1oYVtoYS5sZW5ndGgtMV0qU2F9fWVsc2V7Y29uc3QgU2E9YXJyYXlQcm9kKGhhKTt4YT1NYXRoLnNxcnQoU2EpLGJhPU1hdGguc3FydChTYSl9cmV0dXJuW3hhLGJhXX1jbGFzcyBWYXJpYW5jZVNjYWxpbmcgZXh0ZW5kcyBJbml0aWFsaXplcntjb25zdHJ1Y3RvcihhYSl7aWYoc3VwZXIoKSxhYS5zY2FsZTwwKXRocm93IG5ldyBWYWx1ZUVycm9yKGBzY2FsZSBtdXN0IGJlIGEgcG9zaXRpdmUgZmxvYXQuIEdvdDogJHthYS5zY2FsZX1gKTt0aGlzLnNjYWxlPWFhLnNjYWxlPT1udWxsPzE6YWEuc2NhbGUsdGhpcy5tb2RlPWFhLm1vZGU9PW51bGw/ImZhbkluIjphYS5tb2RlLGNoZWNrRmFuTW9kZSh0aGlzLm1vZGUpLHRoaXMuZGlzdHJpYnV0aW9uPWFhLmRpc3RyaWJ1dGlvbj09bnVsbD8ibm9ybWFsIjphYS5kaXN0cmlidXRpb24sY2hlY2tEaXN0cmlidXRpb24odGhpcy5kaXN0cmlidXRpb24pLHRoaXMuc2VlZD1hYS5zZWVkfWFwcGx5KGFhLHhhKXtjb25zdCBiYT1jb21wdXRlRmFucyhhYSksU2E9YmFbMF0sVGE9YmFbMV07bGV0IHdhPXRoaXMuc2NhbGU7aWYodGhpcy5tb2RlPT09ImZhbkluIj93YS89TWF0aC5tYXgoMSxTYSk6dGhpcy5tb2RlPT09ImZhbk91dCI/d2EvPU1hdGgubWF4KDEsVGEpOndhLz1NYXRoLm1heCgxLChTYStUYSkvMiksdGhpcy5kaXN0cmlidXRpb249PT0ibm9ybWFsIil7Y29uc3QgRWE9TWF0aC5zcXJ0KHdhKTtpZih4YT14YXx8ImZsb2F0MzIiLHhhIT09ImZsb2F0MzIiJiZ4YSE9PSJpbnQzMiIpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYCR7dGhpcy5nZXRDbGFzc05hbWUoKX0gZG9lcyBub3Qgc3VwcG9ydCBkVHlwZSAke3hhfS5gKTtyZXR1cm4gdHJ1bmNhdGVkTm9ybWFsKGFhLDAsRWEseGEsdGhpcy5zZWVkKX1lbHNle2NvbnN0IEVhPU1hdGguc3FydCgzKndhKTtyZXR1cm4gcmFuZG9tVW5pZm9ybShhYSwtRWEsRWEseGEsdGhpcy5zZWVkKX19Z2V0Q29uZmlnKCl7cmV0dXJue3NjYWxlOnRoaXMuc2NhbGUsbW9kZTp0aGlzLm1vZGUsZGlzdHJpYnV0aW9uOnRoaXMuZGlzdHJpYnV0aW9uLHNlZWQ6dGhpcy5zZWVkfX19VmFyaWFuY2VTY2FsaW5nLmNsYXNzTmFtZT0iVmFyaWFuY2VTY2FsaW5nIixyZWdpc3RlckNsYXNzJDEoVmFyaWFuY2VTY2FsaW5nKTtjbGFzcyBHbG9yb3RVbmlmb3JtIGV4dGVuZHMgVmFyaWFuY2VTY2FsaW5ne2NvbnN0cnVjdG9yKGFhKXtzdXBlcih7c2NhbGU6MSxtb2RlOiJmYW5BdmciLGRpc3RyaWJ1dGlvbjoidW5pZm9ybSIsc2VlZDphYT09bnVsbD9udWxsOmFhLnNlZWR9KX1nZXRDbGFzc05hbWUoKXtyZXR1cm4gVmFyaWFuY2VTY2FsaW5nLmNsYXNzTmFtZX19R2xvcm90VW5pZm9ybS5jbGFzc05hbWU9Ikdsb3JvdFVuaWZvcm0iLHJlZ2lzdGVyQ2xhc3MkMShHbG9yb3RVbmlmb3JtKTtjbGFzcyBHbG9yb3ROb3JtYWwgZXh0ZW5kcyBWYXJpYW5jZVNjYWxpbmd7Y29uc3RydWN0b3IoYWEpe3N1cGVyKHtzY2FsZToxLG1vZGU6ImZhbkF2ZyIsZGlzdHJpYnV0aW9uOiJub3JtYWwiLHNlZWQ6YWE9PW51bGw/bnVsbDphYS5zZWVkfSl9Z2V0Q2xhc3NOYW1lKCl7cmV0dXJuIFZhcmlhbmNlU2NhbGluZy5jbGFzc05hbWV9fUdsb3JvdE5vcm1hbC5jbGFzc05hbWU9Ikdsb3JvdE5vcm1hbCIscmVnaXN0ZXJDbGFzcyQxKEdsb3JvdE5vcm1hbCk7Y2xhc3MgSGVOb3JtYWwgZXh0ZW5kcyBWYXJpYW5jZVNjYWxpbmd7Y29uc3RydWN0b3IoYWEpe3N1cGVyKHtzY2FsZToyLG1vZGU6ImZhbkluIixkaXN0cmlidXRpb246Im5vcm1hbCIsc2VlZDphYT09bnVsbD9udWxsOmFhLnNlZWR9KX1nZXRDbGFzc05hbWUoKXtyZXR1cm4gVmFyaWFuY2VTY2FsaW5nLmNsYXNzTmFtZX19SGVOb3JtYWwuY2xhc3NOYW1lPSJIZU5vcm1hbCIscmVnaXN0ZXJDbGFzcyQxKEhlTm9ybWFsKTtjbGFzcyBIZVVuaWZvcm0gZXh0ZW5kcyBWYXJpYW5jZVNjYWxpbmd7Y29uc3RydWN0b3IoYWEpe3N1cGVyKHtzY2FsZToyLG1vZGU6ImZhbkluIixkaXN0cmlidXRpb246InVuaWZvcm0iLHNlZWQ6YWE9PW51bGw/bnVsbDphYS5zZWVkfSl9Z2V0Q2xhc3NOYW1lKCl7cmV0dXJuIFZhcmlhbmNlU2NhbGluZy5jbGFzc05hbWV9fUhlVW5pZm9ybS5jbGFzc05hbWU9IkhlVW5pZm9ybSIscmVnaXN0ZXJDbGFzcyQxKEhlVW5pZm9ybSk7Y2xhc3MgTGVDdW5Ob3JtYWwgZXh0ZW5kcyBWYXJpYW5jZVNjYWxpbmd7Y29uc3RydWN0b3IoYWEpe3N1cGVyKHtzY2FsZToxLG1vZGU6ImZhbkluIixkaXN0cmlidXRpb246Im5vcm1hbCIsc2VlZDphYT09bnVsbD9udWxsOmFhLnNlZWR9KX1nZXRDbGFzc05hbWUoKXtyZXR1cm4gVmFyaWFuY2VTY2FsaW5nLmNsYXNzTmFtZX19TGVDdW5Ob3JtYWwuY2xhc3NOYW1lPSJMZUN1bk5vcm1hbCIscmVnaXN0ZXJDbGFzcyQxKExlQ3VuTm9ybWFsKTtjbGFzcyBMZUN1blVuaWZvcm0gZXh0ZW5kcyBWYXJpYW5jZVNjYWxpbmd7Y29uc3RydWN0b3IoYWEpe3N1cGVyKHtzY2FsZToxLG1vZGU6ImZhbkluIixkaXN0cmlidXRpb246InVuaWZvcm0iLHNlZWQ6YWE9PW51bGw/bnVsbDphYS5zZWVkfSl9Z2V0Q2xhc3NOYW1lKCl7cmV0dXJuIFZhcmlhbmNlU2NhbGluZy5jbGFzc05hbWV9fUxlQ3VuVW5pZm9ybS5jbGFzc05hbWU9IkxlQ3VuVW5pZm9ybSIscmVnaXN0ZXJDbGFzcyQxKExlQ3VuVW5pZm9ybSk7Y2xhc3MgT3J0aG9nb25hbCBleHRlbmRzIEluaXRpYWxpemVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcigpLHRoaXMuREVGQVVMVF9HQUlOPTEsdGhpcy5FTEVNRU5UU19XQVJOX1NMT1c9MmUzLHRoaXMuZ2Fpbj1hYS5nYWluPT1udWxsP3RoaXMuREVGQVVMVF9HQUlOOmFhLmdhaW4sdGhpcy5zZWVkPWFhLnNlZWR9YXBwbHkoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PntpZihhYS5sZW5ndGg8Mil0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiU2hhcGUgbXVzdCBiZSBhdCBsZWFzdCAyRC4iKTtpZih4YSE9PSJpbnQzMiImJnhhIT09ImZsb2F0MzIiJiZ4YSE9PXZvaWQgMCl0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGUgJHt4YX0uYCk7eGE9eGE7Y29uc3QgYmE9c2l6ZUZyb21TaGFwZSQxKGFhLnNsaWNlKDAsLTEpKSxTYT1hYVthYS5sZW5ndGgtMV0sVGE9YmEqU2E7VGE+dGhpcy5FTEVNRU5UU19XQVJOX1NMT1cmJmNvbnNvbGUud2FybihgT3J0aG9nb25hbCBpbml0aWFsaXplciBpcyBiZWluZyBjYWxsZWQgb24gYSBtYXRyaXggd2l0aCBtb3JlIHRoYW4gJHt0aGlzLkVMRU1FTlRTX1dBUk5fU0xPV30gKCR7VGF9KSBlbGVtZW50czogU2xvd25lc3MgbWF5IHJlc3VsdC5gKTtjb25zdCB3YT1bTWF0aC5tYXgoU2EsYmEpLE1hdGgubWluKFNhLGJhKV0sRWE9cmFuZG9tTm9ybWFsKHdhLDAsMSx4YSx0aGlzLnNlZWQpLGthPWxpbmFsZy5xcihFYSwhMSk7bGV0IEFhPWthWzBdO2NvbnN0IExhPWthWzFdLmZsYXR0ZW4oKS5zdHJpZGVkU2xpY2UoWzBdLFtNYXRoLm1pbihTYSxiYSkqTWF0aC5taW4oU2EsYmEpXSxbTWF0aC5taW4oU2EsYmEpKzFdKTtyZXR1cm4gQWE9bXVsJDEoQWEsTGEuc2lnbigpKSxiYTxTYSYmKEFhPUFhLnRyYW5zcG9zZSgpKSxtdWwkMShzY2FsYXIkMSh0aGlzLmdhaW4pLEFhLnJlc2hhcGUoYWEpKX0pfWdldENvbmZpZygpe3JldHVybntnYWluOnRoaXMuZ2FpbixzZWVkOnRoaXMuc2VlZH19fU9ydGhvZ29uYWwuY2xhc3NOYW1lPSJPcnRob2dvbmFsIixyZWdpc3RlckNsYXNzJDEoT3J0aG9nb25hbCk7Y29uc3QgSU5JVElBTElaRVJfSURFTlRJRklFUl9SRUdJU1RSWV9TWU1CT0xfTUFQPXtjb25zdGFudDoiQ29uc3RhbnQiLGdsb3JvdE5vcm1hbDoiR2xvcm90Tm9ybWFsIixnbG9yb3RVbmlmb3JtOiJHbG9yb3RVbmlmb3JtIixoZU5vcm1hbDoiSGVOb3JtYWwiLGhlVW5pZm9ybToiSGVVbmlmb3JtIixpZGVudGl0eToiSWRlbnRpdHkiLGxlQ3VuTm9ybWFsOiJMZUN1bk5vcm1hbCIsbGVDdW5Vbmlmb3JtOiJMZUN1blVuaWZvcm0iLG9uZXM6Ik9uZXMiLG9ydGhvZ29uYWw6Ik9ydGhvZ29uYWwiLHJhbmRvbU5vcm1hbDoiUmFuZG9tTm9ybWFsIixyYW5kb21Vbmlmb3JtOiJSYW5kb21Vbmlmb3JtIix0cnVuY2F0ZWROb3JtYWw6IlRydW5jYXRlZE5vcm1hbCIsdmFyaWFuY2VTY2FsaW5nOiJWYXJpYW5jZVNjYWxpbmciLHplcm9zOiJaZXJvcyJ9O2Z1bmN0aW9uIGRlc2VyaWFsaXplSW5pdGlhbGl6ZXIoaGEsYWE9e30pe3JldHVybiBkZXNlcmlhbGl6ZUtlcmFzT2JqZWN0KGhhLFNlcmlhbGl6YXRpb25NYXAkMS5nZXRNYXAoKS5jbGFzc05hbWVNYXAsYWEsImluaXRpYWxpemVyIil9ZnVuY3Rpb24gc2VyaWFsaXplSW5pdGlhbGl6ZXIoaGEpe3JldHVybiBzZXJpYWxpemVLZXJhc09iamVjdChoYSl9ZnVuY3Rpb24gZ2V0SW5pdGlhbGl6ZXIoaGEpe2lmKHR5cGVvZiBoYT09InN0cmluZyIpe2NvbnN0IGFhPWhhIGluIElOSVRJQUxJWkVSX0lERU5USUZJRVJfUkVHSVNUUllfU1lNQk9MX01BUD9JTklUSUFMSVpFUl9JREVOVElGSUVSX1JFR0lTVFJZX1NZTUJPTF9NQVBbaGFdOmhhO2lmKGFhPT09Ikdsb3JvdE5vcm1hbCIpcmV0dXJuIG5ldyBHbG9yb3ROb3JtYWw7aWYoYWE9PT0iR2xvcm90VW5pZm9ybSIpcmV0dXJuIG5ldyBHbG9yb3RVbmlmb3JtO2lmKGFhPT09IkhlTm9ybWFsIilyZXR1cm4gbmV3IEhlTm9ybWFsO2lmKGFhPT09IkhlVW5pZm9ybSIpcmV0dXJuIG5ldyBIZVVuaWZvcm07aWYoYWE9PT0iTGVDdW5Ob3JtYWwiKXJldHVybiBuZXcgTGVDdW5Ob3JtYWw7aWYoYWE9PT0iTGVDdW5Vbmlmb3JtIilyZXR1cm4gbmV3IExlQ3VuVW5pZm9ybTt7Y29uc3QgeGE9e307cmV0dXJuIHhhLmNsYXNzTmFtZT1hYSx4YS5jb25maWc9e30sZGVzZXJpYWxpemVJbml0aWFsaXplcih4YSl9fWVsc2UgcmV0dXJuIGhhIGluc3RhbmNlb2YgSW5pdGlhbGl6ZXI/aGE6ZGVzZXJpYWxpemVJbml0aWFsaXplcihoYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaXNBcnJheU9mU2hhcGVzKGhhKXtyZXR1cm4gQXJyYXkuaXNBcnJheShoYSkmJkFycmF5LmlzQXJyYXkoaGFbMF0pfWZ1bmN0aW9uIG5vcm1hbGl6ZVNoYXBlTGlzdChoYSl7cmV0dXJuIGhhLmxlbmd0aD09PTA/W106QXJyYXkuaXNBcnJheShoYVswXSk/aGE6W2hhXX1mdW5jdGlvbiBnZXRFeGFjdGx5T25lVGVuc29yKGhhKXtsZXQgYWE7aWYoQXJyYXkuaXNBcnJheShoYSkpe2lmKGhhLmxlbmd0aCE9PTEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEV4cGVjdGVkIFRlbnNvciBsZW5ndGggdG8gYmUgMTsgZ290ICR7aGEubGVuZ3RofWApO2FhPWhhWzBdfWVsc2UgYWE9aGE7cmV0dXJuIGFhfWZ1bmN0aW9uIGdldEV4YWN0bHlPbmVTaGFwZShoYSl7aWYoQXJyYXkuaXNBcnJheShoYSkmJkFycmF5LmlzQXJyYXkoaGFbMF0pKXtpZihoYS5sZW5ndGg9PT0xKXJldHVybiBoYT1oYSxoYVswXTt0aHJvdyBuZXcgVmFsdWVFcnJvcihgRXhwZWN0ZWQgZXhhY3RseSAxIFNoYXBlOyBnb3QgJHtoYS5sZW5ndGh9YCl9ZWxzZSByZXR1cm4gaGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY291bnRQYXJhbXNJbldlaWdodHMoaGEpe2xldCBhYT0wO2Zvcihjb25zdCB4YSBvZiBoYSl4YS5zaGFwZS5sZW5ndGg9PT0wP2FhKz0xOmFhKz14YS5zaGFwZS5yZWR1Y2UoKGJhLFNhKT0+YmEqU2EpO3JldHVybiBhYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBERUZBVUxUX1ZBUklBQkxFX05BTUVfUFJFRklYPSJWYXJpYWJsZSI7Y2xhc3MgTGF5ZXJWYXJpYWJsZXtjb25zdHJ1Y3RvcihhYSx4YT0iZmxvYXQzMiIsYmE9REVGQVVMVF9WQVJJQUJMRV9OQU1FX1BSRUZJWCxTYT0hMCxUYT1udWxsKXt0aGlzLmR0eXBlPXhhPz8iZmxvYXQzMiIsdGhpcy5zaGFwZT1hYS5zaGFwZSx0aGlzLmlkPWdldE5leHRVbmlxdWVUZW5zb3JJZCgpLGJhPWJhPz9ERUZBVUxUX1ZBUklBQkxFX05BTUVfUFJFRklYLHRoaXMub3JpZ2luYWxOYW1lPWdldFNjb3BlZFRlbnNvck5hbWUoYmEpLHRoaXMubmFtZT1nZXRVbmlxdWVUZW5zb3JOYW1lKHRoaXMub3JpZ2luYWxOYW1lKSx0aGlzLnRyYWluYWJsZV89U2EsdGhpcy5jb25zdHJhaW50PVRhLHRoaXMudmFsPXZhcmlhYmxlKGFhLHRoaXMudHJhaW5hYmxlXyx0aGlzLm5hbWUsdGhpcy5kdHlwZSl9cmVhZCgpe3JldHVybiB0aGlzLmFzc2VydE5vdERpc3Bvc2VkKCksdGhpcy52YWx9d3JpdGUoYWEpe3JldHVybiB0aGlzLmFzc2VydE5vdERpc3Bvc2VkKCksY2hlY2tTaGFwZXNNYXRjaCh0aGlzLnZhbCxhYSksdGhpcy52YWwuaWQhPT1hYS5pZCYmKHRoaXMudmFsLmFzc2lnbihhYSksdGhpcy5jb25zdHJhaW50IT1udWxsJiZ0aGlzLnZhbC5hc3NpZ24odGhpcy5jb25zdHJhaW50LmFwcGx5KHRoaXMudmFsKSkpLHRoaXN9ZGlzcG9zZSgpe3RoaXMuYXNzZXJ0Tm90RGlzcG9zZWQoKSx0aGlzLnZhbC5kaXNwb3NlKCl9YXNzZXJ0Tm90RGlzcG9zZWQoKXtpZih0aGlzLnZhbC5pc0Rpc3Bvc2VkKXRocm93IG5ldyBFcnJvcihgTGF5ZXJzVmFyaWFibGUgJHt0aGlzLm5hbWV9IGlzIGFscmVhZHkgZGlzcG9zZWQuYCl9Z2V0IHRyYWluYWJsZSgpe3JldHVybiB0aGlzLnRyYWluYWJsZV99c2V0IHRyYWluYWJsZShhYSl7dGhpcy50cmFpbmFibGVfPWFhLHRoaXMudmFsLnRyYWluYWJsZT1hYX19ZnVuY3Rpb24gY2hlY2tTaGFwZXNNYXRjaChoYSxhYSl7aWYoaGEuc2hhcGUudG9TdHJpbmcoKSE9PWFhLnNoYXBlLnRvU3RyaW5nKCkpdGhyb3cgbmV3IEVycm9yKCJTaGFwZSBtaXNtYXRjaDogIitKU09OLnN0cmluZ2lmeShoYS5zaGFwZSkrIiB2cy4gIitKU09OLnN0cmluZ2lmeShhYS5zaGFwZSkpfWZ1bmN0aW9uIGJhdGNoR2V0VmFsdWUoaGEpe3JldHVybiBoYS5tYXAoYWE9PmFhLnJlYWQoKSl9ZnVuY3Rpb24gYmF0Y2hTZXRWYWx1ZShoYSl7aGEuZm9yRWFjaChhYT0+e2FhWzBdLndyaXRlKGFhWzFdKX0pfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIElucHV0U3BlY3tjb25zdHJ1Y3RvcihhYSl7dGhpcy5kdHlwZT1hYS5kdHlwZSx0aGlzLnNoYXBlPWFhLnNoYXBlLGFhLnNoYXBlIT1udWxsP3RoaXMubmRpbT1hYS5zaGFwZS5sZW5ndGg6dGhpcy5uZGltPWFhLm5kaW0sdGhpcy5tYXhORGltPWFhLm1heE5EaW0sdGhpcy5taW5ORGltPWFhLm1pbk5EaW0sdGhpcy5heGVzPWFhLmF4ZXN8fHt9fX1jbGFzcyBTeW1ib2xpY1RlbnNvcntjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSx3YSxFYSl7dGhpcy5kdHlwZT1hYSx0aGlzLnNoYXBlPXhhLHRoaXMuc291cmNlTGF5ZXI9YmEsdGhpcy5pbnB1dHM9U2EsdGhpcy5jYWxsQXJncz1UYSx0aGlzLm91dHB1dFRlbnNvckluZGV4PUVhLHRoaXMuaWQ9Z2V0TmV4dFVuaXF1ZVRlbnNvcklkKCksd2EhPW51bGwmJih0aGlzLm9yaWdpbmFsTmFtZT1nZXRTY29wZWRUZW5zb3JOYW1lKHdhKSx0aGlzLm5hbWU9Z2V0VW5pcXVlVGVuc29yTmFtZSh0aGlzLm9yaWdpbmFsTmFtZSkpLHRoaXMucmFuaz14YS5sZW5ndGh9fWxldCBfbmV4dE5vZGVJRD0wO2NsYXNzIE5vZGV7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMuY2FsbEFyZ3M9eGEsdGhpcy5pZD1fbmV4dE5vZGVJRCsrLHRoaXMub3V0Ym91bmRMYXllcj1hYS5vdXRib3VuZExheWVyLHRoaXMuaW5ib3VuZExheWVycz1hYS5pbmJvdW5kTGF5ZXJzLHRoaXMubm9kZUluZGljZXM9YWEubm9kZUluZGljZXMsdGhpcy50ZW5zb3JJbmRpY2VzPWFhLnRlbnNvckluZGljZXMsdGhpcy5pbnB1dFRlbnNvcnM9YWEuaW5wdXRUZW5zb3JzLHRoaXMub3V0cHV0VGVuc29ycz1hYS5vdXRwdXRUZW5zb3JzLHRoaXMuaW5wdXRNYXNrcz1hYS5pbnB1dE1hc2tzLHRoaXMub3V0cHV0TWFza3M9YWEub3V0cHV0TWFza3MsdGhpcy5pbnB1dFNoYXBlcz1hYS5pbnB1dFNoYXBlcyx0aGlzLm91dHB1dFNoYXBlcz1hYS5vdXRwdXRTaGFwZXM7Zm9yKGNvbnN0IGJhIG9mIGFhLmluYm91bmRMYXllcnMpYmEhPW51bGwmJmJhLm91dGJvdW5kTm9kZXMucHVzaCh0aGlzKTthYS5vdXRib3VuZExheWVyLmluYm91bmROb2Rlcy5wdXNoKHRoaXMpfWdldENvbmZpZygpe2NvbnN0IGFhPVtdO2Zvcihjb25zdCB4YSBvZiB0aGlzLmluYm91bmRMYXllcnMpeGEhPW51bGw/YWEucHVzaCh4YS5uYW1lKTphYS5wdXNoKG51bGwpO3JldHVybntvdXRib3VuZExheWVyOnRoaXMub3V0Ym91bmRMYXllcj90aGlzLm91dGJvdW5kTGF5ZXIubmFtZTpudWxsLGluYm91bmRMYXllcnM6YWEsbm9kZUluZGljZXM6dGhpcy5ub2RlSW5kaWNlcyx0ZW5zb3JJbmRpY2VzOnRoaXMudGVuc29ySW5kaWNlc319fWxldCBfbmV4dExheWVySUQ9MDtjbGFzcyBMYXllciBleHRlbmRzIFNlcmlhbGl6YWJsZSQxe2NvbnN0cnVjdG9yKGFhPXt9KXtzdXBlcigpLHRoaXMuX2NhbGxIb29rPW51bGwsdGhpcy5fYWRkZWRXZWlnaHROYW1lcz1bXSx0aGlzLl9zdGF0ZWZ1bD0hMSx0aGlzLmlkPV9uZXh0TGF5ZXJJRCsrLHRoaXMuYWN0aXZpdHlSZWd1bGFyaXplcj1udWxsLHRoaXMuaW5wdXRTcGVjPW51bGwsdGhpcy5zdXBwb3J0c01hc2tpbmc9ITEsdGhpcy5fdHJhaW5hYmxlV2VpZ2h0cz1bXSx0aGlzLl9ub25UcmFpbmFibGVXZWlnaHRzPVtdLHRoaXMuX2xvc3Nlcz1bXSx0aGlzLl91cGRhdGVzPVtdLHRoaXMuX2J1aWx0PSExLHRoaXMuaW5ib3VuZE5vZGVzPVtdLHRoaXMub3V0Ym91bmROb2Rlcz1bXTtsZXQgeGE9YWEubmFtZTtpZigheGEpe2NvbnN0IGJhPXRoaXMuZ2V0Q2xhc3NOYW1lKCk7eGE9dG9TbmFrZUNhc2UoYmEpKyJfIitnZXRVaWQoYmEpfWlmKHRoaXMubmFtZT14YSx0aGlzLnRyYWluYWJsZV89YWEudHJhaW5hYmxlPT1udWxsPyEwOmFhLnRyYWluYWJsZSxhYS5pbnB1dFNoYXBlIT1udWxsfHxhYS5iYXRjaElucHV0U2hhcGUhPW51bGwpe2xldCBiYTtpZihhYS5iYXRjaElucHV0U2hhcGUhPW51bGwpYmE9YWEuYmF0Y2hJbnB1dFNoYXBlO2Vsc2UgaWYoYWEuaW5wdXRTaGFwZSE9bnVsbCl7bGV0IFRhPW51bGw7YWEuYmF0Y2hTaXplIT1udWxsJiYoVGE9YWEuYmF0Y2hTaXplKSxiYT1bVGFdLmNvbmNhdChhYS5pbnB1dFNoYXBlKX10aGlzLmJhdGNoSW5wdXRTaGFwZT1iYTtsZXQgU2E9YWEuZHR5cGU7U2E9PW51bGwmJihTYT1hYS5pbnB1dERUeXBlKSxTYT09bnVsbCYmKFNhPSJmbG9hdDMyIiksdGhpcy5kdHlwZT1TYX1hYS53ZWlnaHRzIT1udWxsP3RoaXMuaW5pdGlhbFdlaWdodHM9YWEud2VpZ2h0czp0aGlzLmluaXRpYWxXZWlnaHRzPW51bGwsdGhpcy5fcmVmQ291bnQ9bnVsbCx0aGlzLmZhc3RXZWlnaHRJbml0RHVyaW5nQnVpbGQ9ITF9c3RhdGljIG5vZGVLZXkoYWEseGEpe3JldHVybiBhYS5uYW1lKyJfaWItIit4YS50b1N0cmluZygpfWdldE5vZGVBdEluZGV4KGFhLHhhKXtpZih0aGlzLmluYm91bmROb2Rlcy5sZW5ndGg9PT0wKXRocm93IG5ldyBSdW50aW1lRXJyb3IoYFRoZSBsYXllciBoYXMgbmV2ZXIgYmVlbiBjYWxsZWQgYW5kIHRodXMgaGFzIG5vIGRlZmluZWQgJHt4YX0uYCk7aWYodGhpcy5pbmJvdW5kTm9kZXMubGVuZ3RoPD1hYSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQXNrZWQgdG8gZ2V0ICR7eGF9IGF0IG5vZGUgJHthYX0sIGJ1dCB0aGUgbGF5ZXIgaGFzIG9ubHkgJHt0aGlzLmluYm91bmROb2Rlcy5sZW5ndGh9IGluYm91bmQgbm9kZXMuYCk7cmV0dXJuIHRoaXMuaW5ib3VuZE5vZGVzW2FhXX1nZXRJbnB1dEF0KGFhKXtyZXR1cm4gc2luZ2xldG9uT3JBcnJheSh0aGlzLmdldE5vZGVBdEluZGV4KGFhLCJpbnB1dCIpLmlucHV0VGVuc29ycyl9Z2V0T3V0cHV0QXQoYWEpe3JldHVybiBzaW5nbGV0b25PckFycmF5KHRoaXMuZ2V0Tm9kZUF0SW5kZXgoYWEsIm91dHB1dCIpLm91dHB1dFRlbnNvcnMpfWdldCBpbnB1dCgpe2lmKHRoaXMuaW5ib3VuZE5vZGVzLmxlbmd0aD4xKXRocm93IG5ldyBBdHRyaWJ1dGVFcnJvcihgTGF5ZXIgJHt0aGlzLm5hbWV9IGhhcyBtdWx0aXBsZSBpbmJvdW5kIG5vZGVzLCBoZW5jZSB0aGUgbm90aW9uIG9mICJsYXllciBpbnB1dCIgaXMgaWxsLWRlZmluZWQuIFVzZSBcYGdldElucHV0QXQobm9kZUluZGV4KVxgIGluc3RlYWQuYCk7aWYodGhpcy5pbmJvdW5kTm9kZXMubGVuZ3RoPT09MCl0aHJvdyBuZXcgQXR0cmlidXRlRXJyb3IoYExheWVyICR7dGhpcy5uYW1lfSBpcyBub3QgY29ubmVjdGVkLCBubyBpbnB1dCB0byByZXR1cm4uYCk7cmV0dXJuIHNpbmdsZXRvbk9yQXJyYXkodGhpcy5nZXROb2RlQXRJbmRleCgwLCJpbnB1dCIpLmlucHV0VGVuc29ycyl9Z2V0IG91dHB1dCgpe2lmKHRoaXMuaW5ib3VuZE5vZGVzLmxlbmd0aD09PTApdGhyb3cgbmV3IEF0dHJpYnV0ZUVycm9yKGBMYXllciAke3RoaXMubmFtZX0gaGFzIG5vIGluYm91bmQgbm9kZXMuYCk7aWYodGhpcy5pbmJvdW5kTm9kZXMubGVuZ3RoPjEpdGhyb3cgbmV3IEF0dHJpYnV0ZUVycm9yKGBMYXllciAke3RoaXMubmFtZX0gaGFzIG11bHRpcGxlIGluYm91bmQgbm9kZXMsIGhlbmNlIHRoZSBub3Rpb24gb2YgImxheWVyIG91dHB1dCIgaXMgaWxsLWRlZmluZWQuIFVzZSBcYGdldE91dHB1dEF0KG5vZGVJbmRleClcYCBpbnN0ZWFkLmApO3JldHVybiBzaW5nbGV0b25PckFycmF5KHRoaXMuZ2V0Tm9kZUF0SW5kZXgoMCwib3V0cHV0Iikub3V0cHV0VGVuc29ycyl9Z2V0IGxvc3Nlcygpe3JldHVybiB0aGlzLl9sb3NzZXN9Y2FsY3VsYXRlTG9zc2VzKCl7cmV0dXJuIHRoaXMubG9zc2VzLm1hcChhYT0+YWEoKSl9Z2V0IHVwZGF0ZXMoKXtyZXR1cm4gdGhpcy5fdXBkYXRlc31nZXQgYnVpbHQoKXtyZXR1cm4gdGhpcy5fYnVpbHR9c2V0IGJ1aWx0KGFhKXt0aGlzLl9idWlsdD1hYX1nZXQgdHJhaW5hYmxlKCl7cmV0dXJuIHRoaXMudHJhaW5hYmxlX31zZXQgdHJhaW5hYmxlKGFhKXt0aGlzLl90cmFpbmFibGVXZWlnaHRzLmZvckVhY2goeGE9PnhhLnRyYWluYWJsZT1hYSksdGhpcy50cmFpbmFibGVfPWFhfWdldCB0cmFpbmFibGVXZWlnaHRzKCl7cmV0dXJuIHRoaXMudHJhaW5hYmxlXz90aGlzLl90cmFpbmFibGVXZWlnaHRzLmZpbHRlcihhYT0+YWEudHJhaW5hYmxlKTpbXX1zZXQgdHJhaW5hYmxlV2VpZ2h0cyhhYSl7dGhpcy5fdHJhaW5hYmxlV2VpZ2h0cz1hYX1nZXQgbm9uVHJhaW5hYmxlV2VpZ2h0cygpe3JldHVybiB0aGlzLnRyYWluYWJsZT90aGlzLl90cmFpbmFibGVXZWlnaHRzLmZpbHRlcihhYT0+IWFhLnRyYWluYWJsZSkuY29uY2F0KHRoaXMuX25vblRyYWluYWJsZVdlaWdodHMpOnRoaXMuX3RyYWluYWJsZVdlaWdodHMuY29uY2F0KHRoaXMuX25vblRyYWluYWJsZVdlaWdodHMpfXNldCBub25UcmFpbmFibGVXZWlnaHRzKGFhKXt0aGlzLl9ub25UcmFpbmFibGVXZWlnaHRzPWFhfWdldCB3ZWlnaHRzKCl7cmV0dXJuIHRoaXMudHJhaW5hYmxlV2VpZ2h0cy5jb25jYXQodGhpcy5ub25UcmFpbmFibGVXZWlnaHRzKX1nZXQgc3RhdGVmdWwoKXtyZXR1cm4gdGhpcy5fc3RhdGVmdWx9cmVzZXRTdGF0ZXMoKXtpZighdGhpcy5zdGF0ZWZ1bCl0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBjYWxsIHRoZSByZXNldFN0YXRlcygpIG1ldGhvZCBvZiBhIG5vbi1zdGF0ZWZ1bCBMYXllciBvYmplY3QuIil9YXNzZXJ0SW5wdXRDb21wYXRpYmlsaXR5KGFhKXtjb25zdCB4YT10b0xpc3QoYWEpO2lmKHRoaXMuaW5wdXRTcGVjPT1udWxsfHx0aGlzLmlucHV0U3BlYy5sZW5ndGg9PT0wKXJldHVybjtjb25zdCBiYT10b0xpc3QodGhpcy5pbnB1dFNwZWMpO2lmKHhhLmxlbmd0aCE9PWJhLmxlbmd0aCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgTGF5ZXIgJHt0aGlzLm5hbWV9IGV4cGVjdHMgJHtiYS5sZW5ndGh9IGlucHV0cywgYnV0IGl0IHJlY2VpdmVkICR7eGEubGVuZ3RofSBpbnB1dCB0ZW5zb3JzLiBJbnB1dCByZWNlaXZlZDogJHthYX1gKTtmb3IobGV0IFNhPTA7U2E8eGEubGVuZ3RoO1NhKyspe2NvbnN0IFRhPXhhW1NhXSx3YT1iYVtTYV07aWYod2E9PW51bGwpY29udGludWU7Y29uc3QgRWE9VGEucmFuaztpZih3YS5uZGltIT1udWxsJiZFYSE9PXdhLm5kaW0pdGhyb3cgbmV3IFZhbHVlRXJyb3IoYElucHV0ICR7U2F9IGlzIGluY29tcGF0aWJsZSB3aXRoIGxheWVyICR7dGhpcy5uYW1lfTogZXhwZWN0ZWQgbmRpbT0ke3dhLm5kaW19LCBmb3VuZCBuZGltPSR7RWF9YCk7aWYod2EubWF4TkRpbSE9bnVsbCYmRWE+d2EubWF4TkRpbSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW5wdXQgJHtTYX0gaXMgaW5jb21wYXRpYmxlIHdpdGggbGF5ZXIgJHt0aGlzLm5hbWV9OiBleHBlY3RlZCBtYXhfbmRpbT0ke3dhLm1heE5EaW19LCBmb3VuZCBuZGltPSR7RWF9YCk7aWYod2EubWluTkRpbSE9bnVsbCYmRWE8d2EubWluTkRpbSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW5wdXQgJHtTYX0gaXMgaW5jb21wYXRpYmxlIHdpdGggbGF5ZXIgJHt0aGlzLm5hbWV9OiBleHBlY3RlZCBtaW5fbmRpbT0ke3dhLm1pbk5EaW19LCBmb3VuZCBuZGltPSR7RWF9LmApO2lmKHdhLmR0eXBlIT1udWxsJiZUYS5kdHlwZSE9PXdhLmR0eXBlKXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbnB1dCAke1NhfSBpcyBpbmNvbXBhdGlibGUgd2l0aCBsYXllciAke3RoaXMubmFtZX0gOiBleHBlY3RlZCBkdHlwZT0ke3dhLmR0eXBlfSwgZm91bmQgZHR5cGU9JHtUYS5kdHlwZX0uYCk7aWYod2EuYXhlcyl7Y29uc3Qga2E9VGEuc2hhcGU7Zm9yKGNvbnN0IEFhIGluIHdhLmF4ZXMpe2NvbnN0IEZhPU51bWJlcihBYSksTGE9d2EuYXhlc1tBYV0sZWw9RmE+PTA/a2FbRmFdOmthW2thLmxlbmd0aCtGYV07aWYoTGEhPW51bGwmJltMYSxudWxsXS5pbmRleE9mKGVsKT09PS0xKXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbnB1dCAke1NhfSBpcyBpbmNvbXBhdGlibGUgd2l0aCBsYXllciAke3RoaXMubmFtZX06IGV4cGVjdGVkIGF4aXMgJHtGYX0gb2YgaW5wdXQgc2hhcGUgdG8gaGF2ZSB2YWx1ZSAke0xhfSBidXQgZ290IHNoYXBlICR7a2F9LmApfX1pZih3YS5zaGFwZSE9bnVsbClmb3IobGV0IGthPTA7a2E8d2Euc2hhcGUubGVuZ3RoOysra2Epe2NvbnN0IEFhPXdhLnNoYXBlW2thXSxGYT1UYS5zaGFwZVtrYV07aWYoQWEhPW51bGwmJkZhIT1udWxsJiZBYSE9PUZhKXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbnB1dCAke1NhfSBpcyBpbmNvbXBhdGlibGUgd2l0aCBsYXllciAke3RoaXMubmFtZX06IGV4cGVjdGVkIHNoYXBlPSR7d2Euc2hhcGV9LCBmb3VuZCBzaGFwZT0ke1RhLnNoYXBlfS5gKX19fWNhbGwoYWEseGEpe3JldHVybiBhYX1pbnZva2VDYWxsSG9vayhhYSx4YSl7dGhpcy5fY2FsbEhvb2shPW51bGwmJnRoaXMuX2NhbGxIb29rKGFhLHhhKX1zZXRDYWxsSG9vayhhYSl7dGhpcy5fY2FsbEhvb2s9YWF9Y2xlYXJDYWxsSG9vaygpe3RoaXMuX2NhbGxIb29rPW51bGx9YXBwbHkoYWEseGEpe3hhPXhhfHx7fSx0aGlzLmFzc2VydE5vdERpc3Bvc2VkKCk7Y29uc3QgYmE9dG9MaXN0KGFhKSxTYT1jaGVja0FsbFN5bWJvbGljKGFhKSxUYT1jaGVja05vbmVTeW1ib2xpYyhhYSk7aWYoU2E9PT1UYSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQXJndW1lbnRzIHRvIGFwcGx5KCkgbXVzdCBiZSBhbGwgU3ltYm9saWNUZW5zb3JzIG9yIGFsbCBUZW5zb3JzIik7cmV0dXJuIG5hbWVTY29wZSh0aGlzLm5hbWUsKCk9PntpZighdGhpcy5idWlsdCl7dGhpcy5hc3NlcnRJbnB1dENvbXBhdGliaWxpdHkoYWEpO2NvbnN0IHdhPVtdO2Zvcihjb25zdCBFYSBvZiB0b0xpc3QoYWEpKXdhLnB1c2goRWEuc2hhcGUpO3RoaXMuYnVpbGQoc2luZ2xldG9uT3JBcnJheSh3YSkpLHRoaXMuYnVpbHQ9ITAsdGhpcy5pbml0aWFsV2VpZ2h0cyYmdGhpcy5zZXRXZWlnaHRzKHRoaXMuaW5pdGlhbFdlaWdodHMpLHRoaXMuX3JlZkNvdW50PT09bnVsbCYmVGEmJih0aGlzLl9yZWZDb3VudD0xKX1pZih0aGlzLmFzc2VydElucHV0Q29tcGF0aWJpbGl0eShhYSksVGEpe2xldCB3YT10aGlzLmNhbGwoYWEseGEpO3RoaXMuc3VwcG9ydHNNYXNraW5nJiZ0aGlzLnNldE1hc2tNZXRhZGF0YShhYSx3YSk7Y29uc3QgRWE9dG9MaXN0KHdhKSxrYT1bXTtmb3IobGV0IEFhIG9mIEVhKWJhLmluZGV4T2YoQWEpIT09LTEmJihBYT1BYS5jbG9uZSgpKSxrYS5wdXNoKEFhKTtpZih3YT1zaW5nbGV0b25PckFycmF5KGthKSx0aGlzLmFjdGl2aXR5UmVndWxhcml6ZXIhPW51bGwpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoIkxheWVyIGludm9jYXRpb24gaW4gdGhlIHByZXNlbmNlIG9mIGFjdGl2aXR5IHJlZ3VsYXJpemVyKHMpIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LiIpO3JldHVybiB3YX1lbHNle2NvbnN0IHdhPWNvbGxlY3RJbnB1dFNoYXBlKGFhKSxFYT10aGlzLmNvbXB1dGVPdXRwdXRTaGFwZSh3YSk7bGV0IGthO2NvbnN0IEFhPWd1ZXNzT3V0cHV0RFR5cGUoYWEpO2lmKHRoaXMud2Fybk9uSW5jb21wYXRpYmxlSW5wdXRTaGFwZShBcnJheS5pc0FycmF5KGFhKT93YVswXTp3YSksRWEhPW51bGwmJkVhLmxlbmd0aD4wJiZBcnJheS5pc0FycmF5KEVhWzBdKT9rYT1FYS5tYXAoKEZhLExhKT0+bmV3IFN5bWJvbGljVGVuc29yKEFhLEZhLHRoaXMsdG9MaXN0KGFhKSx4YSx0aGlzLm5hbWUsTGEpKTprYT1uZXcgU3ltYm9saWNUZW5zb3IoQWEsRWEsdGhpcyx0b0xpc3QoYWEpLHhhLHRoaXMubmFtZSksdGhpcy5hZGRJbmJvdW5kTm9kZShhYSxrYSxudWxsLG51bGwsd2EsRWEseGEpLHRoaXMuX3JlZkNvdW50KyssdGhpcy5hY3Rpdml0eVJlZ3VsYXJpemVyIT1udWxsKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJMYXllciBpbnZvY2F0aW9uIGluIHRoZSBwcmVzZW5jZSBvZiBhY3Rpdml0eSByZWd1bGFyaXplcihzKSBpcyBub3Qgc3VwcG9ydGVkIHlldC4iKTtyZXR1cm4ga2F9fSl9d2Fybk9uSW5jb21wYXRpYmxlSW5wdXRTaGFwZShhYSl7aWYodGhpcy5iYXRjaElucHV0U2hhcGUhPW51bGwpaWYoYWEubGVuZ3RoIT09dGhpcy5iYXRjaElucHV0U2hhcGUubGVuZ3RoKWNvbnNvbGUud2FybihgVGhlIHJhbmsgb2YgdGhlIGlucHV0IHRlbnNvciBwcm92aWRlZCAoc2hhcGU6ICR7SlNPTi5zdHJpbmdpZnkoYWEpfSkgZG9lcyBub3QgbWF0Y2ggdGhhdCBvZiB0aGUgYmF0Y2hJbnB1dFNoYXBlICgke0pTT04uc3RyaW5naWZ5KHRoaXMuYmF0Y2hJbnB1dFNoYXBlKX0pIG9mIHRoZSBsYXllciAke3RoaXMubmFtZX1gKTtlbHNle2xldCB4YT0hMTt0aGlzLmJhdGNoSW5wdXRTaGFwZS5mb3JFYWNoKChiYSxTYSk9PntiYSE9bnVsbCYmYWFbU2FdIT1udWxsJiZhYVtTYV0hPT1iYSYmKHhhPSEwKX0pLHhhJiZjb25zb2xlLndhcm4oYFRoZSBzaGFwZSBvZiB0aGUgaW5wdXQgdGVuc29yICgke0pTT04uc3RyaW5naWZ5KGFhKX0pIGRvZXMgbm90IG1hdGNoIHRoZSBleHBlY3RhdGlvbiBvZiBsYXllciAke3RoaXMubmFtZX06ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5iYXRjaElucHV0U2hhcGUpfWApfX1nZXQgb3V0cHV0U2hhcGUoKXtpZih0aGlzLmluYm91bmROb2Rlcz09bnVsbHx8dGhpcy5pbmJvdW5kTm9kZXMubGVuZ3RoPT09MCl0aHJvdyBuZXcgQXR0cmlidXRlRXJyb3IoYFRoZSBsYXllciAke3RoaXMubmFtZX0gaGFzIG5ldmVyIGJlZW4gY2FsbGVkIGFuZCB0aHVzIGhhcyBubyBkZWZpbmVkIG91dHB1dCBzaGFwZS5gKTtjb25zdCBhYT1bXTtmb3IoY29uc3QgeGEgb2YgdGhpcy5pbmJvdW5kTm9kZXMpe2NvbnN0IGJhPUpTT04uc3RyaW5naWZ5KHhhLm91dHB1dFNoYXBlcyk7YWEuaW5kZXhPZihiYSk9PT0tMSYmYWEucHVzaChiYSl9aWYoYWEubGVuZ3RoPT09MSl7Y29uc3QgeGE9dGhpcy5pbmJvdW5kTm9kZXNbMF0ub3V0cHV0U2hhcGVzO3JldHVybiBBcnJheS5pc0FycmF5KHhhKSYmQXJyYXkuaXNBcnJheSh4YVswXSkmJnhhLmxlbmd0aD09PTE/eGFbMF06eGF9ZWxzZSB0aHJvdyBuZXcgQXR0cmlidXRlRXJyb3IoYFRoZSBsYXllciAke3RoaXMubmFtZX0gaGFzIG11bHRpcGxlIGluYm91bmQgbm9kZXMgd2l0aCBkaWZmZXJlbnQgb3V0cHV0IHNoYXBlcy4gSGVuY2UgdGhlIG5vdGlvbiBvZiAib3V0cHV0IHNoYXBlIiBpcyBpbGwtZGVmaW5lZCBmb3IgdGhlIGxheWVyLmApfWNvdW50UGFyYW1zKCl7aWYoIXRoaXMuYnVpbHQpdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgWW91IHRyaWVkIHRvIGNhbGwgY291bnRQYXJhbXMoKSBvbiAke3RoaXMubmFtZX0sIGJ1dCB0aGUgbGF5ZXIgaXMgbm90IGJ1aWx0IHlldC4gQnVpbGQgaXQgZmlyc3QgYnkgY2FsbGluZyBidWlsZChiYXRjaElucHV0U2hhcGUpLmApO3JldHVybiBjb3VudFBhcmFtc0luV2VpZ2h0cyh0aGlzLndlaWdodHMpfWJ1aWxkKGFhKXt0aGlzLmJ1aWx0PSEwfWdldFdlaWdodHMoYWE9ITEpe3JldHVybiBiYXRjaEdldFZhbHVlKGFhP3RoaXMudHJhaW5hYmxlV2VpZ2h0czp0aGlzLndlaWdodHMpfXNldFdlaWdodHMoYWEpe3RpZHkkMSgoKT0+e2NvbnN0IHhhPXRoaXMud2VpZ2h0cztpZih4YS5sZW5ndGghPT1hYS5sZW5ndGgpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFlvdSBjYWxsZWQgc2V0V2VpZ2h0cyh3ZWlnaHRzKSBvbiBsYXllciAiJHt0aGlzLm5hbWV9IiB3aXRoIGEgd2VpZ2h0IGxpc3Qgb2YgbGVuZ3RoICR7YWEubGVuZ3RofSwgYnV0IHRoZSBsYXllciB3YXMgZXhwZWN0aW5nICR7eGEubGVuZ3RofSB3ZWlnaHRzLiBQcm92aWRlZCB3ZWlnaHRzOiAke2FhfS4uLmApO2lmKHhhLmxlbmd0aD09PTApcmV0dXJuO2NvbnN0IGJhPVtdLFNhPWJhdGNoR2V0VmFsdWUoeGEpO2ZvcihsZXQgVGE9MDtUYTxTYS5sZW5ndGg7KytUYSl7Y29uc3Qgd2E9U2FbVGFdLEVhPXhhW1RhXSxrYT1hYVtUYV07aWYoIWFycmF5c0VxdWFsJDEod2Euc2hhcGUsa2Euc2hhcGUpKXRocm93IG5ldyBWYWx1ZUVycm9yKGBMYXllciB3ZWlnaHQgc2hhcGUgJHt3YS5zaGFwZX0gbm90IGNvbXBhdGlibGUgd2l0aCBwcm92aWRlZCB3ZWlnaHQgc2hhcGUgJHtrYS5zaGFwZX1gKTtiYS5wdXNoKFtFYSxrYV0pfWJhdGNoU2V0VmFsdWUoYmEpfSl9YWRkV2VpZ2h0KGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthKXtpZih0aGlzLl9hZGRlZFdlaWdodE5hbWVzLmluZGV4T2YoYWEpIT09LTEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYER1cGxpY2F0ZSB3ZWlnaHQgbmFtZSAke2FhfSBmb3IgbGF5ZXIgJHt0aGlzLm5hbWV9YCk7dGhpcy5fYWRkZWRXZWlnaHROYW1lcy5wdXNoKGFhKSxiYT09bnVsbCYmKGJhPSJmbG9hdDMyIiksdGhpcy5mYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkJiYoU2E9a2EhPW51bGw/a2EoKTpnZXRJbml0aWFsaXplcigiemVyb3MiKSk7Y29uc3QgQWE9U2EuYXBwbHkoeGEsYmEpLEZhPW5ldyBMYXllclZhcmlhYmxlKEFhLGJhLGFhLHdhLEVhKTtyZXR1cm4gQWEuZGlzcG9zZSgpLFRhIT1udWxsJiZ0aGlzLmFkZExvc3MoKCk9PlRhLmFwcGx5KEZhLnJlYWQoKSkpLHdhPT1udWxsJiYod2E9ITApLHdhP3RoaXMuX3RyYWluYWJsZVdlaWdodHMucHVzaChGYSk6dGhpcy5fbm9uVHJhaW5hYmxlV2VpZ2h0cy5wdXNoKEZhKSxGYX1zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKXt0aGlzLmZhc3RXZWlnaHRJbml0RHVyaW5nQnVpbGQ9YWF9YWRkTG9zcyhhYSl7YWE9PW51bGx8fEFycmF5LmlzQXJyYXkoYWEpJiZhYS5sZW5ndGg9PT0wfHwoYWE9dG9MaXN0KGFhKSx0aGlzLl9sb3NzZXMhPT12b2lkIDAmJnRoaXMuX2xvc3NlcyE9PW51bGwmJnRoaXMubG9zc2VzLnB1c2goLi4uYWEpKX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYX1jb21wdXRlTWFzayhhYSx4YSl7aWYoIXRoaXMuc3VwcG9ydHNNYXNraW5nKXtpZih4YSE9bnVsbClpZihBcnJheS5pc0FycmF5KHhhKSl4YS5mb3JFYWNoKGJhPT57aWYoYmEhPW51bGwpdGhyb3cgbmV3IFR5cGVFcnJvcihgTGF5ZXIgJHt0aGlzLm5hbWV9IGRvZXMgbm90IHN1cHBvcnQgbWFza2luZywgYnV0IHdhcyBwYXNzZWQgYW4gaW5wdXRNYXNrLmApfSk7ZWxzZSB0aHJvdyBuZXcgVHlwZUVycm9yKGBMYXllciAke3RoaXMubmFtZX0gZG9lcyBub3Qgc3VwcG9ydCBtYXNraW5nLCBidXQgd2FzIHBhc3NlZCBhbiBpbnB1dE1hc2suYCk7cmV0dXJuIG51bGx9cmV0dXJuIHhhfXNldE1hc2tNZXRhZGF0YShhYSx4YSxiYSl7aWYoIXRoaXMuc3VwcG9ydHNNYXNraW5nKXJldHVybjtjb25zdCBTYT10aGlzLmNvbXB1dGVNYXNrKGFhLGJhKSxUYT10b0xpc3QoeGEpLHdhPXRvTGlzdChTYSk7aWYoVGEubGVuZ3RoIT09d2EubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5hbWV9IG91dHB1dHMgJHtUYS5sZW5ndGh9IHRlbnNvcnMgYnV0ICR7VGEubGVuZ3RofSBtYXNrcyBmb3IgdGhvc2UgdGVuc29yc2ApO2ZvcihsZXQgRWE9MDtFYTxUYS5sZW5ndGg7RWErKylUYVtFYV0ua2VyYXNNYXNrPXdhW0VhXX1hZGRJbmJvdW5kTm9kZShhYSx4YSxiYSxTYSxUYSx3YSxFYT1udWxsKXtjb25zdCBrYT10b0xpc3QoYWEpO3hhPXRvTGlzdCh4YSksYmE9dG9MaXN0KGJhKSxTYT10b0xpc3QoU2EpLFRhPW5vcm1hbGl6ZVNoYXBlTGlzdChUYSksd2E9bm9ybWFsaXplU2hhcGVMaXN0KHdhKTtjb25zdCBBYT1bXSxGYT1bXSxMYT1bXTtmb3IoY29uc3QgZWwgb2Yga2EpQWEucHVzaChlbC5zb3VyY2VMYXllciksRmEucHVzaChlbC5ub2RlSW5kZXgpLExhLnB1c2goZWwudGVuc29ySW5kZXgpO25ldyBOb2RlKHtvdXRib3VuZExheWVyOnRoaXMsaW5ib3VuZExheWVyczpBYSxub2RlSW5kaWNlczpGYSx0ZW5zb3JJbmRpY2VzOkxhLGlucHV0VGVuc29yczprYSxvdXRwdXRUZW5zb3JzOnhhLGlucHV0TWFza3M6YmEsb3V0cHV0TWFza3M6U2EsaW5wdXRTaGFwZXM6VGEsb3V0cHV0U2hhcGVzOndhfSxFYSk7Zm9yKGxldCBlbD0wO2VsPHhhLmxlbmd0aDtlbCsrKXhhW2VsXS5zb3VyY2VMYXllcj10aGlzLHhhW2VsXS5ub2RlSW5kZXg9dGhpcy5pbmJvdW5kTm9kZXMubGVuZ3RoLTEseGFbZWxdLnRlbnNvckluZGV4PWVsfWdldENvbmZpZygpe2NvbnN0IGFhPXtuYW1lOnRoaXMubmFtZSx0cmFpbmFibGU6dGhpcy50cmFpbmFibGV9O3JldHVybiB0aGlzLmJhdGNoSW5wdXRTaGFwZSE9bnVsbCYmKGFhLmJhdGNoSW5wdXRTaGFwZT10aGlzLmJhdGNoSW5wdXRTaGFwZSksdGhpcy5kdHlwZSE9bnVsbCYmKGFhLmR0eXBlPXRoaXMuZHR5cGUpLGFhfWRpc3Bvc2VXZWlnaHRzKCl7cmV0dXJuIHRoaXMud2VpZ2h0cy5mb3JFYWNoKGFhPT5hYS5kaXNwb3NlKCkpLHRoaXMud2VpZ2h0cy5sZW5ndGh9YXNzZXJ0Tm90RGlzcG9zZWQoKXtpZih0aGlzLl9yZWZDb3VudD09PTApdGhyb3cgbmV3IEVycm9yKGBMYXllciAnJHt0aGlzLm5hbWV9JyBpcyBhbHJlYWR5IGRpc3Bvc2VkLmApfWRpc3Bvc2UoKXtpZighdGhpcy5idWlsdCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkaXNwb3NlIExheWVyICR7dGhpcy5uYW1lfSBiZWNhdXNlIGl0IGhhcyBub3QgYmVlbiBidWlsdCB5ZXQuYCk7aWYodGhpcy5fcmVmQ291bnQ9PT1udWxsKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGRpc3Bvc2UgTGF5ZXIgJHt0aGlzLm5hbWV9IGJlY2F1c2UgaXQgaGFzIG5vdCBiZWVuIHVzZWQgeWV0LmApO3RoaXMuYXNzZXJ0Tm90RGlzcG9zZWQoKTtsZXQgYWE9MDtyZXR1cm4tLXRoaXMuX3JlZkNvdW50PT09MCYmKGFhPXRoaXMuZGlzcG9zZVdlaWdodHMoKSkse3JlZkNvdW50QWZ0ZXJEaXNwb3NlOnRoaXMuX3JlZkNvdW50LG51bURpc3Bvc2VkVmFyaWFibGVzOmFhfX19ZnVuY3Rpb24gY29sbGVjdElucHV0U2hhcGUoaGEpe2hhPXRvTGlzdChoYSk7Y29uc3QgYWE9W107Zm9yKGNvbnN0IHhhIG9mIGhhKWFhLnB1c2goeGEuc2hhcGUpO3JldHVybiBzaW5nbGV0b25PckFycmF5KGFhKX1mdW5jdGlvbiBndWVzc091dHB1dERUeXBlKGhhKXtyZXR1cm4iZmxvYXQzMiJ9ZnVuY3Rpb24gZ2V0U291cmNlSW5wdXRzKGhhLGFhLHhhKXtpZigoYWE9PW51bGx8fHhhIT1udWxsJiZ4YT4wKSYmKGFhPWhhLnNvdXJjZUxheWVyLHhhPWhhLm5vZGVJbmRleCksYWEuaW5ib3VuZE5vZGVzLmxlbmd0aD09PTApcmV0dXJuW2hhXTt7Y29uc3QgYmE9YWEuaW5ib3VuZE5vZGVzW3hhXTtpZihiYS5pbmJvdW5kTGF5ZXJzLmxlbmd0aD09PTApcmV0dXJuIGJhLmlucHV0VGVuc29yczt7Y29uc3QgU2E9W107Zm9yKGxldCBUYT0wO1RhPGJhLmluYm91bmRMYXllcnMubGVuZ3RoO1RhKyspe2NvbnN0IHdhPWJhLmlucHV0VGVuc29yc1tUYV0sRWE9YmEuaW5ib3VuZExheWVyc1tUYV0sa2E9YmEubm9kZUluZGljZXNbVGFdLEFhPWdldFNvdXJjZUlucHV0cyh3YSxFYSxrYSk7Zm9yKGNvbnN0IEZhIG9mIEFhKVNhLmluZGV4T2YoRmEpPT09LTEmJlNhLnB1c2goRmEpfXJldHVybiBTYX19fWZ1bmN0aW9uIGNoZWNrQWxsU3ltYm9saWMoaGEpe2xldCBhYT0hMDtmb3IoY29uc3QgeGEgb2YgdG9MaXN0KGhhKSlpZighKHhhIGluc3RhbmNlb2YgU3ltYm9saWNUZW5zb3IpKXthYT0hMTticmVha31yZXR1cm4gYWF9ZnVuY3Rpb24gY2hlY2tOb25lU3ltYm9saWMoaGEpe2xldCBhYT0hMDtmb3IoY29uc3QgeGEgb2YgdG9MaXN0KGhhKSlpZih4YSBpbnN0YW5jZW9mIFN5bWJvbGljVGVuc29yKXthYT0hMTticmVha31yZXR1cm4gYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgSW5wdXRMYXllciBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtpZihzdXBlcih7ZHR5cGU6YWEuZHR5cGUsbmFtZTphYS5uYW1lIT1udWxsP2FhLm5hbWU6Z2V0VWlkKCJpbnB1dCIpLnRvU3RyaW5nKCl9KSxhYS5iYXRjaFNpemU9PW51bGwmJihhYS5iYXRjaFNpemU9bnVsbCksYWEuc3BhcnNlPT1udWxsJiYoYWEuc3BhcnNlPSExKSx0aGlzLnRyYWluYWJsZT0hMSx0aGlzLmJ1aWx0PSEwLHRoaXMuc3BhcnNlPWFhLnNwYXJzZSxhYS5pbnB1dFNoYXBlIT1udWxsJiZhYS5iYXRjaElucHV0U2hhcGUhPW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIk9ubHkgcHJvdmlkZSB0aGUgaW5wdXRTaGFwZSBPUiBiYXRjaElucHV0U2hhcGUgYXJndW1lbnQgdG8gaW5wdXRMYXllciwgbm90IGJvdGggYXQgdGhlIHNhbWUgdGltZS4iKTtsZXQgeGE9YWEuYmF0Y2hJbnB1dFNoYXBlO2lmKHhhPT1udWxsKXtpZihhYS5pbnB1dFNoYXBlPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJBbiBJbnB1dExheWVyIHNob3VsZCBiZSBwYXNzZWQgZWl0aGVyIGEgYGJhdGNoSW5wdXRTaGFwZWAgb3IgYW4gYGlucHV0U2hhcGVgLiIpO3hhPVthYS5iYXRjaFNpemVdLmNvbmNhdChhYS5pbnB1dFNoYXBlKX1lbHNlIGlmKGFhLmJhdGNoU2l6ZSE9bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQ2Fubm90IHNwZWNpZnkgYmF0Y2hTaXplIGlmIGJhdGNoSW5wdXRTaGFwZSBpcyBzcGVjaWZpZWQgd2hlbiBjcmVhdGluZyBhbiBJbnB1dExheWVyLiIpO2NvbnN0IGJhPWFhLmR0eXBlfHwiZmxvYXQzMiI7dGhpcy5iYXRjaElucHV0U2hhcGU9eGEsdGhpcy5kdHlwZT1iYSx0aGlzLmlucHV0U3BlYz1be3NoYXBlOnhhfV07Y29uc3QgU2E9bmV3IFN5bWJvbGljVGVuc29yKHRoaXMuZHR5cGUsdGhpcy5iYXRjaElucHV0U2hhcGUsdGhpcyxbXSx7fSx0aGlzLm5hbWUpO1NhLm5vZGVJbmRleD0wLFNhLnRlbnNvckluZGV4PTAsbmV3IE5vZGUoe291dGJvdW5kTGF5ZXI6dGhpcyxpbmJvdW5kTGF5ZXJzOltdLG5vZGVJbmRpY2VzOltdLHRlbnNvckluZGljZXM6W10saW5wdXRUZW5zb3JzOltTYV0sb3V0cHV0VGVuc29yczpbU2FdLGlucHV0TWFza3M6W251bGxdLG91dHB1dE1hc2tzOltudWxsXSxpbnB1dFNoYXBlczpbeGFdLG91dHB1dFNoYXBlczpbeGFdfSl9YXBwbHkoYWEseGEpe3Rocm93IG5ldyBWYWx1ZUVycm9yKGBDYW5ub3QgcGFzcyBhbnkgaW5wdXQgdG8gYW4gSW5wdXRMYXllcidzIGFwcGx5KCkgbWV0aG9kLiBJbnB1dExheWVyIG5hbWU6ICR7dGhpcy5uYW1lfWApfWRpc3Bvc2UoKXtyZXR1cm57cmVmQ291bnRBZnRlckRpc3Bvc2U6dGhpcy5fcmVmQ291bnQsbnVtRGlzcG9zZWRWYXJpYWJsZXM6MH19Z2V0Q29uZmlnKCl7cmV0dXJue2JhdGNoSW5wdXRTaGFwZTp0aGlzLmJhdGNoSW5wdXRTaGFwZSxkdHlwZTp0aGlzLmR0eXBlLHNwYXJzZTp0aGlzLnNwYXJzZSxuYW1lOnRoaXMubmFtZX19fUlucHV0TGF5ZXIuY2xhc3NOYW1lPSJJbnB1dExheWVyIixyZWdpc3RlckNsYXNzJDEoSW5wdXRMYXllcik7ZnVuY3Rpb24gSW5wdXQoaGEpe2lmKGhhLmJhdGNoU2hhcGU9PW51bGwmJmhhLnNoYXBlPT1udWxsKXRocm93IG5ldyBFcnJvcigiUGxlYXNlIHByb3ZpZGUgdG8gSW5wdXQgZWl0aGVyIGEgYHNoYXBlYCBvciBhIGBiYXRjaFNoYXBlYCBhcmd1bWVudC4gTm90ZSB0aGF0IGBzaGFwZWAgZG9lcyBub3QgaW5jbHVkZSB0aGUgYmF0Y2ggZGltZW5zaW9uLiIpO2lmKGhhLmJhdGNoU2hhcGUhPW51bGwmJmhhLnNoYXBlIT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJQbGVhc2UgcHJvdmlkZSBlaXRoZXIgYSBgc2hhcGVgIG9yIGBiYXRjaFNoYXBlYCBhcmd1bWVudCB0byBJbnB1dCwgYnV0IG5vdCBib3RoLiIpO2xldCBhYT1oYS5iYXRjaFNoYXBlO2hhLnNoYXBlIT1udWxsJiZhYT09bnVsbCYmKGFhPVtudWxsXS5jb25jYXQoaGEuc2hhcGUpKTtsZXQgeGE9aGEuZHR5cGU7cmV0dXJuIHhhPT1udWxsJiYoeGE9ImZsb2F0MzIiKSxuZXcgSW5wdXRMYXllcih7YmF0Y2hJbnB1dFNoYXBlOmFhLG5hbWU6aGEubmFtZSxkdHlwZTp4YSxzcGFyc2U6aGEuc3BhcnNlfSkuaW5ib3VuZE5vZGVzWzBdLm91dHB1dFRlbnNvcnNbMF19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXNzZXJ0RmVlZENvbXBhdGliaWxpdHkoaGEsYWEpe2lmKGhhLmR0eXBlPT1udWxsfHxoYS5kdHlwZT09PWFhLmR0eXBlKXJldHVybiBhYTt0cnl7cmV0dXJuIGNhc3QkNShhYSxoYS5kdHlwZSl9Y2F0Y2h7dGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBkdHlwZSBvZiB0aGUgZmVlZCAoJHthYS5kdHlwZX0pIGNhbiBub3QgYmUgY2FzdCB0byB0aGUgZHR5cGUgb2YgdGhlIGtleSAnJHtoYS5uYW1lfScgKCR7aGEuZHR5cGV9KS5gKX19Y2xhc3MgRmVlZERpY3R7Y29uc3RydWN0b3IoYWEpe2lmKHRoaXMuaWQyVmFsdWU9e30sdGhpcy5pZDJNYXNrPXt9LHRoaXMubmFtZTJJZD17fSxhYSBpbnN0YW5jZW9mIEZlZWREaWN0KWZvcihjb25zdCB4YSBpbiBhYS5pZDJWYWx1ZSl0aGlzLmlkMlZhbHVlW3hhXT1hYS5pZDJWYWx1ZVt4YV0seGEgaW4gYWEuaWQyTWFzayYmKHRoaXMuaWQyTWFza1t4YV09YWEuaWQyTWFza1t4YV0pO2Vsc2V7aWYoYWE9PW51bGwpcmV0dXJuO2Zvcihjb25zdCB4YSBvZiBhYSl0aGlzLmFkZCh4YS5rZXkseGEudmFsdWUpfX1hZGQoYWEseGEsYmEpe2lmKHRoaXMuaWQyVmFsdWVbYWEuaWRdPT1udWxsKXRoaXMuaWQyVmFsdWVbYWEuaWRdPWFzc2VydEZlZWRDb21wYXRpYmlsaXR5KGFhLHhhKSx0aGlzLm5hbWUySWRbYWEubmFtZV09YWEuaWQsYmEhPW51bGwmJih0aGlzLmlkMk1hc2tbYWEuaWRdPWJhKTtlbHNlIHRocm93IG5ldyBWYWx1ZUVycm9yKGBEdXBsaWNhdGUga2V5OiBuYW1lPSR7YWEubmFtZX0sIGlkPSR7YWEuaWR9YCk7cmV0dXJuIHRoaXN9YWRkRmVlZChhYSl7dGhpcy5hZGQoYWEua2V5LGFhLnZhbHVlKX1oYXNLZXkoYWEpe3JldHVybiB0aGlzLmlkMlZhbHVlW2FhLmlkXSE9bnVsbH1uYW1lcygpe3JldHVybiBPYmplY3Qua2V5cyh0aGlzLm5hbWUySWQpfWdldFZhbHVlKGFhKXtpZihhYSBpbnN0YW5jZW9mIFN5bWJvbGljVGVuc29yKXtpZih0aGlzLmlkMlZhbHVlW2FhLmlkXT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgTm9uZXhpc3RlbnQga2V5OiAke2FhLm5hbWV9YCk7cmV0dXJuIHRoaXMuaWQyVmFsdWVbYWEuaWRdfWVsc2V7Y29uc3QgeGE9dGhpcy5uYW1lMklkW2FhXTtpZih4YT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgRmVlZCBkaWN0IGhhcyBubyBTeW1ib2xpY1RlbnNvciBuYW1lOiAke2FhfWApO3JldHVybiB0aGlzLmlkMlZhbHVlW3hhXX19Z2V0TWFzayhhYSl7aWYoYWEgaW5zdGFuY2VvZiBTeW1ib2xpY1RlbnNvcil7aWYodGhpcy5pZDJWYWx1ZVthYS5pZF09PW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYE5vbmV4aXN0ZW50IGtleTogJHthYS5uYW1lfWApO3JldHVybiB0aGlzLmlkMk1hc2tbYWEuaWRdfWVsc2V7Y29uc3QgeGE9dGhpcy5uYW1lMklkW2FhXTtpZih4YT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgRmVlZCBkaWN0IGhhcyBubyBTeW1ib2xpY1RlbnNvciBuYW1lOiAke2FhfWApO3JldHVybiB0aGlzLmlkMk1hc2tbeGFdfX1kaXNwb3NlTWFza3MoKXt0aGlzLmlkMk1hc2shPW51bGwmJmRpc3Bvc2UkMSh0aGlzLmlkMk1hc2spfX1jb25zdCBjYWNoZWRTb3J0ZWQ9bmV3IExydUNhY2hlLGNhY2hlZFJlY2lwaWVudENvdW50cz1uZXcgTHJ1Q2FjaGU7ZnVuY3Rpb24gdXBkYXRlQ2FjaGVNYXhFbnRyaWVzKGhhKXtjYWNoZWRTb3J0ZWQhPW51bGwmJmNhY2hlZFNvcnRlZC5zZXRNYXhFbnRyaWVzKGhhKSxjYWNoZWRSZWNpcGllbnRDb3VudHMhPW51bGwmJmNhY2hlZFJlY2lwaWVudENvdW50cy5zZXRNYXhFbnRyaWVzKGhhKX1mdW5jdGlvbiBleGVjdXRlKGhhLGFhLHhhLGJhKXtjb25zdCBTYT14YT09bnVsbD8hMTp4YS50cmFpbmluZyxUYT1BcnJheS5pc0FycmF5KGhhKSx3YT1UYT9oYTpbaGFdLEVhPXdhLm1hcChubD0+bmwubmFtZSksa2E9W10sQWE9YWEubmFtZXMoKTtmb3IoY29uc3Qgbmwgb2YgRWEpQWEuaW5kZXhPZihubCkhPT0tMT9rYS5wdXNoKGFhLmdldFZhbHVlKG5sKSk6a2EucHVzaChudWxsKTtjb25zdCBGYT1FYS5qb2luKCIsIikrInwiK2FhLm5hbWVzKCkuc29ydCgpLmpvaW4oIiwiKTtsZXQgTGE9Y2FjaGVkU29ydGVkLmdldChGYSksZWw7aWYoTGE9PW51bGwpe2NvbnN0IG5sPWdldFRvcG9sb2dpY2FsU29ydEFuZFJlY2lwaWVudENvdW50cyh3YSxhYSk7TGE9bmwuc29ydGVkLGVsPW5sLnJlY2lwaWVudENvdW50cyxjYWNoZWRTb3J0ZWQucHV0KEZhLExhKSxjYWNoZWRSZWNpcGllbnRDb3VudHMucHV0KEZhLGVsKX1lbD17fSxTYXx8T2JqZWN0LmFzc2lnbihlbCxjYWNoZWRSZWNpcGllbnRDb3VudHMuZ2V0KEZhKSk7Y29uc3QgdGw9bmV3IEZlZWREaWN0KGFhKTtmb3IobGV0IG5sPTA7bmw8TGEubGVuZ3RoOysrbmwpe2NvbnN0IHNsPUxhW25sXSxybD1zbC5zb3VyY2VMYXllcjtpZihybCBpbnN0YW5jZW9mIElucHV0TGF5ZXIpY29udGludWU7Y29uc3Qgb2w9W10sYWw9W10sbGw9W107bGV0IGlsPSExO2Zvcihjb25zdCBwbCBvZiBzbC5pbnB1dHMpe2NvbnN0IGZsPXRsLmdldFZhbHVlKHBsKSxtbD10bC5nZXRNYXNrKHBsKTtvbC5wdXNoKGZsKSxhbC5wdXNoKG1sKSxtbCE9bnVsbCYmKGlsPSEwKSxTYXx8KGVsW3BsLm5hbWVdLS0sZWxbcGwubmFtZV09PT0wJiYhYWEuaGFzS2V5KHBsKSYmRWEuaW5kZXhPZihwbC5uYW1lKT09PS0xJiYhZmwuaXNEaXNwb3NlZCYmcGwuc291cmNlTGF5ZXIuc3RhdGVmdWwhPT0hMCYmbGwucHVzaChmbCkpfWlsJiYoeGE9eGF8fHt9LHhhLm1hc2s9YWxbMF0pO2NvbnN0IGNsPXRvTGlzdChybC5hcHBseShvbCx4YSkpO2xldCB1bD1udWxsO3JsLnN1cHBvcnRzTWFza2luZyYmKHVsPXJsLmNvbXB1dGVNYXNrKG9sLGFsKSk7Y29uc3QgZGw9Z2V0Tm9kZU91dHB1dHMoc2wpLGhsPUFycmF5LmlzQXJyYXkoZGwpP2RsOltkbF07Zm9yKGxldCBwbD0wO3BsPGhsLmxlbmd0aDsrK3BsKXt0bC5oYXNLZXkoaGxbcGxdKXx8dGwuYWRkKGhsW3BsXSxjbFtwbF0sQXJyYXkuaXNBcnJheSh1bCk/dWxbMF06dWwpO2NvbnN0IGZsPUVhLmluZGV4T2YoaGxbcGxdLm5hbWUpO2ZsIT09LTEmJihrYVtmbF09Y2xbcGxdKX1TYXx8ZGlzcG9zZSQxKGxsKX1yZXR1cm4gdGwuZGlzcG9zZU1hc2tzKCksVGE/a2E6a2FbMF19ZnVuY3Rpb24gZ2V0VG9wb2xvZ2ljYWxTb3J0QW5kUmVjaXBpZW50Q291bnRzKGhhLGFhKXthc3NlcnQkMihoYSE9bnVsbCYmaGEubGVuZ3RoPjAsKCk9PiJFeHBlY3RlZCBhdCBsZWFzdCBvbmUgZmV0Y2gsIGdvdCBub25lIik7bGV0IHhhPVtdLGJhPXt9O2lmKGhhLmxlbmd0aD09PTEpe2NvbnN0IFNhPWdldFRvcG9sb2dpY2FsU29ydEFuZFJlY2lwaWVudENvdW50c0Zvck9uZUZldGNoKGhhWzBdLGFhKTt4YT1TYS5zb3J0ZWQsYmE9U2EucmVjaXBpZW50TWFwfWVsc2V7Y29uc3QgU2E9bmV3IFNldDtmb3IoY29uc3QgVGEgb2YgaGEpe2NvbnN0e3NvcnRlZDp3YSxyZWNpcGllbnRNYXA6RWF9PWdldFRvcG9sb2dpY2FsU29ydEFuZFJlY2lwaWVudENvdW50c0Zvck9uZUZldGNoKFRhLGFhKTtmb3IoY29uc3Qga2Egb2Ygd2EpU2EuaGFzKGthLm5hbWUpfHwoeGEucHVzaChrYSksU2EuYWRkKGthLm5hbWUpKTtmb3IoY29uc3Qga2EgaW4gRWEpYmFba2FdPT1udWxsJiYoYmFba2FdPW5ldyBTZXQpLEVhW2thXS5mb3JFYWNoKEFhPT5iYVtrYV0uYWRkKEFhKSl9fXJldHVybntzb3J0ZWQ6eGEscmVjaXBpZW50Q291bnRzOnJlY2lwaWVudE1hcDJDb3VudHMoYmEpfX1mdW5jdGlvbiByZWNpcGllbnRNYXAyQ291bnRzKGhhKXtjb25zdCBhYT17fTtmb3IoY29uc3QgeGEgaW4gaGEpYWFbeGFdPWhhW3hhXS5zaXplO3JldHVybiBhYX1mdW5jdGlvbiBnZXRUb3BvbG9naWNhbFNvcnRBbmRSZWNpcGllbnRDb3VudHNGb3JPbmVGZXRjaChoYSxhYSl7Y29uc3QgeGE9bmV3IFNldCxiYT1bXSxTYT17fTtmb3IoY29uc3QgRWEgb2YgYWEubmFtZXMoKSl4YS5hZGQoRWEpO2NvbnN0IFRhPVtdLHdhPVtdO2ZvcihUYS5wdXNoKGhhKTtUYS5sZW5ndGg+MDspe2NvbnN0IEVhPVRhW1RhLmxlbmd0aC0xXTtpZih4YS5oYXMoRWEubmFtZSkpe1RhLnBvcCgpO2NvbnRpbnVlfWNvbnN0IGthPXdhW3dhLmxlbmd0aC0xXT09PVRhLmxlbmd0aC0xO2lmKEVhLmlucHV0cy5sZW5ndGg9PT0wfHxrYSlUYS5wb3AoKSxiYS5wdXNoKEVhKSx4YS5hZGQoRWEubmFtZSksa2EmJndhLnBvcCgpO2Vsc2V7d2EucHVzaChUYS5sZW5ndGgtMSk7Zm9yKGNvbnN0IEFhIG9mIEVhLmlucHV0cylTYVtBYS5uYW1lXT09bnVsbCYmKFNhW0FhLm5hbWVdPW5ldyBTZXQpLFNhW0FhLm5hbWVdLmFkZChFYS5uYW1lKSwheGEuaGFzKEFhLm5hbWUpJiZUYS5wdXNoKEFhKX19cmV0dXJue3NvcnRlZDpiYSxyZWNpcGllbnRNYXA6U2F9fWZ1bmN0aW9uIGdldE5vZGVPdXRwdXRzKGhhKXtsZXQgYWE7aWYoaGEuc291cmNlTGF5ZXIuaW5ib3VuZE5vZGVzLmxlbmd0aD09PTEpYWE9aGEuc291cmNlTGF5ZXIub3V0cHV0O2Vsc2V7bGV0IHhhPW51bGw7Zm9yKGxldCBiYT0wO2JhPGhhLnNvdXJjZUxheWVyLmluYm91bmROb2Rlcy5sZW5ndGg7KytiYSlmb3IoY29uc3QgU2Egb2YgaGEuc291cmNlTGF5ZXIuaW5ib3VuZE5vZGVzW2JhXS5vdXRwdXRUZW5zb3JzKWlmKFNhLmlkPT09aGEuaWQpe3hhPWJhO2JyZWFrfWFhPWhhLnNvdXJjZUxheWVyLmdldE91dHB1dEF0KHhhKX1yZXR1cm4gYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRU5WJDU9ZW52JDEoKTtFTlYkNS5yZWdpc3RlckZsYWcoIlRPUE9MT0dJQ0FMX1NPUlRfQ0FDSEVfTUFYX0VOVFJJRVMiLCgpPT4xMDAsdXBkYXRlQ2FjaGVNYXhFbnRyaWVzKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjYWxjTDJOb3JtcyhoYSxhYSl7cmV0dXJuIHRpZHkkMSgoKT0+c3FydCQ0KHN1bSQ1KG11bCQxKGhhLGhhKSxhYSwhMCkpKX1jbGFzcyBDb25zdHJhaW50IGV4dGVuZHMgU2VyaWFsaXphYmxlJDF7Z2V0Q29uZmlnKCl7cmV0dXJue319fWNsYXNzIE1heE5vcm0gZXh0ZW5kcyBDb25zdHJhaW50e2NvbnN0cnVjdG9yKGFhKXtzdXBlcigpLHRoaXMuZGVmYXVsdE1heFZhbHVlPTIsdGhpcy5kZWZhdWx0QXhpcz0wLHRoaXMubWF4VmFsdWU9YWEubWF4VmFsdWUhPW51bGw/YWEubWF4VmFsdWU6dGhpcy5kZWZhdWx0TWF4VmFsdWUsdGhpcy5heGlzPWFhLmF4aXMhPW51bGw/YWEuYXhpczp0aGlzLmRlZmF1bHRBeGlzfWFwcGx5KGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgeGE9Y2FsY0wyTm9ybXMoYWEsdGhpcy5heGlzKSxiYT1jbGlwQnlWYWx1ZSQzKHhhLDAsdGhpcy5tYXhWYWx1ZSk7cmV0dXJuIG11bCQxKGFhLGRpdiQyKGJhLGFkZCQzKGVwc2lsb24kMSgpLHhhKSkpfSl9Z2V0Q29uZmlnKCl7cmV0dXJue21heFZhbHVlOnRoaXMubWF4VmFsdWUsYXhpczp0aGlzLmF4aXN9fX1NYXhOb3JtLmNsYXNzTmFtZT0iTWF4Tm9ybSIscmVnaXN0ZXJDbGFzcyQxKE1heE5vcm0pO2NsYXNzIFVuaXROb3JtIGV4dGVuZHMgQ29uc3RyYWludHtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoKSx0aGlzLmRlZmF1bHRBeGlzPTAsdGhpcy5heGlzPWFhLmF4aXMhPW51bGw/YWEuYXhpczp0aGlzLmRlZmF1bHRBeGlzfWFwcGx5KGFhKXtyZXR1cm4gdGlkeSQxKCgpPT5kaXYkMihhYSxhZGQkMyhlcHNpbG9uJDEoKSxjYWxjTDJOb3JtcyhhYSx0aGlzLmF4aXMpKSkpfWdldENvbmZpZygpe3JldHVybntheGlzOnRoaXMuYXhpc319fVVuaXROb3JtLmNsYXNzTmFtZT0iVW5pdE5vcm0iLHJlZ2lzdGVyQ2xhc3MkMShVbml0Tm9ybSk7Y2xhc3MgTm9uTmVnIGV4dGVuZHMgQ29uc3RyYWludHthcHBseShhYSl7cmV0dXJuIHJlbHUkNChhYSl9fU5vbk5lZy5jbGFzc05hbWU9Ik5vbk5lZyIscmVnaXN0ZXJDbGFzcyQxKE5vbk5lZyk7Y2xhc3MgTWluTWF4Tm9ybSBleHRlbmRzIENvbnN0cmFpbnR7Y29uc3RydWN0b3IoYWEpe3N1cGVyKCksdGhpcy5kZWZhdWx0TWluVmFsdWU9MCx0aGlzLmRlZmF1bHRNYXhWYWx1ZT0xLHRoaXMuZGVmYXVsdFJhdGU9MSx0aGlzLmRlZmF1bHRBeGlzPTAsdGhpcy5taW5WYWx1ZT1hYS5taW5WYWx1ZSE9bnVsbD9hYS5taW5WYWx1ZTp0aGlzLmRlZmF1bHRNaW5WYWx1ZSx0aGlzLm1heFZhbHVlPWFhLm1heFZhbHVlIT1udWxsP2FhLm1heFZhbHVlOnRoaXMuZGVmYXVsdE1heFZhbHVlLHRoaXMucmF0ZT1hYS5yYXRlIT1udWxsP2FhLnJhdGU6dGhpcy5kZWZhdWx0UmF0ZSx0aGlzLmF4aXM9YWEuYXhpcyE9bnVsbD9hYS5heGlzOnRoaXMuZGVmYXVsdEF4aXN9YXBwbHkoYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCB4YT1jYWxjTDJOb3JtcyhhYSx0aGlzLmF4aXMpLGJhPWFkZCQzKG11bCQxKHRoaXMucmF0ZSxjbGlwQnlWYWx1ZSQzKHhhLHRoaXMubWluVmFsdWUsdGhpcy5tYXhWYWx1ZSkpLG11bCQxKDEtdGhpcy5yYXRlLHhhKSk7cmV0dXJuIG11bCQxKGFhLGRpdiQyKGJhLGFkZCQzKGVwc2lsb24kMSgpLHhhKSkpfSl9Z2V0Q29uZmlnKCl7cmV0dXJue21pblZhbHVlOnRoaXMubWluVmFsdWUsbWF4VmFsdWU6dGhpcy5tYXhWYWx1ZSxyYXRlOnRoaXMucmF0ZSxheGlzOnRoaXMuYXhpc319fU1pbk1heE5vcm0uY2xhc3NOYW1lPSJNaW5NYXhOb3JtIixyZWdpc3RlckNsYXNzJDEoTWluTWF4Tm9ybSk7Y29uc3QgQ09OU1RSQUlOVF9JREVOVElGSUVSX1JFR0lTVFJZX1NZTUJPTF9NQVA9e21heE5vcm06Ik1heE5vcm0iLG1pbk1heE5vcm06Ik1pbk1heE5vcm0iLG5vbk5lZzoiTm9uTmVnIix1bml0Tm9ybToiVW5pdE5vcm0ifTtmdW5jdGlvbiBzZXJpYWxpemVDb25zdHJhaW50KGhhKXtyZXR1cm4gc2VyaWFsaXplS2VyYXNPYmplY3QoaGEpfWZ1bmN0aW9uIGRlc2VyaWFsaXplQ29uc3RyYWludChoYSxhYT17fSl7cmV0dXJuIGRlc2VyaWFsaXplS2VyYXNPYmplY3QoaGEsU2VyaWFsaXphdGlvbk1hcCQxLmdldE1hcCgpLmNsYXNzTmFtZU1hcCxhYSwiY29uc3RyYWludCIpfWZ1bmN0aW9uIGdldENvbnN0cmFpbnQoaGEpe2lmKGhhPT1udWxsKXJldHVybiBudWxsO2lmKHR5cGVvZiBoYT09InN0cmluZyIpe2NvbnN0IHhhPXtjbGFzc05hbWU6aGEgaW4gQ09OU1RSQUlOVF9JREVOVElGSUVSX1JFR0lTVFJZX1NZTUJPTF9NQVA/Q09OU1RSQUlOVF9JREVOVElGSUVSX1JFR0lTVFJZX1NZTUJPTF9NQVBbaGFdOmhhLGNvbmZpZzp7fX07cmV0dXJuIGRlc2VyaWFsaXplQ29uc3RyYWludCh4YSl9ZWxzZSByZXR1cm4gaGEgaW5zdGFuY2VvZiBDb25zdHJhaW50P2hhOmRlc2VyaWFsaXplQ29uc3RyYWludChoYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNjYWxhcnNJbkxvZ3MoaGEpe2lmKGhhPT1udWxsKXJldHVybjtjb25zdCBhYT1bXSx4YT1bXSxiYT1bXTtmb3IoY29uc3QgU2EgaW4gaGEpe2NvbnN0IFRhPWhhW1NhXTtpZih0eXBlb2YgVGEhPSJudW1iZXIiKXtjb25zdCB3YT1UYTthYS5wdXNoKHdhLmRhdGEoKSkseGEucHVzaChTYSksYmEucHVzaCh3YSl9fWlmKGFhLmxlbmd0aD4wKXtjb25zdCBTYT1hd2FpdCBQcm9taXNlLmFsbChhYSk7Zm9yKGxldCBUYT0wO1RhPFNhLmxlbmd0aDsrK1RhKWhhW3hhW1RhXV09U2FbVGFdWzBdO2Rpc3Bvc2UkMShiYSl9fWZ1bmN0aW9uIGRpc3Bvc2VUZW5zb3JzSW5Mb2dzKGhhKXtpZihoYSE9bnVsbClmb3IoY29uc3QgYWEgaW4gaGEpe2NvbnN0IHhhPWhhW2FhXTt0eXBlb2YgeGEhPSJudW1iZXIiJiZ4YS5kaXNwb3NlKCl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBNb2RlbExvZ2dpbmdWZXJib3NpdHk7KGZ1bmN0aW9uKGhhKXtoYVtoYS5TSUxFTlQ9MF09IlNJTEVOVCIsaGFbaGEuVkVSQk9TRT0xXT0iVkVSQk9TRSJ9KShNb2RlbExvZ2dpbmdWZXJib3NpdHl8fChNb2RlbExvZ2dpbmdWZXJib3NpdHk9e30pKTtjb25zdCBERUZBVUxUX1lJRUxEX0VWRVJZX01TPTEyNTtjbGFzcyBCYXNlQ2FsbGJhY2t7Y29uc3RydWN0b3IoKXt0aGlzLnZhbGlkYXRpb25EYXRhPW51bGx9c2V0UGFyYW1zKGFhKXt0aGlzLnBhcmFtcz1hYX1hc3luYyBvbkVwb2NoQmVnaW4oYWEseGEpe31hc3luYyBvbkVwb2NoRW5kKGFhLHhhKXt9YXN5bmMgb25CYXRjaEJlZ2luKGFhLHhhKXt9YXN5bmMgb25CYXRjaEVuZChhYSx4YSl7fWFzeW5jIG9uVHJhaW5CZWdpbihhYSl7fWFzeW5jIG9uVHJhaW5FbmQoYWEpe31zZXRNb2RlbChhYSl7fX1jbGFzcyBDYWxsYmFja0xpc3R7Y29uc3RydWN0b3IoYWEseGE9MTApe2FhPT1udWxsJiYoYWE9W10pLHRoaXMuY2FsbGJhY2tzPWFhLHRoaXMucXVldWVMZW5ndGg9eGF9YXBwZW5kKGFhKXt0aGlzLmNhbGxiYWNrcy5wdXNoKGFhKX1zZXRQYXJhbXMoYWEpe2Zvcihjb25zdCB4YSBvZiB0aGlzLmNhbGxiYWNrcyl4YS5zZXRQYXJhbXMoYWEpfXNldE1vZGVsKGFhKXtmb3IoY29uc3QgeGEgb2YgdGhpcy5jYWxsYmFja3MpeGEuc2V0TW9kZWwoYWEpfWFzeW5jIG9uRXBvY2hCZWdpbihhYSx4YSl7eGE9PW51bGwmJih4YT17fSk7Zm9yKGNvbnN0IGJhIG9mIHRoaXMuY2FsbGJhY2tzKWF3YWl0IGJhLm9uRXBvY2hCZWdpbihhYSx4YSl9YXN5bmMgb25FcG9jaEVuZChhYSx4YSl7eGE9PW51bGwmJih4YT17fSk7Zm9yKGNvbnN0IGJhIG9mIHRoaXMuY2FsbGJhY2tzKWF3YWl0IGJhLm9uRXBvY2hFbmQoYWEseGEpfWFzeW5jIG9uQmF0Y2hCZWdpbihhYSx4YSl7eGE9PW51bGwmJih4YT17fSk7Zm9yKGNvbnN0IGJhIG9mIHRoaXMuY2FsbGJhY2tzKWF3YWl0IGJhLm9uQmF0Y2hCZWdpbihhYSx4YSl9YXN5bmMgb25CYXRjaEVuZChhYSx4YSl7eGE9PW51bGwmJih4YT17fSk7Zm9yKGNvbnN0IGJhIG9mIHRoaXMuY2FsbGJhY2tzKWF3YWl0IGJhLm9uQmF0Y2hFbmQoYWEseGEpfWFzeW5jIG9uVHJhaW5CZWdpbihhYSl7YWE9PW51bGwmJihhYT17fSk7Zm9yKGNvbnN0IHhhIG9mIHRoaXMuY2FsbGJhY2tzKWF3YWl0IHhhLm9uVHJhaW5CZWdpbihhYSl9YXN5bmMgb25UcmFpbkVuZChhYSl7YWE9PW51bGwmJihhYT17fSk7Zm9yKGNvbnN0IHhhIG9mIHRoaXMuY2FsbGJhY2tzKWF3YWl0IHhhLm9uVHJhaW5FbmQoYWEpfX1jbGFzcyBCYXNlTG9nZ2VyIGV4dGVuZHMgQmFzZUNhbGxiYWNre2NvbnN0cnVjdG9yKCl7c3VwZXIoKX1hc3luYyBvbkVwb2NoQmVnaW4oYWEpe3RoaXMuc2Vlbj0wLHRoaXMudG90YWxzPXt9fWFzeW5jIG9uQmF0Y2hFbmQoYWEseGEpe3hhPT1udWxsJiYoeGE9e30pO2NvbnN0IGJhPXhhLnNpemU9PW51bGw/MDp4YS5zaXplO3RoaXMuc2Vlbis9YmE7Zm9yKGNvbnN0IFNhIGluIHhhKXtjb25zdCBUYT14YVtTYV07aWYodHlwZW9mIFRhPT0ibnVtYmVyIil0aGlzLnRvdGFscy5oYXNPd25Qcm9wZXJ0eShTYSl8fCh0aGlzLnRvdGFsc1tTYV09MCksdGhpcy50b3RhbHNbU2FdPXRoaXMudG90YWxzW1NhXStUYSpiYTtlbHNle2xldCB3YTtTYSBpbiB0aGlzLnRvdGFscz93YT10aGlzLnRvdGFsc1tTYV06dGhpcy50b3RhbHNbU2FdPTA7Y29uc3QgRWE9dGlkeSQxKCgpPT5hZGQkMyh0aGlzLnRvdGFsc1tTYV0sbXVsJDEoVGEsYmEpKSk7dGhpcy50b3RhbHNbU2FdPUVhLHdhIT1udWxsJiZ3YS5kaXNwb3NlKCl9fX1hc3luYyBvbkVwb2NoRW5kKGFhLHhhKXtpZih4YSE9bnVsbClmb3IoY29uc3QgYmEgb2YgdGhpcy5wYXJhbXMubWV0cmljcyl0aGlzLnRvdGFsc1tiYV0hPW51bGwmJih0eXBlb2YgdGhpcy50b3RhbHNbYmFdPT0ibnVtYmVyIj94YVtiYV09dGhpcy50b3RhbHNbYmFdL3RoaXMuc2Vlbjp0aWR5JDEoKCk9Pntjb25zdCBTYT1tdWwkMShkaXYkMigxLHRoaXMuc2VlbiksdGhpcy50b3RhbHNbYmFdKTt4YVtiYV09U2EsdGhpcy50b3RhbHNbYmFdLmRpc3Bvc2UoKSxrZWVwJDEoeGFbYmFdKX0pKX19Y2xhc3MgSGlzdG9yeSBleHRlbmRzIEJhc2VDYWxsYmFja3thc3luYyBvblRyYWluQmVnaW4oYWEpe3RoaXMuZXBvY2g9W10sdGhpcy5oaXN0b3J5PXt9fWFzeW5jIG9uRXBvY2hFbmQoYWEseGEpe3hhPT1udWxsJiYoeGE9e30pLHRoaXMuZXBvY2gucHVzaChhYSk7Zm9yKGNvbnN0IGJhIGluIHhhKXRoaXMuaGlzdG9yeVtiYV09PW51bGwmJih0aGlzLmhpc3RvcnlbYmFdPVtdKSx0aGlzLmhpc3RvcnlbYmFdLnB1c2goeGFbYmFdKX1hc3luYyBzeW5jRGF0YSgpe2NvbnN0IGFhPVtdLHhhPVtdLGJhPVtdO2Zvcihjb25zdCBUYSBpbiB0aGlzLmhpc3Rvcnkpe2NvbnN0IHdhPXRoaXMuaGlzdG9yeVtUYV07Zm9yKGxldCBFYT0wO0VhPHdhLmxlbmd0aDsrK0VhKWlmKHR5cGVvZiB3YVtFYV0hPSJudW1iZXIiKXtjb25zdCBrYT13YVtFYV07YWEucHVzaChrYS5kYXRhKCkpLHhhLnB1c2goVGEpLGJhLnB1c2goRWEpfX1jb25zdCBTYT1hd2FpdCBQcm9taXNlLmFsbChhYSk7Zm9yKGxldCBUYT0wO1RhPFNhLmxlbmd0aDsrK1RhKXRoaXMuaGlzdG9yeVt4YVtUYV1dW2JhW1RhXV0uZGlzcG9zZSgpLHRoaXMuaGlzdG9yeVt4YVtUYV1dW2JhW1RhXV09U2FbVGFdWzBdfX1jbGFzcyBDdXN0b21DYWxsYmFjayBleHRlbmRzIEJhc2VDYWxsYmFja3tjb25zdHJ1Y3RvcihhYSx4YSl7aWYoc3VwZXIoKSx0aGlzLmN1cnJlbnRFcG9jaD0wLHRoaXMubm93RnVuYz1hYS5ub3dGdW5jLHRoaXMubmV4dEZyYW1lRnVuYz1hYS5uZXh0RnJhbWVGdW5jfHxuZXh0RnJhbWUkMSx0aGlzLnlpZWxkRXZlcnk9eGF8fCJhdXRvIix0aGlzLnlpZWxkRXZlcnk9PT0iYXV0byImJih0aGlzLnlpZWxkRXZlcnk9REVGQVVMVF9ZSUVMRF9FVkVSWV9NUyksdGhpcy55aWVsZEV2ZXJ5PT09Im5ldmVyIiYmYWEub25ZaWVsZCE9bnVsbCl0aHJvdyBuZXcgRXJyb3IoInlpZWxkRXZlcnkgaXMgYG5ldmVyYCBidXQgeW91IHByb3ZpZGVkIGFuIGBvbllpZWxkYCBjYWxsYmFjay4gRWl0aGVyIGNoYW5nZSBgeWllbGRFdmVyeWAgb3IgcmVtb3ZlIHRoZSBjYWxsYmFjayIpO2lzTnVtYmVyJDEodGhpcy55aWVsZEV2ZXJ5KSYmKHRoaXMubWF5YmVXYWl0PWRlYm91bmNlKHRoaXMubWF5YmVXYWl0LmJpbmQodGhpcyksdGhpcy55aWVsZEV2ZXJ5LHRoaXMubm93RnVuYykpLHRoaXMudHJhaW5CZWdpbj1hYS5vblRyYWluQmVnaW4sdGhpcy50cmFpbkVuZD1hYS5vblRyYWluRW5kLHRoaXMuZXBvY2hCZWdpbj1hYS5vbkVwb2NoQmVnaW4sdGhpcy5lcG9jaEVuZD1hYS5vbkVwb2NoRW5kLHRoaXMuYmF0Y2hCZWdpbj1hYS5vbkJhdGNoQmVnaW4sdGhpcy5iYXRjaEVuZD1hYS5vbkJhdGNoRW5kLHRoaXMueWllbGQ9YWEub25ZaWVsZH1hc3luYyBtYXliZVdhaXQoYWEseGEsYmEpe2NvbnN0IFNhPVtdO3RoaXMueWllbGQhPW51bGwmJihhd2FpdCByZXNvbHZlU2NhbGFyc0luTG9ncyhiYSksU2EucHVzaCh0aGlzLnlpZWxkKGFhLHhhLGJhKSkpLFNhLnB1c2godGhpcy5uZXh0RnJhbWVGdW5jKCkpLGF3YWl0IFByb21pc2UuYWxsKFNhKX1hc3luYyBvbkVwb2NoQmVnaW4oYWEseGEpe3RoaXMuY3VycmVudEVwb2NoPWFhLHRoaXMuZXBvY2hCZWdpbiE9bnVsbCYmKGF3YWl0IHJlc29sdmVTY2FsYXJzSW5Mb2dzKHhhKSxhd2FpdCB0aGlzLmVwb2NoQmVnaW4oYWEseGEpKX1hc3luYyBvbkVwb2NoRW5kKGFhLHhhKXtjb25zdCBiYT1bXTt0aGlzLmVwb2NoRW5kIT1udWxsJiYoYXdhaXQgcmVzb2x2ZVNjYWxhcnNJbkxvZ3MoeGEpLGJhLnB1c2godGhpcy5lcG9jaEVuZChhYSx4YSkpKSx0aGlzLnlpZWxkRXZlcnk9PT0iZXBvY2giJiZiYS5wdXNoKHRoaXMubmV4dEZyYW1lRnVuYygpKSxhd2FpdCBQcm9taXNlLmFsbChiYSl9YXN5bmMgb25CYXRjaEJlZ2luKGFhLHhhKXt0aGlzLmJhdGNoQmVnaW4hPW51bGwmJihhd2FpdCByZXNvbHZlU2NhbGFyc0luTG9ncyh4YSksYXdhaXQgdGhpcy5iYXRjaEJlZ2luKGFhLHhhKSl9YXN5bmMgb25CYXRjaEVuZChhYSx4YSl7Y29uc3QgYmE9W107dGhpcy5iYXRjaEVuZCE9bnVsbCYmKGF3YWl0IHJlc29sdmVTY2FsYXJzSW5Mb2dzKHhhKSxiYS5wdXNoKHRoaXMuYmF0Y2hFbmQoYWEseGEpKSksdGhpcy55aWVsZEV2ZXJ5PT09ImJhdGNoIj9iYS5wdXNoKHRoaXMubmV4dEZyYW1lRnVuYygpKTppc051bWJlciQxKHRoaXMueWllbGRFdmVyeSkmJmJhLnB1c2godGhpcy5tYXliZVdhaXQodGhpcy5jdXJyZW50RXBvY2gsYWEseGEpKSxhd2FpdCBQcm9taXNlLmFsbChiYSl9YXN5bmMgb25UcmFpbkJlZ2luKGFhKXt0aGlzLnRyYWluQmVnaW4hPW51bGwmJihhd2FpdCByZXNvbHZlU2NhbGFyc0luTG9ncyhhYSksYXdhaXQgdGhpcy50cmFpbkJlZ2luKGFhKSl9YXN5bmMgb25UcmFpbkVuZChhYSl7dGhpcy50cmFpbkVuZCE9bnVsbCYmKGF3YWl0IHJlc29sdmVTY2FsYXJzSW5Mb2dzKGFhKSxhd2FpdCB0aGlzLnRyYWluRW5kKGFhKSl9fWZ1bmN0aW9uIHN0YW5kYXJkaXplQ2FsbGJhY2tzKGhhLGFhKXtyZXR1cm4gaGE9PW51bGwmJihoYT17fSksaGEgaW5zdGFuY2VvZiBCYXNlQ2FsbGJhY2s/W2hhXTpBcnJheS5pc0FycmF5KGhhKSYmaGFbMF1pbnN0YW5jZW9mIEJhc2VDYWxsYmFjaz9oYTp0b0xpc3QoaGEpLm1hcChiYT0+bmV3IEN1c3RvbUNhbGxiYWNrKGJhLGFhKSl9Y2xhc3MgQ2FsbGJhY2tDb25zdHJ1Y3RvclJlZ2lzdHJ5e2NvbnN0cnVjdG9yKCl7fXN0YXRpYyByZWdpc3RlckNhbGxiYWNrQ29uc3RydWN0b3IoYWEseGEpe2Fzc2VydCQyKGFhPj0wJiZOdW1iZXIuaXNJbnRlZ2VyKGFhKSwoKT0+YFZlcmJvc2l0eSBsZXZlbCBpcyBleHBlY3RlZCB0byBiZSBhbiBpbnRlZ2VyID49IDAsIGJ1dCBnb3QgJHthYX1gKSxDYWxsYmFja0NvbnN0cnVjdG9yUmVnaXN0cnkuY2hlY2tGb3JEdXBsaWNhdGUoeGEpLENhbGxiYWNrQ29uc3RydWN0b3JSZWdpc3RyeS5jb25zdHJ1Y3RvcnNbYWFdPT1udWxsJiYoQ2FsbGJhY2tDb25zdHJ1Y3RvclJlZ2lzdHJ5LmNvbnN0cnVjdG9yc1thYV09W10pLENhbGxiYWNrQ29uc3RydWN0b3JSZWdpc3RyeS5jb25zdHJ1Y3RvcnNbYWFdLnB1c2goeGEpfXN0YXRpYyBjaGVja0ZvckR1cGxpY2F0ZShhYSl7Zm9yKGNvbnN0IHhhIGluIENhbGxiYWNrQ29uc3RydWN0b3JSZWdpc3RyeS5jb25zdHJ1Y3RvcnMpQ2FsbGJhY2tDb25zdHJ1Y3RvclJlZ2lzdHJ5LmNvbnN0cnVjdG9yc1sreGFdLmZvckVhY2goU2E9PntpZihTYT09PWFhKXRocm93IG5ldyBWYWx1ZUVycm9yKCJEdXBsaWNhdGUgY2FsbGJhY2sgY29uc3RydWN0b3IuIil9KX1zdGF0aWMgY2xlYXIoKXtDYWxsYmFja0NvbnN0cnVjdG9yUmVnaXN0cnkuY29uc3RydWN0b3JzPXt9fXN0YXRpYyBjcmVhdGVDYWxsYmFja3MoYWEpe2NvbnN0IHhhPVtdO2Zvcihjb25zdCBiYSBpbiBDYWxsYmFja0NvbnN0cnVjdG9yUmVnaXN0cnkuY29uc3RydWN0b3JzKXtjb25zdCBTYT0rYmE7YWE+PVNhJiZ4YS5wdXNoKC4uLkNhbGxiYWNrQ29uc3RydWN0b3JSZWdpc3RyeS5jb25zdHJ1Y3RvcnNbU2FdKX1yZXR1cm4geGEubWFwKGJhPT5uZXcgYmEpfX1DYWxsYmFja0NvbnN0cnVjdG9yUmVnaXN0cnkuY29uc3RydWN0b3JzPXt9O2Z1bmN0aW9uIGNvbmZpZ3VyZUNhbGxiYWNrcyhoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSl7Y29uc3QgQWE9bmV3IEhpc3RvcnksRmE9W25ldyBCYXNlTG9nZ2VyLC4uLkNhbGxiYWNrQ29uc3RydWN0b3JSZWdpc3RyeS5jcmVhdGVDYWxsYmFja3MoYWEpXTtoYSE9bnVsbCYmRmEucHVzaCguLi5oYSksRmEucHVzaChBYSk7Y29uc3QgTGE9bmV3IENhbGxiYWNrTGlzdChGYSk7cmV0dXJuIExhLnNldFBhcmFtcyh7ZXBvY2hzOnhhLGluaXRpYWxFcG9jaDpiYSxzYW1wbGVzOlNhLHN0ZXBzOlRhLGJhdGNoU2l6ZTp3YSx2ZXJib3NlOmFhLGRvVmFsaWRhdGlvbjpFYSxtZXRyaWNzOmthfSkse2NhbGxiYWNrTGlzdDpMYSxoaXN0b3J5OkFhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZXNlcmlhbGl6ZShoYSxhYT17fSx4YT0hMSl7cmV0dXJuIGRlc2VyaWFsaXplS2VyYXNPYmplY3QoaGEsU2VyaWFsaXphdGlvbk1hcCQxLmdldE1hcCgpLmNsYXNzTmFtZU1hcCxhYSwibGF5ZXIiLHhhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsMk5vcm1hbGl6ZShoYSxhYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2hhLmR0eXBlIT09ImZsb2F0MzIiJiYoaGE9Y2FzdCQ1KGhhLCJmbG9hdDMyIikpO2NvbnN0IHhhPXN1bSQ1KHNxdWFyZSQzKGhhKSxhYSwhMCksYmE9ZmlsbCQ0KHhhLnNoYXBlLGVwc2lsb24kMSgpKSxTYT1zcXJ0JDQobWF4aW11bSQ0KHhhLGJhKSk7cmV0dXJuIGRpdiQyKGhhLFNhKX0pfWZ1bmN0aW9uIG1lYW5TcXVhcmVkRXJyb3IoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pm1lYW4kMShzcXVhcmUkMyhzdWIkNChhYSxoYSkpLC0xKSl9ZnVuY3Rpb24gbWVhbkFic29sdXRlRXJyb3IoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pm1lYW4kMShhYnMkNChzdWIkNChhYSxoYSkpLC0xKSl9ZnVuY3Rpb24gbWVhbkFic29sdXRlUGVyY2VudGFnZUVycm9yKGhhLGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgeGE9c3ViJDQoaGEsYWEpLGJhPWNsaXBCeVZhbHVlJDMoYWJzJDQoaGEpLGVwc2lsb24kMSgpLE51bWJlci5NQVhfVkFMVUUpLFNhPWFicyQ0KGRpdiQyKHhhLGJhKSk7cmV0dXJuIG11bCQxKDEwMCxtZWFuJDEoU2EsLTEpKX0pfWZ1bmN0aW9uIG1lYW5TcXVhcmVkTG9nYXJpdGhtaWNFcnJvcihoYSxhYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IHhhPWNsaXBCeVZhbHVlJDMoYWEsZXBzaWxvbiQxKCksTnVtYmVyLk1BWF9WQUxVRSksYmE9bG9nJDQoYWRkJDMoMSx4YSkpLFNhPWNsaXBCeVZhbHVlJDMoaGEsZXBzaWxvbiQxKCksTnVtYmVyLk1BWF9WQUxVRSksVGE9bG9nJDQoYWRkJDMoMSxTYSkpO3JldHVybiBtZWFuJDEoc3F1YXJlJDMoc3ViJDQoYmEsVGEpKSwtMSl9KX1mdW5jdGlvbiBzcXVhcmVkSGluZ2UoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCB4YT1tYXhpbXVtJDQoMCxzdWIkNCgxLG11bCQxKGhhLGFhKSkpO3JldHVybiBtZWFuJDEoc3F1YXJlJDMoeGEpLC0xKX0pfWZ1bmN0aW9uIGhpbmdlKGhhLGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgeGE9bWF4aW11bSQ0KDAsc3ViJDQoMSxtdWwkMShoYSxhYSkpKTtyZXR1cm4gbWVhbiQxKHhhLC0xKX0pfWZ1bmN0aW9uIGNhdGVnb3JpY2FsSGluZ2UoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCB4YT1zdW0kNShtdWwkMShoYSxhYSksLTEpLGJhPW1heCQ0KG11bCQxKHN1YiQ0KDEsaGEpLGFhKSwtMSk7cmV0dXJuIG1heGltdW0kNCgwLGFkZCQzKDEsc3ViJDQoYmEseGEpKSl9KX1mdW5jdGlvbiBsb2djb3NoKGhhLGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgeGE9TWF0aC5sb2coMiksYmE9c3ViJDQoYWEsaGEpLFNhPXN1YiQ0KGFkZCQzKGJhLHNvZnRwbHVzJDMobXVsJDEoLTIsYmEpKSkseGEpO3JldHVybiBtZWFuJDEoU2EsLTEpfSl9ZnVuY3Rpb24gY2F0ZWdvcmljYWxDcm9zc2VudHJvcHkkMShoYSxhYSx4YT0hMSl7cmV0dXJuIHRpZHkkMSgoKT0+e2lmKHhhKWFhPXNvZnRtYXgkMyhhYSk7ZWxzZXtjb25zdCBiYT1zdW0kNShhYSxhYS5zaGFwZS5sZW5ndGgtMSwhMCk7YWE9ZGl2JDIoYWEsYmEpfXJldHVybiBhYT1jbGlwQnlWYWx1ZSQzKGFhLGVwc2lsb24kMSgpLDEtZXBzaWxvbiQxKCkpLG5lZyQzKHN1bSQ1KG11bCQxKGNhc3QkNShoYSwiZmxvYXQzMiIpLGxvZyQ0KGFhKSksYWEuc2hhcGUubGVuZ3RoLTEpKX0pfWZ1bmN0aW9uIHNwYXJzZUNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5JDEoaGEsYWEseGE9ITEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT1jYXN0JDUoZmxvb3IkMyhmbGF0dGVuJDEoaGEpKSwiaW50MzIiKTthYT1jbGlwQnlWYWx1ZSQzKGFhLGVwc2lsb24kMSgpLDEtZXBzaWxvbiQxKCkpO2NvbnN0IFNhPWFhLnNoYXBlLFRhPXJlc2hhcGUkNChvbmVIb3QkMyhiYSxTYVtTYS5sZW5ndGgtMV0pLFNhKTtyZXR1cm4gY2F0ZWdvcmljYWxDcm9zc2VudHJvcHkkMShUYSxhYSx4YSl9KX1mdW5jdGlvbiBzaWdtb2lkQ3Jvc3NFbnRyb3B5V2l0aExvZ2l0cyhoYSxhYSl7aWYoIWFycmF5c0VxdWFsJDEoaGEuc2hhcGUsYWEuc2hhcGUpKXRocm93IG5ldyBWYWx1ZUVycm9yKGBsb2dpdHMgYW5kIGxhYmVscyBtdXN0IGhhdmUgdGhlIHNhbWUgc2hhcGUsIGJ1dCBnb3Qgc2hhcGVzICR7SlNPTi5zdHJpbmdpZnkoaGEuc2hhcGUpfSBhbmQgJHtKU09OLnN0cmluZ2lmeShhYS5zaGFwZSl9YCk7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IHhhPXJlbHUkNChhYSksYmE9bmVnJDMoYWJzJDQoYWEpKTtyZXR1cm4gYWRkJDMoc3ViJDQoeGEsbXVsJDEoYWEsaGEpKSxsb2cxcCQzKGV4cCQzKGJhKSkpfSl9ZnVuY3Rpb24gYmluYXJ5Q3Jvc3NlbnRyb3B5JDEoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9PntsZXQgeGE7cmV0dXJuIHhhPWNsaXBCeVZhbHVlJDMoYWEsZXBzaWxvbiQxKCksMS1lcHNpbG9uJDEoKSkseGE9bG9nJDQoZGl2JDIoeGEsc3ViJDQoMSx4YSkpKSxtZWFuJDEoc2lnbW9pZENyb3NzRW50cm9weVdpdGhMb2dpdHMoaGEseGEpLC0xKX0pfWZ1bmN0aW9uIGt1bGxiYWNrTGVpYmxlckRpdmVyZ2VuY2UoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCB4YT1jbGlwQnlWYWx1ZSQzKGhhLGVwc2lsb24kMSgpLDEpLGJhPWNsaXBCeVZhbHVlJDMoYWEsZXBzaWxvbiQxKCksMSk7cmV0dXJuIHN1bSQ1KG11bCQxKGhhLGxvZyQ0KGRpdiQyKHhhLGJhKSkpLC0xKX0pfWZ1bmN0aW9uIHBvaXNzb24oaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCB4YT1sb2ckNChhZGQkMyhlcHNpbG9uJDEoKSxhYSkpO3JldHVybiBtZWFuJDEoc3ViJDQoYWEsbXVsJDEoaGEseGEpKSwtMSl9KX1mdW5jdGlvbiBjb3NpbmVQcm94aW1pdHkoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCB4YT1sMk5vcm1hbGl6ZShoYSwtMSksYmE9bDJOb3JtYWxpemUoYWEsLTEpLFNhPW11bCQxKHhhLGJhKTtyZXR1cm4gbmVnJDMoc3VtJDUoU2EsLTEpKX0pfWNvbnN0IGxvc3Nlc01hcD17bWVhblNxdWFyZWRFcnJvcixtZWFuQWJzb2x1dGVFcnJvcixtZWFuQWJzb2x1dGVQZXJjZW50YWdlRXJyb3IsbWVhblNxdWFyZWRMb2dhcml0aG1pY0Vycm9yLHNxdWFyZWRIaW5nZSxoaW5nZSxjYXRlZ29yaWNhbEhpbmdlLGxvZ2Nvc2gsY2F0ZWdvcmljYWxDcm9zc2VudHJvcHk6Y2F0ZWdvcmljYWxDcm9zc2VudHJvcHkkMSxzcGFyc2VDYXRlZ29yaWNhbENyb3NzZW50cm9weTpzcGFyc2VDYXRlZ29yaWNhbENyb3NzZW50cm9weSQxLGJpbmFyeUNyb3NzZW50cm9weTpiaW5hcnlDcm9zc2VudHJvcHkkMSxrdWxsYmFja0xlaWJsZXJEaXZlcmdlbmNlLHBvaXNzb24sY29zaW5lUHJveGltaXR5fTtmdW5jdGlvbiBnZXQkMShoYSl7aWYodHlwZW9mIGhhPT0ic3RyaW5nIil7aWYoaGEgaW4gbG9zc2VzTWFwKXJldHVybiBsb3NzZXNNYXBbaGFdO2xldCBhYT1gVW5rbm93biBsb3NzICR7aGF9YDt0aHJvdyBoYS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCJzb2Z0bWF4Y3Jvc3NlbnRyb3B5IikmJihhYT1gVW5rbm93biBsb3NzICR7aGF9LiBVc2UgImNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5IiBhcyB0aGUgc3RyaW5nIG5hbWUgZm9yIHRmLmxvc3Nlcy5zb2Z0bWF4Q3Jvc3NFbnRyb3B5YCksbmV3IFZhbHVlRXJyb3IoYWEpfWVsc2UgcmV0dXJuIGhhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJpbmFyeUFjY3VyYWN5KGhhLGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgeGE9bXVsJDEoLjUsb25lc0xpa2UkMyhhYSkpLGJhPWNhc3QkNChncmVhdGVyJDMoYWEseGEpLGhhLmR0eXBlKTtyZXR1cm4gbWVhbiQxKGVxdWFsJDMoaGEsYmEpLC0xKX0pfWZ1bmN0aW9uIGNhdGVnb3JpY2FsQWNjdXJhY3koaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9PmNhc3QkNChlcXVhbCQzKGFyZ01heCQzKGhhLC0xKSxhcmdNYXgkMyhhYSwtMSkpLCJmbG9hdDMyIikpfWZ1bmN0aW9uIHRydWVQb3NpdGl2ZXMoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9PmNhc3QkNShzdW0kNShsb2dpY2FsQW5kJDMoZXF1YWwkMyhoYSwxKSxlcXVhbCQzKGFhLDEpKSksImZsb2F0MzIiKSl9ZnVuY3Rpb24gZmFsc2VQb3NpdGl2ZXMoaGEsYWEpe3JldHVybiB0aWR5JDEoKCk9PmNhc3QkNShzdW0kNShsb2dpY2FsQW5kJDMoZXF1YWwkMyhoYSwwKSxlcXVhbCQzKGFhLDEpKSksImZsb2F0MzIiKSl9ZnVuY3Rpb24gcHJlY2lzaW9uKGhhLGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgeGE9dHJ1ZVBvc2l0aXZlcyhoYSxhYSksYmE9ZmFsc2VQb3NpdGl2ZXMoaGEsYWEpLFNhPWFkZCQzKHhhLGJhKTtyZXR1cm4gY2FzdCQ1KHdoZXJlKGdyZWF0ZXIkMyhTYSwwKSxkaXYkMih4YSxTYSksMCksImZsb2F0MzIiKX0pfWZ1bmN0aW9uIGJpbmFyeUNyb3NzZW50cm9weShoYSxhYSl7cmV0dXJuIGJpbmFyeUNyb3NzZW50cm9weSQxKGhhLGFhKX1mdW5jdGlvbiBzcGFyc2VDYXRlZ29yaWNhbEFjY3VyYWN5KGhhLGFhKXtyZXR1cm4gaGEucmFuaz09PWFhLnJhbmsmJihoYT1zcXVlZXplKGhhLFtoYS5yYW5rLTFdKSksYWE9YXJnTWF4JDMoYWEsLTEpLGFhLmR0eXBlIT09aGEuZHR5cGUmJihhYT1jYXN0JDUoYWEsaGEuZHR5cGUpKSxjYXN0JDUoZXF1YWwkMyhoYSxhYSksImZsb2F0MzIiKX1jb25zdCBtc2U9bWVhblNxdWFyZWRFcnJvcixNU0U9bWVhblNxdWFyZWRFcnJvcixtYWU9bWVhbkFic29sdXRlRXJyb3IsTUFFPW1lYW5BYnNvbHV0ZUVycm9yLG1hcGU9bWVhbkFic29sdXRlUGVyY2VudGFnZUVycm9yLE1BUEU9bWVhbkFic29sdXRlUGVyY2VudGFnZUVycm9yLGNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5PWNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5JDEsY29zaW5lPWNvc2luZVByb3hpbWl0eSxzcGFyc2VDYXRlZ29yaWNhbENyb3NzZW50cm9weT1zcGFyc2VDYXRlZ29yaWNhbENyb3NzZW50cm9weSQxLG1ldHJpY3NNYXA9e2JpbmFyeUFjY3VyYWN5LGNhdGVnb3JpY2FsQWNjdXJhY3kscHJlY2lzaW9uLGNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5LHNwYXJzZUNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5LG1zZSxNU0UsbWFlLE1BRSxtYXBlLE1BUEUsY29zaW5lfTtmdW5jdGlvbiBnZXQoaGEpe2lmKHR5cGVvZiBoYT09InN0cmluZyImJmhhIGluIG1ldHJpY3NNYXApcmV0dXJuIG1ldHJpY3NNYXBbaGFdO2lmKHR5cGVvZiBoYSE9InN0cmluZyImJmhhIT1udWxsKXJldHVybiBoYTt0aHJvdyBuZXcgVmFsdWVFcnJvcihgVW5rbm93biBtZXRyaWMgJHtoYX1gKX1mdW5jdGlvbiBnZXRMb3NzT3JNZXRyaWNOYW1lKGhhKXtpZihhc3NlcnQkMShoYSE9PW51bGwsYFVua25vd24gTG9zc09yTWV0cmljRm4gJHtoYX1gKSx0eXBlb2YgaGE9PSJzdHJpbmciKXJldHVybiBoYTt7bGV0IGFhO2Zvcihjb25zdCB4YSBvZiBPYmplY3Qua2V5cyhsb3NzZXNNYXApKWlmKGxvc3Nlc01hcFt4YV09PT1oYSl7YWE9eGE7YnJlYWt9aWYoYWEhPT12b2lkIDApcmV0dXJuIGFhO2Zvcihjb25zdCB4YSBvZiBPYmplY3Qua2V5cyhtZXRyaWNzTWFwKSlpZihtZXRyaWNzTWFwW3hhXT09PWhhKXthYT14YTticmVha31yZXR1cm4gYWEhPT12b2lkIDA/YWE6aGEubmFtZX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0T3B0aW1pemVyKGhhKXtjb25zdCBhYT17QWRhZ3JhZDooKT0+dHJhaW4uYWRhZ3JhZCguMDEpLEFkYWRlbHRhOigpPT50cmFpbi5hZGFkZWx0YSgxLC45NSxlcHNpbG9uJDEoKSksQWRhbTooKT0+dHJhaW4uYWRhbSguMDAxLC45LC45OTksZXBzaWxvbiQxKCkpLEFkYW1heDooKT0+dHJhaW4uYWRhbWF4KC4wMDIsLjksLjk5OSxlcHNpbG9uJDEoKSwwKSxSTVNQcm9wOigpPT50cmFpbi5ybXNwcm9wKC4wMDEsLjksMCxlcHNpbG9uJDEoKSksU0dEOigpPT50cmFpbi5zZ2QoLjAxKX07aWYoYWEuYWRhZ3JhZD1hYS5BZGFncmFkLGFhLmFkYWRlbHRhPWFhLkFkYWRlbHRhLGFhLmFkYW09YWEuQWRhbSxhYS5hZGFtYXg9YWEuQWRhbWF4LGFhLnJtc3Byb3A9YWEuUk1TUHJvcCxhYS5zZ2Q9YWEuU0dELGhhIGluIGFhKXJldHVybiBhYVtoYV0oKTt0aHJvdyBuZXcgVmFsdWVFcnJvcihgVW5rbm93biBPcHRpbWl6ZXIgJHtoYX1gKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBNQVhfVVNFUl9ERUZJTkVEX01FVEFEQVRBX1NFUklBTElaRURfTEVOR1RIPTEqMTAyNCoxMDI0O2Z1bmN0aW9uIGNoZWNrVXNlckRlZmluZWRNZXRhZGF0YShoYSxhYSx4YT0hMSl7aWYoaGE9PW51bGx8fHR5cGVvZiBoYSE9Im9iamVjdCJ8fE9iamVjdC5nZXRQcm90b3R5cGVPZihoYSkhPT1PYmplY3QucHJvdG90eXBlfHwhcGxhaW5PYmplY3RDaGVjayhoYSkpdGhyb3cgbmV3IEVycm9yKCJVc2VyLWRlZmluZWQgbWV0YWRhdGEgaXMgZXhwZWN0ZWQgdG8gYmUgYSBKU09OIG9iamVjdCwgYnV0IGlzIG5vdC4iKTtpZih4YSl7Y29uc3QgYmE9SlNPTi5zdHJpbmdpZnkoaGEpO2JhLmxlbmd0aD5NQVhfVVNFUl9ERUZJTkVEX01FVEFEQVRBX1NFUklBTElaRURfTEVOR1RIJiZjb25zb2xlLndhcm4oYFVzZXItZGVmaW5lZCBtZXRhZGF0YSBvZiBtb2RlbCAiJHthYX0iIGlzIHRvbyBsYXJnZSBpbiBzaXplIChsZW5ndGg9JHtiYS5sZW5ndGh9IHdoZW4gc2VyaWFsaXplZCkuIEl0IGlzIG5vdCByZWNvbW1lbmRlZCB0byBzdG9yZSBzdWNoIGxhcmdlIG9iamVjdHMgaW4gdXNlci1kZWZpbmVkIG1ldGFkYXRhLiBQbGVhc2UgbWFrZSBzdXJlIGl0cyBzZXJpYWxpemVkIGxlbmd0aCBpcyA8PSAke01BWF9VU0VSX0RFRklORURfTUVUQURBVEFfU0VSSUFMSVpFRF9MRU5HVEh9LmApfX1mdW5jdGlvbiBwbGFpbk9iamVjdENoZWNrKGhhKXtpZihoYT09PW51bGwpcmV0dXJuITA7aWYodHlwZW9mIGhhPT0ib2JqZWN0IilpZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoaGEpPT09T2JqZWN0LnByb3RvdHlwZSl7Y29uc3QgYWE9T2JqZWN0LmtleXMoaGEpO2Zvcihjb25zdCB4YSBvZiBhYSlpZih0eXBlb2YgeGEhPSJzdHJpbmcifHwhcGxhaW5PYmplY3RDaGVjayhoYVt4YV0pKXJldHVybiExO3JldHVybiEwfWVsc2UgaWYoQXJyYXkuaXNBcnJheShoYSkpe2Zvcihjb25zdCBhYSBvZiBoYSlpZighcGxhaW5PYmplY3RDaGVjayhhYSkpcmV0dXJuITE7cmV0dXJuITB9ZWxzZSByZXR1cm4hMTtlbHNle2NvbnN0IGFhPXR5cGVvZiBoYTtyZXR1cm4gYWE9PT0ic3RyaW5nInx8YWE9PT0ibnVtYmVyInx8YWE9PT0iYm9vbGVhbiJ9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHByaW50U3VtbWFyeShoYSxhYSx4YSxiYT1jb25zb2xlLmxvZyl7Y29uc3QgU2E9aXNNb2RlbFNlcXVlbnRpYWxMaWtlKGhhKSxUYT1bIkxheWVyICh0eXBlKSIsIklucHV0IFNoYXBlIiwiT3V0cHV0IHNoYXBlIiwiUGFyYW0gIyJdO1NhPyhhYT1hYXx8OTAseGE9eGF8fFsuMzIsLjYxLC44OSwxXSk6KGFhPWFhfHwxMTUseGE9eGF8fFsuMjQsLjQ4LC43LC44LDFdKSx4YVt4YS5sZW5ndGgtMV08PTEmJih4YT14YS5tYXAoRmE9Pk1hdGguZmxvb3IoYWEqRmEpKSk7bGV0IHdhO2lmKCFTYSl7VGEucHVzaCgiUmVjZWl2ZXMgaW5wdXRzIiksd2E9W107Zm9yKGNvbnN0IEZhIGluIGhhLm5vZGVzQnlEZXB0aCl3YS5wdXNoKC4uLmhhLm5vZGVzQnlEZXB0aFtGYV0pfWJhKCJfIi5yZXBlYXQoYWEpKSxwcmludFJvdyhUYSx4YSxiYSksYmEoIj0iLnJlcGVhdChhYSkpO2NvbnN0IEVhPWhhLmxheWVycztmb3IobGV0IEZhPTA7RmE8RWEubGVuZ3RoOysrRmEpU2E/cHJpbnRMYXllclN1bW1hcnkoRWFbRmFdLHhhLGJhKTpwcmludExheWVyU3VtbWFyeVdpdGhDb25uZWN0aW9ucyhFYVtGYV0seGEsd2EsYmEpLGJhKChGYT09PUVhLmxlbmd0aC0xPyI9IjoiXyIpLnJlcGVhdChhYSkpO2hhLmNoZWNrVHJhaW5hYmxlV2VpZ2h0c0NvbnNpc3RlbmN5KCk7Y29uc3Qga2E9Y291bnRUcmFpbmFibGVQYXJhbXMoaGEpLEFhPWNvdW50UGFyYW1zSW5XZWlnaHRzKGhhLm5vblRyYWluYWJsZVdlaWdodHMpO2JhKGBUb3RhbCBwYXJhbXM6ICR7a2ErQWF9YCksYmEoYFRyYWluYWJsZSBwYXJhbXM6ICR7a2F9YCksYmEoYE5vbi10cmFpbmFibGUgcGFyYW1zOiAke0FhfWApLGJhKCJfIi5yZXBlYXQoYWEpKX1mdW5jdGlvbiBjb3VudFRyYWluYWJsZVBhcmFtcyhoYSl7bGV0IGFhO3JldHVybiBoYS5jb2xsZWN0ZWRUcmFpbmFibGVXZWlnaHRzIT1udWxsP2FhPWNvdW50UGFyYW1zSW5XZWlnaHRzKGhhLmNvbGxlY3RlZFRyYWluYWJsZVdlaWdodHMpOmFhPWNvdW50UGFyYW1zSW5XZWlnaHRzKGhhLnRyYWluYWJsZVdlaWdodHMpLGFhfWZ1bmN0aW9uIGlzTW9kZWxTZXF1ZW50aWFsTGlrZShoYSl7bGV0IGFhPSEwO2NvbnN0IHhhPVtdLGJhPVtdO2Zvcihjb25zdCBTYSBpbiBoYS5ub2Rlc0J5RGVwdGgpeGEucHVzaChoYS5ub2Rlc0J5RGVwdGhbU2FdKTtmb3IoY29uc3QgU2Egb2YgeGEpe2lmKFNhLmxlbmd0aD4xfHxTYS5sZW5ndGg9PT0xJiZTYVswXS5pbmJvdW5kTGF5ZXJzLmxlbmd0aD4xKXthYT0hMTticmVha31iYS5wdXNoKC4uLlNhKX1pZihhYSlmb3IoY29uc3QgU2Egb2YgaGEubGF5ZXJzKXtsZXQgVGE9ITE7Zm9yKGNvbnN0IHdhIG9mIFNhLmluYm91bmROb2RlcylpZihiYS5pbmRleE9mKHdhKSE9PS0xKWlmKFRhKXthYT0hMTticmVha31lbHNlIFRhPSEwO2lmKCFhYSlicmVha31yZXR1cm4gYWF9ZnVuY3Rpb24gcHJpbnRSb3coaGEsYWEseGE9Y29uc29sZS5sb2cpe2xldCBiYT0iIjtmb3IobGV0IFNhPTA7U2E8aGEubGVuZ3RoOysrU2EpU2E+MCYmKGJhPWJhLnNsaWNlKDAsYmEubGVuZ3RoLTEpKyIgIiksYmErPWhhW1NhXSxiYT1iYS5zbGljZSgwLGFhW1NhXSksYmErPSIgIi5yZXBlYXQoYWFbU2FdLWJhLmxlbmd0aCk7eGEoYmEpfWZ1bmN0aW9uIHByaW50TGF5ZXJTdW1tYXJ5KGhhLGFhLHhhKXtsZXQgYmEsU2E7dHJ5e1NhPWhhLmluYm91bmROb2Rlcy5tYXAoa2E9PkpTT04uc3RyaW5naWZ5KGthLmlucHV0U2hhcGVzKSkuam9pbigiLCIpfWNhdGNoe1NhPSJtdWx0aXBsZSJ9dHJ5e2JhPUpTT04uc3RyaW5naWZ5KGhhLm91dHB1dFNoYXBlKX1jYXRjaHtiYT0ibXVsdGlwbGUifWNvbnN0IFRhPWhhLm5hbWUsd2E9aGEuZ2V0Q2xhc3NOYW1lKCksRWE9W2Ake1RhfSAoJHt3YX0pYCxTYSxiYSxoYS5jb3VudFBhcmFtcygpLnRvU3RyaW5nKCldO3ByaW50Um93KEVhLGFhLHhhKX1mdW5jdGlvbiBwcmludExheWVyU3VtbWFyeVdpdGhDb25uZWN0aW9ucyhoYSxhYSx4YSxiYSl7bGV0IFNhLFRhO3RyeXtUYT1oYS5pbmJvdW5kTm9kZXMubWFwKExhPT5KU09OLnN0cmluZ2lmeShMYS5pbnB1dFNoYXBlcykpLmpvaW4oIiwiKX1jYXRjaHtUYT0ibXVsdGlwbGUifXRyeXtTYT1KU09OLnN0cmluZ2lmeShoYS5vdXRwdXRTaGFwZSl9Y2F0Y2h7U2E9Im11bHRpcGxlIn1jb25zdCB3YT1bXTtmb3IoY29uc3QgTGEgb2YgaGEuaW5ib3VuZE5vZGVzKWlmKCEoeGEhPW51bGwmJnhhLmxlbmd0aD4wJiZ4YS5pbmRleE9mKExhKT09PS0xKSlmb3IobGV0IGVsPTA7ZWw8TGEuaW5ib3VuZExheWVycy5sZW5ndGg7KytlbCl7Y29uc3QgdGw9TGEuaW5ib3VuZExheWVyc1tlbF0ubmFtZSxubD1MYS5ub2RlSW5kaWNlc1tlbF0sc2w9TGEudGVuc29ySW5kaWNlc1tlbF07d2EucHVzaChgJHt0bH1bJHtubH1dWyR7c2x9XWApfWNvbnN0IEVhPWhhLm5hbWUsa2E9aGEuZ2V0Q2xhc3NOYW1lKCksQWE9d2EubGVuZ3RoPT09MD8iIjp3YVswXSxGYT1bYCR7RWF9ICgke2thfSlgLFRhLFNhLGhhLmNvdW50UGFyYW1zKCkudG9TdHJpbmcoKSxBYV07cHJpbnRSb3coRmEsYWEsYmEpO2ZvcihsZXQgTGE9MTtMYTx3YS5sZW5ndGg7KytMYSlwcmludFJvdyhbIiIsIiIsIiIsIiIsd2FbTGFdXSxhYSxiYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaXNBcnJheUl0ZW1JbnB1dE9yT3V0cHV0TmFtZShoYSxhYSx4YSl7cmV0dXJuKGhhPT09ImluYm91bmROb2RlcyJ8fGhhPT09Im91dHB1dExheWVycyJ8fGhhPT09ImlucHV0TGF5ZXJzIikmJmFhPT09MCYmdHlwZW9mIHhhPT0ic3RyaW5nIn1mdW5jdGlvbiBjb252ZXJ0UHl0aG9uaWNUb1RzKGhhLGFhKXtpZihoYT09PW51bGwpcmV0dXJuIG51bGw7aWYodHlwZW9mIGhhPT0ic3RyaW5nIilyZXR1cm4gdG9DYW1lbENhc2UoaGEpO2lmKHR5cGVvZiBoYT09Im51bWJlciJ8fHR5cGVvZiBoYT09ImJvb2xlYW4iKXJldHVybiBoYTtpZihoYSBpbnN0YW5jZW9mIEFycmF5KXtjb25zdCB4YT1bXSxiYT1oYS5sZW5ndGg7Zm9yKGxldCBTYT0wO1NhPGJhOysrU2Epe2NvbnN0IFRhPWhhW1NhXTtpc0FycmF5SXRlbUlucHV0T3JPdXRwdXROYW1lKGFhLFNhLFRhKT94YS5wdXNoKFRhKTp4YS5wdXNoKGNvbnZlcnRQeXRob25pY1RvVHMoVGEsYWEpKX1yZXR1cm4geGF9ZWxzZXtjb25zdCB4YT17fTtmb3IoY29uc3QgYmEgb2YgT2JqZWN0LmtleXMoaGEpKXtjb25zdCBTYT1oYVtiYV07aWYoYmE9PT0ibmFtZSImJnR5cGVvZiBTYT09InN0cmluZyIpeGFbYmFdPVNhO2Vsc2V7Y29uc3QgVGE9dG9DYW1lbENhc2UoYmEpO3hhW1RhXT1jb252ZXJ0UHl0aG9uaWNUb1RzKFNhLFRhKX19cmV0dXJuIHhhfX1mdW5jdGlvbiBjb252ZXJ0VHNUb1B5dGhvbmljKGhhLGFhKXtpZihoYT09bnVsbClyZXR1cm4gbnVsbDtpZih0eXBlb2YgaGE9PSJzdHJpbmciKXJldHVybiB0b1NuYWtlQ2FzZShoYSk7aWYodHlwZW9mIGhhPT0ibnVtYmVyInx8dHlwZW9mIGhhPT0iYm9vbGVhbiIpcmV0dXJuIGhhO2lmKGhhIGluc3RhbmNlb2YgQXJyYXkpe2NvbnN0IHhhPVtdLGJhPWhhLmxlbmd0aDtmb3IobGV0IFNhPTA7U2E8YmE7KytTYSl7Y29uc3QgVGE9aGFbU2FdO2lzQXJyYXlJdGVtSW5wdXRPck91dHB1dE5hbWUoYWEsU2EsVGEpP3hhLnB1c2goVGEpOnhhLnB1c2goY29udmVydFRzVG9QeXRob25pYyhUYSxhYSkpfXJldHVybiB4YX1lbHNle2NvbnN0IHhhPXt9O2Zvcihjb25zdCBiYSBvZiBPYmplY3Qua2V5cyhoYSkpe2NvbnN0IFNhPWhhW2JhXSxUYT10b1NuYWtlQ2FzZShiYSk7KGJhPT09Im5hbWUifHxiYT09PSJjbGFzc05hbWUiKSYmdHlwZW9mIFNhPT0ic3RyaW5nIj94YVtUYV09U2E6eGFbVGFdPWNvbnZlcnRUc1RvUHl0aG9uaWMoU2EsYmEpfXJldHVybiB4YX19LyoqIEBsaWNlbnNlIFNlZSB0aGUgTElDRU5TRSBmaWxlLiAqL2NvbnN0IHZlcnNpb249IjQuMjEuMCI7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgaXNLZXJhc1NhdmVkTW9kZWxGb3JtYXQ9aGE9Pntjb25zdCBhYT1PYmplY3Qua2V5cyhoYSk7aWYoYWEubGVuZ3RoPT09MClyZXR1cm4hMTtjb25zdCB4YT1hYVswXS5zcGxpdCgiLyIpO3JldHVybiFpc05hTihwYXJzZUludCh4YVt4YS5sZW5ndGgtMV0sMTApKX07Y2xhc3MgQ29udGFpbmVyIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKHN1cGVyKHt9KSx0aGlzLmNvbnRhaW5lck5vZGVzPW5ldyBTZXQsdGhpcy5uYW1lPWFhLm5hbWUsdGhpcy5uYW1lPT1udWxsKXtjb25zdCBhbD10aGlzLmdldENsYXNzTmFtZSgpLnRvTG93ZXJDYXNlKCk7dGhpcy5uYW1lPWdldFVpZChhbCl9aWYodGhpcy5zdXBwb3J0c01hc2tpbmc9ITEsdGhpcy50cmFpbmFibGVfPSEwLEFycmF5LmlzQXJyYXkoYWEuaW5wdXRzKT90aGlzLmlucHV0cz1hYS5pbnB1dHMuc2xpY2UoKTp0aGlzLmlucHV0cz1bYWEuaW5wdXRzXSxBcnJheS5pc0FycmF5KGFhLm91dHB1dHMpP3RoaXMub3V0cHV0cz1hYS5vdXRwdXRzLnNsaWNlKCk6dGhpcy5vdXRwdXRzPVthYS5vdXRwdXRzXSx1bmlxdWUkMyh0aGlzLmlucHV0cykubGVuZ3RoIT09dGhpcy5pbnB1dHMubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBUaGUgbGlzdCBvZiBpbnB1dHMgcGFzc2VkIHRvIHRoZSBtb2RlbCBpcyByZWR1bmRhbnQuIEFsbCBpbnB1dHMgc2hvdWxkIG9ubHkgYXBwZWFyIG9uY2UuIEZvdW5kOiAke3RoaXMuaW5wdXRzLm1hcChhbD0+YWwubmFtZSl9YCk7dW5pcXVlJDModGhpcy5vdXRwdXRzKS5sZW5ndGghPT10aGlzLm91dHB1dHMubGVuZ3RoJiZjb25zb2xlLndhcm4oYFRoZSBsaXN0IG9mIG91dHB1dHMgcGFzc2VkIHRvIHRoZSBtb2RlbCBpcyByZWR1bmRhbnQuIEFsbCBvdXRwdXRzIHNob3VsZCBvbmx5IGFwcGVhciBvbmNlLiBGb3VuZDogJHt0aGlzLm91dHB1dHMubWFwKGFsPT5hbC5uYW1lKX1gKSx0aGlzLmlucHV0TGF5ZXJzPVtdLHRoaXMuaW5wdXRMYXllcnNOb2RlSW5kaWNlcz1bXSx0aGlzLmlucHV0TGF5ZXJzVGVuc29ySW5kaWNlcz1bXSx0aGlzLm91dHB1dExheWVycz1bXSx0aGlzLm91dHB1dExheWVyc05vZGVJbmRpY2VzPVtdLHRoaXMub3V0cHV0TGF5ZXJzVGVuc29ySW5kaWNlcz1bXSx0aGlzLmxheWVycz1bXSx0aGlzLmludGVybmFsQ29udGFpbmVyUmVmcz1bXTtmb3IoY29uc3QgYWwgb2YgdGhpcy5vdXRwdXRzKXtjb25zdCBsbD1hbC5zb3VyY2VMYXllcixpbD1hbC5ub2RlSW5kZXgsY2w9YWwudGVuc29ySW5kZXg7dGhpcy5vdXRwdXRMYXllcnMucHVzaChsbCksdGhpcy5vdXRwdXRMYXllcnNOb2RlSW5kaWNlcy5wdXNoKGlsKSx0aGlzLm91dHB1dExheWVyc1RlbnNvckluZGljZXMucHVzaChjbCl9Zm9yKGNvbnN0IGFsIG9mIHRoaXMuaW5wdXRzKXtjb25zdCBsbD1hbC5zb3VyY2VMYXllcixpbD1hbC5ub2RlSW5kZXgsY2w9YWwudGVuc29ySW5kZXg7YXNzZXJ0JDEoaWw9PT0wLCJpbnB1dCBsYXllciBoYXMgPjEgbm9kZXMiKSxhc3NlcnQkMShjbD09PTAsImlucHV0IGxheWVyIGhhcyA+MSB0ZW5zb3JzIiksdGhpcy5pbnB1dExheWVycy5wdXNoKGxsKSx0aGlzLmlucHV0TGF5ZXJzTm9kZUluZGljZXMucHVzaChpbCksdGhpcy5pbnB1dExheWVyc1RlbnNvckluZGljZXMucHVzaChjbCl9dGhpcy5pbnB1dE5hbWVzPVtdLHRoaXMub3V0cHV0TmFtZXM9W10sdGhpcy5mZWVkSW5wdXRTaGFwZXM9W10sdGhpcy5mZWVkSW5wdXROYW1lcz1bXSx0aGlzLmZlZWRPdXRwdXROYW1lcz1bXTtmb3IobGV0IGFsPTA7YWw8dGhpcy5pbnB1dExheWVycy5sZW5ndGg7YWwrKyl7Y29uc3QgbGw9dGhpcy5pbnB1dExheWVyc1thbF07aWYoIShsbCBpbnN0YW5jZW9mIElucHV0TGF5ZXIpKXRocm93IG5ldyBUeXBlRXJyb3IoYElucHV0IGxheWVycyB0byBhIExheWVyc01vZGVsIG11c3QgYmUgSW5wdXRMYXllciBvYmplY3RzLiBSZWNlaXZlZCBpbnB1dHM6ICR7YWEuaW5wdXRzfS4gSW5wdXQgJHthbH0gKDAtYmFzZWQpIG9yaWdpbmF0ZXMgZnJvbSBsYXllciB0eXBlICR7bGwuZ2V0Q2xhc3NOYW1lKCl9LmApO3RoaXMuaW5wdXROYW1lcy5wdXNoKGxsLm5hbWUpLHRoaXMuZmVlZElucHV0U2hhcGVzLnB1c2gobGwuYmF0Y2hJbnB1dFNoYXBlKSx0aGlzLmZlZWRJbnB1dE5hbWVzLnB1c2gobGwubmFtZSl9Zm9yKGNvbnN0IGFsIG9mIHRoaXMub3V0cHV0TGF5ZXJzKXRoaXMub3V0cHV0TmFtZXMucHVzaChhbC5uYW1lKTt0aGlzLmludGVybmFsSW5wdXRTaGFwZXM9dGhpcy5pbnB1dHMubWFwKGFsPT5hbC5zaGFwZSksdGhpcy5pbnRlcm5hbE91dHB1dFNoYXBlcz10aGlzLm91dHB1dHMubWFwKGFsPT5hbC5zaGFwZSk7Y29uc3QgeGE9e30sYmE9e30sU2E9e30sVGE9e30sd2E9e30sRWE9W10sa2E9KGFsLGxsLGlsLGNsLHVsLGRsKT0+eyhjbD09bnVsbHx8dWw9PW51bGx8fGRsPT1udWxsKSYmKGNsPWFsLnNvdXJjZUxheWVyLHVsPWFsLm5vZGVJbmRleCxkbD1hbC50ZW5zb3JJbmRleCk7Y29uc3QgaGw9Y2wuaW5ib3VuZE5vZGVzW3VsXTtpZihpbC5pbmRleE9mKGhsKSE9PS0xKXRocm93IG5ldyBSdW50aW1lRXJyb3IoYFRoZSB0ZW5zb3IgJHthbC5uYW1lfSBhdCBsYXllciAiJHtjbC5uYW1lfSIgaXMgcGFydCBvZiBhIGN5Y2xlLmApO2lmKGxsLmluZGV4T2YoaGwpIT09LTEpcmV0dXJuO3RoaXMuY29udGFpbmVyTm9kZXMuYWRkKENvbnRhaW5lci5ub2RlS2V5KGNsLHVsKSksY2wuaWQgaW4gd2F8fCh3YVtjbC5pZF09T2JqZWN0LmtleXMod2EpLmxlbmd0aCksaWwuaW5kZXhPZihobCk9PT0tMSYmaWwucHVzaChobCk7Y29uc3QgcGw9aGwuaW5ib3VuZExheWVycy5sZW5ndGg7Zm9yKGxldCBmbD0wO2ZsPHBsO2ZsKyspe2NvbnN0IG1sPWhsLmlucHV0VGVuc29yc1tmbF0sZ2w9aGwuaW5ib3VuZExheWVyc1tmbF0sJGw9aGwubm9kZUluZGljZXNbZmxdLHhsPWhsLnRlbnNvckluZGljZXNbZmxdO2thKG1sLGxsLGlsLGdsLCRsLHhsKX1mb3IobGwucHVzaChobCk7aWwuaW5kZXhPZihobCk+PTA7KWlsLnNwbGljZShpbC5pbmRleE9mKGhsKSwxKTtFYS5wdXNoKGhsKX0sQWE9W10sRmE9W107Zm9yKGNvbnN0IGFsIG9mIHRoaXMub3V0cHV0cylrYShhbCxBYSxGYSk7Y29uc3QgTGE9RWEuc2xpY2UoKS5yZXZlcnNlKCk7Zm9yKGNvbnN0IGFsIG9mIExhKXtiYVthbC5pZF09YWwsYWwuaWQgaW4geGF8fCh4YVthbC5pZF09MCk7bGV0IGxsPXhhW2FsLmlkXTtjb25zdCBpbD1TYVthbC5vdXRib3VuZExheWVyLmlkXT09bnVsbD8wOlNhW2FsLm91dGJvdW5kTGF5ZXIuaWRdO2xsPU1hdGgubWF4KGxsLGlsKSxTYVthbC5vdXRib3VuZExheWVyLmlkXT1sbCxUYVthbC5vdXRib3VuZExheWVyLmlkXT1hbC5vdXRib3VuZExheWVyLHhhW2FsLmlkXT1sbDtmb3IobGV0IGNsPTA7Y2w8YWwuaW5ib3VuZExheWVycy5sZW5ndGg7Y2wrKyl7Y29uc3QgdWw9YWwuaW5ib3VuZExheWVyc1tjbF0sZGw9YWwubm9kZUluZGljZXNbY2xdLGhsPXVsLmluYm91bmROb2Rlc1tkbF0scGw9eGFbaGwuaWRdPT1udWxsPzA6eGFbaGwuaWRdO3hhW2hsLmlkXT1NYXRoLm1heChsbCsxLHBsKSxiYVtobC5pZF09aGx9fWNvbnN0IGVsPXt9O2Zvcihjb25zdCBhbCBpbiB4YSl7Y29uc3QgbGw9eGFbYWxdO2xsIGluIGVsfHwoZWxbbGxdPVtdKSxlbFtsbF0ucHVzaChiYVthbF0pfWNvbnN0IHRsPXt9O2Zvcihjb25zdCBhbCBpbiBTYSl7Y29uc3QgbGw9U2FbYWxdO2xsIGluIHRsfHwodGxbbGxdPVtdKSx0bFtsbF0ucHVzaChUYVthbF0pfWxldCBubD1PYmplY3Qua2V5cyh0bCkubWFwKGFsPT5wYXJzZUludChhbCwxMCkpLnNvcnQocmV2ZXJzZU51bWJlckNvbXBhcmUpO3RoaXMubGF5ZXJzPVtdO2Zvcihjb25zdCBhbCBvZiBubCl7Y29uc3QgbGw9dGxbYWxdO2xsLnNvcnQoKGlsLGNsKT0+e2NvbnN0IHVsPXdhW2lsLmlkXSxkbD13YVtjbC5pZF07cmV0dXJuIHVsPGRsPy0xOnVsPmRsPzE6MH0pO2Zvcihjb25zdCBpbCBvZiBsbClpbCBpbnN0YW5jZW9mIENvbnRhaW5lciYmdGhpcy5pbnRlcm5hbENvbnRhaW5lclJlZnMucHVzaChpbCksdGhpcy5sYXllcnMucHVzaChpbCl9dGhpcy5sYXllcnNCeURlcHRoPXRsLG5sPU9iamVjdC5rZXlzKGVsKS5tYXAoYWw9PnBhcnNlSW50KGFsLDEwKSkuc29ydChyZXZlcnNlTnVtYmVyQ29tcGFyZSk7Y29uc3Qgc2w9dGhpcy5pbnB1dHMuc2xpY2UoKSxybD1bXTtmb3IoY29uc3QgYWwgb2YgbmwpZm9yKGNvbnN0IGxsIG9mIGVsW2FsXSl7Y29uc3QgaWw9bGwub3V0Ym91bmRMYXllcjtpZihpbCE9bnVsbCl7Zm9yKGNvbnN0IGNsIG9mIGxsLmlucHV0VGVuc29ycylpZihzbC5pbmRleE9mKGNsKT09PS0xKXRocm93IG5ldyBSdW50aW1lRXJyb3IoYEdyYXBoIGRpc2Nvbm5lY3RlZDogY2Fubm90IG9idGFpbiB2YWx1ZSBmb3IgdGVuc29yICR7Y2x9IGF0IGxheWVyICIke2lsLm5hbWV9Ii4gVGhlIGZvbGxvd2luZyBwcmV2aW91cyBsYXllcnMgd2VyZSBhY2Nlc3NlZCB3aXRob3V0IGlzc3VlOiAke3JsfWApO2Zvcihjb25zdCBjbCBvZiBsbC5vdXRwdXRUZW5zb3JzKXNsLnB1c2goY2wpO3JsLnB1c2goaWwubmFtZSl9fXRoaXMubm9kZXNCeURlcHRoPWVsO2NvbnN0IG9sPXRoaXMubGF5ZXJzLm1hcChhbD0+YWwubmFtZSk7Zm9yKGNvbnN0IGFsIG9mIG9sKXtjb25zdCBsbD1vbC5maWx0ZXIoaWw9PmlsPT09YWwpLmxlbmd0aDtpZihsbCE9PTEpdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihgVGhlIG5hbWUgIiR7YWx9IiBpcyB1c2VkICR7bGx9IHRpbWVzIGluIHRoZSBtb2RlbC4gQWxsIGxheWVyIG5hbWVzIHNob3VsZCBiZSB1bmlxdWUuIExheWVyIG5hbWVzOiBgK0pTT04uc3RyaW5naWZ5KG9sKSl9dGhpcy5vdXRib3VuZE5vZGVzPVtdLHRoaXMuaW5ib3VuZE5vZGVzPVtdLG5ldyBOb2RlKHtvdXRib3VuZExheWVyOnRoaXMsaW5ib3VuZExheWVyczpbXSxub2RlSW5kaWNlczpbXSx0ZW5zb3JJbmRpY2VzOltdLGlucHV0VGVuc29yczp0aGlzLmlucHV0cyxvdXRwdXRUZW5zb3JzOnRoaXMub3V0cHV0cyxpbnB1dE1hc2tzOnRoaXMuaW5wdXRzLm1hcChhbD0+bnVsbCksb3V0cHV0TWFza3M6dGhpcy5vdXRwdXRzLm1hcChhbD0+bnVsbCksaW5wdXRTaGFwZXM6dGhpcy5pbnB1dHMubWFwKGFsPT5hbC5zaGFwZSksb3V0cHV0U2hhcGVzOnRoaXMub3V0cHV0cy5tYXAoYWw9PmFsLnNoYXBlKX0pLHRoaXMuYnVpbHQ9ITAsdGhpcy5fcmVmQ291bnQ9MX1hc3NlcnROb3REaXNwb3NlZCgpe2lmKHRoaXMuX3JlZkNvdW50PT09MCl0aHJvdyBuZXcgRXJyb3IoYENvbnRhaW5lciAnJHt0aGlzLm5hbWV9JyBpcyBhbHJlYWR5IGRpc3Bvc2VkLmApfWRpc3Bvc2UoKXt0aGlzLmFzc2VydE5vdERpc3Bvc2VkKCk7Y29uc3QgYWE9e3JlZkNvdW50QWZ0ZXJEaXNwb3NlOm51bGwsbnVtRGlzcG9zZWRWYXJpYWJsZXM6MH07aWYoLS10aGlzLl9yZWZDb3VudD09PTApe2Zvcihjb25zdCB4YSBvZiB0aGlzLmxheWVycylhYS5udW1EaXNwb3NlZFZhcmlhYmxlcys9eGEuZGlzcG9zZSgpLm51bURpc3Bvc2VkVmFyaWFibGVzO2Zvcihjb25zdCB4YSBvZiB0aGlzLmludGVybmFsQ29udGFpbmVyUmVmcylhYS5udW1EaXNwb3NlZFZhcmlhYmxlcys9eGEuZGlzcG9zZSgpLm51bURpc3Bvc2VkVmFyaWFibGVzfXJldHVybiBhYS5yZWZDb3VudEFmdGVyRGlzcG9zZT10aGlzLl9yZWZDb3VudCxhYX1nZXQgdHJhaW5hYmxlKCl7cmV0dXJuIHRoaXMudHJhaW5hYmxlX31zZXQgdHJhaW5hYmxlKGFhKXt0aGlzLmxheWVycy5mb3JFYWNoKHhhPT57eGEuX3RyYWluYWJsZVdlaWdodHMuZm9yRWFjaChiYT0+YmEudHJhaW5hYmxlPWFhKX0pLHRoaXMudHJhaW5hYmxlXz1hYX1nZXQgdHJhaW5hYmxlV2VpZ2h0cygpe2lmKHRoaXMuX3RyYWluYWJsZVdlaWdodHMubGVuZ3RoPjApdGhyb3cgbmV3IFZhbHVlRXJyb3IoIkNvbnRhaW5lciBpbnN0YW5jZSB1bmV4cGVjdGVkbHkgY29udGFpbnMgX3RyYWluYWJsZVdlaWdodHMuVGhlIHRyYWluYWJsZSB3ZWlnaHRzIG9mIGEgQ29udGFpbmVyIGFyZSBhIHVuaW9uIG9mIHRoZSB0cmFpbmFibGUgd2VpZ2h0cyBvZiBpdHMgY29uc2l0dWVudCBMYXllcnMuIEl0cyBvd24gX3RyYWluYWJsZVdlaWdodHMgbXVzdCByZW1haW4gYW4gZW1wdHkgQXJyYXkuIik7aWYoIXRoaXMudHJhaW5hYmxlKXJldHVybltdO2xldCBhYT1bXTtmb3IoY29uc3QgeGEgb2YgdGhpcy5sYXllcnMpYWE9YWEuY29uY2F0KHhhLnRyYWluYWJsZVdlaWdodHMpO3JldHVybiBhYX1nZXQgbm9uVHJhaW5hYmxlV2VpZ2h0cygpe2NvbnN0IGFhPVtdO2Zvcihjb25zdCB4YSBvZiB0aGlzLmxheWVycylhYS5wdXNoKC4uLnhhLm5vblRyYWluYWJsZVdlaWdodHMpO2lmKCF0aGlzLnRyYWluYWJsZSl7Y29uc3QgeGE9W107Zm9yKGNvbnN0IGJhIG9mIHRoaXMubGF5ZXJzKXhhLnB1c2goLi4uYmEudHJhaW5hYmxlV2VpZ2h0cyk7cmV0dXJuIHhhLmNvbmNhdChhYSl9cmV0dXJuIGFhfWdldCB3ZWlnaHRzKCl7cmV0dXJuIHRoaXMudHJhaW5hYmxlV2VpZ2h0cy5jb25jYXQodGhpcy5ub25UcmFpbmFibGVXZWlnaHRzKX1sb2FkV2VpZ2h0cyhhYSx4YT0hMCl7Y29uc3QgYmE9e307bGV0IFNhPTA7Y29uc3QgVGE9aXNLZXJhc1NhdmVkTW9kZWxGb3JtYXQoYWEpO1RhJiZ0aGlzLnBhcnNlV2VpZ2h0cyhhYSk7Zm9yKGNvbnN0IEVhIG9mIHRoaXMubGF5ZXJzKWZvcihjb25zdFtrYSxBYV1vZiBFYS53ZWlnaHRzLmVudHJpZXMoKSl7Y29uc3QgRmE9VGE/YCR7QWEubmFtZS5zcGxpdCgiLyIpLnNsaWNlKDAsLTEpLmpvaW4oIi8iKSsiLyJ9JHtrYX1gOkFhLm9yaWdpbmFsTmFtZTtpZihiYVtGYV0hPW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYER1cGxpY2F0ZSB3ZWlnaHQgbmFtZTogJHtGYX1gKTtiYVtGYV09QWEsU2ErK31jb25zdCB3YT1bXTtmb3IoY29uc3QgRWEgaW4gYWEpe2xldCBrYT1FYTtpZihiYVtFYV09PW51bGwpe2NvbnN0IEFhPUVhLnNwbGl0KCIvIik7a2E9QWEuc2xpY2UoMCwtMikuY29uY2F0KFtBYVtBYS5sZW5ndGgtMV1dKS5qb2luKCIvIil9aWYoYmFba2FdIT1udWxsKXdhLnB1c2goW2JhW2thXSxhYVtFYV1dKTtlbHNlIGlmKHhhKXRocm93IG5ldyBWYWx1ZUVycm9yKGBQcm92aWRlZCB3ZWlnaHQgZGF0YSBoYXMgbm8gdGFyZ2V0IHZhcmlhYmxlOiAke0VhfWApO2RlbGV0ZSBiYVtrYV19aWYoeGEpe2NvbnN0IEVhPVtdO2Zvcihjb25zdCBrYSBpbiBiYSlFYS5wdXNoKGthKTtpZihFYS5sZW5ndGg+MCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgJHtFYS5sZW5ndGh9IG9mICR7U2F9IHdlaWdodHMgYXJlIG5vdCBzZXQ6ICR7RWF9YCl9YmF0Y2hTZXRWYWx1ZSh3YSl9cGFyc2VXZWlnaHRzKGFhKXtmb3IoY29uc3QgeGEgaW4gT2JqZWN0LmtleXMoYWEpKXtjb25zdCBiYT14YS5zcGxpdCgiLyIpLFNhPVsidmFycyIsImxheWVyX2NoZWNrcG9pbnRfZGVwZW5kZW5jaWVzIl0sVGE9YmEubWFwKHdhPT53YS5zdGFydHNXaXRoKCJfIik/d2Euc2xpY2UoMSk6d2EpLmZpbHRlcih3YT0+IVNhLmluY2x1ZGVzKHdhKSkuam9pbigiLyIpO1RhIT09eGEmJihhYVtUYV09YWFbeGFdLGRlbGV0ZSBhYVt4YV0pfX11cGRhdGVkQ29uZmlnKCl7Y29uc3QgYWE9dGhpcy5nZXRDb25maWcoKSx4YT17fTtyZXR1cm4geGEuY2xhc3NOYW1lPXRoaXMuZ2V0Q2xhc3NOYW1lKCkseGEuY29uZmlnPWFhLHhhLmtlcmFzVmVyc2lvbj1gdGZqcy1sYXllcnMgJHt2ZXJzaW9ufWAseGEuYmFja2VuZD0iVGVuc29yRmxvdy5qcyIseGF9dG9KU09OKGFhLHhhPSEwKXtjb25zdCBiYT1jb252ZXJ0VHNUb1B5dGhvbmljKHRoaXMudXBkYXRlZENvbmZpZygpKTtyZXR1cm4geGE/SlNPTi5zdHJpbmdpZnkoYmEpOmJhfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PnthYT10b0xpc3QoYWEpO2NvbnN0IGJhPW5ldyBGZWVkRGljdDtmb3IobGV0IFNhPTA7U2E8dGhpcy5pbnB1dHMubGVuZ3RoOysrU2EpYmEuYWRkKHRoaXMuaW5wdXRzW1NhXSxhYVtTYV0pO3JldHVybiBleGVjdXRlKHRoaXMub3V0cHV0cyxiYSx4YSl9KX1jb21wdXRlTWFzayhhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2FhPXRvTGlzdChhYSk7bGV0IGJhO3JldHVybiB4YT09bnVsbD9iYT1weUxpc3RSZXBlYXQobnVsbCxhYS5sZW5ndGgpOmJhPXRvTGlzdCh4YSksdGhpcy5ydW5JbnRlcm5hbEdyYXBoKGFhLGJhKVsxXX0pfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7Y29uc3QgeGE9bm9ybWFsaXplU2hhcGVMaXN0KGFhKTtpZih4YS5sZW5ndGghPT10aGlzLmlucHV0TGF5ZXJzLmxlbmd0aCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW52YWxpZCBpbnB1dFNoYXBlIGFyZ3VtZW50ICR7YWF9OiBtb2RlbCBoYXMgJHt0aGlzLmlucHV0TGF5ZXJzLmxlbmd0aH0gdGVuc29yIGlucHV0cy5gKTtjb25zdCBiYT17fTtmb3IobGV0IEVhPTA7RWE8eGEubGVuZ3RoO0VhKyspe2NvbnN0IGthPXRoaXMuaW5wdXRMYXllcnNbRWFdLEFhPXhhW0VhXSxGYT1rYS5uYW1lKyJfMF8wIjtiYVtGYV09QWF9Y29uc3QgU2E9T2JqZWN0LmtleXModGhpcy5ub2Rlc0J5RGVwdGgpLm1hcChFYT0+cGFyc2VJbnQoRWEsMTApKS5zb3J0KHJldmVyc2VOdW1iZXJDb21wYXJlKTtpZihTYS5sZW5ndGg+MSlmb3IoY29uc3QgRWEgb2YgU2Epe2NvbnN0IGthPXRoaXMubm9kZXNCeURlcHRoW0VhXTtmb3IoY29uc3QgQWEgb2Yga2Epe2NvbnN0IEZhPUFhLm91dGJvdW5kTGF5ZXI7aWYodGhpcy5pbnB1dExheWVycy5tYXAoc2w9PnNsLmlkKS5pbmRleE9mKEZhLmlkKSE9PS0xKWNvbnRpbnVlO2NvbnN0IExhPVtdO2ZvcihsZXQgc2w9MDtzbDxBYS5pbmJvdW5kTGF5ZXJzLmxlbmd0aDtzbCsrKXtjb25zdCBybD1BYS5pbmJvdW5kTGF5ZXJzW3NsXSxvbD1BYS5ub2RlSW5kaWNlc1tzbF0sYWw9QWEudGVuc29ySW5kaWNlc1tzbF0sbGw9YCR7cmwubmFtZX1fJHtvbH1fJHthbH1gLGlsPWJhW2xsXTtMYS5wdXNoKGlsKX1jb25zdCBlbD1GYS5jb21wdXRlT3V0cHV0U2hhcGUoc2luZ2xldG9uT3JBcnJheShMYSkpLHRsPW5vcm1hbGl6ZVNoYXBlTGlzdChlbCksbmw9RmEuaW5ib3VuZE5vZGVzLmluZGV4T2YoQWEpO2ZvcihsZXQgc2w9MDtzbDx0bC5sZW5ndGg7c2wrKyl7Y29uc3Qgcmw9YCR7RmEubmFtZX1fJHtubH1fJHtzbH1gO2JhW3JsXT10bFtzbF19fX1jb25zdCBUYT1bXSx3YT1bXTtmb3IobGV0IEVhPTA7RWE8dGhpcy5vdXRwdXRMYXllcnMubGVuZ3RoO0VhKyspe2NvbnN0IGthPXRoaXMub3V0cHV0TGF5ZXJzW0VhXSxBYT10aGlzLm91dHB1dExheWVyc05vZGVJbmRpY2VzW0VhXSxGYT10aGlzLm91dHB1dExheWVyc1RlbnNvckluZGljZXNbRWFdLExhPWAke2thLm5hbWV9XyR7QWF9XyR7RmF9YDt3YS5wdXNoKExhKX1mb3IobGV0IEVhPTA7RWE8d2EubGVuZ3RoO0VhKyspe2NvbnN0IGthPXdhW0VhXTthc3NlcnQkMShrYSBpbiBiYSksVGEucHVzaChiYVtrYV0pfXJldHVybiBzaW5nbGV0b25PckFycmF5KFRhKX1ydW5JbnRlcm5hbEdyYXBoKGFhLHhhKXt4YT09bnVsbCYmKHhhPXB5TGlzdFJlcGVhdChudWxsLGFhLmxlbmd0aCkpO2NvbnN0IGJhPXt9O2ZvcihsZXQga2E9MDtrYTx0aGlzLmlucHV0cy5sZW5ndGg7KytrYSl7Y29uc3QgQWE9dGhpcy5pbnB1dHNba2FdLEZhPWFhW2thXSxMYT14YVtrYV07YmFbQWEuaWRdPVtGYSxMYV19Y29uc3QgU2E9T2JqZWN0LmtleXModGhpcy5ub2Rlc0J5RGVwdGgpLm1hcChrYT0+cGFyc2VJbnQoa2EsMTApKS5zb3J0KHJldmVyc2VOdW1iZXJDb21wYXJlKTtmb3IoY29uc3Qga2Egb2YgU2Epe2NvbnN0IEFhPXRoaXMubm9kZXNCeURlcHRoW2thXTtmb3IoY29uc3QgRmEgb2YgQWEpe2NvbnN0IExhPUZhLm91dGJvdW5kTGF5ZXIsZWw9RmEuaW5wdXRUZW5zb3JzLHRsPUZhLm91dHB1dFRlbnNvcnMsbmw9bmV3IEFycmF5O2Zvcihjb25zdCBzbCBvZiBlbClzbC5pZCBpbiBiYSYmbmwucHVzaChiYVtzbC5pZF0pO2lmKG5sLmxlbmd0aD09PWVsLmxlbmd0aCl7bGV0IHNsPXt9LHJsLG9sLGFsLGxsO2lmKEZhLmNhbGxBcmdzIT1udWxsJiYoc2w9RmEuY2FsbEFyZ3MpLG5sLmxlbmd0aD09PTEpe2NvbnN0W2lsLGNsXT1ubFswXTtzbC5tYXNrPT1udWxsJiYoc2wubWFzaz1jbCksYWw9dG9MaXN0KExhLmNhbGwoaWwsc2wpKSxsbD10b0xpc3QoTGEuY29tcHV0ZU1hc2soaWwsY2wpKSxybD1baWxdLG9sPVtjbF19ZWxzZSBybD1ubC5tYXAoaWw9PmlsWzBdKSxvbD1ubC5tYXAoaWw9PmlsWzFdKSxzbC5tYXNrPT1udWxsJiYoc2wubWFzaz1vbCksYWw9dG9MaXN0KExhLmNhbGwocmwsc2wpKSxsbD10b0xpc3QoTGEuY29tcHV0ZU1hc2socmwsb2wpKTtpZihMYS5hY3Rpdml0eVJlZ3VsYXJpemVyKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJMYXllcnNNb2RlbCBpbnZvY2F0aW9uIHdpdGggY29uY3JldGUgVGVuc29yIHZhbHVlKHMpIGluIHRoZSBwcmVzZW5jZSBvZiBhY3Rpdml0eSByZWd1bGFyaXplcihzKSBpcyBub3Qgc3VwcG9ydGVkIHlldC4iKTtmb3IobGV0IGlsPTA7aWw8dGwubGVuZ3RoOysraWwpe2NvbnN0IGNsPXRsW2lsXSx1bD1hbFtpbF0sZGw9bGxbaWxdO2JhW2NsLmlkXT1bdWwsZGxdfX19fWNvbnN0IFRhPVtdLHdhPVtdLEVhPVtdO2Zvcihjb25zdCBrYSBvZiB0aGlzLm91dHB1dHMpe2Fzc2VydCQxKGthLmlkIGluIGJhLGBDb3VsZCBub3QgY29tcHV0ZSBvdXRwdXQgJHtrYS5uYW1lfSA6ICR7a2EuaWR9YCk7Y29uc3RbQWEsRmFdPWJhW2thLmlkXTtFYS5wdXNoKEFhLnNoYXBlKSxUYS5wdXNoKEFhKSx3YS5wdXNoKEZhKX1yZXR1cm5bVGEsd2EsRWFdfWJ1aWxkTm9kZUNvbnZlcnNpb25NYXAoYWEpe2NvbnN0IHhhPXt9O2xldCBiYTtmb3IoY29uc3QgU2Egb2YgdGhpcy5sYXllcnMpe2JhPVNhIGluc3RhbmNlb2YgQ29udGFpbmVyPzE6MDtmb3IobGV0IFRhPTA7VGE8U2EuaW5ib3VuZE5vZGVzLmxlbmd0aDtUYSsrKXtjb25zdCB3YT1Db250YWluZXIubm9kZUtleShTYSxUYSk7dGhpcy5jb250YWluZXJOb2Rlcy5oYXMod2EpJiYoeGFbd2FdPWJhLGJhKz0xKX19cmV0dXJuIHhhfWdldExheWVyKGFhLHhhKXtpZih4YSE9bnVsbClyZXR1cm4gdGhpcy5maW5kTGF5ZXIoeGEpO2lmKGFhPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJQcm92aWRlIGVpdGhlciBhIGxheWVyIG5hbWUgb3IgbGF5ZXIgaW5kZXgiKTtpZih0eXBlb2YgYWE9PSJudW1iZXIiKXJldHVybiB0aGlzLmZpbmRMYXllcihhYSk7Zm9yKGNvbnN0IGJhIG9mIHRoaXMubGF5ZXJzKWlmKGJhLm5hbWU9PT1hYSlyZXR1cm4gYmE7dGhyb3cgbmV3IFZhbHVlRXJyb3IoYE5vIHN1Y2ggbGF5ZXI6ICR7YWF9YCl9ZmluZExheWVyKGFhKXtpZih0aGlzLmxheWVycy5sZW5ndGg8PWFhKXRocm93IG5ldyBWYWx1ZUVycm9yKGBXYXMgYXNrZWQgdG8gcmV0cmlldmUgbGF5ZXIgYXQgaW5kZXggJHthYX0sIGJ1dCBtb2RlbCBvbmx5IGhhcyAke3RoaXMubGF5ZXJzLmxlbmd0aH0gbGF5ZXIocykuYCk7cmV0dXJuIHRoaXMubGF5ZXJzW2FhXX1jYWxjdWxhdGVMb3NzZXMoKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgYWE9W107Zm9yKGNvbnN0IHhhIG9mIHRoaXMubGF5ZXJzKWZvcihsZXQgYmE9MDtiYTx4YS5pbmJvdW5kTm9kZXMubGVuZ3RoOysrYmEpe2NvbnN0IFNhPUNvbnRhaW5lci5ub2RlS2V5KHhhLGJhKTt0aGlzLmNvbnRhaW5lck5vZGVzLmhhcyhTYSkmJmFhLnB1c2goLi4ueGEuY2FsY3VsYXRlTG9zc2VzKCkpfXJldHVybiBhYX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXtuYW1lOnRoaXMubmFtZX0seGE9dGhpcy5idWlsZE5vZGVDb252ZXJzaW9uTWFwKHRoaXMubGF5ZXJzKSxiYT1bXTtmb3IoY29uc3Qgd2Egb2YgdGhpcy5sYXllcnMpe2NvbnN0IEVhPXdhLmdldENsYXNzTmFtZSgpLGthPXdhLmdldENvbmZpZygpLEFhPVtdO2ZvcihsZXQgTGE9MDtMYTx3YS5pbmJvdW5kTm9kZXMubGVuZ3RoO0xhKyspe2NvbnN0IGVsPXdhLmluYm91bmROb2Rlc1tMYV0sdGw9Q29udGFpbmVyLm5vZGVLZXkod2EsTGEpO2xldCBubD17fTtpZih0aGlzLmNvbnRhaW5lck5vZGVzLmhhcyh0bCkpe2lmKGVsLmNhbGxBcmdzKXRyeXtKU09OLnN0cmluZ2lmeShlbC5jYWxsQXJncyksbmw9ZWwuY2FsbEFyZ3N9Y2F0Y2h7Y29uc29sZS53YXJuKGBMYXllciAke3dhLm5hbWV9IHdhcyBwYXNzZWQgbm9uLXNlcmlhbGl6YWJsZSBrZXl3b3JkIGFyZ3VtZW50czogJHtlbC5jYWxsQXJnc30uIFRoZXkgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHNlcmlhbGl6ZWQgbW9kZWwgKGFuZCB0aHVzIHdpbGwgYmUgbWlzc2luZyBhdCBkZXNlcmlhbGl6YXRpb24gdGltZSkuYCksbmw9e319aWYoZWwuaW5ib3VuZExheWVycy5sZW5ndGg+MCl7Y29uc3Qgc2w9W107Zm9yKGxldCBybD0wO3JsPGVsLmluYm91bmRMYXllcnMubGVuZ3RoO3JsKyspe2NvbnN0IG9sPWVsLmluYm91bmRMYXllcnNbcmxdLGFsPWVsLm5vZGVJbmRpY2VzW3JsXSxsbD1lbC50ZW5zb3JJbmRpY2VzW3JsXSxpbD1Db250YWluZXIubm9kZUtleShvbCxhbCk7bGV0IGNsPXhhW2lsXTtjbD09bnVsbCYmKGNsPTApLHNsLnB1c2goW29sLm5hbWUsY2wsbGwsbmxdKX1BYS5wdXNoKHNsKX19fWNvbnN0IEZhPXt9O0ZhLm5hbWU9d2EubmFtZSxGYS5jbGFzc05hbWU9RWEsRmEuY29uZmlnPWthLEZhLmluYm91bmROb2Rlcz1BYSxiYS5wdXNoKEZhKX1hYS5sYXllcnM9YmE7Y29uc3QgU2E9W107Zm9yKGxldCB3YT0wO3dhPHRoaXMuaW5wdXRMYXllcnMubGVuZ3RoO3dhKyspe2NvbnN0IEVhPXRoaXMuaW5wdXRMYXllcnNbd2FdLGthPXRoaXMuaW5wdXRMYXllcnNOb2RlSW5kaWNlc1t3YV0sQWE9Q29udGFpbmVyLm5vZGVLZXkoRWEsa2EpO2lmKCF0aGlzLmNvbnRhaW5lck5vZGVzLmhhcyhBYSkpY29udGludWU7bGV0IEZhPXhhW0FhXTtGYT09bnVsbCYmKEZhPTApO2NvbnN0IExhPXRoaXMuaW5wdXRMYXllcnNUZW5zb3JJbmRpY2VzW3dhXTtTYS5wdXNoKFtFYS5uYW1lLEZhLExhXSl9YWEuaW5wdXRMYXllcnM9U2E7Y29uc3QgVGE9W107Zm9yKGxldCB3YT0wO3dhPHRoaXMub3V0cHV0TGF5ZXJzLmxlbmd0aDt3YSsrKXtjb25zdCBFYT10aGlzLm91dHB1dExheWVyc1t3YV0sa2E9dGhpcy5vdXRwdXRMYXllcnNOb2RlSW5kaWNlc1t3YV0sQWE9Q29udGFpbmVyLm5vZGVLZXkoRWEsa2EpO2lmKCF0aGlzLmNvbnRhaW5lck5vZGVzLmhhcyhBYSkpY29udGludWU7bGV0IEZhPXhhW0FhXTtGYT09bnVsbCYmKEZhPTApO2NvbnN0IExhPXRoaXMub3V0cHV0TGF5ZXJzVGVuc29ySW5kaWNlc1t3YV07VGEucHVzaChbRWEubmFtZSxGYSxMYV0pfXJldHVybiBhYS5vdXRwdXRMYXllcnM9VGEsYWF9c3RhdGljIGZyb21Db25maWcoYWEseGEsYmE9e30sU2E9ITEpe2NvbnN0IFRhPXt9LHdhPXt9O2Z1bmN0aW9uIEVhKHJsLG9sKXtybC5uYW1lIGluIHdhP3dhW3JsLm5hbWVdLnB1c2gob2wpOndhW3JsLm5hbWVdPVtvbF19ZnVuY3Rpb24ga2Eocmwsb2wpe2NvbnN0IGFsPVtdO2xldCBsbDtmb3IoY29uc3QgaWwgb2Ygb2wpe2NvbnN0IGNsPWlsWzBdLHVsPWlsWzFdLGRsPWlsWzJdO2lmKGxsPWlsWzNdPT1udWxsP3t9OmlsWzNdLCEoY2wgaW4gVGEpKXtFYShybCxvbCk7cmV0dXJufWNvbnN0IGhsPVRhW2NsXTtpZihobC5pbmJvdW5kTm9kZXMubGVuZ3RoPD11bCl7RWEocmwsb2wpO3JldHVybn1jb25zdCBwbD1obC5pbmJvdW5kTm9kZXNbdWxdO2FsLnB1c2gocGwub3V0cHV0VGVuc29yc1tkbF0pfWFsLmxlbmd0aD4wJiZybC5hcHBseShzaW5nbGV0b25PckFycmF5KGFsKSxsbCl9ZnVuY3Rpb24gQWEocmwpe2NvbnN0IG9sPXJsLm5hbWUsYWw9ZGVzZXJpYWxpemUocmwseGEuY3VzdG9tT2JqZWN0cyE9bnVsbD94YS5jdXN0b21PYmplY3RzOnt9KTthbC5zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKFNhKSxUYVtvbF09YWwscmwuaW5ib3VuZE5vZGVzLmZvckVhY2goaWw9PntpZighKGlsIGluc3RhbmNlb2YgQXJyYXkpKXRocm93IG5ldyBWYWx1ZUVycm9yKGBDb3JydXB0ZWQgY29uZmlndXJhdGlvbiwgZXhwZWN0ZWQgYXJyYXkgZm9yIG5vZGVEYXRhOiAke2lsfWApO0VhKGFsLGlsKX0pfWNvbnN0IEZhPXhhLm5hbWUsTGE9eGEubGF5ZXJzO2Zvcihjb25zdCBybCBvZiBMYSlBYShybCk7Zm9yKDshaXNPYmplY3RFbXB0eSh3YSk7KWZvcihjb25zdCBybCBvZiBMYSl7Y29uc3Qgb2w9VGFbcmwubmFtZV07aWYob2wubmFtZSBpbiB3YSl7Y29uc3QgYWw9d2Fbb2wubmFtZV07ZGVsZXRlIHdhW29sLm5hbWVdO2Zvcihjb25zdCBsbCBvZiBhbClrYShvbCxsbCl9fWNvbnN0IGVsPVtdLHRsPVtdLG5sPXhhLmlucHV0TGF5ZXJzO2Zvcihjb25zdCBybCBvZiBubCl7Y29uc3Qgb2w9cmxbMF0sYWw9cmxbMV0sbGw9cmxbMl07YXNzZXJ0JDEob2wgaW4gVGEpO2NvbnN0IGNsPVRhW29sXS5pbmJvdW5kTm9kZXNbYWxdLm91dHB1dFRlbnNvcnM7ZWwucHVzaChjbFtsbF0pfWNvbnN0IHNsPXhhLm91dHB1dExheWVycztmb3IoY29uc3Qgcmwgb2Ygc2wpe2NvbnN0IG9sPXJsWzBdLGFsPXJsWzFdLGxsPXJsWzJdO2Fzc2VydCQxKG9sIGluIFRhKTtjb25zdCBjbD1UYVtvbF0uaW5ib3VuZE5vZGVzW2FsXS5vdXRwdXRUZW5zb3JzO3RsLnB1c2goY2xbbGxdKX1yZXR1cm4gbmV3IGFhKHtpbnB1dHM6ZWwsb3V0cHV0czp0bCxuYW1lOkZhfSl9Z2V0IHN0YXRlZnVsKCl7aWYodGhpcy5fc3RhdGVmdWwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIkNvbnRhaW5lciBpbnN0YW5jZSB1bmV4cGVjdGVkbHkgaGFzIF9zdGF0ZWZ1bCA9IHRydWUuIFRoZSBzdGF0ZWZ1bG5lc3Mgb2YgYSBDb250YWluZXIgaXMgZGV0ZXJtaW5lZCBieSB0aGUgTGF5ZXJzIGl0IGNvbnRhaW5zLiBJdHMgX3N0YXRlZnVsIHByb3BlcnR5IG11c3QgcmVtYWluIHRoZSBkZWZhdWx0IGZhbHNlLiIpO2Zvcihjb25zdCBhYSBvZiB0aGlzLmxheWVycylpZihhYS5zdGF0ZWZ1bClyZXR1cm4hMDtyZXR1cm4hMX1yZXNldFN0YXRlcygpe3RpZHkkMSgoKT0+e3RoaXMubGF5ZXJzLmZvckVhY2goYWE9PnthYS5zdGF0ZWZ1bCYmYWEucmVzZXRTdGF0ZXMoKX0pfSl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0YW5kYXJkaXplU2FtcGxlT3JDbGFzc1dlaWdodHMoaGEsYWEseGEpe2NvbnN0IGJhPWFhLmxlbmd0aDtpZihoYT09bnVsbHx8QXJyYXkuaXNBcnJheShoYSkmJmhhLmxlbmd0aD09PTApcmV0dXJuIGFhLm1hcChTYT0+bnVsbCk7aWYoYmE9PT0xKXJldHVybiBBcnJheS5pc0FycmF5KGhhKSYmaGEubGVuZ3RoPT09MT9oYTp0eXBlb2YgaGE9PSJvYmplY3QiJiZhYVswXWluIGhhP1toYVthYVswXV1dOltoYV07aWYoQXJyYXkuaXNBcnJheShoYSkpe2lmKGhhLmxlbmd0aCE9PWJhKXRocm93IG5ldyBFcnJvcihgUHJvdmlkZWQgJHt4YX0gaXMgYW4gYXJyYXkgb2YgJHtoYS5sZW5ndGh9IGVsZW1lbnQocyksIGJ1dCB0aGUgbW9kZWwgaGFzICR7YmF9IG91dHB1dHMuIE1ha2Ugc3VyZSBhIHNldCBvZiB3ZWlnaHRzIGlzIHByb3ZpZGVkIGZvciBlYWNoIG1vZGVsIG91dHB1dC5gKTtyZXR1cm4gaGF9ZWxzZSBpZih0eXBlb2YgaGE9PSJvYmplY3QiJiZPYmplY3Qua2V5cyhoYSkubGVuZ3RoPjAmJnR5cGVvZiBoYVtPYmplY3Qua2V5cyhoYSlbMF1dPT0ib2JqZWN0Iil7Y29uc3QgU2E9W107cmV0dXJuIGFhLmZvckVhY2goVGE9PntUYSBpbiBoYT9TYS5wdXNoKGhhW1RhXSk6U2EucHVzaChudWxsKX0pLFNhfWVsc2UgdGhyb3cgbmV3IEVycm9yKGBUaGUgbW9kZWwgaGFzIG11bHRpcGxlICgke2JhfSkgb3V0cHV0cywgc28gJHt4YX0gbXVzdCBiZSBlaXRoZXIgYW4gYXJyYXkgd2l0aCAke2JhfSBlbGVtZW50cyBvciBhbiBvYmplY3Qgd2l0aCAke2FhfSBrZXlzLiBQcm92aWRlZCAke3hhfSBub3QgdW5kZXJzdG9vZDogJHtKU09OLnN0cmluZ2lmeShoYSl9YCl9ZnVuY3Rpb24gc3RhbmRhcmRpemVDbGFzc1dlaWdodHMoaGEsYWEpe3JldHVybiBzdGFuZGFyZGl6ZVNhbXBsZU9yQ2xhc3NXZWlnaHRzKGhhLGFhLCJjbGFzc1dlaWdodCIpfWFzeW5jIGZ1bmN0aW9uIHN0YW5kYXJkaXplV2VpZ2h0cyhoYSxhYSx4YSxiYSl7aWYoeGEhPW51bGwpe2NvbnN0IFNhPXRpZHkkMSgoKT0+e2lmKGhhLnNoYXBlLmxlbmd0aD09PTEpcmV0dXJuIGNsb25lJDEoaGEpO2lmKGhhLnNoYXBlLmxlbmd0aD09PTIpe2lmKGhhLnNoYXBlWzFdPjEpcmV0dXJuIGFyZ01heCQzKGhhLDEpO2lmKGhhLnNoYXBlWzFdPT09MSlyZXR1cm4gcmVzaGFwZSQ0KGhhLFtoYS5zaGFwZVswXV0pO3Rocm93IG5ldyBFcnJvcihgRW5jb3VudGVyZWQgdW5leHBlY3RlZCBsYXN0LWRpbWVuc2lvbiBzaXplICgke2hhLnNoYXBlWzFdfSkgZHVyaW5nIGhhbmRsaW5nIG9mIGNsYXNzIHdlaWdodHMuIFRoZSBzaXplIGlzIGV4cGVjdGVkIHRvIGJlID49IDEuYCl9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgcmFuayBvZiB0YXJnZXQgKHkpIHRlbnNvciAoJHtoYS5yYW5rfSkgZHVyaW5nIGhhbmRsaW5nIG9mIGNsYXNzIHdlaWdodHMuIFRoZSByYW5rIGlzIGV4cGVjdGVkIHRvIGJlIDEgb3IgMi5gKX0pLFRhPUFycmF5LmZyb20oYXdhaXQgU2EuZGF0YSgpKTtkaXNwb3NlJDEoU2EpO2NvbnN0IHdhPVtdO3JldHVybiBUYS5mb3JFYWNoKEVhPT57aWYoeGFbRWFdPT1udWxsKXRocm93IG5ldyBFcnJvcihgY2xhc3NXZWlnaHQgbXVzdCBjb250YWluIGFsbCBjbGFzc2VzIGluIHRoZSB0cmFpbmluZyBkYXRhLiBUaGUgY2xhc3MgJHtFYX0gZXhpc3RzIGluIHRoZSBkYXRhIGJ1dCBub3QgaW4gY2xhc3NXZWlnaHRgKTt3YS5wdXNoKHhhW0VhXSl9KSx0ZW5zb3IxZCh3YSwiZmxvYXQzMiIpfWVsc2UgcmV0dXJuIG51bGx9ZnVuY3Rpb24gY29tcHV0ZVdlaWdodGVkTG9zcyhoYSxhYSl7cmV0dXJuIG11bCQxKGhhLGFhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBERUZBVUxUX1ZBTElEQVRJT05fQkFUQ0hfU0laRT0zMjtmdW5jdGlvbiBzdGFuZGFyZGl6ZURhdGFJdGVyYXRvck91dHB1dChoYSxhYSl7bGV0IHhhLGJhO2NvbnN0IFNhPWFhO3hhPVNhLnhzLGJhPVNhLnlzLGFzc2VydCQyKHhhIT1udWxsJiZiYSE9bnVsbCwoKT0+YEEgRGF0YXNldCBpdGVyYXRvciBmb3IgZml0RGF0YXNldCgpIGlzIGV4cGVjdGVkIHRvIGdlbmVyYXRlIG9iamVjdHMgb2YgdGhlIGZvcm0gXGB7eHM6IHhWYWwsIHlzOiB5VmFsfVxgLCB3aGVyZSB0aGUgdHdvIHZhbHVlcyBtYXkgYmUgXGB0Zi5UZW5zb3JcYCwgYW4gYXJyYXkgb2YgVGVuc29ycywgb3IgYSBtYXAgb2Ygc3RyaW5nIHRvIFRlbnNvci4gIFRoZSBwcm92aWRlZCBEYXRhc2V0IGluc3RlYWQgZ2VuZXJhdGVzICR7YWF9YCk7Y29uc3QgVGE9ZmxhdHRlblRlbnNvck9yQXJyYXlPck1hcCgiaW5wdXQiLGhhLmlucHV0TmFtZXMseGEpLHdhPWZsYXR0ZW5UZW5zb3JPckFycmF5T3JNYXAoIm91dHB1dCIsaGEub3V0cHV0TmFtZXMsYmEpLEVhPVRhWzBdLnNoYXBlWzBdO2Fzc2VydCQyKFRhLmxlbmd0aD09PWhhLmlucHV0cy5sZW5ndGgsKCk9PmBMYXllcnNNb2RlbCBoYXMgJHtoYS5pbnB1dHMubGVuZ3RofSBpbnB1dHMsIGJ1dCB0aGUgZGF0YXNldCBwcm92aWRlcyAke1RhLmxlbmd0aH0gaW5wdXRzLiAgKEV4cGVjdGVkIGlucHV0IGtleXM6ICR7SlNPTi5zdHJpbmdpZnkoaGEuaW5wdXROYW1lcyl9KWApLGFzc2VydCQyKHdhLmxlbmd0aD09PWhhLm91dHB1dHMubGVuZ3RoLCgpPT5gTGF5ZXJzTW9kZWwgaGFzICR7aGEub3V0cHV0cy5sZW5ndGh9IG91dHB1dHMsIGJ1dCB0aGUgZGF0YXNldCBwcm92aWRlcyAke3dhLmxlbmd0aH0gb3V0cHV0cy4gIChFeHBlY3RlZCBvdXRwdXQga2V5czogJHtKU09OLnN0cmluZ2lmeShoYS5vdXRwdXROYW1lcyl9KWApO2ZvcihsZXQga2E9MDtrYTxUYS5sZW5ndGg7a2ErKylhc3NlcnQkMihUYVtrYV0uc2hhcGVbMF09PT1FYSwoKT0+YEJhdGNoIHNpemUgbWlzbWF0Y2g6IGlucHV0ICR7aGEuaW5wdXROYW1lc1trYV19IGhhcyAke1RhW2thXS5zaGFwZVswXX07IGV4cGVjdGVkICAke0VhfSBiYXNlZCBvbiBpbnB1dCAke2hhLmlucHV0TmFtZXNbMF19LmApO2ZvcihsZXQga2E9MDtrYTx3YS5sZW5ndGg7a2ErKylhc3NlcnQkMih3YVtrYV0uc2hhcGVbMF09PT1FYSwoKT0+YEJhdGNoIHNpemUgbWlzbWF0Y2g6IG91dHB1dCAke2hhLm91dHB1dE5hbWVzW2thXX0gaGFzICR7d2Fba2FdLnNoYXBlWzBdfTsgZXhwZWN0ZWQgICR7RWF9IGJhc2VkIG9uIGlucHV0ICR7aGEuaW5wdXROYW1lc1swXX0uYCk7cmV0dXJue3hzOlRhLHlzOndhfX1mdW5jdGlvbiBmbGF0dGVuVGVuc29yT3JBcnJheU9yTWFwKGhhLGFhLHhhKXtpZih4YSBpbnN0YW5jZW9mIFRlbnNvciQxKXJldHVyblt4YV07aWYoQXJyYXkuaXNBcnJheSh4YSkpcmV0dXJuIGFzc2VydCQyKHhhLmxlbmd0aD09PWFhLmxlbmd0aCwoKT0+YFJlY2VpdmVkIGFuIGFycmF5IG9mICR7eGEubGVuZ3RofSBUZW5zb3JzLCBidXQgZXhwZWN0ZWQgJHthYS5sZW5ndGh9IHRvIG1hdGNoIHRoZSAke2hhfSBrZXlzICR7YWF9LmApLHhhO3tjb25zdCBiYT1bXTtmb3IoY29uc3QgU2Egb2YgYWEpe2lmKHhhW1NhXT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgVGhlIGZlYXR1cmUgZGF0YSBnZW5lcmF0ZWQgYnkgdGhlIGRhdGFzZXQgbGFja3MgdGhlIHJlcXVpcmVkICR7aGF9IGtleSAnJHtTYX0nLmApO2JhLnB1c2goeGFbU2FdKX1yZXR1cm4gYmF9fWZ1bmN0aW9uIHN0YW5kYXJkaXplVGVuc29yVmFsaWRhdGlvbkRhdGEoaGEpe2lmKGhhLmxlbmd0aD09PTMpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoIlZhbGlkYXRpb24gd2l0aCBzYW1wbGUgd2VpZ2h0cyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO3JldHVybnt4czpoYVswXSx5czpoYVsxXX19YXN5bmMgZnVuY3Rpb24gZml0RGF0YXNldChoYSxhYSx4YSl7Y29uc3QgYmE9eGEuYmF0Y2hlc1BlckVwb2NoIT1udWxsO2lmKGFzc2VydCQyKGhhLm9wdGltaXplciE9bnVsbCwoKT0+IllvdSBtdXN0IGNvbXBpbGUgYSBtb2RlbCBiZWZvcmUgdHJhaW5pbmcvdGVzdGluZy4gVXNlIExheWVyc01vZGVsLmNvbXBpbGUobW9kZWxDb21waWxlQ29uZmlnKS4iKSxhc3NlcnQkMih4YSE9bnVsbCwoKT0+IkZvciBmaXREYXRhc2V0KCksIHRoZSAybmQgYXJndW1lbnQgKGNvbmZpZykgaXMgcmVxdWlyZWQsIGJ1dCBpdCBpcyBub3QgcHJvdmlkZWQgaW4gdGhpcyBjYWxsLiIpLGFzc2VydCQyKHhhLmVwb2NocyE9bnVsbCYmeGEuZXBvY2hzPjAmJk51bWJlci5pc0ludGVnZXIoeGEuZXBvY2hzKSwoKT0+YEZvciBmaXREYXRhc2V0KCksIGNvbmZpZy5lcG9jaHMgaXMgZXhwZWN0ZWQgdG8gYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBidXQgZ290ICR7eGEuZXBvY2hzfWApLGFzc2VydCQyKCFiYXx8eGEuYmF0Y2hlc1BlckVwb2NoPjAmJk51bWJlci5pc0ludGVnZXIoeGEuYmF0Y2hlc1BlckVwb2NoKSwoKT0+YEZvciBmaXREYXRhc2V0KCksIGNvbmZpZy5iYXRjaGVzUGVyRXBvY2ggaXMgZXhwZWN0ZWQgdG8gYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyIGlmIHNwZWNpZmllZCwgYnV0IGdvdCAke3hhLmJhdGNoZXNQZXJFcG9jaH1gKSxhc3NlcnQkMih4YS52YWxpZGF0aW9uU3BsaXQ9PW51bGwsKCk9PiJgdmFsaWRhdGlvblNwbGl0YCBpcyBub3Qgc3VwcG9ydGVkIGJ5IGBmaXREYXRhc2V0KClgLiBVc2UgdmFsaWRhdGlvbkRhdGEgaW5zdGVhZC4iKSxoYS5pc1RyYWluaW5nKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IHN0YXJ0IHRyYWluaW5nIGJlY2F1c2UgYW5vdGhlciBmaXQoKSBjYWxsIGlzIG9uZ29pbmcuIik7aGEuaXNUcmFpbmluZz0hMDt0cnl7Y29uc3QgU2E9eGEudmFsaWRhdGlvbkRhdGEhPW51bGw7bGV0IFRhLHdhO2lmKFNhKWlmKGlzRGF0YXNldE9iamVjdCh4YS52YWxpZGF0aW9uRGF0YSkpYXNzZXJ0JDIoeGEudmFsaWRhdGlvbkJhdGNoZXM9PW51bGx8fHhhLnZhbGlkYXRpb25CYXRjaGVzPjAmJk51bWJlci5pc0ludGVnZXIoeGEudmFsaWRhdGlvbkJhdGNoZXMpLCgpPT5gRm9yIGZpdERhdGFzZXQoKSB3aXRoIGRhdGFzZXQtYmFzZWQgdmFsaWRhdGlvbiwgY29uZmlnLnZhbGlkYXRpb25CYXRjaGVzIGlzIGV4cGVjdGVkIG5vdCB0byBiZSBwcm92aWRlZCwgb3IgdG8gYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBidXQgZ290ICR7eGEudmFsaWRhdGlvbkJhdGNoZXN9YCk7ZWxzZXtjb25zdCBybD1zdGFuZGFyZGl6ZVRlbnNvclZhbGlkYXRpb25EYXRhKHhhLnZhbGlkYXRpb25EYXRhKTtUYT1ybC54cyx3YT1ybC55c31jb25zdCBFYT1oYS5tYWtlVHJhaW5GdW5jdGlvbigpLGthPWhhLmdldERlZHVwZWRNZXRyaWNzTmFtZXMoKTtsZXQgQWE7U2E/QWE9a2Euc2xpY2UoKS5jb25jYXQoa2EubWFwKHJsPT4idmFsXyIrcmwpKTpBYT1rYS5zbGljZSgpO2NvbnN0IEZhPXN0YW5kYXJkaXplQ2FsbGJhY2tzKHhhLmNhbGxiYWNrcyx4YS55aWVsZEV2ZXJ5KSxMYT14YS52ZXJib3NlPT1udWxsPzE6eGEudmVyYm9zZSx7Y2FsbGJhY2tMaXN0OmVsLGhpc3Rvcnk6dGx9PWNvbmZpZ3VyZUNhbGxiYWNrcyhGYSxMYSx4YS5lcG9jaHMsbnVsbCxudWxsLGdldFN0ZXBzUGVyRXBvY2goYWEseGEpLG51bGwsU2EsQWEpO2VsLnNldE1vZGVsKGhhKSxoYS5oaXN0b3J5PXRsLGF3YWl0IGVsLm9uVHJhaW5CZWdpbigpLGhhLnN0b3BUcmFpbmluZ189ITE7bGV0IG5sPXhhLmluaXRpYWxFcG9jaD09bnVsbD8wOnhhLmluaXRpYWxFcG9jaCxzbD1hd2FpdCBhYS5pdGVyYXRvcigpO2Zvcig7bmw8eGEuZXBvY2hzOyl7Y29uc3Qgcmw9e307YXdhaXQgZWwub25FcG9jaEJlZ2luKG5sKTtsZXQgb2w9MCxhbD0wO2ZvcihiYXx8KHNsPWF3YWl0IGFhLml0ZXJhdG9yKCkpOyFiYXx8b2w8eGEuYmF0Y2hlc1BlckVwb2NoOyl7Y29uc3QgbGw9YXdhaXQgc2wubmV4dCgpO2lmKGJhJiZsbC5kb25lKXtjb25zb2xlLndhcm4oYFlvdSBwcm92aWRlZCBcYGJhdGNoZXNQZXJFcG9jaFxgIGFzICR7eGEuYmF0Y2hlc1BlckVwb2NofSwgYnV0IHlvdXIgZGF0YXNldCBpdGVyYXRvciByYW4gb3V0IG9mIGRhdGEgYWZ0ZXIgJHtvbH0gYmF0Y2hlczsgaW50ZXJydXB0aW5nIHRyYWluaW5nLiBNYWtlIHN1cmUgdGhhdCB5b3VyIGRhdGFzZXQgY2FuIGdlbmVyYXRlIGF0IGxlYXN0IFxgYmF0Y2hlc1BlckVwb2NoICogZXBvY2hzXGAgYmF0Y2hlcyAoaW4gdGhpcyBjYXNlLCAke3hhLmJhdGNoZXNQZXJFcG9jaCp4YS5lcG9jaHN9IGJhdGNoZXMpLiBZb3UgbWF5IG5lZWQgdG8gdXNlIHRoZSByZXBlYXQoKSBmdW5jdGlvbiB3aGVuIGJ1aWxkaW5nIHlvdXIgZGF0YXNldC5gKTticmVha31pZihsbC52YWx1ZSE9bnVsbCl7Y29uc3R7eHM6aWwseXM6Y2x9PXN0YW5kYXJkaXplRGF0YUl0ZXJhdG9yT3V0cHV0KGhhLGxsLnZhbHVlKSx1bD17fTt1bC5iYXRjaD1hbCx1bC5zaXplPWlsWzBdLnNoYXBlWzBdLGF3YWl0IGVsLm9uQmF0Y2hCZWdpbihhbCx1bCk7Y29uc3QgZGw9W107aWYoeGEuY2xhc3NXZWlnaHQhPW51bGwpe2NvbnN0IGZsPXN0YW5kYXJkaXplQ2xhc3NXZWlnaHRzKHhhLmNsYXNzV2VpZ2h0LGhhLm91dHB1dE5hbWVzKTtmb3IobGV0IG1sPTA7bWw8ZmwubGVuZ3RoOysrbWwpZGwucHVzaChhd2FpdCBzdGFuZGFyZGl6ZVdlaWdodHMoY2xbbWxdLG51bGwsZmxbbWxdKSl9Y29uc3QgaGw9aWwuY29uY2F0KGNsKS5jb25jYXQoZGwpLHBsPUVhKGhsKTtkaXNwb3NlJDEoaGwpO2ZvcihsZXQgZmw9MDtmbDxrYS5sZW5ndGg7KytmbCl7Y29uc3QgbWw9a2FbZmxdLGdsPXBsW2ZsXTt1bFttbF09Z2wsa2VlcCQxKGdsKX1hd2FpdCBlbC5vbkJhdGNoRW5kKGFsLHVsKSxkaXNwb3NlVGVuc29yc0luTG9ncyh1bCksYWwrKyxvbCsrfWlmKGJhP29sPj14YS5iYXRjaGVzUGVyRXBvY2g6bGwuZG9uZSl7aWYoU2Epe2xldCBpbDtpc0RhdGFzZXRPYmplY3QoeGEudmFsaWRhdGlvbkRhdGEpP2lsPXRvTGlzdChhd2FpdCBoYS5ldmFsdWF0ZURhdGFzZXQoeGEudmFsaWRhdGlvbkRhdGEse2JhdGNoZXM6eGEudmFsaWRhdGlvbkJhdGNoZXN9KSk6aWw9dG9MaXN0KGhhLmV2YWx1YXRlKFRhLHdhLHtiYXRjaFNpemU6eGEudmFsaWRhdGlvbkJhdGNoU2l6ZT09bnVsbD9ERUZBVUxUX1ZBTElEQVRJT05fQkFUQ0hfU0laRTp4YS52YWxpZGF0aW9uQmF0Y2hTaXplLHZlcmJvc2U6MH0pKTtmb3IobGV0IGNsPTA7Y2w8aGEubWV0cmljc05hbWVzLmxlbmd0aDsrK2NsKXJsW2B2YWxfJHtoYS5tZXRyaWNzTmFtZXNbY2xdfWBdPWlsW2NsXX1icmVha31pZihoYS5zdG9wVHJhaW5pbmdfKWJyZWFrfWlmKGF3YWl0IGVsLm9uRXBvY2hFbmQobmwscmwpLG5sKyssaGEuc3RvcFRyYWluaW5nXylicmVha31yZXR1cm4gYXdhaXQgZWwub25UcmFpbkVuZCgpLGF3YWl0IGhhLmhpc3Rvcnkuc3luY0RhdGEoKSxoYS5oaXN0b3J5fWZpbmFsbHl7aGEuaXNUcmFpbmluZz0hMX19ZnVuY3Rpb24gZ2V0U3RlcHNQZXJFcG9jaChoYSxhYSl7bGV0IHhhPW51bGw7cmV0dXJuIGFhLmJhdGNoZXNQZXJFcG9jaCE9bnVsbD94YT1hYS5iYXRjaGVzUGVyRXBvY2g6TnVtYmVyLmlzRmluaXRlKGhhLnNpemUpJiYoeGE9aGEuc2l6ZSkseGF9ZnVuY3Rpb24gaXNEYXRhc2V0T2JqZWN0KGhhKXtyZXR1cm4gdHlwZW9mIGhhLml0ZXJhdG9yPT0iZnVuY3Rpb24ifWZ1bmN0aW9uIGlzTGF6eUl0ZXJhdG9yT2JqZWN0KGhhKXtyZXR1cm4gdHlwZW9mIGhhLm5leHQ9PSJmdW5jdGlvbiJ9YXN5bmMgZnVuY3Rpb24gZXZhbHVhdGVEYXRhc2V0KGhhLGFhLHhhKXt4YT14YXx8e307Y29uc3QgYmE9eGEuYmF0Y2hlcyE9bnVsbCxTYT1oYS50ZXN0RnVuY3Rpb247bGV0IFRhPVtdO2lmKHhhLnZlcmJvc2U+MCl0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiVmVyYm9zZSBtb2RlIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuIik7YXNzZXJ0JDIoIWJhfHx4YS5iYXRjaGVzPjAmJk51bWJlci5pc0ludGVnZXIoeGEuYmF0Y2hlcyksKCk9PmBUZXN0IGxvb3AgZXhwZWN0cyBcYGJhdGNoZXNcYCB0byBiZSBhIHBvc2l0aXZlIGludGVnZXIsIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KHhhLmJhdGNoZXMpfWApO2NvbnN0IHdhPWlzTGF6eUl0ZXJhdG9yT2JqZWN0KGFhKT9hYTphd2FpdCBhYS5pdGVyYXRvcigpO2xldCBFYT0wLGthPTA7Zm9yKDshYmF8fGthPHhhLmJhdGNoZXM7KXtjb25zdCBBYT1hd2FpdCB3YS5uZXh0KCk7aWYoVGE9dGlkeSQxKCgpPT57aWYoQWEudmFsdWUpe2NvbnN0e3hzOkZhLHlzOkxhfT1zdGFuZGFyZGl6ZURhdGFJdGVyYXRvck91dHB1dChoYSxBYS52YWx1ZSksZWw9RmEuY29uY2F0KExhKSx0bD10aWR5JDEoKCk9PlNhKGVsKSk7aWYoZGlzcG9zZSQxKGVsKSxrYT09PTApZm9yKGxldCBzbD0wO3NsPHRsLmxlbmd0aDsrK3NsKVRhLnB1c2goc2NhbGFyJDEoMCkpO2NvbnN0IG5sPWVsWzBdLnNoYXBlWzBdO2ZvcihsZXQgc2w9MDtzbDx0bC5sZW5ndGg7KytzbCl7Y29uc3Qgcmw9dGxbc2xdLG9sPVRhW3NsXTtUYVtzbF09dGlkeSQxKCgpPT5hZGQkMyhUYVtzbF0sbXVsJDEobmwscmwpKSksa2E+MCYmZGlzcG9zZSQxKG9sKX1kaXNwb3NlJDEodGwpLEVhKz1ubCwrK2thfXJldHVybiBUYX0pLEFhLmRvbmUpe2JhJiZjb25zb2xlLndhcm4oYFlvdXIgZGF0YXNldCBpdGVyYXRvciByYW4gb3V0IG9mIGRhdGEgZHVyaW5nIGV2YWx1YXRlRGF0YXNldCgpLiBJbnRlcnJ1cHRpbmcgZXZhbHV0aW9uLiBNYWtlIHN1cmUgdGhhdCB5b3VyIGRhdGFzZXQgY2FuIGdlbmVyYXRlIGF0IGxlYXN0IFxgYmF0Y2hlc1xgIGJhdGNoZXMgKGluIHRoaXMgY2FzZSwgJHt4YS5iYXRjaGVzfSBiYXRjaGVzKS4gWW91IG1heSBuZWVkIHRvIHVzZSB0aGUgcmVwZWF0KCkgZnVuY3Rpb24gd2hlbiBidWlsZGluZyB5b3VyIGRhdGFzZXQuYCk7YnJlYWt9fWZvcihsZXQgQWE9MDtBYTxUYS5sZW5ndGg7KytBYSl7Y29uc3QgRmE9VGFbQWFdO1RhW0FhXT1kaXYkMihUYVtBYV0sRWEpLGRpc3Bvc2UkMShGYSl9cmV0dXJuIHNpbmdsZXRvbk9yQXJyYXkoVGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNoZWNrQmF0Y2hTaXplKGhhKXthc3NlcnQkMihoYT4wJiZOdW1iZXIuaXNJbnRlZ2VyKGhhKSwoKT0+YGJhdGNoU2l6ZSBpcyByZXF1aXJlZCB0byBiZSBhIHBvc2l0aXZlIGludGVnZXIsIGJ1dCBnb3QgJHtoYX1gKX1mdW5jdGlvbiBzbGljZUFycmF5cyhoYSxhYSx4YSl7cmV0dXJuIGhhPT1udWxsP1tudWxsXTpBcnJheS5pc0FycmF5KGhhKT9oYS5tYXAoYmE9PnNsaWNlQWxvbmdGaXJzdEF4aXMoYmEsYWEseGEtYWEpKTpzbGljZUFsb25nRmlyc3RBeGlzKGhhLGFhLHhhLWFhKX1mdW5jdGlvbiBzbGljZUFycmF5c0J5SW5kaWNlcyhoYSxhYSl7cmV0dXJuIHRpZHkkMSgoKT0+aGE9PW51bGw/bnVsbDpBcnJheS5pc0FycmF5KGhhKT9oYS5tYXAoeGE9PnNsaWNlQXJyYXlzQnlJbmRpY2VzKHhhLGFhKSk6Z2F0aGVyKGhhLGFhLmR0eXBlPT09ImludDMyIj9hYTpjYXN0JDUoYWEsImludDMyIikpKX1mdW5jdGlvbiBtYWtlQmF0Y2hlcyhoYSxhYSl7Y29uc3QgeGE9W107bGV0IGJhPTAsU2E9bnVsbDtmb3IoO2JhPGhhOylTYT1iYSthYSxTYT49aGEmJihTYT1oYSkseGEucHVzaChbYmEsU2FdKSxiYT1TYTtyZXR1cm4geGF9ZnVuY3Rpb24gZW5zdXJlVGVuc29yc1JhbmsyT3JIaWdoZXIoaGEpe2NvbnN0IGFhPVtdO2hhIGluc3RhbmNlb2YgVGVuc29yJDEmJihoYT1baGFdKTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoOysreGEpe2NvbnN0IGJhPWhhW3hhXTtpZihiYS5yYW5rPT09MSlhYS5wdXNoKGV4cGFuZERpbXMkMyhiYSwxKSk7ZWxzZXtpZihiYS5yYW5rPT09MCl0aHJvdyBuZXcgRXJyb3IoIkV4cGVjdGVkIHRlbnNvciB0byBiZSBhdCBsZWFzdCAxRCwgYnV0IHJlY2VpdmVkIGEgMEQgdGVuc29yIChzY2FsYXIpLiIpO2FhLnB1c2goYmEpfX1yZXR1cm4gYWF9ZnVuY3Rpb24gZGlzcG9zZU5ld1RlbnNvcnMoaGEsYWEpe2lmKGhhPT1udWxsKXJldHVybjtjb25zdCB4YT1bXTtpZihhYSBpbnN0YW5jZW9mIFRlbnNvciQxKXhhLnB1c2goYWEuaWQpO2Vsc2UgaWYoQXJyYXkuaXNBcnJheShhYSkpYWEuZm9yRWFjaChTYT0+eGEucHVzaChTYS5pZCkpO2Vsc2UgaWYoYWEhPW51bGwpZm9yKGNvbnN0IFNhIGluIGFhKXtjb25zdCBUYT1hYVtTYV07eGEucHVzaChUYS5pZCl9Y29uc3QgYmE9W107aWYoaGEgaW5zdGFuY2VvZiBUZW5zb3IkMSl4YS5pbmRleE9mKGhhLmlkKT09PS0xJiZiYS5wdXNoKGhhKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoaGEpKWhhLmZvckVhY2goU2E9Pnt4YS5pbmRleE9mKFNhLmlkKT09PS0xJiZiYS5wdXNoKFNhKX0pO2Vsc2UgaWYoaGEhPW51bGwpZm9yKGNvbnN0IFNhIGluIGhhKXtjb25zdCBUYT1oYVtTYV07eGEuaW5kZXhPZihUYS5pZCk9PT0tMSYmYmEucHVzaChUYSl9YmEuZm9yRWFjaChTYT0+e1NhLmlzRGlzcG9zZWR8fFNhLmRpc3Bvc2UoKX0pfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlzRGF0YVRlbnNvcihoYSl7cmV0dXJuIGhhIGluc3RhbmNlb2YgVGVuc29yJDF9ZnVuY3Rpb24gaXNEYXRhQXJyYXkoaGEpe3JldHVybiBBcnJheS5pc0FycmF5KGhhKX1mdW5jdGlvbiBpc0RhdGFEaWN0KGhhKXtyZXR1cm4haXNEYXRhVGVuc29yKGhhKSYmIWlzRGF0YUFycmF5KGhhKX1mdW5jdGlvbiBzdGFuZGFyZGl6ZUlucHV0RGF0YShoYSxhYSx4YSxiYT0hMCxTYT0iIil7aWYoYWE9PW51bGx8fGFhLmxlbmd0aD09PTApe2lmKGhhIT1udWxsKXtsZXQgd2E9ITE7aWYoaXNEYXRhQXJyYXkoaGEpJiZoYS5sZW5ndGg+MCl3YT0hMDtlbHNlIGlmKGlzRGF0YURpY3QoaGEpKXtmb3IoY29uc3QgRWEgaW4gaGEpaWYoaGEuaGFzT3duUHJvcGVydHkoRWEpKXt3YT0hMDticmVha319ZWxzZSB3YT0hMDtpZih3YSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgRXJyb3Igd2hlbiBjaGVja2luZyBtb2RlbCAke1NhfSBleHBlY3RlZCBubyBkYXRhLCBidXQgZ290ICR7aGF9YCl9cmV0dXJuW119aWYoaGE9PW51bGwpcmV0dXJuIGFhLm1hcCh3YT0+bnVsbCk7bGV0IFRhO2lmKGlzRGF0YURpY3QoaGEpKXtoYT1oYSxUYT1bXTtmb3IoY29uc3Qgd2Egb2YgYWEpe2lmKGhhW3dhXT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgTm8gZGF0YSBwcm92aWRlZCBmb3IgIiR7d2F9Ii4gTmVlZCBkYXRhIGZvciBlYWNoIGtleSBpbjogJHthYX1gKTtUYS5wdXNoKGhhW3dhXSl9fWVsc2UgaWYoaXNEYXRhQXJyYXkoaGEpKXtpZihoYT1oYSxoYS5sZW5ndGghPT1hYS5sZW5ndGgpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEVycm9yIHdoZW4gY2hlY2tpbmcgbW9kZWwgJHtTYX06IHRoZSBBcnJheSBvZiBUZW5zb3JzIHRoYXQgeW91IGFyZSBwYXNzaW5nIHRvIHlvdXIgbW9kZWwgaXMgbm90IHRoZSBzaXplIHRoZSBtb2RlbCBleHBlY3RlZC4gRXhwZWN0ZWQgdG8gc2VlICR7YWEubGVuZ3RofSBUZW5zb3IocyksIGJ1dCBpbnN0ZWFkIGdvdCB0aGUgZm9sbG93aW5nIGxpc3Qgb2YgVGVuc29yKHMpOiAke2hhfWApO1RhPWhhfWVsc2V7aWYoaGE9aGEsYWEubGVuZ3RoPjEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBtb2RlbCAke1NhfSBleHBlY3RzICR7YWEubGVuZ3RofSBUZW5zb3IocyksIGJ1dCBvbmx5IHJlY2VpdmVkIG9uZSBUZW5zb3IuIEZvdW5kOiBUZW5zb3Igd2l0aCBzaGFwZSAke2hhLnNoYXBlfWApO1RhPVtoYV19aWYoVGE9ZW5zdXJlVGVuc29yc1JhbmsyT3JIaWdoZXIoVGEpLHhhIT1udWxsKWZvcihsZXQgd2E9MDt3YTxhYS5sZW5ndGg7Kyt3YSl7aWYoeGFbd2FdPT1udWxsKWNvbnRpbnVlO2NvbnN0IEVhPVRhW3dhXTtpZihFYS5zaGFwZS5sZW5ndGghPT14YVt3YV0ubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBFcnJvciB3aGVuIGNoZWNraW5nICR7U2F9OiBleHBlY3RlZCAke2FhW3dhXX0gdG8gaGF2ZSAke3hhW3dhXS5sZW5ndGh9IGRpbWVuc2lvbihzKS4gYnV0IGdvdCBhcnJheSB3aXRoIHNoYXBlICR7RWEuc2hhcGV9YCk7Zm9yKGxldCBrYT0wO2thPHhhW3dhXS5sZW5ndGg7KytrYSl7aWYoa2E9PT0wJiYhYmEpY29udGludWU7Y29uc3QgQWE9RWEuc2hhcGVba2FdLEZhPXhhW3dhXVtrYV07aWYoRmEhPW51bGwmJkZhPj0wJiZBYSE9PUZhKXRocm93IG5ldyBWYWx1ZUVycm9yKGAke1NhfSBleHBlY3RlZCBhIGJhdGNoIG9mIGVsZW1lbnRzIHdoZXJlIGVhY2ggZXhhbXBsZSBoYXMgc2hhcGUgWyR7eGFbd2FdLnNsaWNlKDEseGFbd2FdLmxlbmd0aCl9XSAoaS5lLix0ZW5zb3Igc2hhcGUgWyosJHt4YVt3YV0uc2xpY2UoMSx4YVt3YV0ubGVuZ3RoKX1dKSBidXQgdGhlICR7U2F9IHJlY2VpdmVkIGFuIGlucHV0IHdpdGggJHtFYS5zaGFwZVswXX0gZXhhbXBsZXMsIGVhY2ggd2l0aCBzaGFwZSBbJHtFYS5zaGFwZS5zbGljZSgxLEVhLnNoYXBlLmxlbmd0aCl9XSAodGVuc29yIHNoYXBlIFske0VhLnNoYXBlfV0pYCl9fXJldHVybiBUYX1mdW5jdGlvbiBjaGVja0FycmF5TGVuZ3RocyhoYSxhYSx4YSl7Y29uc3QgYmE9dW5pcXVlJDMoaGEubWFwKFRhPT5UYS5zaGFwZVswXSkpO2JhLnNvcnQoKTtjb25zdCBTYT11bmlxdWUkMyhhYS5tYXAoVGE9PlRhLnNoYXBlWzBdKSk7aWYoU2Euc29ydCgpLGJhLmxlbmd0aD4xKXRocm93IG5ldyBWYWx1ZUVycm9yKGBBbGwgaW5wdXQgVGVuc29ycyAoeCkgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIHNhbXBsZXMuIEdvdCBhcnJheSBzaGFwZXM6ICR7SlNPTi5zdHJpbmdpZnkoaGEubWFwKFRhPT5UYS5zaGFwZSkpfWApO2lmKFNhLmxlbmd0aD4xKXRocm93IG5ldyBWYWx1ZUVycm9yKGBBbGwgdGFyZ2V0IFRlbnNvcnMgKHkpIHNob3VsZCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBzYW1wbGVzLiBHb3QgYXJyYXkgc2hhcGVzOiAke0pTT04uc3RyaW5naWZ5KGFhLm1hcChUYT0+VGEuc2hhcGUpKX1gKTtpZihiYS5sZW5ndGg+MCYmU2EubGVuZ3RoPjAmJiFhcnJheXNFcXVhbCQxKGJhLFNhKSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW5wdXQgVGVuc29ycyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2Ygc2FtcGxlcyBhcyB0YXJnZXQgVGVuc29ycy4gRm91bmQgJHtiYVswXX0gaW5wdXQgc2FtcGxlKHMpIGFuZCAke1NhWzBdfSB0YXJnZXQgc2FtcGxlKHMpLmApfWZ1bmN0aW9uIGNoZWNrTG9zc0FuZFRhcmdldENvbXBhdGliaWxpdHkoaGEsYWEseGEpe2NvbnN0IGJhPVttZWFuU3F1YXJlZEVycm9yLGJpbmFyeUNyb3NzZW50cm9weSQxLGNhdGVnb3JpY2FsQ3Jvc3NlbnRyb3B5JDFdO2ZvcihsZXQgU2E9MDtTYTxoYS5sZW5ndGg7KytTYSl7Y29uc3QgVGE9aGFbU2FdLHdhPWFhW1NhXSxFYT14YVtTYV07aWYod2EhPW51bGwpe2lmKHdhPT09Y2F0ZWdvcmljYWxDcm9zc2VudHJvcHkkMSYmVGEuc2hhcGVbVGEuc2hhcGUubGVuZ3RoLTFdPT09MSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgWW91IGFyZSBwYXNzaW5nIGEgdGFyZ2V0IGFycmF5IG9mIHNoYXBlICR7VGEuc2hhcGV9IHdoaWxlIHVzaW5nIGEgbG9zcyAnY2F0ZWdvcmljYWxfY3Jvc3NlbnRyb3B5Jy4gJ2NhdGVnb3JpY2FsX2Nyb3NzZW50cm9weSdleHBlY3RzIHRhcmdldHMgdG8gYmUgYmluYXJ5IG1hdHJpY2VzICgxcyBhbmQgMHMpIG9mIHNoYXBlIFtzYW1wbGVzLCBjbGFzc2VzXS5gKTtpZihiYS5pbmRleE9mKHdhKSE9PS0xKXtjb25zdCBrYT1UYS5zaGFwZS5zbGljZSgxKSxBYT1FYS5zbGljZSgxKTtmb3IobGV0IEZhPTA7RmE8a2EubGVuZ3RoOysrRmEpe2NvbnN0IExhPWthW0ZhXSxlbD1BYVtGYV07aWYoZWwhPW51bGwmJkxhIT09ZWwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEEgdGFyZ2V0IFRlbnNvciB3aXRoIHNoYXBlICR7VGEuc2hhcGV9IHdhcyBwYXNzZWQgZm9yIGFuIG91dHB1dCBvZiBzaGFwZSAke0VhfSwgd2hpbGUgdXNpbmcgYSBsb3NzIGZ1bmN0aW9uIHRoYXQgZXhwZWN0cyB0YXJnZXRzIHRvIGhhdmUgdGhlIHNhbWUgc2hhcGUgYXMgdGhlIG91dHB1dC5gKX19fX19ZnVuY3Rpb24gY2hlY2tJbnB1dERhdGEoaGEsYWEseGEsYmE9ITAsU2E9IiIpe2xldCBUYTtpZihBcnJheS5pc0FycmF5KGhhKSl7aWYoaGEubGVuZ3RoIT09YWEubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBFcnJvciB3aGVuIGNoZWNraW5nIG1vZGVsICR7U2F9OiB0aGUgQXJyYXkgb2YgVGVuc29ycyB0aGF0IHlvdSBhcmUgcGFzc2luZyB0byB5b3VyIG1vZGVsIGlzIG5vdCB0aGUgc2l6ZSB0aGUgdGhlIG1vZGVsIGV4cGVjdGVkLiBFeHBlY3RlZCB0byBzZWUgJHthYS5sZW5ndGh9IFRlbnNvcihzKSwgYnV0IGluc3RlYWQgZ290ICR7aGEubGVuZ3RofSBUZW5zb3JzKHMpLmApO1RhPWhhfWVsc2V7aWYoYWEubGVuZ3RoPjEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBtb2RlbCBleHBlY3RzICR7YWEubGVuZ3RofSAke1NhfSBUZW5zb3JzLCBidXQgb25seSByZWNlaXZlZCBvbmUgVGVuc29yLiBGb3VuZDogYXJyYXkgd2l0aCBzaGFwZSAke0pTT04uc3RyaW5naWZ5KGhhLnNoYXBlKX0uYCk7VGE9W2hhXX1pZih4YSE9bnVsbClmb3IobGV0IHdhPTA7d2E8YWEubGVuZ3RoOysrd2Epe2lmKHhhW3dhXT09bnVsbCljb250aW51ZTtjb25zdCBFYT1UYVt3YV07aWYoRWEuc2hhcGUubGVuZ3RoIT09eGFbd2FdLmxlbmd0aCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgRXJyb3Igd2hlbiBjaGVja2luZyAke1NhfTogZXhwZWN0ZWQgJHthYVt3YV19IHRvIGhhdmUgJHt4YVt3YV0ubGVuZ3RofSBkaW1lbnNpb24ocyksIGJ1dCBnb3QgYXJyYXkgd2l0aCBzaGFwZSAke0pTT04uc3RyaW5naWZ5KEVhLnNoYXBlKX1gKTtmb3IobGV0IGthPTA7a2E8eGFbd2FdLmxlbmd0aDsrK2thKXtpZihrYT09PTAmJiFiYSljb250aW51ZTtjb25zdCBBYT1FYS5zaGFwZVtrYV0sRmE9eGFbd2FdW2thXTtpZihGYSE9bnVsbCYmRmEhPT1BYSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgRXJyb3Igd2hlbiBjaGVja2luZyAke1NhfTogZXhwZWN0ZWQgJHthYVt3YV19IHRvIGhhdmUgc2hhcGUgJHtKU09OLnN0cmluZ2lmeSh4YVt3YV0pfSBidXQgZ290IGFycmF5IHdpdGggc2hhcGUgJHtKU09OLnN0cmluZ2lmeShFYS5zaGFwZSl9LmApfX19ZnVuY3Rpb24gY29sbGVjdE1ldHJpY3MoaGEsYWEpe2lmKGhhPT1udWxsfHxBcnJheS5pc0FycmF5KGhhKSYmaGEubGVuZ3RoPT09MClyZXR1cm4gYWEubWFwKGJhPT5bXSk7bGV0IHhhO2lmKHR5cGVvZiBoYT09InN0cmluZyJ8fHR5cGVvZiBoYT09ImZ1bmN0aW9uIil4YT1baGFdO2Vsc2UgaWYoQXJyYXkuaXNBcnJheShoYSl8fHR5cGVvZiBoYT09Im9iamVjdCIpeGE9aGE7ZWxzZSB0aHJvdyBuZXcgVHlwZUVycm9yKGBUeXBlIG9mIG1ldHJpY3MgYXJndW1lbnQgbm90IHVuZGVyc3Rvb2QuIEV4cGVjdGVkIGFuIHN0cmluZyxmdW5jdGlvbiwgQXJyYXksIG9yIE9iamVjdCwgZm91bmQ6ICR7aGF9YCk7aWYoQXJyYXkuaXNBcnJheSh4YSkpcmV0dXJuIGFhLm1hcChiYT0+eGEpO3tjb25zdCBiYT1bXTtmb3IoY29uc3QgU2Egb2YgYWEpe2xldCBUYT14YS5oYXNPd25Qcm9wZXJ0eShTYSk/eGFbU2FdOltdO0FycmF5LmlzQXJyYXkoVGEpfHwoVGE9W1RhXSksYmEucHVzaChUYSl9cmV0dXJuIGJhfX1jb25zdCBMQVlFUlNfTU9ERUxfRk9STUFUX05BTUU9ImxheWVycy1tb2RlbCI7Y2xhc3MgTGF5ZXJzTW9kZWwgZXh0ZW5kcyBDb250YWluZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSx0aGlzLmlzVHJhaW5pbmc9ITF9c3VtbWFyeShhYSx4YSxiYT1jb25zb2xlLmxvZyl7aWYoIXRoaXMuYnVpbHQpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIlRoaXMgbW9kZWwgaGFzIG5ldmVyIGJlZW4gY2FsbGVkLCB0aHVzIGl0cyB3ZWlnaHRzIGhhdmUgbm90IGJlZW4gY3JlYXRlZCB5ZXQuIFNvIG5vIHN1bW1hcnkgY2FuIGJlIGRpc3BsYXllZC4gQnVpbGQgdGhlIG1vZGVsIGZpcnN0IChlLmcuLCBieSBjYWxsaW5nIGl0IG9uIHNvbWUgdGVzdCBkYXRhKS4iKTtwcmludFN1bW1hcnkodGhpcyxhYSx4YSxiYSl9Y29tcGlsZShhYSl7aWYoYWEubG9zcz09bnVsbCYmKGFhLmxvc3M9W10pLHRoaXMubG9zcz1hYS5sb3NzLHR5cGVvZiBhYS5vcHRpbWl6ZXI9PSJzdHJpbmciKXRoaXMub3B0aW1pemVyXz1nZXRPcHRpbWl6ZXIoYWEub3B0aW1pemVyKSx0aGlzLmlzT3B0aW1pemVyT3duZWQ9ITA7ZWxzZXtpZighKGFhLm9wdGltaXplciBpbnN0YW5jZW9mIE9wdGltaXplciQxKSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiVXNlci1kZWZpbmVkIG9wdGltaXplciBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIHRmLk9wdGltaXplci4iKTt0aGlzLm9wdGltaXplcl89YWEub3B0aW1pemVyLHRoaXMuaXNPcHRpbWl6ZXJPd25lZD0hMX1sZXQgeGE9W107aWYoIUFycmF5LmlzQXJyYXkoYWEubG9zcykmJnR5cGVvZiBhYS5sb3NzIT0ic3RyaW5nIiYmdHlwZW9mIGFhLmxvc3MhPSJmdW5jdGlvbiIpe2FhLmxvc3M9YWEubG9zcztmb3IoY29uc3Qgd2EgaW4gYWEubG9zcylpZih0aGlzLm91dHB1dE5hbWVzLmluZGV4T2Yod2EpPT09LTEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFVua25vd24gZW50cnkgaW4gbG9zcyBkaWN0aW9uYXJ5OiAiJHt3YX0iLiBPbmx5IGV4cGVjdGVkIHRoZSBmb2xsb3dpbmcga2V5czogJHt0aGlzLm91dHB1dE5hbWVzfWApO2Zvcihjb25zdCB3YSBvZiB0aGlzLm91dHB1dE5hbWVzKWFhLmxvc3Nbd2FdPT1udWxsJiZjb25zb2xlLndhcm4oYE91dHB1dCAiJHt3YX0iIGlzIG1pc3NpbmcgZnJvbSBsb3NzIGRpY3Rpb25hcnkuIFdlIGFzc3VtZSB0aGlzIHdhcyBkb25lIG9uIHB1cnBvc2UsIGFuZCB3ZSB3aWxsIG5vdCBiZSBleHBlY3RpbmcgZGF0YSB0byBiZSBwYXNzZWQgdG8gJHt3YX0gZHVyaW5nIHRyYWluaW5nYCkseGEucHVzaChnZXQkMShhYS5sb3NzW3dhXSkpfWVsc2UgaWYoQXJyYXkuaXNBcnJheShhYS5sb3NzKSl7aWYoYWEubG9zcy5sZW5ndGghPT10aGlzLm91dHB1dHMubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBXaGVuIHBhc3NpbmcgYW4gQXJyYXkgYXMgbG9zcywgaXQgc2hvdWxkIGhhdmUgb25lIGVudHJ5IHBlciBtb2RlbCBvdXRwdXQuIFRoZSBtb2RlbCBoYXMgJHt0aGlzLm91dHB1dHMubGVuZ3RofSBvdXRwdXQocyksIGJ1dCB5b3UgcGFzc2VkIGxvc3M9JHthYS5sb3NzfS5gKTt4YT1hYS5sb3NzLm1hcChFYT0+Z2V0JDEoRWEpKX1lbHNle2NvbnN0IHdhPWdldCQxKGFhLmxvc3MpO3RoaXMub3V0cHV0cy5mb3JFYWNoKEVhPT57eGEucHVzaCh3YSl9KX10aGlzLmxvc3NGdW5jdGlvbnM9eGEsdGhpcy5mZWVkT3V0cHV0TmFtZXM9W10sdGhpcy5mZWVkT3V0cHV0U2hhcGVzPVtdLHRoaXMuZmVlZExvc3NGbnM9W107Zm9yKGxldCB3YT0wO3dhPHRoaXMub3V0cHV0cy5sZW5ndGg7Kyt3YSl7Y29uc3QgRWE9dGhpcy5pbnRlcm5hbE91dHB1dFNoYXBlc1t3YV0sa2E9dGhpcy5vdXRwdXROYW1lc1t3YV07dGhpcy5mZWVkT3V0cHV0TmFtZXMucHVzaChrYSksdGhpcy5mZWVkT3V0cHV0U2hhcGVzLnB1c2goRWEpLHRoaXMuZmVlZExvc3NGbnMucHVzaCh0aGlzLmxvc3NGdW5jdGlvbnNbd2FdKX1jb25zdCBiYT1bXTt0aGlzLm1ldHJpY3M9YWEubWV0cmljcyx0aGlzLm1ldHJpY3NOYW1lcz1bImxvc3MiXSx0aGlzLm1ldHJpY3NUZW5zb3JzPVtdLG5hbWVTY29wZSgibG9zcyIsKCk9Pntmb3IobGV0IHdhPTA7d2E8dGhpcy5vdXRwdXRzLmxlbmd0aDsrK3dhKXtpZihiYS5pbmRleE9mKHdhKSE9PS0xKWNvbnRpbnVlO2NvbnN0IEVhPXRoaXMubG9zc0Z1bmN0aW9uc1t3YV07dGhpcy5vdXRwdXRzLmxlbmd0aD4xJiYodGhpcy5tZXRyaWNzVGVuc29ycy5wdXNoKFtFYSx3YV0pLHRoaXMubWV0cmljc05hbWVzLnB1c2godGhpcy5vdXRwdXROYW1lc1t3YV0rIl9sb3NzIikpfX0pO2NvbnN0IFNhPWNvbGxlY3RNZXRyaWNzKGFhLm1ldHJpY3MsdGhpcy5vdXRwdXROYW1lcyksVGE9KHdhLEVhLGthKT0+e3RoaXMub3V0cHV0TmFtZXMubGVuZ3RoPjEmJihFYT10aGlzLm91dHB1dE5hbWVzW3dhXSsiXyIrRWEpLHRoaXMubWV0cmljc05hbWVzLnB1c2goRWEpLHRoaXMubWV0cmljc1RlbnNvcnMucHVzaChba2Esd2FdKX07bmFtZVNjb3BlKCJtZXRyaWMiLCgpPT57Zm9yKGxldCB3YT0wO3dhPHRoaXMub3V0cHV0cy5sZW5ndGg7Kyt3YSl7aWYoYmEuaW5kZXhPZih3YSkhPT0tMSljb250aW51ZTtjb25zdCBFYT1TYVt3YV07KEFhPT57Y29uc3QgRmE9IiI7bGV0IExhLGVsLHRsO2Zvcihjb25zdCBubCBvZiBBYSl7aWYodHlwZW9mIG5sPT0ic3RyaW5nIiYmWyJhY2N1cmFjeSIsImFjYyIsImNyb3NzZW50cm9weSIsImNlIl0uaW5kZXhPZihubCkhPT0tMSl7Y29uc3Qgcmw9dGhpcy5pbnRlcm5hbE91dHB1dFNoYXBlc1t3YV07cmxbcmwubGVuZ3RoLTFdPT09MXx8dGhpcy5sb3NzRnVuY3Rpb25zW3dhXT09PWJpbmFyeUNyb3NzZW50cm9weSQxP1siYWNjdXJhY3kiLCJhY2MiXS5pbmRleE9mKG5sKSE9PS0xP2VsPWJpbmFyeUFjY3VyYWN5OlsiY3Jvc3NlbnRyb3B5IiwiY2UiXS5pbmRleE9mKG5sKSE9PS0xJiYoZWw9YmluYXJ5Q3Jvc3NlbnRyb3B5KTp0aGlzLmxvc3NGdW5jdGlvbnNbd2FdPT09c3BhcnNlQ2F0ZWdvcmljYWxDcm9zc2VudHJvcHkkMT9bImFjY3VyYWN5IiwiYWNjIl0uaW5kZXhPZihubCkhPT0tMT9lbD1zcGFyc2VDYXRlZ29yaWNhbEFjY3VyYWN5OlsiY3Jvc3NlbnRyb3B5IiwiY2UiXS5pbmRleE9mKG5sKSE9PS0xJiYoZWw9c3BhcnNlQ2F0ZWdvcmljYWxDcm9zc2VudHJvcHkpOlsiYWNjdXJhY3kiLCJhY2MiXS5pbmRleE9mKG5sKSE9PS0xP2VsPWNhdGVnb3JpY2FsQWNjdXJhY3k6WyJjcm9zc2VudHJvcHkiLCJjZSJdLmluZGV4T2YobmwpIT09LTEmJihlbD1jYXRlZ29yaWNhbENyb3NzZW50cm9weSk7bGV0IG9sO1siYWNjdXJhY3kiLCJhY2MiXS5pbmRleE9mKG5sKSE9PS0xP29sPSJhY2MiOlsiY3Jvc3NlbnRyb3B5IiwiY2UiXS5pbmRleE9mKG5sKSE9PS0xJiYob2w9ImNlIiksdGw9ZWwsTGE9RmErb2x9ZWxzZSB0bD1nZXQobmwpLExhPUZhK2dldExvc3NPck1ldHJpY05hbWUobmwpO2xldCBzbDtuYW1lU2NvcGUoTGEsKCk9PntzbD10bH0pLFRhKHdhLExhLHNsKX19KShFYSl9fSksdGhpcy5jb2xsZWN0ZWRUcmFpbmFibGVXZWlnaHRzPXRoaXMudHJhaW5hYmxlV2VpZ2h0c31jaGVja1RyYWluYWJsZVdlaWdodHNDb25zaXN0ZW5jeSgpe3RoaXMuY29sbGVjdGVkVHJhaW5hYmxlV2VpZ2h0cyE9bnVsbCYmdGhpcy50cmFpbmFibGVXZWlnaHRzLmxlbmd0aCE9PXRoaXMuY29sbGVjdGVkVHJhaW5hYmxlV2VpZ2h0cy5sZW5ndGgmJmNvbnNvbGUud2FybigiRGlzY3JlcGFuY3kgYmV0d2VlbiB0cmFpbmFibGV3ZWlnaHRzIGFuZCBjb2xsZWN0ZWQgdHJhaW5hYmxlIHdlaWdodHMuIERpZCB5b3Ugc2V0IGBtb2RlbC50cmFpbmFibGVgIHdpdGhvdXQgY2FsbGluZyBgbW9kZWwuY29tcGlsZSgpYCBhZnRlcndhcmRzPyIpfWV2YWx1YXRlKGFhLHhhLGJhPXt9KXtjb25zdCBTYT1iYS5iYXRjaFNpemU9PW51bGw/MzI6YmEuYmF0Y2hTaXplO2NoZWNrQmF0Y2hTaXplKFNhKTtjb25zdCB3YT10aGlzLnN0YW5kYXJkaXplVXNlckRhdGFYWShhYSx4YSwhMCxTYSk7dHJ5e2NvbnN0IEVhPXdhWzBdLmNvbmNhdCh3YVsxXSk7dGhpcy5tYWtlVGVzdEZ1bmN0aW9uKCk7Y29uc3Qga2E9dGhpcy50ZXN0RnVuY3Rpb24sQWE9dGhpcy50ZXN0TG9vcChrYSxFYSxTYSxiYS52ZXJib3NlLGJhLnN0ZXBzKTtyZXR1cm4gc2luZ2xldG9uT3JBcnJheShBYSl9ZmluYWxseXtkaXNwb3NlTmV3VGVuc29ycyh3YVswXSxhYSksZGlzcG9zZU5ld1RlbnNvcnMod2FbMV0seGEpfX1hc3luYyBldmFsdWF0ZURhdGFzZXQoYWEseGEpe3JldHVybiB0aGlzLm1ha2VUZXN0RnVuY3Rpb24oKSxldmFsdWF0ZURhdGFzZXQodGhpcyxhYSx4YSl9Y2hlY2tOdW1TYW1wbGVzKGFhLHhhLGJhLFNhPSJzdGVwcyIpe2xldCBUYTtpZihiYSE9bnVsbCl7aWYoVGE9bnVsbCx4YSE9bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSWYgJHtTYX0gaXMgc2V0LCBiYXRjaFNpemUgbXVzdCBiZSBudWxsIG9yIHVuZGVmaW5lZC5Hb3QgYmF0Y2hTaXplID0gJHt4YX1gKX1lbHNlIGlmKGFhIT1udWxsKUFycmF5LmlzQXJyYXkoYWEpP1RhPWFhWzBdLnNoYXBlWzBdOlRhPWFhLnNoYXBlWzBdO2Vsc2UgdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEVpdGhlciB0aGUgaW5wdXQgZGF0YSBzaG91bGQgaGF2ZSBhIGRlZmluZWQgc2hhcGUsIG9yICR7U2F9IHNob3VkIGJlIHNwZWNpZmllZC5gKTtyZXR1cm4gVGF9ZXhlY3V0ZShhYSx4YSl7aWYoQXJyYXkuaXNBcnJheSh4YSkmJnhhLmxlbmd0aD09PTApdGhyb3cgbmV3IFZhbHVlRXJyb3IoImBvdXRwdXRzYCBpcyBhbiBlbXB0eSBBcnJheSwgd2hpY2ggaXMgbm90IGFsbG93ZWQuIik7Y29uc3QgYmE9QXJyYXkuaXNBcnJheSh4YSksU2E9YmE/eGE6W3hhXSxUYT10aGlzLnJldHJpZXZlU3ltYm9saWNUZW5zb3JzKFNhKSx3YT1uZXcgRmVlZERpY3Q7aWYoYWEgaW5zdGFuY2VvZiBUZW5zb3IkMSYmKGFhPVthYV0pLEFycmF5LmlzQXJyYXkoYWEpKXtpZihhYS5sZW5ndGghPT10aGlzLmlucHV0cy5sZW5ndGgpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBudW1iZXIgb2YgaW5wdXRzIHByb3ZpZGVkICgke2FhLmxlbmd0aH0pIGRvZXMgbm90IG1hdGNoIHRoZSBudW1iZXIgb2YgaW5wdXRzIG9mIHRoaXMgbW9kZWwgKCR7dGhpcy5pbnB1dHMubGVuZ3RofSkuYCk7Zm9yKGxldCBrYT0wO2thPHRoaXMuaW5wdXRzLmxlbmd0aDsrK2thKXdhLmFkZCh0aGlzLmlucHV0c1trYV0sYWFba2FdKX1lbHNlIGZvcihjb25zdCBrYSBvZiB0aGlzLmlucHV0cyl7Y29uc3QgQWE9YWFba2EubmFtZV07aWYoQWE9PW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYE5vIHZhbHVlIGlzIHByb3ZpZGVkIGZvciB0aGUgbW9kZWwncyBpbnB1dCAke2thLm5hbWV9YCk7d2EuYWRkKGthLEFhKX1jb25zdCBFYT1leGVjdXRlKFRhLHdhKTtyZXR1cm4gYmE/RWE6RWFbMF19cmV0cmlldmVTeW1ib2xpY1RlbnNvcnMoYWEpe2NvbnN0IHhhPXB5TGlzdFJlcGVhdChudWxsLGFhLmxlbmd0aCk7bGV0IGJhPWFhLmxlbmd0aDtmb3IoY29uc3QgU2Egb2YgdGhpcy5sYXllcnMpe2NvbnN0IFRhPUFycmF5LmlzQXJyYXkoU2Eub3V0cHV0KT9TYS5vdXRwdXQ6W1NhLm91dHB1dF0sd2E9VGEubWFwKEVhPT5FYS5uYW1lKTtmb3IobGV0IEVhPTA7RWE8YWEubGVuZ3RoOysrRWEpe2NvbnN0IGthPXdhLmluZGV4T2YoYWFbRWFdKTtpZihrYSE9PS0xJiYoeGFbRWFdPVRhW2thXSxiYS0tKSxiYT09PTApYnJlYWt9aWYoYmE9PT0wKWJyZWFrfWlmKGJhPjApe2NvbnN0IFNhPVtdO3Rocm93IHhhLmZvckVhY2goKFRhLHdhKT0+e1RhPT1udWxsJiZTYS5wdXNoKGFhW3dhXSl9KSxuZXcgVmFsdWVFcnJvcihgQ2Fubm90IGZpbmQgU3ltYm9saWNUZW5zb3JzIGZvciBvdXRwdXQgbmFtZShzKTogJHtKU09OLnN0cmluZ2lmeShTYSl9YCl9cmV0dXJuIHhhfXByZWRpY3RMb29wKGFhLHhhPTMyLGJhPSExKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgU2E9dGhpcy5jaGVja051bVNhbXBsZXMoYWEpO2lmKGJhKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJWZXJib3NlIHByZWRpY3RMb29wKCkgaXMgbm90IGltcGxlbWVudGVkIHlldC4iKTtjb25zdCBUYT1tYWtlQmF0Y2hlcyhTYSx4YSksd2E9dGhpcy5vdXRwdXRzLm1hcChFYT0+W10pO2ZvcihsZXQgRWE9MDtFYTxUYS5sZW5ndGg7KytFYSl0aWR5JDEoKCk9Pntjb25zdCBBYT1UYVtFYV1bMF0sRmE9VGFbRWFdWzFdLExhPXNsaWNlQXJyYXlzKGFhLEFhLEZhKSxlbD1bXTtpZihBcnJheS5pc0FycmF5KExhKSlmb3IobGV0IG5sPTA7bmw8TGEubGVuZ3RoOysrbmwpZWwucHVzaCh7a2V5OnRoaXMuaW5wdXRzW25sXSx2YWx1ZTpMYVtubF19KTtlbHNlIGVsLnB1c2goe2tleTp0aGlzLmlucHV0c1swXSx2YWx1ZTpMYX0pO2NvbnN0IHRsPW5ldyBGZWVkRGljdChlbCk7cmV0dXJuIGV4ZWN1dGUodGhpcy5vdXRwdXRzLHRsKX0pLmZvckVhY2goKEFhLEZhKT0+d2FbRmFdLnB1c2goQWEpKTtyZXR1cm4gc2luZ2xldG9uT3JBcnJheSh3YS5tYXAoRWE9PmNvbmNhdCQzKEVhLDApKSl9KX1wcmVkaWN0KGFhLHhhPXt9KXtjb25zdCBiYT1lbnN1cmVUZW5zb3JzUmFuazJPckhpZ2hlcihhYSk7Y2hlY2tJbnB1dERhdGEoYmEsdGhpcy5pbnB1dE5hbWVzLHRoaXMuZmVlZElucHV0U2hhcGVzLCExKTt0cnl7Y29uc3QgU2E9eGEuYmF0Y2hTaXplPT1udWxsPzMyOnhhLmJhdGNoU2l6ZTtyZXR1cm4gY2hlY2tCYXRjaFNpemUoU2EpLHRoaXMucHJlZGljdExvb3AoYmEsU2EpfWZpbmFsbHl7ZGlzcG9zZU5ld1RlbnNvcnMoYmEsYWEpfX1wcmVkaWN0T25CYXRjaChhYSl7Y2hlY2tJbnB1dERhdGEoYWEsdGhpcy5pbnB1dE5hbWVzLHRoaXMuZmVlZElucHV0U2hhcGVzLCEwKTtjb25zdCB4YT0oQXJyYXkuaXNBcnJheShhYSk/YWFbMF06YWEpLnNoYXBlWzBdO3JldHVybiB0aGlzLnByZWRpY3RMb29wKGFhLHhhKX1zdGFuZGFyZGl6ZVVzZXJEYXRhWFkoYWEseGEsYmE9ITAsU2Epe2lmKHRoaXMub3B0aW1pemVyXz09bnVsbCl0aHJvdyBuZXcgUnVudGltZUVycm9yKCJZb3UgbXVzdCBjb21waWxlIGEgbW9kZWwgYmVmb3JlIHRyYWluaW5nL3Rlc3RpbmcuIFVzZSBMYXllcnNNb2RlbC5jb21waWxlKG1vZGVsQ29tcGlsZUFyZ3MpLiIpO2NvbnN0IFRhPVtdO2ZvcihsZXQgd2E9MDt3YTx0aGlzLmZlZWRPdXRwdXRTaGFwZXMubGVuZ3RoOysrd2Epe2NvbnN0IEVhPXRoaXMuZmVlZE91dHB1dFNoYXBlc1t3YV07dGhpcy5mZWVkTG9zc0Zuc1t3YV09PT1zcGFyc2VDYXRlZ29yaWNhbENyb3NzZW50cm9weSQxP1RhLnB1c2goRWEuc2xpY2UoMCxFYS5sZW5ndGgtMSkuY29uY2F0KFsxXSkpOlRhLnB1c2goRWEpfWlmKGFhPXN0YW5kYXJkaXplSW5wdXREYXRhKGFhLHRoaXMuZmVlZElucHV0TmFtZXMsdGhpcy5mZWVkSW5wdXRTaGFwZXMsITEsImlucHV0IikseGE9c3RhbmRhcmRpemVJbnB1dERhdGEoeGEsdGhpcy5mZWVkT3V0cHV0TmFtZXMsVGEsITEsInRhcmdldCIpLGNoZWNrQXJyYXlMZW5ndGhzKGFhLHhhKSxjaGVja0xvc3NBbmRUYXJnZXRDb21wYXRpYmlsaXR5KHhhLHRoaXMuZmVlZExvc3NGbnMsdGhpcy5mZWVkT3V0cHV0U2hhcGVzKSx0aGlzLnN0YXRlZnVsJiZTYSE9bnVsbCYmU2E+MCYmYWFbMF0uc2hhcGVbMF0lU2EhPT0wKXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbiBhIHN0YXRlZnVsIG5ldHdvcmssIHlvdSBzaG91bGQgb25seSBwYXNzIGlucHV0cyB3aXRoIGEgbnVtYmVyIG9mIHNhbXBsZXMgdGhhdCBpcyBkaXZpc2libGUgYnkgdGhlIGJhdGNoIHNpemUgJHtTYX0uIEZvdW5kOiAke2FhWzBdLnNoYXBlWzBdfSBzYW1wbGUocykuYCk7cmV0dXJuW2FhLHhhXX1hc3luYyBzdGFuZGFyZGl6ZVVzZXJEYXRhKGFhLHhhLGJhLFNhLFRhPSEwLHdhKXtjb25zdFtFYSxrYV09dGhpcy5zdGFuZGFyZGl6ZVVzZXJEYXRhWFkoYWEseGEsVGEsd2EpO2lmKGJhIT1udWxsKXRocm93IG5ldyBFcnJvcigic2FtcGxlIHdlaWdodCBpcyBub3Qgc3VwcG9ydGVkIHlldC4iKTtsZXQgQWE9bnVsbDtpZihTYSE9bnVsbCl7Y29uc3QgRmE9c3RhbmRhcmRpemVDbGFzc1dlaWdodHMoU2EsdGhpcy5vdXRwdXROYW1lcyk7QWE9W107Zm9yKGxldCBMYT0wO0xhPEZhLmxlbmd0aDsrK0xhKUFhLnB1c2goYXdhaXQgc3RhbmRhcmRpemVXZWlnaHRzKGthW0xhXSxudWxsLEZhW0xhXSkpfXJldHVybltFYSxrYSxBYV19dGVzdExvb3AoYWEseGEsYmEsU2E9MCxUYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IHdhPXRoaXMuY2hlY2tOdW1TYW1wbGVzKHhhLGJhLFRhLCJzdGVwcyIpLEVhPVtdO2lmKFNhPjApdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoIlZlcmJvc2UgbW9kZSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO2lmKFRhIT1udWxsKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJzdGVwcyBtb2RlIGluIHRlc3RMb29wKCkgaXMgbm90IGltcGxlbWVudGVkIHlldCIpO3tjb25zdCBrYT1tYWtlQmF0Y2hlcyh3YSxiYSksQWE9dGVuc29yMWQocmFuZ2UkMygwLHdhKSk7Zm9yKGxldCBGYT0wO0ZhPGthLmxlbmd0aDsrK0ZhKXtjb25zdCBMYT1rYVtGYV1bMF0sZWw9a2FbRmFdWzFdLHRsPXNsaWNlQWxvbmdGaXJzdEF4aXMoQWEsTGEsZWwtTGEpLG5sPXNsaWNlQXJyYXlzQnlJbmRpY2VzKHhhLHRsKSxzbD1hYShubCk7aWYoRmE9PT0wKWZvcihsZXQgcmw9MDtybDxzbC5sZW5ndGg7KytybClFYS5wdXNoKHNjYWxhciQxKDApKTtmb3IobGV0IHJsPTA7cmw8c2wubGVuZ3RoOysrcmwpe2NvbnN0IG9sPXNsW3JsXTtFYVtybF09YWRkJDMoRWFbcmxdLG11bCQxKGVsLUxhLG9sKSl9fWZvcihsZXQgRmE9MDtGYTxFYS5sZW5ndGg7KytGYSlFYVtGYV09ZGl2JDIoRWFbRmFdLHdhKX1yZXR1cm4gRWF9KX1nZXREZWR1cGVkTWV0cmljc05hbWVzKCl7Y29uc3QgYWE9dGhpcy5tZXRyaWNzTmFtZXMseGE9W107Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aDsrK2JhKXtjb25zdCBTYT1hYVtiYV07bGV0IFRhPVNhO2lmKGNvdW50KGFhLFNhKT4xKXtjb25zdCB3YT1jb3VudChhYS5zbGljZSgwLGJhKSxTYSk7VGErPWBfJHt3YX1gfXhhLnB1c2goVGEpfXJldHVybiB4YX1tYWtlVHJhaW5GdW5jdGlvbigpe3JldHVybiBhYT0+e2NvbnN0IHhhPVtdLGJhPWFhLnNsaWNlKDAsdGhpcy5pbnB1dHMubGVuZ3RoKSxTYT1hYS5zbGljZSh0aGlzLmlucHV0cy5sZW5ndGgsdGhpcy5pbnB1dHMubGVuZ3RoK3RoaXMub3V0cHV0cy5sZW5ndGgpLFRhPWFhLnNsaWNlKHRoaXMuaW5wdXRzLmxlbmd0aCt0aGlzLm91dHB1dHMubGVuZ3RoLHRoaXMuaW5wdXRzLmxlbmd0aCt0aGlzLm91dHB1dHMubGVuZ3RoKjIpLHdhPVtdLEVhPSgpPT57Y29uc3QgTGE9W107Zm9yKGxldCBzbD0wO3NsPHRoaXMuaW5wdXRzLmxlbmd0aDsrK3NsKUxhLnB1c2goe2tleTp0aGlzLmlucHV0c1tzbF0sdmFsdWU6YmFbc2xdfSk7Y29uc3QgZWw9bmV3IEZlZWREaWN0KExhKSx0bD1leGVjdXRlKHRoaXMub3V0cHV0cyxlbCx7dHJhaW5pbmc6ITB9KTtsZXQgbmw7Zm9yKGxldCBzbD0wO3NsPHRoaXMubG9zc0Z1bmN0aW9ucy5sZW5ndGg7KytzbCl7Y29uc3Qgcmw9dGhpcy5sb3NzRnVuY3Rpb25zW3NsXTtsZXQgb2w9cmwoU2Fbc2xdLHRsW3NsXSk7VGFbc2xdIT1udWxsJiYob2w9Y29tcHV0ZVdlaWdodGVkTG9zcyhvbCxUYVtzbF0pKTtjb25zdCBhbD1tZWFuJDEob2wpO3hhLnB1c2goYWwpLHNsPT09MD9ubD1vbDpubD1hZGQkMyhubCxvbCl9Zm9yKGxldCBzbD0wO3NsPHRoaXMubWV0cmljc1RlbnNvcnMubGVuZ3RoOysrc2wpe2xldCBybDtpZih0aGlzLm91dHB1dHMubGVuZ3RoPjEmJnNsPHRoaXMub3V0cHV0cy5sZW5ndGgpcmw9eGFbc2xdO2Vsc2V7Y29uc3Qgb2w9dGhpcy5tZXRyaWNzVGVuc29yc1tzbF1bMF0sYWw9dGhpcy5tZXRyaWNzVGVuc29yc1tzbF1bMV07cmw9bWVhbiQxKG9sKFNhW2FsXSx0bFthbF0pKX1rZWVwJDEocmwpLHdhLnB1c2gocmwpfXJldHVybiBubD1tZWFuJDEobmwpLHRoaXMuY2FsY3VsYXRlTG9zc2VzKCkuZm9yRWFjaChzbD0+e25sPWFkZCQzKG5sLHNsKX0pLG5sfSxrYT10aGlzLmNvbGxlY3RlZFRyYWluYWJsZVdlaWdodHMubWFwKExhPT5MYS5yZWFkKCkpO3JldHVyblt0aGlzLm9wdGltaXplcl8ubWluaW1pemUoRWEsITAsa2EpXS5jb25jYXQod2EpfX1tYWtlVGVzdEZ1bmN0aW9uKCl7dGhpcy50ZXN0RnVuY3Rpb249YWE9PnRpZHkkMSgoKT0+e2NvbnN0IHhhPVtdO2xldCBiYTtjb25zdCBTYT1hYS5zbGljZSgwLHRoaXMuaW5wdXRzLmxlbmd0aCksVGE9YWEuc2xpY2UodGhpcy5pbnB1dHMubGVuZ3RoLHRoaXMuaW5wdXRzLmxlbmd0aCt0aGlzLm91dHB1dHMubGVuZ3RoKSx3YT1bXTtmb3IobGV0IEFhPTA7QWE8dGhpcy5pbnB1dHMubGVuZ3RoOysrQWEpd2EucHVzaCh7a2V5OnRoaXMuaW5wdXRzW0FhXSx2YWx1ZTpTYVtBYV19KTtjb25zdCBFYT1uZXcgRmVlZERpY3Qod2EpLGthPWV4ZWN1dGUodGhpcy5vdXRwdXRzLEVhKTtmb3IobGV0IEFhPTA7QWE8dGhpcy5sb3NzRnVuY3Rpb25zLmxlbmd0aDsrK0FhKXtjb25zdCBGYT10aGlzLmxvc3NGdW5jdGlvbnNbQWFdLExhPW1lYW4kMShGYShUYVtBYV0sa2FbQWFdKSk7QWE9PT0wP2JhPUxhOmJhPWFkZCQzKGJhLExhKSx4YS5wdXNoKGJhKX1mb3IobGV0IEFhPTA7QWE8dGhpcy5tZXRyaWNzVGVuc29ycy5sZW5ndGg7KytBYSl7Y29uc3QgRmE9dGhpcy5tZXRyaWNzVGVuc29yc1tBYV1bMF0sTGE9dGhpcy5tZXRyaWNzVGVuc29yc1tBYV1bMV0sZWw9bWVhbiQxKEZhKFRhW0xhXSxrYVtMYV0pKTt4YS5wdXNoKGVsKX1yZXR1cm4geGF9KX1hc3luYyBmaXQoYWEseGEsYmE9e30pe2lmKHRoaXMuaXNUcmFpbmluZyl0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBzdGFydCB0cmFpbmluZyBiZWNhdXNlIGFub3RoZXIgZml0KCkgY2FsbCBpcyBvbmdvaW5nLiIpO3RoaXMuaXNUcmFpbmluZz0hMDtsZXQgU2EsVGEsd2EsRWEsa2EsQWEsRmEsTGEsZWw7dHJ5e2NvbnN0IHRsPWJhLmJhdGNoU2l6ZT09bnVsbD8zMjpiYS5iYXRjaFNpemU7Y2hlY2tCYXRjaFNpemUodGwpO2NvbnN0IHNsPWF3YWl0IHRoaXMuc3RhbmRhcmRpemVVc2VyRGF0YShhYSx4YSxiYS5zYW1wbGVXZWlnaHQsYmEuY2xhc3NXZWlnaHQsITEsdGwpO1NhPXNsWzBdLFRhPXNsWzFdLGVsPXNsWzJdO2xldCBybD0hMSxvbDtpZihiYS52YWxpZGF0aW9uRGF0YSE9bnVsbCYmYmEudmFsaWRhdGlvbkRhdGEubGVuZ3RoPjApe2lmKHJsPSEwLGJhLnZhbGlkYXRpb25EYXRhLmxlbmd0aD09PTIpa2E9YmEudmFsaWRhdGlvbkRhdGFbMF0sQWE9YmEudmFsaWRhdGlvbkRhdGFbMV07ZWxzZSB0aHJvdyBiYS52YWxpZGF0aW9uRGF0YS5sZW5ndGg9PT0zP25ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJ2YWxpZGF0aW9uRGF0YSBpbmNsdWRpbmcgc2FtcGxlIHdlaWdodHMgaXMgbm90IHN1cHBvcnRlZCB5ZXQuIik6bmV3IFZhbHVlRXJyb3IoYFdoZW4gcGFzc2luZyB2YWxpZGF0aW9uIGRhdGEsIGl0IG11c3QgY29udGFpbiAyICh2YWxYLCB2YWxZKSBvciAzICh2YWxYLCB2YWxZLCB2YWxTYW1wbGVXZWlnaHQpIGl0ZW1zOyAke2JhLnZhbGlkYXRpb25EYXRhfSBpcyBpbnZhbGlkLmApO2NvbnN0IGZsPWF3YWl0IHRoaXMuc3RhbmRhcmRpemVVc2VyRGF0YShrYSxBYSxudWxsLG51bGwsITAsdGwpO0ZhPWZsWzBdLExhPWZsWzFdLG9sPUZhLmNvbmNhdChMYSl9ZWxzZSBpZihiYS52YWxpZGF0aW9uU3BsaXQhPW51bGwmJmJhLnZhbGlkYXRpb25TcGxpdD4wJiZiYS52YWxpZGF0aW9uU3BsaXQ8MSl7cmw9ITA7Y29uc3QgcGw9TWF0aC5mbG9vcihTYVswXS5zaGFwZVswXSooMS1iYS52YWxpZGF0aW9uU3BsaXQpKSxmbD1TYVswXS5zaGFwZVswXTtGYT1zbGljZUFycmF5cyhTYSxwbCxmbCksd2E9U2EsU2E9c2xpY2VBcnJheXMoU2EsMCxwbCksTGE9c2xpY2VBcnJheXMoVGEscGwsZmwpLEVhPVRhLFRhPXNsaWNlQXJyYXlzKFRhLDAscGwpLG9sPUZhLmNvbmNhdChMYSl9ZWxzZSBiYS52YWxpZGF0aW9uU3RlcHMhPW51bGwmJihybD0hMCk7Y29uc3QgYWw9U2EuY29uY2F0KFRhKS5jb25jYXQoZWwpO3RoaXMuY2hlY2tUcmFpbmFibGVXZWlnaHRzQ29uc2lzdGVuY3koKTtjb25zdCBsbD10aGlzLm1ha2VUcmFpbkZ1bmN0aW9uKCksaWw9dGhpcy5nZXREZWR1cGVkTWV0cmljc05hbWVzKCk7bGV0IGNsLHVsO3JsPyh0aGlzLm1ha2VUZXN0RnVuY3Rpb24oKSxjbD10aGlzLnRlc3RGdW5jdGlvbix1bD1pbC5zbGljZSgpLmNvbmNhdChpbC5tYXAocGw9PiJ2YWxfIitwbCkpKTooY2w9bnVsbCxvbD1bXSx1bD1pbC5zbGljZSgpKTtjb25zdCBkbD1zdGFuZGFyZGl6ZUNhbGxiYWNrcyhiYS5jYWxsYmFja3MsYmEueWllbGRFdmVyeSk7cmV0dXJuIGF3YWl0IHRoaXMuZml0TG9vcChsbCxhbCxpbCx0bCxiYS5lcG9jaHMsYmEudmVyYm9zZSxkbCxjbCxvbCxiYS5zaHVmZmxlLHVsLGJhLmluaXRpYWxFcG9jaCxudWxsLG51bGwpfWZpbmFsbHl7dGhpcy5pc1RyYWluaW5nPSExLGRpc3Bvc2VOZXdUZW5zb3JzKFNhLGFhKSxkaXNwb3NlTmV3VGVuc29ycyhUYSx4YSksZGlzcG9zZU5ld1RlbnNvcnMod2EsYWEpLGRpc3Bvc2VOZXdUZW5zb3JzKEVhLHhhKSxkaXNwb3NlTmV3VGVuc29ycyhGYSxrYSksZGlzcG9zZU5ld1RlbnNvcnMoTGEsQWEpLGVsIT1udWxsJiZkaXNwb3NlJDEoZWwpfX1hc3luYyBmaXRMb29wKGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthLEFhLEZhLExhLGVsLHRsLG5sKXtTYT09bnVsbCYmKFNhPTMyKSxUYT09bnVsbCYmKFRhPTEpLEZhPT1udWxsJiYoRmE9ITApLGVsPT1udWxsJiYoZWw9MCk7bGV0IHNsPSExO2lmKGthIT1udWxsJiZBYSE9bnVsbCYmKHNsPSEwKSxubCE9bnVsbCYmKHNsPSEwLHRsPT1udWxsKSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQ2FuIG9ubHkgdXNlIGB2YWxpZGF0aW9uU3RlcHNgIHdoZW4gZG9pbmcgc3RlcC13aXNlIHRyYWluaW5nLCBpLmUuLCBgc3RlcHNQZXJFcG9jaGAgbXVzdCBiZSBzZXQuIik7Y29uc3Qgcmw9dGhpcy5jaGVja051bVNhbXBsZXMoeGEsU2EsdGwsInN0ZXBzX3Blcl9lcG9jaCIpO2xldCBvbDtybCE9bnVsbCYmKG9sPXJhbmdlJDMoMCxybCkpLHdhPT1udWxsJiYod2E9MSk7Y29uc3R7Y2FsbGJhY2tMaXN0OmFsLGhpc3Rvcnk6bGx9PWNvbmZpZ3VyZUNhbGxiYWNrcyhFYSx3YSxUYSxlbCxybCx0bCxTYSxzbCxMYSk7YWwuc2V0TW9kZWwodGhpcyksdGhpcy5oaXN0b3J5PWxsLGF3YWl0IGFsLm9uVHJhaW5CZWdpbigpLHRoaXMuc3RvcFRyYWluaW5nXz0hMTtmb3IobGV0IGlsPWVsO2lsPFRhOysraWwpe2F3YWl0IGFsLm9uRXBvY2hCZWdpbihpbCk7Y29uc3QgY2w9e307aWYodGwhPW51bGwpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoInN0ZXBzUGVyRXBvY2ggbW9kZSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO3tpZihGYT09PSJiYXRjaCIpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoImJhdGNoIHNodWZmbGluZyBpcyBub3QgaW1wbGVtbmV0ZWQgeWV0Iik7RmEmJnNodWZmbGUob2wpO2NvbnN0IHVsPXRlbnNvcjFkKG9sKSxkbD1tYWtlQmF0Y2hlcyhybCxTYSk7Zm9yKGxldCBobD0wO2hsPGRsLmxlbmd0aDsrK2hsKXtjb25zdCBwbD17fTtpZihhd2FpdCBhbC5vbkJhdGNoQmVnaW4oaGwscGwpLHRpZHkkMSgoKT0+e2NvbnN0IGZsPWRsW2hsXVswXSxtbD1kbFtobF1bMV0sZ2w9c2xpY2VBbG9uZ0ZpcnN0QXhpcyh1bCxmbCxtbC1mbCk7cGwuYmF0Y2g9aGwscGwuc2l6ZT1tbC1mbDtjb25zdCAkbD1zbGljZUFycmF5c0J5SW5kaWNlcyh4YSxnbCkseGw9YWEoJGwpO2ZvcihsZXQgeWw9MDt5bDxiYS5sZW5ndGg7Kyt5bCl7Y29uc3QgYmw9YmFbeWxdLFNsPXhsW3lsXTtwbFtibF09U2wsa2VlcCQxKFNsKX1pZihobD09PWRsLmxlbmd0aC0xJiZzbCl7Y29uc3QgeWw9dGhpcy50ZXN0TG9vcChrYSxBYSxTYSk7Zm9yKGxldCBibD0wO2JsPGJhLmxlbmd0aDsrK2JsKXtjb25zdCBTbD1iYVtibF0sQ2w9eWxbYmxdO2tlZXAkMShDbCksY2xbInZhbF8iK1NsXT1DbH19fSksYXdhaXQgYWwub25CYXRjaEVuZChobCxwbCksZGlzcG9zZVRlbnNvcnNJbkxvZ3MocGwpLHRoaXMuc3RvcFRyYWluaW5nXylicmVha311bC5kaXNwb3NlKCl9aWYoYXdhaXQgYWwub25FcG9jaEVuZChpbCxjbCksdGhpcy5zdG9wVHJhaW5pbmdfKWJyZWFrfXJldHVybiBhd2FpdCBhbC5vblRyYWluRW5kKCksYXdhaXQgdGhpcy5oaXN0b3J5LnN5bmNEYXRhKCksdGhpcy5oaXN0b3J5fWFzeW5jIGZpdERhdGFzZXQoYWEseGEpe3JldHVybiBmaXREYXRhc2V0KHRoaXMsYWEseGEpfWFzeW5jIHRyYWluT25CYXRjaChhYSx4YSl7Y29uc3QgYmE9YXdhaXQgdGhpcy5zdGFuZGFyZGl6ZVVzZXJEYXRhKGFhLHhhKSxTYT1iYVswXSxUYT1iYVsxXSxFYT10aGlzLm1ha2VUcmFpbkZ1bmN0aW9uKCkoU2EuY29uY2F0KFRhKSksa2E9W107Zm9yKGNvbnN0IEFhIG9mIEVhKXtjb25zdCBGYT1hd2FpdCBBYS5kYXRhKCk7a2EucHVzaChGYVswXSl9cmV0dXJuIGRpc3Bvc2UkMShFYSksZGlzcG9zZU5ld1RlbnNvcnMoYmFbMF0sYWEpLGRpc3Bvc2VOZXdUZW5zb3JzKGJhWzFdLHhhKSxzaW5nbGV0b25PckFycmF5KGthKX1nZXROYW1lZFdlaWdodHMoYWEpe2NvbnN0IHhhPVtdLGJhPWFhIT1udWxsJiZhYS50cmFpbmFibGVPbmx5LFNhPWJhP3RoaXMudHJhaW5hYmxlV2VpZ2h0czp0aGlzLndlaWdodHMsVGE9dGhpcy5nZXRXZWlnaHRzKGJhKTtmb3IobGV0IHdhPTA7d2E8U2EubGVuZ3RoOysrd2EpYmEmJiFTYVt3YV0udHJhaW5hYmxlfHx4YS5wdXNoKHtuYW1lOlNhW3dhXS5vcmlnaW5hbE5hbWUsdGVuc29yOlRhW3dhXX0pO3JldHVybiB4YX1zZXQgc3RvcFRyYWluaW5nKGFhKXt0aGlzLnN0b3BUcmFpbmluZ189YWF9Z2V0IHN0b3BUcmFpbmluZygpe3JldHVybiB0aGlzLnN0b3BUcmFpbmluZ199Z2V0IG9wdGltaXplcigpe3JldHVybiB0aGlzLm9wdGltaXplcl99c2V0IG9wdGltaXplcihhYSl7dGhpcy5vcHRpbWl6ZXJfIT09YWEmJih0aGlzLm9wdGltaXplcl89YWEsdGhpcy5pc09wdGltaXplck93bmVkPSExKX1kaXNwb3NlKCl7Y29uc3QgYWE9c3VwZXIuZGlzcG9zZSgpO2lmKGFhLnJlZkNvdW50QWZ0ZXJEaXNwb3NlPT09MCYmdGhpcy5vcHRpbWl6ZXIhPW51bGwmJnRoaXMuaXNPcHRpbWl6ZXJPd25lZCl7Y29uc3QgeGE9bWVtb3J5KCkubnVtVGVuc29yczt0aGlzLm9wdGltaXplcl8uZGlzcG9zZSgpLGFhLm51bURpc3Bvc2VkVmFyaWFibGVzKz14YS1tZW1vcnkoKS5udW1UZW5zb3JzfXJldHVybiBhYX1nZXRMb3NzSWRlbnRpZmllcnMoKXtsZXQgYWE7aWYodHlwZW9mIHRoaXMubG9zcz09InN0cmluZyIpYWE9dG9TbmFrZUNhc2UodGhpcy5sb3NzKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkodGhpcy5sb3NzKSl7Zm9yKGNvbnN0IHhhIG9mIHRoaXMubG9zcylpZih0eXBlb2YgeGEhPSJzdHJpbmciKXRocm93IG5ldyBFcnJvcigiU2VyaWFsaXphdGlvbiBvZiBub24tc3RyaW5nIGxvc3MgaXMgbm90IHN1cHBvcnRlZC4iKTthYT10aGlzLmxvc3MubWFwKHhhPT50b1NuYWtlQ2FzZSh4YSkpfWVsc2V7Y29uc3QgeGE9T2JqZWN0LmtleXModGhpcy5sb3NzKTthYT17fTtjb25zdCBiYT10aGlzLmxvc3M7Zm9yKGNvbnN0IFNhIG9mIHhhKWlmKHR5cGVvZiBiYVtTYV09PSJzdHJpbmciKWFhW1NhXT10b1NuYWtlQ2FzZShiYVtTYV0pO2Vsc2UgdGhyb3cgbmV3IEVycm9yKCJTZXJpYWxpemF0aW9uIG9mIG5vbi1zdHJpbmcgbG9zcyBpcyBub3Qgc3VwcG9ydGVkLiIpfXJldHVybiBhYX1nZXRNZXRyaWNJZGVudGlmaWVycygpe2lmKHR5cGVvZiB0aGlzLm1ldHJpY3M9PSJzdHJpbmcifHx0eXBlb2YgdGhpcy5tZXRyaWNzPT0iZnVuY3Rpb24iKXJldHVyblt0b1NuYWtlQ2FzZShnZXRMb3NzT3JNZXRyaWNOYW1lKHRoaXMubWV0cmljcykpXTtpZihBcnJheS5pc0FycmF5KHRoaXMubWV0cmljcykpcmV0dXJuIHRoaXMubWV0cmljcy5tYXAoYWE9PnRvU25ha2VDYXNlKGdldExvc3NPck1ldHJpY05hbWUoYWEpKSk7e2NvbnN0IGFhPXt9O2Zvcihjb25zdCB4YSBpbiB0aGlzLm1ldHJpY3MpYWFbeGFdPXRvU25ha2VDYXNlKGdldExvc3NPck1ldHJpY05hbWUodGhpcy5tZXRyaWNzW3hhXSkpO3JldHVybiBhYX19Z2V0VHJhaW5pbmdDb25maWcoKXtyZXR1cm57bG9zczp0aGlzLmdldExvc3NJZGVudGlmaWVycygpLG1ldHJpY3M6dGhpcy5nZXRNZXRyaWNJZGVudGlmaWVycygpLG9wdGltaXplcl9jb25maWc6e2NsYXNzX25hbWU6dGhpcy5vcHRpbWl6ZXIuZ2V0Q2xhc3NOYW1lKCksY29uZmlnOnRoaXMub3B0aW1pemVyLmdldENvbmZpZygpfX19bG9hZFRyYWluaW5nQ29uZmlnKGFhKXtpZihhYS53ZWlnaHRlZF9tZXRyaWNzIT1udWxsKXRocm93IG5ldyBFcnJvcigiTG9hZGluZyB3ZWlnaHRfbWV0cmljcyBpcyBub3Qgc3VwcG9ydGVkIHlldC4iKTtpZihhYS5sb3NzX3dlaWdodHMhPW51bGwpdGhyb3cgbmV3IEVycm9yKCJMb2FkaW5nIGxvc3Nfd2VpZ2h0cyBpcyBub3Qgc3VwcG9ydGVkIHlldC4iKTtpZihhYS5zYW1wbGVfd2VpZ2h0X21vZGUhPW51bGwpdGhyb3cgbmV3IEVycm9yKCJMb2FkaW5nIHNhbXBsZV93ZWlnaHRfbW9kZSBpcyBub3Qgc3VwcG9ydGVkIHlldC4iKTtjb25zdCB4YT1jb252ZXJ0UHl0aG9uaWNUb1RzKGFhLm9wdGltaXplcl9jb25maWcpLGJhPWRlc2VyaWFsaXplKHhhKTtsZXQgU2E7aWYodHlwZW9mIGFhLmxvc3M9PSJzdHJpbmciKVNhPXRvQ2FtZWxDYXNlKGFhLmxvc3MpO2Vsc2UgaWYoQXJyYXkuaXNBcnJheShhYS5sb3NzKSlTYT1hYS5sb3NzLm1hcCh3YT0+dG9DYW1lbENhc2Uod2EpKTtlbHNlIGlmKGFhLmxvc3MhPW51bGwpe1NhPXt9O2Zvcihjb25zdCB3YSBpbiBhYS5sb3NzKVNhW3dhXT10b0NhbWVsQ2FzZShhYS5sb3NzW3dhXSl9bGV0IFRhO2lmKEFycmF5LmlzQXJyYXkoYWEubWV0cmljcykpVGE9YWEubWV0cmljcy5tYXAod2E9PnRvQ2FtZWxDYXNlKHdhKSk7ZWxzZSBpZihhYS5tZXRyaWNzIT1udWxsKXtUYT17fTtmb3IoY29uc3Qgd2EgaW4gYWEubWV0cmljcylUYVt3YV09dG9DYW1lbENhc2UoYWEubWV0cmljc1t3YV0pfXRoaXMuY29tcGlsZSh7bG9zczpTYSxtZXRyaWNzOlRhLG9wdGltaXplcjpiYX0pfWFzeW5jIHNhdmUoYWEseGEpe2lmKHR5cGVvZiBhYT09InN0cmluZyIpe2NvbnN0IEFhPWdldFNhdmVIYW5kbGVycyhhYSk7aWYoQWEubGVuZ3RoPT09MCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQ2Fubm90IGZpbmQgYW55IHNhdmUgaGFuZGxlcnMgZm9yIFVSTCAnJHthYX0nYCk7aWYoQWEubGVuZ3RoPjEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEZvdW5kIG1vcmUgdGhhbiBvbmUgKCR7QWEubGVuZ3RofSkgc2F2ZSBoYW5kbGVycyBmb3IgVVJMICcke2FhfSdgKTthYT1BYVswXX1pZihhYS5zYXZlPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJMYXllcnNNb2RlbC5zYXZlKCkgY2Fubm90IHByb2NlZWQgYmVjYXVzZSB0aGUgSU9IYW5kbGVyIHByb3ZpZGVkIGRvZXMgbm90IGhhdmUgdGhlIGBzYXZlYCBhdHRyaWJ1dGUgZGVmaW5lZC4iKTtjb25zdCBiYT1hd2FpdCBlbmNvZGVXZWlnaHRzKHRoaXMuZ2V0TmFtZWRXZWlnaHRzKHhhKSksRWE9e21vZGVsVG9wb2xvZ3k6dGhpcy50b0pTT04obnVsbCwhMSksZm9ybWF0OkxBWUVSU19NT0RFTF9GT1JNQVRfTkFNRSxnZW5lcmF0ZWRCeTpgVGVuc29yRmxvdy5qcyB0ZmpzLWxheWVycyB2JHt2ZXJzaW9ufWAsY29udmVydGVkQnk6bnVsbH07aWYoKHhhPT1udWxsPyExOnhhLmluY2x1ZGVPcHRpbWl6ZXIpJiZ0aGlzLm9wdGltaXplciE9bnVsbCl7RWEudHJhaW5pbmdDb25maWc9dGhpcy5nZXRUcmFpbmluZ0NvbmZpZygpO2NvbnN0IEFhPSJvcHRpbWl6ZXIiLHtkYXRhOkZhLHNwZWNzOkxhfT1hd2FpdCBlbmNvZGVXZWlnaHRzKGF3YWl0IHRoaXMub3B0aW1pemVyLmdldFdlaWdodHMoKSxBYSk7YmEuc3BlY3MucHVzaCguLi5MYSksYmEuZGF0YT1jb25jYXRlbmF0ZUFycmF5QnVmZmVycyQxKFtiYS5kYXRhLEZhXSl9cmV0dXJuIHRoaXMudXNlckRlZmluZWRNZXRhZGF0YSE9bnVsbCYmKGNoZWNrVXNlckRlZmluZWRNZXRhZGF0YSh0aGlzLnVzZXJEZWZpbmVkTWV0YWRhdGEsdGhpcy5uYW1lLCEwKSxFYS51c2VyRGVmaW5lZE1ldGFkYXRhPXRoaXMudXNlckRlZmluZWRNZXRhZGF0YSksRWEud2VpZ2h0RGF0YT1iYS5kYXRhLEVhLndlaWdodFNwZWNzPWJhLnNwZWNzLGFhLnNhdmUoRWEpfXNldFVzZXJEZWZpbmVkTWV0YWRhdGEoYWEpe2NoZWNrVXNlckRlZmluZWRNZXRhZGF0YShhYSx0aGlzLm5hbWUpLHRoaXMudXNlckRlZmluZWRNZXRhZGF0YT1hYX1nZXRVc2VyRGVmaW5lZE1ldGFkYXRhKCl7cmV0dXJuIHRoaXMudXNlckRlZmluZWRNZXRhZGF0YX19TGF5ZXJzTW9kZWwuY2xhc3NOYW1lPSJNb2RlbCIscmVnaXN0ZXJDbGFzcyQxKExheWVyc01vZGVsKTtjbGFzcyBGdW5jdGlvbmFsIGV4dGVuZHMgTGF5ZXJzTW9kZWx7fUZ1bmN0aW9uYWwuY2xhc3NOYW1lPSJGdW5jdGlvbmFsIixyZWdpc3RlckNsYXNzJDEoRnVuY3Rpb25hbCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgU2VxdWVudGlhbCBleHRlbmRzIExheWVyc01vZGVse2NvbnN0cnVjdG9yKGFhKXtpZihzdXBlcih7aW5wdXRzOltdLG91dHB1dHM6W119KSxhYT1hYXx8e30sdGhpcy50cmFpbmFibGU9ITAsdGhpcy5idWlsdD0hMSx0aGlzLm5hbWU9YWEubmFtZSE9bnVsbD9hYS5uYW1lOmdldFVpZCgic2VxdWVudGlhbF8iKSxhYS5sYXllcnMhPW51bGwpZm9yKGNvbnN0IHhhIG9mIGFhLmxheWVycyl0aGlzLmFkZCh4YSl9Y2hlY2tTaGFwZShhYSl7aWYoYWEuaW5ib3VuZE5vZGVzWzBdLm91dHB1dFRlbnNvcnNbMF0uc2hhcGUuc29tZShiYT0+YmE8MCkpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYE5lZ2F0aXZlIGRpbWVuc2lvbiBzaXplIGNhdXNlZCBieSBhZGRpbmcgbGF5ZXIgJHthYS5uYW1lfSB3aXRoIGlucHV0IHNoYXBlIFske2FhLmluYm91bmROb2Rlc1swXS5pbnB1dFRlbnNvcnNbMF0uc2hhcGV9XWApfWFkZChhYSl7Y29uc3QgeGE9YWEgaW5zdGFuY2VvZiBTZXF1ZW50aWFsfHxhYSBpbnN0YW5jZW9mIExheWVyc01vZGVsO2xldCBiYTtpZih4YSl7aWYoYmE9YWEsYmEub3V0cHV0cy5sZW5ndGghPT0xKXRocm93IG5ldyBWYWx1ZUVycm9yKCJBbGwgbGF5ZXJzIGluIGEgU2VxdWVudGlhbCBtb2RlbCBzaG91bGQgaGF2ZSBhIHNpbmdsZSBvdXRwdXQgdGVuc29yLiBGb3IgbXVsdGktb3V0cHV0IGxheWVycywgdXNlIHRoZSBmdW5jdGlvbmFsIEFQSS4iKTtpZihiYS5pbnB1dHMubGVuZ3RoIT09MSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQWxsIGxheWVycyBpbiBhIFNlcXVlbnRpYWwgbW9kZWwgc2hvdWxkIGhhdmUgYSBzaW5nbGUgaW5wdXQgdGVuc29yLiBGb3IgbXVsdGktaW5wdXQgbGF5ZXJzLCB1c2UgdGhlIGZ1bmN0aW9uYWwgQVBJLiIpfWlmKHRoaXMub3V0cHV0cy5sZW5ndGg9PT0wKXtpZihhYS5pbmJvdW5kTm9kZXMubGVuZ3RoPT09MCl7aWYoYWEuYmF0Y2hJbnB1dFNoYXBlPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJUaGUgZmlyc3QgbGF5ZXIgaW4gYSBTZXF1ZW50aWFsIG1vZGVsIG11c3QgZ2V0IGFuIGBpbnB1dFNoYXBlYCBvciBgYmF0Y2hJbnB1dFNoYXBlYCBhcmd1bWVudC4iKTtjb25zdCBTYT1JbnB1dCh7YmF0Y2hTaGFwZTphYS5iYXRjaElucHV0U2hhcGUsZHR5cGU6YWEuZHR5cGUsbmFtZTphYS5uYW1lKyJfaW5wdXQifSk7YWEuYXBwbHkoU2EpfWlmKHhhKXRoaXMub3V0cHV0cz1iYS5vdXRwdXRzLHRoaXMuaW5wdXRzPWJhLmlucHV0cztlbHNle2lmKGFhLmluYm91bmROb2Rlcy5sZW5ndGghPT0xKXRocm93IG5ldyBWYWx1ZUVycm9yKGBBIGxheWVyIGFkZGVkIHRvIGEgU2VxdWVudGlhbCBtb2RlbCBtdXN0IG5vdCBhbHJlYWR5IGJlIGNvbm5lY3RlZCBzb21ld2hlcmUgZWxzZS4gTGF5ZXJzTW9kZWwgcmVjZWl2ZWQgbGF5ZXIgJHthYS5uYW1lfSB3aGljaCBoYXMgJHthYS5pbmJvdW5kTm9kZXMubGVuZ3RofSBwcmUtZXhpc3RpbmcgaW5ib3VuZCBjb25uZWN0aW9ucy5gKTtpZihhYS5pbmJvdW5kTm9kZXNbMF0ub3V0cHV0VGVuc29ycy5sZW5ndGghPT0xKXRocm93IG5ldyBWYWx1ZUVycm9yKCJBbGwgbGF5ZXJzIGluIGEgU2VxdWVudGlhbCBtb2RlbCBzaG91bGQgaGF2ZSBhIHNpbmdsZSBvdXRwdXQgdGVuc29yLiBGb3IgbXVsdGktb3V0cHV0IGxheWVycywgdXNlIHRoZSBmdW5jdGlvbmFsIEFQSS4iKTt0aGlzLmNoZWNrU2hhcGUoYWEpLHRoaXMub3V0cHV0cz1bYWEuaW5ib3VuZE5vZGVzWzBdLm91dHB1dFRlbnNvcnNbMF1dLHRoaXMuaW5wdXRzPWdldFNvdXJjZUlucHV0cyh0aGlzLm91dHB1dHNbMF0pfXRoaXMuaW5ib3VuZE5vZGVzPVtdLG5ldyBOb2RlKHtvdXRib3VuZExheWVyOnRoaXMsaW5ib3VuZExheWVyczpbXSxub2RlSW5kaWNlczpbXSx0ZW5zb3JJbmRpY2VzOltdLGlucHV0VGVuc29yczp0aGlzLmlucHV0cyxvdXRwdXRUZW5zb3JzOnRoaXMub3V0cHV0cyxpbnB1dE1hc2tzOnB5TGlzdFJlcGVhdChudWxsLHRoaXMuaW5wdXRzLmxlbmd0aCksb3V0cHV0TWFza3M6W251bGxdLGlucHV0U2hhcGVzOnRoaXMuaW5wdXRzLm1hcChTYT0+U2Euc2hhcGUpLG91dHB1dFNoYXBlczp0aGlzLm91dHB1dHNbMF0uc2hhcGV9KX1lbHNle2NvbnN0IFNhPWFhLmFwcGx5KHRoaXMub3V0cHV0c1swXSk7aWYoQXJyYXkuaXNBcnJheShTYSkpdGhyb3cgbmV3IFR5cGVFcnJvcigiQWxsIGxheWVycyBpbiBhIFNlcXVlbnRpYWwgbW9kZWwgc2hvdWxkIGhhdmUgYSBzaW5nbGUgb3V0cHV0IHRlbnNvci4gRm9yIG11bHRpLW91dHB1dCBsYXllcnMsIHVzZSB0aGUgZnVuY3Rpb25hbCBBUEkuIik7dGhpcy5jaGVja1NoYXBlKGFhKSx0aGlzLm91dHB1dHM9W1NhXSx0aGlzLmluYm91bmROb2Rlc1swXS5vdXRwdXRUZW5zb3JzPXRoaXMub3V0cHV0cyx0aGlzLmluYm91bmROb2Rlc1swXS5vdXRwdXRTaGFwZXM9W3RoaXMub3V0cHV0c1swXS5zaGFwZV19dGhpcy5sYXllcnMucHVzaChhYSksdGhpcy5idWlsdD0hMX1wb3AoKXtpZih0aGlzLmxheWVycy5sZW5ndGg9PT0wKXRocm93IG5ldyBUeXBlRXJyb3IoIlRoZXJlIGFyZSBubyBsYXllcnMgaW4gdGhlIG1vZGVsLiIpO2lmKHRoaXMubGF5ZXJzLnBvcCgpLHRoaXMubGF5ZXJzLmxlbmd0aD09PTApdGhpcy5vdXRwdXRzPVtdLHRoaXMuaW5ib3VuZE5vZGVzPVtdLHRoaXMub3V0Ym91bmROb2Rlcz1bXTtlbHNle2NvbnN0IGFhPXRoaXMubGF5ZXJzLmxlbmd0aC0xO3RoaXMubGF5ZXJzW2FhXS5vdXRib3VuZE5vZGVzPVtdLHRoaXMub3V0cHV0cz1bdGhpcy5sYXllcnNbYWFdLm91dHB1dF0sdGhpcy5pbmJvdW5kTm9kZXNbMF0ub3V0cHV0VGVuc29ycz10aGlzLm91dHB1dHMsdGhpcy5pbmJvdW5kTm9kZXNbMF0ub3V0cHV0U2hhcGVzPVt0aGlzLm91dHB1dHNbMF0uc2hhcGVdfX1jYWxsKGFhLHhhKXtyZXR1cm4gdGhpcy5tb2RlbD09bnVsbCYmdGhpcy5idWlsZCgpLHRoaXMubW9kZWwuY2FsbChhYSx4YSl9YnVpbGQoYWEpe2lmKGdldEV4YWN0bHlPbmVTaGFwZShhYSksdGhpcy5pbnB1dHMubGVuZ3RoPT09MHx8dGhpcy5vdXRwdXRzLmxlbmd0aD09PTApdGhyb3cgbmV3IFR5cGVFcnJvcigiU2VxdWVudGlhbCBtb2RlbCBjYW5ub3QgYmUgYnVpbHQ6IG1vZGVsIGlzIGVtcHR5LiBBZGQgc29tZSBsYXllcnMgZmlyc3QuIik7dGhpcy5tb2RlbD1uZXcgTGF5ZXJzTW9kZWwoe2lucHV0czp0aGlzLmlucHV0cyxvdXRwdXRzOnRoaXMub3V0cHV0c1swXSxuYW1lOnRoaXMubmFtZSsiX21vZGVsIn0pLHRoaXMubW9kZWwudHJhaW5hYmxlPXRoaXMudHJhaW5hYmxlLHRoaXMuc3VwcG9ydHNNYXNraW5nPXRoaXMubW9kZWwuc3VwcG9ydHNNYXNraW5nLHRoaXMuaW5wdXRMYXllcnM9dGhpcy5tb2RlbC5pbnB1dExheWVycyx0aGlzLmlucHV0TGF5ZXJzTm9kZUluZGljZXM9dGhpcy5tb2RlbC5pbnB1dExheWVyc05vZGVJbmRpY2VzLHRoaXMuaW5wdXRMYXllcnNUZW5zb3JJbmRpY2VzPXRoaXMubW9kZWwuaW5wdXRMYXllcnNUZW5zb3JJbmRpY2VzLHRoaXMub3V0cHV0TGF5ZXJzPXRoaXMubW9kZWwub3V0cHV0TGF5ZXJzLHRoaXMub3V0cHV0TGF5ZXJzTm9kZUluZGljZXM9dGhpcy5tb2RlbC5vdXRwdXRMYXllcnNOb2RlSW5kaWNlcyx0aGlzLm91dHB1dExheWVyc1RlbnNvckluZGljZXM9dGhpcy5tb2RlbC5vdXRwdXRMYXllcnNUZW5zb3JJbmRpY2VzLHRoaXMubm9kZXNCeURlcHRoPXRoaXMubW9kZWwubm9kZXNCeURlcHRoLHRoaXMuY29udGFpbmVyTm9kZXM9dGhpcy5tb2RlbC5jb250YWluZXJOb2Rlcyx0aGlzLm91dHB1dE5hbWVzPXRoaXMubW9kZWwub3V0cHV0TmFtZXMsdGhpcy5pbnB1dE5hbWVzPXRoaXMubW9kZWwuaW5wdXROYW1lcyx0aGlzLmJ1aWx0PSEwfWNvdW50UGFyYW1zKCl7cmV0dXJuIHRoaXMuYnVpbHR8fHRoaXMuYnVpbGQoKSxzdXBlci5jb3VudFBhcmFtcygpfXN1bW1hcnkoYWEseGEsYmE9Y29uc29sZS5sb2cpe3RoaXMuYnVpbHR8fHRoaXMuYnVpbGQoKSxzdXBlci5zdW1tYXJ5KGFhLHhhLGJhKX1zZXRXZWlnaHRzKGFhKXt0aGlzLm1vZGVsPT1udWxsJiZ0aGlzLmJ1aWxkKCksdGhpcy5tb2RlbC5zZXRXZWlnaHRzKGFhKX1ldmFsdWF0ZShhYSx4YSxiYT17fSl7aWYoIXRoaXMuYnVpbHQpdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigiVGhlIG1vZGVsIG5lZWRzIHRvIGJlIGNvbXBpbGVkIGJlZm9yZSBiZWluZyB1c2VkLiIpO3JldHVybiB0aGlzLm1vZGVsLmV2YWx1YXRlKGFhLHhhLGJhKX1hc3luYyBldmFsdWF0ZURhdGFzZXQoYWEseGEpe2lmKCF0aGlzLmJ1aWx0KXRocm93IG5ldyBSdW50aW1lRXJyb3IoIlRoZSBtb2RlbCBuZWVkcyB0byBiZSBjb21waWxlZCBiZWZvcmUgYmVpbmcgdXNlZC4iKTtyZXR1cm4gdGhpcy5tb2RlbC5ldmFsdWF0ZURhdGFzZXQoYWEseGEpfXByZWRpY3QoYWEseGE9e30pe3JldHVybiB0aGlzLm1vZGVsPT1udWxsJiZ0aGlzLmJ1aWxkKCksdGhpcy5tb2RlbC5wcmVkaWN0KGFhLHhhKX1wcmVkaWN0T25CYXRjaChhYSl7cmV0dXJuIHRoaXMubW9kZWw9PW51bGwmJnRoaXMuYnVpbGQoKSx0aGlzLm1vZGVsLnByZWRpY3RPbkJhdGNoKGFhKX1jb21waWxlKGFhKXt0aGlzLmJ1aWxkKCksdGhpcy5tb2RlbC5jb21waWxlKGFhKSx0aGlzLm9wdGltaXplcl89dGhpcy5tb2RlbC5vcHRpbWl6ZXIsdGhpcy5pc09wdGltaXplck93bmVkPXRoaXMubW9kZWwuaXNPcHRpbWl6ZXJPd25lZCx0aGlzLmxvc3M9dGhpcy5tb2RlbC5sb3NzLHRoaXMubWV0cmljcz10aGlzLm1vZGVsLm1ldHJpY3MsdGhpcy5tZXRyaWNzVGVuc29ycz10aGlzLm1vZGVsLm1ldHJpY3NUZW5zb3JzLHRoaXMubWV0cmljc05hbWVzPXRoaXMubW9kZWwubWV0cmljc05hbWVzfWdldCBvcHRpbWl6ZXIoKXtyZXR1cm4gdGhpcy5tb2RlbD09bnVsbD92b2lkIDA6dGhpcy5tb2RlbC5vcHRpbWl6ZXJ9c2V0IG9wdGltaXplcihhYSl7dGhpcy5tb2RlbC5vcHRpbWl6ZXI9YWF9YXN5bmMgZml0KGFhLHhhLGJhPXt9KXtpZighdGhpcy5idWlsdCl0aHJvdyBuZXcgUnVudGltZUVycm9yKCJUaGUgbW9kZWwgbmVlZHMgdG8gYmUgY29tcGlsZWQgYmVmb3JlIGJlaW5nIHVzZWQuIik7cmV0dXJuIHRoaXMubW9kZWwuZml0KGFhLHhhLGJhKX1hc3luYyBmaXREYXRhc2V0KGFhLHhhKXtpZighdGhpcy5idWlsdCl0aHJvdyBuZXcgUnVudGltZUVycm9yKCJUaGUgbW9kZWwgbmVlZHMgdG8gYmUgY29tcGlsZWQgYmVmb3JlIGJlaW5nIHVzZWQuIik7cmV0dXJuIHRoaXMubW9kZWwuZml0RGF0YXNldChhYSx4YSl9YXN5bmMgdHJhaW5PbkJhdGNoKGFhLHhhKXtyZXR1cm4gdGhpcy5tb2RlbC50cmFpbk9uQmF0Y2goYWEseGEpfXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhLGJhPXt9LFNhPSExKXtsZXQgVGEsd2E9e307aWYoeGEgaW5zdGFuY2VvZiBBcnJheSl7aWYoeGFbMF0uY2xhc3NOYW1lPT1udWxsfHx4YVswXS5jbGFzc05hbWU9PT0iTWVyZ2UiKXRocm93IG5ldyBWYWx1ZUVycm9yKCJMZWdhY3kgc2VyaWFsaXphdGlvbiBmb3JtYXQgbm90IHN1cHBvcnRlZCB5ZXQuIik7VGE9eGF9ZWxzZSBhc3NlcnQkMih4YS5sYXllcnMhPW51bGwsKCk9PiJXaGVuIHRoZSBjb25maWcgZGF0YSBmb3IgYSBTZXF1ZW50aWFsIG1vZGVsIGlzIG5vdCBhbiBBcnJheSwgaXQgbXVzdCBiZSBhbiBPYmplY3QgdGhhdCBjb250YWlucyB0aGUgJ2xheWVycycgZmllbGQuIiksVGE9eGEubGF5ZXJzLGRlbGV0ZSB4YS5sYXllcnMsd2E9eGE7Y29uc3QgRWE9bmV3IGFhKHdhKTtpZighKEVhIGluc3RhbmNlb2YgU2VxdWVudGlhbCkpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYFNlcXVlbnRpYWwuZnJvbUNvbmZpZyBjYWxsZWQgb24gbm9uLVNlcXVlbnRpYWwgaW5wdXQ6ICR7RWF9YCk7Zm9yKGNvbnN0IGthIG9mIFRhKXtjb25zdCBGYT1kZXNlcmlhbGl6ZShrYSx2b2lkIDAsU2EpO1NhJiZGYS5zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKCEwKSxFYS5hZGQoRmEpfXJldHVybiBFYX1zZXQgc3RvcFRyYWluaW5nKGFhKXtpZih0aGlzLm1vZGVsPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJDYW5ub3Qgc2V0IHRoZSBzdG9wVHJhaW5pbmcgcHJvcGVydHkgb2YgYSBzZXF1ZW50aWFsIG1vZGVsIGJlZm9yZSBpdCBpcyBjb21waWxlZC4iKTt0aGlzLm1vZGVsLnN0b3BUcmFpbmluZz1hYX1nZXQgc3RvcFRyYWluaW5nKCl7aWYodGhpcy5tb2RlbD09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQ2Fubm90IGdldCB0aGUgc3RvcFRyYWluaW5nIHByb3BlcnR5IG9mIGEgc2VxdWVudGlhbCBtb2RlbCBiZWZvcmUgaXQgaXMgY29tcGlsZWQuIik7cmV0dXJuIHRoaXMubW9kZWwuc3RvcFRyYWluaW5nfWdldENvbmZpZygpe2NvbnN0IGFhPVtdO2Zvcihjb25zdCB4YSBvZiB0aGlzLmxheWVycyl7Y29uc3QgYmE9e307YmEuY2xhc3NOYW1lPXhhLmdldENsYXNzTmFtZSgpLGJhLmNvbmZpZz14YS5nZXRDb25maWcoKSxhYS5wdXNoKGJhKX1yZXR1cm57bmFtZTp0aGlzLm5hbWUsbGF5ZXJzOmFhfX19U2VxdWVudGlhbC5jbGFzc05hbWU9IlNlcXVlbnRpYWwiLHJlZ2lzdGVyQ2xhc3MkMShTZXF1ZW50aWFsKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWN0aXZhdGlvbiQxPWNsYXNzIGV4dGVuZHMgU2VyaWFsaXphYmxlJDF7Z2V0Q29uZmlnKCl7cmV0dXJue319fSxFbHUkMT1jbGFzcyBleHRlbmRzIEFjdGl2YXRpb24kMXthcHBseShhYSx4YT0xKXtyZXR1cm4gZWx1JDQoYWEseGEpfX07RWx1JDEuY2xhc3NOYW1lPSJlbHUiLHJlZ2lzdGVyQ2xhc3MkMShFbHUkMSk7bGV0IFNlbHUkMT1jbGFzcyBleHRlbmRzIEFjdGl2YXRpb24kMXthcHBseShhYSl7cmV0dXJuIHNlbHUkMyhhYSl9fTtTZWx1JDEuY2xhc3NOYW1lPSJzZWx1IixyZWdpc3RlckNsYXNzJDEoU2VsdSQxKTtsZXQgUmVsdSQxPWNsYXNzIGV4dGVuZHMgQWN0aXZhdGlvbiQxe2FwcGx5KGFhKXtyZXR1cm4gcmVsdSQ0KGFhKX19O1JlbHUkMS5jbGFzc05hbWU9InJlbHUiLHJlZ2lzdGVyQ2xhc3MkMShSZWx1JDEpO2xldCBSZWx1NiQxPWNsYXNzIGV4dGVuZHMgQWN0aXZhdGlvbiQxe2FwcGx5KGFhKXtyZXR1cm4gdGlkeSQxKCgpPT5taW5pbXVtJDMoNixyZWx1JDQoYWEpKSl9fTtSZWx1NiQxLmNsYXNzTmFtZT0icmVsdTYiLHJlZ2lzdGVyQ2xhc3MkMShSZWx1NiQxKTtjbGFzcyBMaW5lYXIgZXh0ZW5kcyBBY3RpdmF0aW9uJDF7YXBwbHkoYWEpe3JldHVybiBhYX19TGluZWFyLmNsYXNzTmFtZT0ibGluZWFyIixyZWdpc3RlckNsYXNzJDEoTGluZWFyKTtsZXQgU2lnbW9pZCQxPWNsYXNzIGV4dGVuZHMgQWN0aXZhdGlvbiQxe2FwcGx5KGFhKXtyZXR1cm4gc2lnbW9pZCQ0KGFhKX19O1NpZ21vaWQkMS5jbGFzc05hbWU9InNpZ21vaWQiLHJlZ2lzdGVyQ2xhc3MkMShTaWdtb2lkJDEpO2NsYXNzIEhhcmRTaWdtb2lkIGV4dGVuZHMgQWN0aXZhdGlvbiQxe2FwcGx5KGFhKXtyZXR1cm4gaGFyZFNpZ21vaWQoYWEpfX1IYXJkU2lnbW9pZC5jbGFzc05hbWU9ImhhcmRTaWdtb2lkIixyZWdpc3RlckNsYXNzJDEoSGFyZFNpZ21vaWQpO2xldCBTb2Z0cGx1cyQxPWNsYXNzIGV4dGVuZHMgQWN0aXZhdGlvbiQxe2FwcGx5KGFhKXtyZXR1cm4gc29mdHBsdXMkMyhhYSl9fTtTb2Z0cGx1cyQxLmNsYXNzTmFtZT0ic29mdHBsdXMiLHJlZ2lzdGVyQ2xhc3MkMShTb2Z0cGx1cyQxKTtjbGFzcyBTb2Z0c2lnbiBleHRlbmRzIEFjdGl2YXRpb24kMXthcHBseShhYSl7cmV0dXJuIHNvZnRzaWduKGFhKX19U29mdHNpZ24uY2xhc3NOYW1lPSJzb2Z0c2lnbiIscmVnaXN0ZXJDbGFzcyQxKFNvZnRzaWduKTtsZXQgVGFuaCQxPWNsYXNzIGV4dGVuZHMgQWN0aXZhdGlvbiQxe2FwcGx5KGFhKXtyZXR1cm4gdGFuaCQzKGFhKX19O1RhbmgkMS5jbGFzc05hbWU9InRhbmgiLHJlZ2lzdGVyQ2xhc3MkMShUYW5oJDEpO2xldCBTb2Z0bWF4JDI9Y2xhc3MgZXh0ZW5kcyBBY3RpdmF0aW9uJDF7YXBwbHkoYWEseGE9LTEpe3JldHVybiBzb2Z0bWF4JDMoYWEseGEpfX07U29mdG1heCQyLmNsYXNzTmFtZT0ic29mdG1heCIscmVnaXN0ZXJDbGFzcyQxKFNvZnRtYXgkMik7Y2xhc3MgTG9nU29mdG1heCBleHRlbmRzIEFjdGl2YXRpb24kMXthcHBseShhYSx4YT0tMSl7cmV0dXJuIGxvZ1NvZnRtYXgoYWEseGEpfX1Mb2dTb2Z0bWF4LmNsYXNzTmFtZT0ibG9nU29mdG1heCIscmVnaXN0ZXJDbGFzcyQxKExvZ1NvZnRtYXgpO2NsYXNzIEdlbHUgZXh0ZW5kcyBBY3RpdmF0aW9uJDF7YXBwbHkoYWEpe3JldHVybiB0aWR5JDEoKCk9PnRpZHkkMSgoKT0+e2NvbnN0IHhhPU1hdGguc3FydCgyKSxiYT1tdWwkMSguNSxhZGQkMygxLGVyZiQzKGRpdiQyKGFhLHhhKSkpKTtyZXR1cm4gbXVsJDEoYWEsYmEpfSkpfX1HZWx1LmNsYXNzTmFtZT0iZ2VsdSIscmVnaXN0ZXJDbGFzcyQxKEdlbHUpO2NsYXNzIEdlbHVOZXcgZXh0ZW5kcyBBY3RpdmF0aW9uJDF7YXBwbHkoYWEpe3JldHVybiB0aWR5JDEoKCk9Pm11bCQxKC41LG11bCQxKGFhLGFkZCQzKDEsdGFuaCQzKG11bCQxKHNxcnQkNChkaXYkMigyLE1hdGguUEkpKSxhZGQkMyhhYSxtdWwkMSguMDQ0NzE1LHBvdyQ0KGFhLDMpKSkpKSkpKSl9fUdlbHVOZXcuY2xhc3NOYW1lPSJnZWx1X25ldyIscmVnaXN0ZXJDbGFzcyQxKEdlbHVOZXcpO2NsYXNzIE1pc2ggZXh0ZW5kcyBBY3RpdmF0aW9uJDF7YXBwbHkoYWEpe3JldHVybiB0aWR5JDEoKCk9Pm11bCQxKGFhLHRhbmgkMyhzb2Z0cGx1cyQzKGFhKSkpKX19TWlzaC5jbGFzc05hbWU9Im1pc2giLHJlZ2lzdGVyQ2xhc3MkMShNaXNoKTtjbGFzcyBTd2lzaCBleHRlbmRzIEFjdGl2YXRpb24kMXthcHBseShhYSx4YT0xKXtyZXR1cm4gdGlkeSQxKCgpPT5tdWwkMShzaWdtb2lkJDQobXVsJDEoYWEseGEpKSxhYSkpfX1Td2lzaC5jbGFzc05hbWU9InN3aXNoIixyZWdpc3RlckNsYXNzJDEoU3dpc2gpO2Z1bmN0aW9uIHNlcmlhbGl6ZUFjdGl2YXRpb24oaGEpe3JldHVybiBoYS5nZXRDbGFzc05hbWUoKX1mdW5jdGlvbiBkZXNlcmlhbGl6ZUFjdGl2YXRpb24oaGEsYWE9e30pe3JldHVybiBkZXNlcmlhbGl6ZUtlcmFzT2JqZWN0KGhhLFNlcmlhbGl6YXRpb25NYXAkMS5nZXRNYXAoKS5jbGFzc05hbWVNYXAsYWEsImFjdGl2YXRpb24iKX1mdW5jdGlvbiBnZXRBY3RpdmF0aW9uKGhhKXtpZihoYT09bnVsbCl7Y29uc3QgYWE9e307cmV0dXJuIGFhLmNsYXNzTmFtZT0ibGluZWFyIixhYS5jb25maWc9e30sZGVzZXJpYWxpemVBY3RpdmF0aW9uKGFhKX1pZih0eXBlb2YgaGE9PSJzdHJpbmciKXtjb25zdCBhYT17fTtyZXR1cm4gYWEuY2xhc3NOYW1lPWhhLGFhLmNvbmZpZz17fSxkZXNlcmlhbGl6ZUFjdGl2YXRpb24oYWEpfWVsc2UgcmV0dXJuIGhhIGluc3RhbmNlb2YgQWN0aXZhdGlvbiQxP2hhOmRlc2VyaWFsaXplQWN0aXZhdGlvbihoYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXNzZXJ0T2JqZWN0QXJncyhoYSl7aWYoaGEhPW51bGwmJnR5cGVvZiBoYSE9Im9iamVjdCIpdGhyb3cgbmV3IEVycm9yKGBBcmd1bWVudCB0byBMMUwyIHJlZ3VsYXJpemVyJ3MgY29uc3RydWN0b3IgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICR7aGF9YCl9Y2xhc3MgUmVndWxhcml6ZXIgZXh0ZW5kcyBTZXJpYWxpemFibGUkMXt9Y2xhc3MgTDFMMiBleHRlbmRzIFJlZ3VsYXJpemVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcigpLGFzc2VydE9iamVjdEFyZ3MoYWEpLHRoaXMubDE9YWE9PW51bGx8fGFhLmwxPT1udWxsPy4wMTphYS5sMSx0aGlzLmwyPWFhPT1udWxsfHxhYS5sMj09bnVsbD8uMDE6YWEubDIsdGhpcy5oYXNMMT10aGlzLmwxIT09MCx0aGlzLmhhc0wyPXRoaXMubDIhPT0wfWFwcGx5KGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IHhhPXplcm9zJDIoWzFdKTtyZXR1cm4gdGhpcy5oYXNMMSYmKHhhPWFkZCQzKHhhLHN1bSQ1KG11bCQxKHRoaXMubDEsYWJzJDQoYWEpKSkpKSx0aGlzLmhhc0wyJiYoeGE9YWRkJDMoeGEsc3VtJDUobXVsJDEodGhpcy5sMixzcXVhcmUkMyhhYSkpKSkpLHJlc2hhcGUkNCh4YSxbXSl9KX1nZXRDb25maWcoKXtyZXR1cm57bDE6dGhpcy5sMSxsMjp0aGlzLmwyfX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh7bDE6eGEubDEsbDI6eGEubDJ9KX19TDFMMi5jbGFzc05hbWU9IkwxTDIiLHJlZ2lzdGVyQ2xhc3MkMShMMUwyKTtjb25zdCBSRUdVTEFSSVpFUl9JREVOVElGSUVSX1JFR0lTVFJZX1NZTUJPTF9NQVA9e2wxbDI6IkwxTDIifTtmdW5jdGlvbiBzZXJpYWxpemVSZWd1bGFyaXplcihoYSl7cmV0dXJuIHNlcmlhbGl6ZUtlcmFzT2JqZWN0KGhhKX1mdW5jdGlvbiBkZXNlcmlhbGl6ZVJlZ3VsYXJpemVyKGhhLGFhPXt9KXtyZXR1cm4gZGVzZXJpYWxpemVLZXJhc09iamVjdChoYSxTZXJpYWxpemF0aW9uTWFwJDEuZ2V0TWFwKCkuY2xhc3NOYW1lTWFwLGFhLCJyZWd1bGFyaXplciIpfWZ1bmN0aW9uIGdldFJlZ3VsYXJpemVyKGhhKXtpZihoYT09bnVsbClyZXR1cm4gbnVsbDtpZih0eXBlb2YgaGE9PSJzdHJpbmciKXtjb25zdCB4YT17Y2xhc3NOYW1lOmhhIGluIFJFR1VMQVJJWkVSX0lERU5USUZJRVJfUkVHSVNUUllfU1lNQk9MX01BUD9SRUdVTEFSSVpFUl9JREVOVElGSUVSX1JFR0lTVFJZX1NZTUJPTF9NQVBbaGFdOmhhLGNvbmZpZzp7fX07cmV0dXJuIGRlc2VyaWFsaXplUmVndWxhcml6ZXIoeGEpfWVsc2UgcmV0dXJuIGhhIGluc3RhbmNlb2YgUmVndWxhcml6ZXI/aGE6ZGVzZXJpYWxpemVSZWd1bGFyaXplcihoYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmVMVSBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYT8/e30pLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwLGFhIT1udWxsJiYodGhpcy5tYXhWYWx1ZT1hYS5tYXhWYWx1ZSl9Y2FsbChhYSx4YSl7YWE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSk7bGV0IGJhPXJlbHUkNChhYSk7cmV0dXJuIHRoaXMubWF4VmFsdWUhPW51bGwmJihiYT1jbGlwQnlWYWx1ZSQzKGJhLDAsdGhpcy5tYXhWYWx1ZSkpLGJhfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7cmV0dXJuIGFhfWdldENvbmZpZygpe2NvbnN0IGFhPXttYXhWYWx1ZTp0aGlzLm1heFZhbHVlfSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9fVJlTFUuY2xhc3NOYW1lPSJSZUxVIixyZWdpc3RlckNsYXNzJDEoUmVMVSk7Y2xhc3MgTGVha3lSZUxVIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhPz97fSksdGhpcy5ERUZBVUxUX0FMUEhBPS4zLGFhPT1udWxsJiYoYWE9e30pLHRoaXMuYWxwaGE9YWEuYWxwaGE9PW51bGw/dGhpcy5ERUZBVUxUX0FMUEhBOmFhLmFscGhhfWNhbGwoYWEseGEpe2NvbnN0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO3JldHVybiBsZWFreVJlbHUkNChiYSx0aGlzLmFscGhhKX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYX1nZXRDb25maWcoKXtjb25zdCBhYT17YWxwaGE6dGhpcy5hbHBoYX0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1MZWFreVJlTFUuY2xhc3NOYW1lPSJMZWFreVJlTFUiLHJlZ2lzdGVyQ2xhc3MkMShMZWFreVJlTFUpO2NsYXNzIFBSZUxVIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKHN1cGVyKGFhPz97fSksdGhpcy5ERUZBVUxUX0FMUEhBX0lOSVRJQUxJWkVSPSJ6ZXJvcyIsYWE9PW51bGwmJihhYT17fSksdGhpcy5zdXBwb3J0c01hc2tpbmc9ITAsdGhpcy5hbHBoYUluaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLmFscGhhSW5pdGlhbGl6ZXJ8fHRoaXMuREVGQVVMVF9BTFBIQV9JTklUSUFMSVpFUiksdGhpcy5hbHBoYVJlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmFscGhhUmVndWxhcml6ZXIpLHRoaXMuYWxwaGFDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEuYWxwaGFDb25zdHJhaW50KSxhYS5zaGFyZWRBeGVzPT1udWxsKXRoaXMuc2hhcmVkQXhlcz1udWxsO2Vsc2UgaWYoQXJyYXkuaXNBcnJheShhYS5zaGFyZWRBeGVzKSl0aGlzLnNoYXJlZEF4ZXM9YWEuc2hhcmVkQXhlcztlbHNlIGlmKHR5cGVvZiBhYS5zaGFyZWRBeGVzPT0ibnVtYmVyIil0aGlzLnNoYXJlZEF4ZXM9W2FhLnNoYXJlZEF4ZXNdO2Vsc2UgdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEV4cGVjdGVkIHNoYXJlZEF4ZXMgdG8gYmUgYSBudW1iZXIgb3IgYW4gYXJyYXkgb2YgbnVtYmVycywgYnV0IGdvdCAke2FhLnNoYXJlZEF4ZXN9YCl9YnVpbGQoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9YWEuc2xpY2UoMSk7aWYodGhpcy5zaGFyZWRBeGVzIT1udWxsKWZvcihjb25zdCBTYSBvZiB0aGlzLnNoYXJlZEF4ZXMpeGFbU2EtMV09MTt0aGlzLmFscGhhPXRoaXMuYWRkV2VpZ2h0KCJhbHBoYSIseGEsImZsb2F0MzIiLHRoaXMuYWxwaGFJbml0aWFsaXplcix0aGlzLmFscGhhUmVndWxhcml6ZXIsITAsdGhpcy5hbHBoYUNvbnN0cmFpbnQpO2NvbnN0IGJhPXt9O2lmKHRoaXMuc2hhcmVkQXhlcyE9bnVsbClmb3IobGV0IFNhPTE7U2E8YWEubGVuZ3RoOysrU2EpYmFbU2FdPWFhW1NhXTt0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTphYS5sZW5ndGgsYXhlczpiYX0pXSx0aGlzLmJ1aWx0PSEwfWNhbGwoYWEseGEpe3JldHVybiBhYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKSxwcmVsdSQ0KGFhLHRoaXMuYWxwaGEucmVhZCgpKX1nZXRDb25maWcoKXtjb25zdCBhYT17YWxwaGFJbml0aWFsaXplcjpzZXJpYWxpemVJbml0aWFsaXplcih0aGlzLmFscGhhSW5pdGlhbGl6ZXIpLGFscGhhUmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5hbHBoYVJlZ3VsYXJpemVyKSxhbHBoYUNvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmFscGhhQ29uc3RyYWludCksc2hhcmVkQXhlczp0aGlzLnNoYXJlZEF4ZXN9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19UFJlTFUuY2xhc3NOYW1lPSJQUmVMVSIscmVnaXN0ZXJDbGFzcyQxKFBSZUxVKTtsZXQgRUxVJDY9Y2xhc3MgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7aWYoc3VwZXIoYWE/P3t9KSx0aGlzLkRFRkFVTFRfQUxQSEE9MSxhYT09bnVsbCYmKGFhPXt9KSxhYS5hbHBoYSE9bnVsbCYmYWEuYWxwaGEhPT10aGlzLkRFRkFVTFRfQUxQSEEpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYE5vbi1kZWZhdWx0IGFscGhhIHZhbHVlICgke2FhLmFscGhhfSkgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgRUxVIGxheWVyIHlldC5gKTt0aGlzLmFscGhhPWFhLmFscGhhPT1udWxsP3RoaXMuREVGQVVMVF9BTFBIQTphYS5hbHBoYX1jYWxsKGFhLHhhKXtjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtyZXR1cm4gZWx1JDUoYmEpfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7cmV0dXJuIGFhfWdldENvbmZpZygpe2NvbnN0IGFhPXthbHBoYTp0aGlzLmFscGhhfSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9fTtFTFUkNi5jbGFzc05hbWU9IkVMVSIscmVnaXN0ZXJDbGFzcyQxKEVMVSQ2KTtjbGFzcyBUaHJlc2hvbGRlZFJlTFUgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWE/P3t9KSx0aGlzLkRFRkFVTFRfVEhFVEE9MSxhYT09bnVsbCYmKGFhPXt9KSx0aGlzLnRoZXRhPWFhLnRoZXRhPT1udWxsP3RoaXMuREVGQVVMVF9USEVUQTphYS50aGV0YX1jYWxsKGFhLHhhKXtjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtyZXR1cm4gbXVsJDEoYmEsY2FzdCQ1KGdyZWF0ZXIkMyhiYSx0aGlzLnRoZXRhKSwiZmxvYXQzMiIpKX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYX1nZXRDb25maWcoKXtjb25zdCBhYT17dGhldGE6dGhpcy50aGV0YX0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1UaHJlc2hvbGRlZFJlTFUuY2xhc3NOYW1lPSJUaHJlc2hvbGRlZFJlTFUiLHJlZ2lzdGVyQ2xhc3MkMShUaHJlc2hvbGRlZFJlTFUpO2xldCBTb2Z0bWF4JDE9Y2xhc3MgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWE/P3t9KSx0aGlzLkRFRkFVTFRfQVhJUz0xLGFhPT1udWxsJiYoYWE9e30pLHRoaXMuc29mdG1heD1uZXcgU29mdG1heCQyKCkuYXBwbHksdGhpcy5heGlzPWFhLmF4aXM9PW51bGw/dGhpcy5ERUZBVUxUX0FYSVM6YWEuYXhpc31jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO2NvbnN0IFNhPXhhLm1hc2s7aWYoU2EhPW51bGwpe2NvbnN0IFRhPW11bCQxKHN1YiQ0KG9uZXMkMShiYS5zaGFwZSksY2FzdCQ1KFNhLGJhLmR0eXBlKSksc2NhbGFyJDEoLTFlOSkpO2JhPWFkZCQzKGJhLFRhKX1yZXR1cm4gdGhpcy5heGlzIGluc3RhbmNlb2YgQXJyYXk/dGhpcy5heGlzLmxlbmd0aD4xP2V4cCQzKHN1YiQ0KGJhLGxvZ1N1bUV4cChiYSx0aGlzLmF4aXMsITApKSk6dGhpcy5zb2Z0bWF4KGJhLHRoaXMuYXhpc1swXSk6dGhpcy5zb2Z0bWF4KGJhLHRoaXMuYXhpcyl9KX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYX1nZXRDb25maWcoKXtjb25zdCBhYT17YXhpczp0aGlzLmF4aXN9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19O1NvZnRtYXgkMS5jbGFzc05hbWU9IlNvZnRtYXgiLHJlZ2lzdGVyQ2xhc3MkMShTb2Z0bWF4JDEpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5vcm1hbGl6ZUFycmF5KGhhLGFhLHhhKXtpZih0eXBlb2YgaGE9PSJudW1iZXIiKXJldHVybiBweUxpc3RSZXBlYXQoaGEsYWEpO2lmKGhhLmxlbmd0aCE9PWFhKXRocm93IG5ldyBWYWx1ZUVycm9yKGBUaGUgJHt4YX0gYXJndW1lbnQgbXVzdCBiZSBhbiBpbnRlZ2VyIG9yIHR1cGxlIG9mICR7YWF9IGludGVnZXJzLiBSZWNlaXZlZDogJHtoYS5sZW5ndGh9IGVsZW1lbnRzLmApO2ZvcihsZXQgYmE9MDtiYTxhYTsrK2JhKXtjb25zdCBTYT1oYVtiYV07aWYoIWlzSW50ZWdlcihTYSkpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSAke3hhfSBhcmd1bWVudCBtdXN0IGJlIGFuIGludGVnZXIgb3IgdHVwbGUgb2YgJHthYX0gaW50ZWdlcnMuIFJlY2VpdmVkOiAke0pTT04uc3RyaW5naWZ5KGhhKX0gaW5jbHVkaW5nIGEgbm9uLWludGVnZXIgbnVtYmVyICR7U2F9YCl9cmV0dXJuIGhhfWZ1bmN0aW9uIGNvbnZPdXRwdXRMZW5ndGgoaGEsYWEseGEsYmEsU2E9MSl7aWYoaGE9PW51bGwpcmV0dXJuIGhhO2NvbnN0IFRhPWFhKyhhYS0xKSooU2EtMSk7bGV0IHdhO3JldHVybiB4YT09PSJzYW1lIj93YT1oYTp3YT1oYS1UYSsxLE1hdGguZmxvb3IoKHdhK2JhLTEpL2JhKX1mdW5jdGlvbiBkZWNvbnZMZW5ndGgoaGEsYWEseGEsYmEpe2lmKGhhPT1udWxsKXJldHVybiBudWxsO2lmKGJhPT09InZhbGlkIiloYT1oYSphYSttYXgkMyhbeGEtYWEsMF0pO2Vsc2UgaWYoYmE9PT0ic2FtZSIpaGE9aGEqYWE7ZWxzZSB0aHJvdyBuZXcgVmFsdWVFcnJvcihgVW5zdXBwb3J0IHBhZGRpbmcgbW9kZTogJHtiYX0uYCk7cmV0dXJuIGhhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHByZXByb2Nlc3NDb252MkRJbnB1dChoYSxhYSl7cmV0dXJuIHRpZHkkMSgoKT0+KGNoZWNrRGF0YUZvcm1hdChhYSksYWE9PT0iY2hhbm5lbHNGaXJzdCI/dHJhbnNwb3NlJDMoaGEsWzAsMiwzLDFdKTpoYSkpfWZ1bmN0aW9uIHByZXByb2Nlc3NDb252M0RJbnB1dChoYSxhYSl7cmV0dXJuIHRpZHkkMSgoKT0+KGNoZWNrRGF0YUZvcm1hdChhYSksYWE9PT0iY2hhbm5lbHNGaXJzdCI/dHJhbnNwb3NlJDMoaGEsWzAsMiwzLDQsMV0pOmhhKSl9ZnVuY3Rpb24gY29udjFkV2l0aEJpYXMoaGEsYWEseGEsYmE9MSxTYT0idmFsaWQiLFRhLHdhPTEpe3JldHVybiB0aWR5JDEoKCk9PntpZihUYT09bnVsbCYmKFRhPWltYWdlRGF0YUZvcm1hdCgpKSxjaGVja0RhdGFGb3JtYXQoVGEpLGhhLnNoYXBlLmxlbmd0aCE9PTMpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBpbnB1dCBvZiBhIGNvbnYxZFdpdGhCaWFzIG9wZXJhdGlvbiBzaG91bGQgYmUgMywgYnV0IGlzICR7aGEuc2hhcGUubGVuZ3RofSBpbnN0ZWFkLmApO2lmKGFhLnNoYXBlLmxlbmd0aCE9PTMpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRoZSBrZXJuZWwgZm9yIGEgY29udjFkV2l0aEJpYXMgb3BlcmF0aW9uIHNob3VsZCBiZSAzLCBidXQgaXMgJHthYS5zaGFwZS5sZW5ndGh9IGluc3RlYWRgKTtpZih4YSE9bnVsbCYmeGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgVGhlIGJpYXMgZm9yIGEgY29udjFkV2l0aEJpYXMgb3BlcmF0aW9uIHNob3VsZCBiZSAxLCBidXQgaXMgJHt4YS5zaGFwZS5sZW5ndGh9IGluc3RlYWRgKTtpZihUYT09PSJjaGFubmVsc0ZpcnN0IiYmKGhhPXRyYW5zcG9zZSQzKGhhLFswLDIsMV0pKSxTYT09PSJjYXVzYWwiKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJUaGUgc3VwcG9ydCBmb3IgQ0FVU0FMIHBhZGRpbmcgbW9kZSBpbiBjb252MWRXaXRoQmlhcyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO2xldCBFYT1jb252MWQoaGEsYWEsYmEsU2E9PT0ic2FtZSI/InNhbWUiOiJ2YWxpZCIsIk5XQyIsd2EpO3JldHVybiB4YSE9bnVsbCYmKEVhPWJpYXNBZGQoRWEseGEpKSxFYX0pfWZ1bmN0aW9uIGNvbnYyZFdpdGhCaWFzQWN0aXZhdGlvbihoYSxhYSx4YSxiYT1bMSwxXSxTYT0idmFsaWQiLFRhLHdhLEVhPW51bGwpe3JldHVybiB0aWR5JDEoKCk9PntpZihUYT09bnVsbCYmKFRhPWltYWdlRGF0YUZvcm1hdCgpKSxjaGVja0RhdGFGb3JtYXQoVGEpLGhhLnJhbmshPT0zJiZoYS5yYW5rIT09NCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgY29udjJkV2l0aEJpYXNBY3RpdmF0aW9uIGV4cGVjdHMgaW5wdXQgdG8gYmUgb2YgcmFuayAzIG9yIDQsIGJ1dCByZWNlaXZlZCAke2hhLnJhbmt9LmApO2lmKGFhLnJhbmshPT0zJiZhYS5yYW5rIT09NCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgY29udjJkV2l0aEJpYXNBY3RpdmF0aW9uIGV4cGVjdHMga2VybmVsIHRvIGJlIG9mIHJhbmsgMyBvciA0LCBidXQgcmVjZWl2ZWQgJHtoYS5yYW5rfS5gKTtsZXQga2E9cHJlcHJvY2Vzc0NvbnYyRElucHV0KGhhLFRhKTtpZihTYT09PSJjYXVzYWwiKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJUaGUgc3VwcG9ydCBmb3IgQ0FVU0FMIHBhZGRpbmcgbW9kZSBpbiBjb252MWRXaXRoQmlhcyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO3JldHVybiBrYT1jb252MmQkMih7eDprYSxmaWx0ZXI6YWEsc3RyaWRlczpiYSxwYWQ6U2E9PT0ic2FtZSI/InNhbWUiOiJ2YWxpZCIsZGlsYXRpb25zOndhLGRhdGFGb3JtYXQ6Ik5IV0MiLGJpYXM6eGEsYWN0aXZhdGlvbjpFYX0pLFRhPT09ImNoYW5uZWxzRmlyc3QiJiYoa2E9dHJhbnNwb3NlJDMoa2EsWzAsMywxLDJdKSksa2F9KX1mdW5jdGlvbiBjb252M2RXaXRoQmlhcyhoYSxhYSx4YSxiYT1bMSwxLDFdLFNhPSJ2YWxpZCIsVGEsd2Epe3JldHVybiB0aWR5JDEoKCk9PntpZihUYT09bnVsbCYmKFRhPWltYWdlRGF0YUZvcm1hdCgpKSxjaGVja0RhdGFGb3JtYXQoVGEpLGhhLnJhbmshPT00JiZoYS5yYW5rIT09NSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgY29udjNkV2l0aEJpYXMgZXhwZWN0cyBpbnB1dCB0byBiZSBvZiByYW5rIDQgb3IgNSwgYnV0IHJlY2VpdmVkICR7aGEucmFua30uYCk7aWYoYWEucmFuayE9PTQmJmFhLnJhbmshPT01KXRocm93IG5ldyBWYWx1ZUVycm9yKGBjb252M2RXaXRoQmlhcyBleHBlY3RzIGtlcm5lbCB0byBiZSBvZiByYW5rIDQgb3IgNSwgYnV0IHJlY2VpdmVkICR7aGEucmFua30uYCk7bGV0IEVhPXByZXByb2Nlc3NDb252M0RJbnB1dChoYSxUYSk7aWYoU2E9PT0iY2F1c2FsIil0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiVGhlIHN1cHBvcnQgZm9yIENBVVNBTCBwYWRkaW5nIG1vZGUgaW4gY29udjNkV2l0aEJpYXMgaXMgbm90IGltcGxlbWVudGVkIHlldC4iKTtyZXR1cm4gRWE9Y29udjNkKEVhLGFhLGJhLFNhPT09InNhbWUiPyJzYW1lIjoidmFsaWQiLCJOREhXQyIsd2EpLHhhIT1udWxsJiYoRWE9Ymlhc0FkZChFYSx4YSkpLFRhPT09ImNoYW5uZWxzRmlyc3QiJiYoRWE9dHJhbnNwb3NlJDMoRWEsWzAsNCwxLDIsM10pKSxFYX0pfWNsYXNzIEJhc2VDb252IGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEseGEpe2lmKHN1cGVyKHhhKSx0aGlzLmJpYXM9bnVsbCx0aGlzLkRFRkFVTFRfS0VSTkVMX0lOSVRJQUxJWkVSPSJnbG9yb3ROb3JtYWwiLHRoaXMuREVGQVVMVF9CSUFTX0lOSVRJQUxJWkVSPSJ6ZXJvcyIsQmFzZUNvbnYudmVyaWZ5QXJncyh4YSksdGhpcy5yYW5rPWFhLGFzc2VydFBvc2l0aXZlSW50ZWdlcih0aGlzLnJhbmssInJhbmsiKSx0aGlzLnJhbmshPT0xJiZ0aGlzLnJhbmshPT0yJiZ0aGlzLnJhbmshPT0zKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKGBDb252b2x1dGlvbiBsYXllciBmb3IgcmFuayBvdGhlciB0aGFuIDEsIDIsIG9yIDMgKCR7dGhpcy5yYW5rfSkgaXMgbm90IGltcGxlbWVudGVkIHlldC5gKTtpZih0aGlzLmtlcm5lbFNpemU9bm9ybWFsaXplQXJyYXkoeGEua2VybmVsU2l6ZSxhYSwia2VybmVsU2l6ZSIpLHRoaXMuc3RyaWRlcz1ub3JtYWxpemVBcnJheSh4YS5zdHJpZGVzPT1udWxsPzE6eGEuc3RyaWRlcyxhYSwic3RyaWRlcyIpLHRoaXMucGFkZGluZz14YS5wYWRkaW5nPT1udWxsPyJ2YWxpZCI6eGEucGFkZGluZyxjaGVja1BhZGRpbmdNb2RlKHRoaXMucGFkZGluZyksdGhpcy5kYXRhRm9ybWF0PXhhLmRhdGFGb3JtYXQ9PW51bGw/ImNoYW5uZWxzTGFzdCI6eGEuZGF0YUZvcm1hdCxjaGVja0RhdGFGb3JtYXQodGhpcy5kYXRhRm9ybWF0KSx0aGlzLmFjdGl2YXRpb249Z2V0QWN0aXZhdGlvbih4YS5hY3RpdmF0aW9uKSx0aGlzLnVzZUJpYXM9eGEudXNlQmlhcz09bnVsbD8hMDp4YS51c2VCaWFzLHRoaXMuYmlhc0luaXRpYWxpemVyPWdldEluaXRpYWxpemVyKHhhLmJpYXNJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX0JJQVNfSU5JVElBTElaRVIpLHRoaXMuYmlhc0NvbnN0cmFpbnQ9Z2V0Q29uc3RyYWludCh4YS5iaWFzQ29uc3RyYWludCksdGhpcy5iaWFzUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoeGEuYmlhc1JlZ3VsYXJpemVyKSx0aGlzLmFjdGl2aXR5UmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoeGEuYWN0aXZpdHlSZWd1bGFyaXplciksdGhpcy5kaWxhdGlvblJhdGU9bm9ybWFsaXplQXJyYXkoeGEuZGlsYXRpb25SYXRlPT1udWxsPzE6eGEuZGlsYXRpb25SYXRlLGFhLCJkaWxhdGlvblJhdGUiKSx0aGlzLnJhbms9PT0xJiZBcnJheS5pc0FycmF5KHRoaXMuZGlsYXRpb25SYXRlKSYmdGhpcy5kaWxhdGlvblJhdGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgZGlsYXRpb25SYXRlIG11c3QgYmUgYSBudW1iZXIgb3IgYW4gYXJyYXkgb2YgYSBzaW5nbGUgbnVtYmVyIGZvciAxRCBjb252b2x1dGlvbiwgYnV0IHJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkodGhpcy5kaWxhdGlvblJhdGUpfWApO2lmKHRoaXMucmFuaz09PTIpe2lmKHR5cGVvZiB0aGlzLmRpbGF0aW9uUmF0ZT09Im51bWJlciIpdGhpcy5kaWxhdGlvblJhdGU9W3RoaXMuZGlsYXRpb25SYXRlLHRoaXMuZGlsYXRpb25SYXRlXTtlbHNlIGlmKHRoaXMuZGlsYXRpb25SYXRlLmxlbmd0aCE9PTIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYGRpbGF0aW9uUmF0ZSBtdXN0IGJlIGEgbnVtYmVyIG9yIGFycmF5IG9mIHR3byBudW1iZXJzIGZvciAyRCBjb252b2x1dGlvbiwgYnV0IHJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkodGhpcy5kaWxhdGlvblJhdGUpfWApfWVsc2UgaWYodGhpcy5yYW5rPT09Myl7aWYodHlwZW9mIHRoaXMuZGlsYXRpb25SYXRlPT0ibnVtYmVyIil0aGlzLmRpbGF0aW9uUmF0ZT1bdGhpcy5kaWxhdGlvblJhdGUsdGhpcy5kaWxhdGlvblJhdGUsdGhpcy5kaWxhdGlvblJhdGVdO2Vsc2UgaWYodGhpcy5kaWxhdGlvblJhdGUubGVuZ3RoIT09Myl0aHJvdyBuZXcgVmFsdWVFcnJvcihgZGlsYXRpb25SYXRlIG11c3QgYmUgYSBudW1iZXIgb3IgYXJyYXkgb2YgdGhyZWUgbnVtYmVycyBmb3IgM0QgY29udm9sdXRpb24sIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KHRoaXMuZGlsYXRpb25SYXRlKX1gKX19c3RhdGljIHZlcmlmeUFyZ3MoYWEpe2lmKGFzc2VydCQxKCJrZXJuZWxTaXplImluIGFhLCJyZXF1aXJlZCBrZXkgJ2tlcm5lbFNpemUnIG5vdCBpbiBjb25maWciKSx0eXBlb2YgYWEua2VybmVsU2l6ZSE9Im51bWJlciImJiFjaGVja0FycmF5VHlwZUFuZExlbmd0aChhYS5rZXJuZWxTaXplLCJudW1iZXIiLDEsMykpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEJhc2VDb252IGV4cGVjdHMgY29uZmlnLmtlcm5lbFNpemUgdG8gYmUgbnVtYmVyIG9yIG51bWJlcltdIHdpdGggbGVuZ3RoIDEsIDIsIG9yIDMsIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KGFhLmtlcm5lbFNpemUpfS5gKX1nZXRDb25maWcoKXtjb25zdCBhYT17a2VybmVsU2l6ZTp0aGlzLmtlcm5lbFNpemUsc3RyaWRlczp0aGlzLnN0cmlkZXMscGFkZGluZzp0aGlzLnBhZGRpbmcsZGF0YUZvcm1hdDp0aGlzLmRhdGFGb3JtYXQsZGlsYXRpb25SYXRlOnRoaXMuZGlsYXRpb25SYXRlLGFjdGl2YXRpb246c2VyaWFsaXplQWN0aXZhdGlvbih0aGlzLmFjdGl2YXRpb24pLHVzZUJpYXM6dGhpcy51c2VCaWFzLGJpYXNJbml0aWFsaXplcjpzZXJpYWxpemVJbml0aWFsaXplcih0aGlzLmJpYXNJbml0aWFsaXplciksYmlhc1JlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuYmlhc1JlZ3VsYXJpemVyKSxhY3Rpdml0eVJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuYWN0aXZpdHlSZWd1bGFyaXplciksYmlhc0NvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmJpYXNDb25zdHJhaW50KX0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1jbGFzcyBDb252IGV4dGVuZHMgQmFzZUNvbnZ7Y29uc3RydWN0b3IoYWEseGEpe3N1cGVyKGFhLHhhKSx0aGlzLmtlcm5lbD1udWxsLENvbnYudmVyaWZ5QXJncyh4YSksdGhpcy5maWx0ZXJzPXhhLmZpbHRlcnMsYXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHRoaXMuZmlsdGVycywiZmlsdGVycyIpLHRoaXMua2VybmVsSW5pdGlhbGl6ZXI9Z2V0SW5pdGlhbGl6ZXIoeGEua2VybmVsSW5pdGlhbGl6ZXJ8fHRoaXMuREVGQVVMVF9LRVJORUxfSU5JVElBTElaRVIpLHRoaXMua2VybmVsQ29uc3RyYWludD1nZXRDb25zdHJhaW50KHhhLmtlcm5lbENvbnN0cmFpbnQpLHRoaXMua2VybmVsUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoeGEua2VybmVsUmVndWxhcml6ZXIpfWJ1aWxkKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IHhhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij8xOmFhLmxlbmd0aC0xO2lmKGFhW3hhXT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgVGhlIGNoYW5uZWwgZGltZW5zaW9uIG9mIHRoZSBpbnB1dCBzaG91bGQgYmUgZGVmaW5lZC4gRm91bmQgJHthYVt4YV19YCk7Y29uc3QgYmE9YWFbeGFdLFNhPXRoaXMua2VybmVsU2l6ZS5jb25jYXQoW2JhLHRoaXMuZmlsdGVyc10pO3RoaXMua2VybmVsPXRoaXMuYWRkV2VpZ2h0KCJrZXJuZWwiLFNhLG51bGwsdGhpcy5rZXJuZWxJbml0aWFsaXplcix0aGlzLmtlcm5lbFJlZ3VsYXJpemVyLCEwLHRoaXMua2VybmVsQ29uc3RyYWludCksdGhpcy51c2VCaWFzJiYodGhpcy5iaWFzPXRoaXMuYWRkV2VpZ2h0KCJiaWFzIixbdGhpcy5maWx0ZXJzXSxudWxsLHRoaXMuYmlhc0luaXRpYWxpemVyLHRoaXMuYmlhc1JlZ3VsYXJpemVyLCEwLHRoaXMuYmlhc0NvbnN0cmFpbnQpKSx0aGlzLmlucHV0U3BlYz1be25kaW06dGhpcy5yYW5rKzIsYXhlczp7W3hhXTpiYX19XSx0aGlzLmJ1aWx0PSEwfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PnthYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtsZXQgYmE7Y29uc3QgU2E9dGhpcy5iaWFzPT1udWxsP251bGw6dGhpcy5iaWFzLnJlYWQoKSxUYT1tYXBBY3RpdmF0aW9uVG9GdXNlZEtlcm5lbCh0aGlzLmFjdGl2YXRpb24uZ2V0Q2xhc3NOYW1lKCkpO2lmKFRhIT1udWxsJiZ0aGlzLnJhbms9PT0yKWJhPWNvbnYyZFdpdGhCaWFzQWN0aXZhdGlvbihhYSx0aGlzLmtlcm5lbC5yZWFkKCksU2EsdGhpcy5zdHJpZGVzLHRoaXMucGFkZGluZyx0aGlzLmRhdGFGb3JtYXQsdGhpcy5kaWxhdGlvblJhdGUsVGEpO2Vsc2V7aWYodGhpcy5yYW5rPT09MSliYT1jb252MWRXaXRoQmlhcyhhYSx0aGlzLmtlcm5lbC5yZWFkKCksU2EsdGhpcy5zdHJpZGVzWzBdLHRoaXMucGFkZGluZyx0aGlzLmRhdGFGb3JtYXQsdGhpcy5kaWxhdGlvblJhdGVbMF0pO2Vsc2UgaWYodGhpcy5yYW5rPT09MiliYT1jb252MmRXaXRoQmlhc0FjdGl2YXRpb24oYWEsdGhpcy5rZXJuZWwucmVhZCgpLFNhLHRoaXMuc3RyaWRlcyx0aGlzLnBhZGRpbmcsdGhpcy5kYXRhRm9ybWF0LHRoaXMuZGlsYXRpb25SYXRlKTtlbHNlIGlmKHRoaXMucmFuaz09PTMpYmE9Y29udjNkV2l0aEJpYXMoYWEsdGhpcy5rZXJuZWwucmVhZCgpLFNhLHRoaXMuc3RyaWRlcyx0aGlzLnBhZGRpbmcsdGhpcy5kYXRhRm9ybWF0LHRoaXMuZGlsYXRpb25SYXRlKTtlbHNlIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJjb252b2x1dGlvbnMgZ3JlYXRlciB0aGFuIDNEIGFyZSBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO3RoaXMuYWN0aXZhdGlvbiE9bnVsbCYmKGJhPXRoaXMuYWN0aXZhdGlvbi5hcHBseShiYSkpfXJldHVybiBiYX0pfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKTtjb25zdCB4YT1bXSxiYT10aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNMYXN0Ij9hYS5zbGljZSgxLGFhLmxlbmd0aC0xKTphYS5zbGljZSgyKTtmb3IobGV0IFRhPTA7VGE8YmEubGVuZ3RoOysrVGEpe2NvbnN0IHdhPWNvbnZPdXRwdXRMZW5ndGgoYmFbVGFdLHRoaXMua2VybmVsU2l6ZVtUYV0sdGhpcy5wYWRkaW5nLHRoaXMuc3RyaWRlc1tUYV0sdHlwZW9mIHRoaXMuZGlsYXRpb25SYXRlPT0ibnVtYmVyIj90aGlzLmRpbGF0aW9uUmF0ZTp0aGlzLmRpbGF0aW9uUmF0ZVtUYV0pO3hhLnB1c2god2EpfWxldCBTYT1bYWFbMF1dO3JldHVybiB0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNMYXN0Ij8oU2E9U2EuY29uY2F0KHhhKSxTYS5wdXNoKHRoaXMuZmlsdGVycykpOihTYS5wdXNoKHRoaXMuZmlsdGVycyksU2E9U2EuY29uY2F0KHhhKSksU2F9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e2ZpbHRlcnM6dGhpcy5maWx0ZXJzLGtlcm5lbEluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMua2VybmVsSW5pdGlhbGl6ZXIpLGtlcm5lbFJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMua2VybmVsUmVndWxhcml6ZXIpLGtlcm5lbENvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmtlcm5lbENvbnN0cmFpbnQpfSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9c3RhdGljIHZlcmlmeUFyZ3MoYWEpe2lmKCEoImZpbHRlcnMiaW4gYWEpfHx0eXBlb2YgYWEuZmlsdGVycyE9Im51bWJlciJ8fGFhLmZpbHRlcnM8MSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQ29udm9sdXRpb24gbGF5ZXIgZXhwZWN0ZWQgY29uZmlnLmZpbHRlcnMgdG8gYmUgYSAnbnVtYmVyJyA+IDAgYnV0IGdvdCAke0pTT04uc3RyaW5naWZ5KGFhLmZpbHRlcnMpfWApfX1sZXQgQ29udjJEJDE9Y2xhc3MgdWMgZXh0ZW5kcyBDb252e2NvbnN0cnVjdG9yKGFhKXtzdXBlcigyLGFhKSx1Yy52ZXJpZnlBcmdzKGFhKX1nZXRDb25maWcoKXtjb25zdCBhYT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gZGVsZXRlIGFhLnJhbmssYWF9c3RhdGljIHZlcmlmeUFyZ3MoYWEpe2lmKHR5cGVvZiBhYS5rZXJuZWxTaXplIT0ibnVtYmVyIiYmIWNoZWNrQXJyYXlUeXBlQW5kTGVuZ3RoKGFhLmtlcm5lbFNpemUsIm51bWJlciIsMSwyKSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQ29udjJEIGV4cGVjdHMgY29uZmlnLmtlcm5lbFNpemUgdG8gYmUgbnVtYmVyIG9yIG51bWJlcltdIHdpdGggbGVuZ3RoIDEgb3IgMiwgYnV0IHJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkoYWEua2VybmVsU2l6ZSl9LmApfX07Q29udjJEJDEuY2xhc3NOYW1lPSJDb252MkQiLHJlZ2lzdGVyQ2xhc3MkMShDb252MkQkMSk7bGV0IENvbnYzRCQxPWNsYXNzIGRjIGV4dGVuZHMgQ29udntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoMyxhYSksZGMudmVyaWZ5QXJncyhhYSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIGRlbGV0ZSBhYS5yYW5rLGFhfXN0YXRpYyB2ZXJpZnlBcmdzKGFhKXtpZih0eXBlb2YgYWEua2VybmVsU2l6ZSE9Im51bWJlciImJiEoQXJyYXkuaXNBcnJheShhYS5rZXJuZWxTaXplKSYmKGFhLmtlcm5lbFNpemUubGVuZ3RoPT09MXx8YWEua2VybmVsU2l6ZS5sZW5ndGg9PT0zKSkpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYENvbnYzRCBleHBlY3RzIGNvbmZpZy5rZXJuZWxTaXplIHRvIGJlIG51bWJlciBvciBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KGFhLmtlcm5lbFNpemUpfS5gKX19O0NvbnYzRCQxLmNsYXNzTmFtZT0iQ29udjNEIixyZWdpc3RlckNsYXNzJDEoQ29udjNEJDEpO2NsYXNzIENvbnYyRFRyYW5zcG9zZSBleHRlbmRzIENvbnYyRCQxe2NvbnN0cnVjdG9yKGFhKXtpZihzdXBlcihhYSksdGhpcy5pbnB1dFNwZWM9W25ldyBJbnB1dFNwZWMoe25kaW06NH0pXSx0aGlzLnBhZGRpbmchPT0ic2FtZSImJnRoaXMucGFkZGluZyE9PSJ2YWxpZCIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYENvbnYyRFRyYW5zcG9zZSBjdXJyZW50bHkgc3VwcG9ydHMgb25seSBwYWRkaW5nIG1vZGVzICdzYW1lJyBhbmQgJ3ZhbGlkJywgYnV0IHJlY2VpdmVkIHBhZGRpbmcgbW9kZSAke3RoaXMucGFkZGluZ31gKX1idWlsZChhYSl7aWYoYWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKSxhYS5sZW5ndGghPT00KXRocm93IG5ldyBWYWx1ZUVycm9yKCJJbnB1dCBzaG91bGQgaGF2ZSByYW5rIDQ7IFJlY2VpdmVkIGlucHV0IHNoYXBlOiAiK0pTT04uc3RyaW5naWZ5KGFhKSk7Y29uc3QgeGE9dGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiPzE6YWEubGVuZ3RoLTE7aWYoYWFbeGFdPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJUaGUgY2hhbm5lbCBkaW1lbnNpb24gb2YgdGhlIGlucHV0cyBzaG91bGQgYmUgZGVmaW5lZC4gRm91bmQgYE5vbmVgLiIpO2NvbnN0IGJhPWFhW3hhXSxTYT10aGlzLmtlcm5lbFNpemUuY29uY2F0KFt0aGlzLmZpbHRlcnMsYmFdKTt0aGlzLmtlcm5lbD10aGlzLmFkZFdlaWdodCgia2VybmVsIixTYSwiZmxvYXQzMiIsdGhpcy5rZXJuZWxJbml0aWFsaXplcix0aGlzLmtlcm5lbFJlZ3VsYXJpemVyLCEwLHRoaXMua2VybmVsQ29uc3RyYWludCksdGhpcy51c2VCaWFzJiYodGhpcy5iaWFzPXRoaXMuYWRkV2VpZ2h0KCJiaWFzIixbdGhpcy5maWx0ZXJzXSwiZmxvYXQzMiIsdGhpcy5iaWFzSW5pdGlhbGl6ZXIsdGhpcy5iaWFzUmVndWxhcml6ZXIsITAsdGhpcy5iaWFzQ29uc3RyYWludCkpLHRoaXMuaW5wdXRTcGVjPVtuZXcgSW5wdXRTcGVjKHtuZGltOjQsYXhlczp7W3hhXTpiYX19KV0sdGhpcy5idWlsdD0hMH1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO2lmKGJhLnNoYXBlLmxlbmd0aCE9PTQpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYENvbnYyRFRyYW5zcG9zZS5jYWxsKCkgZXhwZWN0cyBpbnB1dCB0ZW5zb3IgdG8gYmUgcmFuay00LCBidXQgcmVjZWl2ZWQgYSB0ZW5zb3Igb2YgcmFuay0ke2JhLnNoYXBlLmxlbmd0aH1gKTtjb25zdCBTYT1iYS5zaGFwZSxUYT1TYVswXTtsZXQgd2EsRWE7dGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiPyh3YT0yLEVhPTMpOih3YT0xLEVhPTIpO2NvbnN0IGthPVNhW3dhXSxBYT1TYVtFYV0sRmE9dGhpcy5rZXJuZWxTaXplWzBdLExhPXRoaXMua2VybmVsU2l6ZVsxXSxlbD10aGlzLnN0cmlkZXNbMF0sdGw9dGhpcy5zdHJpZGVzWzFdLG5sPWRlY29udkxlbmd0aChrYSxlbCxGYSx0aGlzLnBhZGRpbmcpLHNsPWRlY29udkxlbmd0aChBYSx0bCxMYSx0aGlzLnBhZGRpbmcpLHJsPVtUYSxubCxzbCx0aGlzLmZpbHRlcnNdO3RoaXMuZGF0YUZvcm1hdCE9PSJjaGFubmVsc0xhc3QiJiYoYmE9dHJhbnNwb3NlJDMoYmEsWzAsMiwzLDFdKSk7bGV0IG9sPWNvbnYyZFRyYW5zcG9zZShiYSx0aGlzLmtlcm5lbC5yZWFkKCkscmwsdGhpcy5zdHJpZGVzLHRoaXMucGFkZGluZyk7cmV0dXJuIHRoaXMuZGF0YUZvcm1hdCE9PSJjaGFubmVsc0xhc3QiJiYob2w9dHJhbnNwb3NlJDMob2wsWzAsMywxLDJdKSksdGhpcy5iaWFzIT1udWxsJiYob2w9Ymlhc0FkZChvbCx0aGlzLmJpYXMucmVhZCgpLHRoaXMuZGF0YUZvcm1hdCkpLHRoaXMuYWN0aXZhdGlvbiE9bnVsbCYmKG9sPXRoaXMuYWN0aXZhdGlvbi5hcHBseShvbCkpLG9sfSl9Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IHhhPWFhLnNsaWNlKCk7bGV0IGJhLFNhLFRhO3RoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij8oYmE9MSxTYT0yLFRhPTMpOihiYT0zLFNhPTEsVGE9Mik7Y29uc3Qgd2E9dGhpcy5rZXJuZWxTaXplWzBdLEVhPXRoaXMua2VybmVsU2l6ZVsxXSxrYT10aGlzLnN0cmlkZXNbMF0sQWE9dGhpcy5zdHJpZGVzWzFdO3JldHVybiB4YVtiYV09dGhpcy5maWx0ZXJzLHhhW1NhXT1kZWNvbnZMZW5ndGgoeGFbU2FdLGthLHdhLHRoaXMucGFkZGluZykseGFbVGFdPWRlY29udkxlbmd0aCh4YVtUYV0sQWEsRWEsdGhpcy5wYWRkaW5nKSx4YX1nZXRDb25maWcoKXtjb25zdCBhYT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gZGVsZXRlIGFhLmRpbGF0aW9uUmF0ZSxhYX19Q29udjJEVHJhbnNwb3NlLmNsYXNzTmFtZT0iQ29udjJEVHJhbnNwb3NlIixyZWdpc3RlckNsYXNzJDEoQ29udjJEVHJhbnNwb3NlKTtjbGFzcyBDb252M0RUcmFuc3Bvc2UgZXh0ZW5kcyBDb252M0QkMXtjb25zdHJ1Y3RvcihhYSl7aWYoc3VwZXIoYWEpLHRoaXMuaW5wdXRTcGVjPVtuZXcgSW5wdXRTcGVjKHtuZGltOjV9KV0sdGhpcy5wYWRkaW5nIT09InNhbWUiJiZ0aGlzLnBhZGRpbmchPT0idmFsaWQiKXRocm93IG5ldyBWYWx1ZUVycm9yKGBDb252M0RUcmFuc3Bvc2UgY3VycmVudGx5IHN1cHBvcnRzIG9ubHkgcGFkZGluZyBtb2RlcyAnc2FtZScgYW5kICd2YWxpZCcsIGJ1dCByZWNlaXZlZCBwYWRkaW5nIG1vZGUgJHt0aGlzLnBhZGRpbmd9YCl9YnVpbGQoYWEpe2lmKGFhPWdldEV4YWN0bHlPbmVTaGFwZShhYSksYWEubGVuZ3RoIT09NSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiSW5wdXQgc2hvdWxkIGhhdmUgcmFuayA1OyBSZWNlaXZlZCBpbnB1dCBzaGFwZTogIitKU09OLnN0cmluZ2lmeShhYSkpO2NvbnN0IHhhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij8xOmFhLmxlbmd0aC0xO2lmKGFhW3hhXT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcigiVGhlIGNoYW5uZWwgZGltZW5zaW9uIG9mIHRoZSBpbnB1dHMgc2hvdWxkIGJlIGRlZmluZWQuIEZvdW5kIGBOb25lYC4iKTtjb25zdCBiYT1hYVt4YV0sU2E9dGhpcy5rZXJuZWxTaXplLmNvbmNhdChbdGhpcy5maWx0ZXJzLGJhXSk7dGhpcy5rZXJuZWw9dGhpcy5hZGRXZWlnaHQoImtlcm5lbCIsU2EsImZsb2F0MzIiLHRoaXMua2VybmVsSW5pdGlhbGl6ZXIsdGhpcy5rZXJuZWxSZWd1bGFyaXplciwhMCx0aGlzLmtlcm5lbENvbnN0cmFpbnQpLHRoaXMudXNlQmlhcyYmKHRoaXMuYmlhcz10aGlzLmFkZFdlaWdodCgiYmlhcyIsW3RoaXMuZmlsdGVyc10sImZsb2F0MzIiLHRoaXMuYmlhc0luaXRpYWxpemVyLHRoaXMuYmlhc1JlZ3VsYXJpemVyLCEwLHRoaXMuYmlhc0NvbnN0cmFpbnQpKSx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTo1LGF4ZXM6e1t4YV06YmF9fSldLHRoaXMuYnVpbHQ9ITB9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2xldCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtpZihiYS5zaGFwZS5sZW5ndGghPT01KXRocm93IG5ldyBWYWx1ZUVycm9yKGBDb252M0RUcmFuc3Bvc2UuY2FsbCgpIGV4cGVjdHMgaW5wdXQgdGVuc29yIHRvIGJlIHJhbmstNCwgYnV0IHJlY2VpdmVkIGEgdGVuc29yIG9mIHJhbmstJHtiYS5zaGFwZS5sZW5ndGh9YCk7Y29uc3QgU2E9YmEuc2hhcGUsVGE9U2FbMF07bGV0IHdhLEVhLGthO3RoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij8oa2E9Mix3YT0zLEVhPTQpOihrYT0xLHdhPTIsRWE9Myk7Y29uc3QgQWE9U2Fba2FdLEZhPVNhW3dhXSxMYT1TYVtFYV0sZWw9dGhpcy5rZXJuZWxTaXplWzBdLHRsPXRoaXMua2VybmVsU2l6ZVsxXSxubD10aGlzLmtlcm5lbFNpemVbMl0sc2w9dGhpcy5zdHJpZGVzWzBdLHJsPXRoaXMuc3RyaWRlc1sxXSxvbD10aGlzLnN0cmlkZXNbMl0sYWw9ZGVjb252TGVuZ3RoKEFhLHNsLGVsLHRoaXMucGFkZGluZyksbGw9ZGVjb252TGVuZ3RoKEZhLHJsLHRsLHRoaXMucGFkZGluZyksaWw9ZGVjb252TGVuZ3RoKExhLG9sLG5sLHRoaXMucGFkZGluZyksY2w9W1RhLGFsLGxsLGlsLHRoaXMuZmlsdGVyc107dGhpcy5kYXRhRm9ybWF0IT09ImNoYW5uZWxzTGFzdCImJihiYT10cmFuc3Bvc2UkMyhiYSxbMCwyLDMsNCwxXSkpO2xldCB1bD1jb252M2RUcmFuc3Bvc2UoYmEsdGhpcy5rZXJuZWwucmVhZCgpLGNsLHRoaXMuc3RyaWRlcyx0aGlzLnBhZGRpbmcpO3JldHVybiB0aGlzLmRhdGFGb3JtYXQhPT0iY2hhbm5lbHNMYXN0IiYmKHVsPXRyYW5zcG9zZSQzKHVsLFswLDQsMSwyLDNdKSksdGhpcy5iaWFzIT09bnVsbCYmKHVsPWJpYXNBZGQodWwsdGhpcy5iaWFzLnJlYWQoKSx0aGlzLmRhdGFGb3JtYXQpKSx0aGlzLmFjdGl2YXRpb24hPT1udWxsJiYodWw9dGhpcy5hY3RpdmF0aW9uLmFwcGx5KHVsKSksdWx9KX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9YWEuc2xpY2UoKTtsZXQgYmEsU2EsVGEsd2E7dGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiPyhiYT0xLFNhPTIsVGE9Myx3YT00KTooYmE9NCxTYT0xLFRhPTIsd2E9Myk7Y29uc3QgRWE9dGhpcy5rZXJuZWxTaXplWzBdLGthPXRoaXMua2VybmVsU2l6ZVsxXSxBYT10aGlzLmtlcm5lbFNpemVbMl0sRmE9dGhpcy5zdHJpZGVzWzBdLExhPXRoaXMuc3RyaWRlc1sxXSxlbD10aGlzLnN0cmlkZXNbMl07cmV0dXJuIHhhW2JhXT10aGlzLmZpbHRlcnMseGFbU2FdPWRlY29udkxlbmd0aCh4YVtTYV0sRmEsRWEsdGhpcy5wYWRkaW5nKSx4YVtUYV09ZGVjb252TGVuZ3RoKHhhW1RhXSxMYSxrYSx0aGlzLnBhZGRpbmcpLHhhW3dhXT1kZWNvbnZMZW5ndGgoeGFbd2FdLGVsLEFhLHRoaXMucGFkZGluZykseGF9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIGRlbGV0ZSBhYS5kaWxhdGlvblJhdGUsYWF9fUNvbnYzRFRyYW5zcG9zZS5jbGFzc05hbWU9IkNvbnYzRFRyYW5zcG9zZSIscmVnaXN0ZXJDbGFzcyQxKENvbnYzRFRyYW5zcG9zZSk7Y2xhc3MgU2VwYXJhYmxlQ29udiBleHRlbmRzIENvbnZ7Y29uc3RydWN0b3IoYWEseGEpe2lmKHN1cGVyKGFhLHhhKSx0aGlzLkRFRkFVTFRfREVQVEhXSVNFX0lOSVRJQUxJWkVSPSJnbG9yb3RVbmlmb3JtIix0aGlzLkRFRkFVTFRfUE9JTlRXSVNFX0lOSVRJQUxJWkVSPSJnbG9yb3RVbmlmb3JtIix0aGlzLmRlcHRod2lzZUtlcm5lbD1udWxsLHRoaXMucG9pbnR3aXNlS2VybmVsPW51bGwseGEuZmlsdGVycz09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcigiVGhlIGBmaWx0ZXJzYCBjb25maWd1cmF0aW9uIGZpZWxkIGlzIHJlcXVpcmVkIGJ5IFNlcGFyYWJsZUNvbnYsIGJ1dCBpcyB1bnNwZWNpZmllZC4iKTtpZih4YS5rZXJuZWxJbml0aWFsaXplciE9bnVsbHx8eGEua2VybmVsUmVndWxhcml6ZXIhPW51bGx8fHhhLmtlcm5lbENvbnN0cmFpbnQhPW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIkZpZWxkcyBrZXJuZWxJbml0aWFsaXplciwga2VybmVsUmVndWxhcml6ZXIgYW5kIGtlcm5lbENvbnN0cmFpbnQgYXJlIGludmFsaWQgZm9yIFNlcGFyYWJsZUNvbnYyRC4gVXNlIGRlcHRod2lzZUluaXRpYWxpemVyLCBkZXB0aHdpc2VSZWd1bGFyaXplciwgZGVwdGh3aXNlQ29uc3RyYWludCwgcG9pbnR3aXNlSW5pdGlhbGl6ZXIsIHBvaW50d2lzZVJlZ3VsYXJpemVyIGFuZCBwb2ludHdpc2VDb25zdHJhaW50IGluc3RlYWQuIik7aWYoeGEucGFkZGluZyE9bnVsbCYmeGEucGFkZGluZyE9PSJzYW1lIiYmeGEucGFkZGluZyE9PSJ2YWxpZCIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFNlcGFyYWJsZUNvbnYke3RoaXMucmFua31EIHN1cHBvcnRzIG9ubHkgcGFkZGluZyBtb2RlczogJ3NhbWUnIGFuZCAndmFsaWQnLCBidXQgcmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeSh4YS5wYWRkaW5nKX1gKTt0aGlzLmRlcHRoTXVsdGlwbGllcj14YS5kZXB0aE11bHRpcGxpZXI9PW51bGw/MTp4YS5kZXB0aE11bHRpcGxpZXIsdGhpcy5kZXB0aHdpc2VJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcih4YS5kZXB0aHdpc2VJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX0RFUFRIV0lTRV9JTklUSUFMSVpFUiksdGhpcy5kZXB0aHdpc2VSZWd1bGFyaXplcj1nZXRSZWd1bGFyaXplcih4YS5kZXB0aHdpc2VSZWd1bGFyaXplciksdGhpcy5kZXB0aHdpc2VDb25zdHJhaW50PWdldENvbnN0cmFpbnQoeGEuZGVwdGh3aXNlQ29uc3RyYWludCksdGhpcy5wb2ludHdpc2VJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcih4YS5kZXB0aHdpc2VJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX1BPSU5UV0lTRV9JTklUSUFMSVpFUiksdGhpcy5wb2ludHdpc2VSZWd1bGFyaXplcj1nZXRSZWd1bGFyaXplcih4YS5wb2ludHdpc2VSZWd1bGFyaXplciksdGhpcy5wb2ludHdpc2VDb25zdHJhaW50PWdldENvbnN0cmFpbnQoeGEucG9pbnR3aXNlQ29uc3RyYWludCl9YnVpbGQoYWEpe2lmKGFhPWdldEV4YWN0bHlPbmVTaGFwZShhYSksYWEubGVuZ3RoPHRoaXMucmFuaysyKXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbnB1dHMgdG8gU2VwYXJhYmxlQ29udiR7dGhpcy5yYW5rfUQgc2hvdWxkIGhhdmUgcmFuayAke3RoaXMucmFuaysyfSwgYnV0IHJlY2VpdmVkIGlucHV0IHNoYXBlOiAke0pTT04uc3RyaW5naWZ5KGFhKX1gKTtjb25zdCB4YT10aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCI/MTphYS5sZW5ndGgtMTtpZihhYVt4YV09PW51bGx8fGFhW3hhXTwwKXRocm93IG5ldyBWYWx1ZUVycm9yKGBUaGUgY2hhbm5lbCBkaW1lbnNpb24gb2YgdGhlIGlucHV0cyBzaG91bGQgYmUgZGVmaW5lZCwgYnV0IGZvdW5kICR7SlNPTi5zdHJpbmdpZnkoYWFbeGFdKX1gKTtjb25zdCBiYT1hYVt4YV0sU2E9dGhpcy5rZXJuZWxTaXplLmNvbmNhdChbYmEsdGhpcy5kZXB0aE11bHRpcGxpZXJdKSxUYT1bXTtmb3IobGV0IEVhPTA7RWE8dGhpcy5yYW5rOysrRWEpVGEucHVzaCgxKTtUYS5wdXNoKGJhKnRoaXMuZGVwdGhNdWx0aXBsaWVyLHRoaXMuZmlsdGVycyk7Y29uc3Qgd2E9ITA7dGhpcy5kZXB0aHdpc2VLZXJuZWw9dGhpcy5hZGRXZWlnaHQoImRlcHRod2lzZV9rZXJuZWwiLFNhLCJmbG9hdDMyIix0aGlzLmRlcHRod2lzZUluaXRpYWxpemVyLHRoaXMuZGVwdGh3aXNlUmVndWxhcml6ZXIsd2EsdGhpcy5kZXB0aHdpc2VDb25zdHJhaW50KSx0aGlzLnBvaW50d2lzZUtlcm5lbD10aGlzLmFkZFdlaWdodCgicG9pbnR3aXNlX2tlcm5lbCIsVGEsImZsb2F0MzIiLHRoaXMucG9pbnR3aXNlSW5pdGlhbGl6ZXIsdGhpcy5wb2ludHdpc2VSZWd1bGFyaXplcix3YSx0aGlzLnBvaW50d2lzZUNvbnN0cmFpbnQpLHRoaXMudXNlQmlhcz90aGlzLmJpYXM9dGhpcy5hZGRXZWlnaHQoImJpYXMiLFt0aGlzLmZpbHRlcnNdLCJmbG9hdDMyIix0aGlzLmJpYXNJbml0aWFsaXplcix0aGlzLmJpYXNSZWd1bGFyaXplcix3YSx0aGlzLmJpYXNDb25zdHJhaW50KTp0aGlzLmJpYXM9bnVsbCx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTp0aGlzLnJhbmsrMixheGVzOntbeGFdOmJhfX0pXSx0aGlzLmJ1aWx0PSEwfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PnthYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtsZXQgYmE7aWYodGhpcy5yYW5rPT09MSl0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiMUQgc2VwYXJhYmxlIGNvbnZvbHV0aW9uIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuIik7cmV0dXJuIHRoaXMucmFuaz09PTImJih0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCImJihhYT10cmFuc3Bvc2UkMyhhYSxbMCwyLDMsMV0pKSxiYT1zZXBhcmFibGVDb252MmQoYWEsdGhpcy5kZXB0aHdpc2VLZXJuZWwucmVhZCgpLHRoaXMucG9pbnR3aXNlS2VybmVsLnJlYWQoKSx0aGlzLnN0cmlkZXMsdGhpcy5wYWRkaW5nLHRoaXMuZGlsYXRpb25SYXRlLCJOSFdDIikpLHRoaXMudXNlQmlhcyYmKGJhPWJpYXNBZGQoYmEsdGhpcy5iaWFzLnJlYWQoKSx0aGlzLmRhdGFGb3JtYXQpKSx0aGlzLmFjdGl2YXRpb24hPW51bGwmJihiYT10aGlzLmFjdGl2YXRpb24uYXBwbHkoYmEpKSx0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCImJihiYT10cmFuc3Bvc2UkMyhiYSxbMCwzLDEsMl0pKSxiYX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBkZWxldGUgYWEucmFuayxkZWxldGUgYWEua2VybmVsSW5pdGlhbGl6ZXIsZGVsZXRlIGFhLmtlcm5lbFJlZ3VsYXJpemVyLGRlbGV0ZSBhYS5rZXJuZWxDb25zdHJhaW50LGFhLmRlcHRod2lzZUluaXRpYWxpemVyPXNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuZGVwdGh3aXNlSW5pdGlhbGl6ZXIpLGFhLnBvaW50d2lzZUluaXRpYWxpemVyPXNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMucG9pbnR3aXNlSW5pdGlhbGl6ZXIpLGFhLmRlcHRod2lzZVJlZ3VsYXJpemVyPXNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuZGVwdGh3aXNlUmVndWxhcml6ZXIpLGFhLnBvaW50d2lzZVJlZ3VsYXJpemVyPXNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMucG9pbnR3aXNlUmVndWxhcml6ZXIpLGFhLmRlcHRod2lzZUNvbnN0cmFpbnQ9c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmRlcHRod2lzZUNvbnN0cmFpbnQpLGFhLnBvaW50d2lzZUNvbnN0cmFpbnQ9c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLnBvaW50d2lzZUNvbnN0cmFpbnQpLGFhfX1TZXBhcmFibGVDb252LmNsYXNzTmFtZT0iU2VwYXJhYmxlQ29udiI7Y2xhc3MgU2VwYXJhYmxlQ29udjJEIGV4dGVuZHMgU2VwYXJhYmxlQ29udntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoMixhYSl9fVNlcGFyYWJsZUNvbnYyRC5jbGFzc05hbWU9IlNlcGFyYWJsZUNvbnYyRCIscmVnaXN0ZXJDbGFzcyQxKFNlcGFyYWJsZUNvbnYyRCk7Y2xhc3MgQ29udjFEIGV4dGVuZHMgQ29udntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoMSxhYSksQ29udjFELnZlcmlmeUFyZ3MoYWEpLHRoaXMuaW5wdXRTcGVjPVt7bmRpbTozfV19Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIGRlbGV0ZSBhYS5yYW5rLGRlbGV0ZSBhYS5kYXRhRm9ybWF0LGFhfXN0YXRpYyB2ZXJpZnlBcmdzKGFhKXtpZih0eXBlb2YgYWEua2VybmVsU2l6ZSE9Im51bWJlciImJiFjaGVja0FycmF5VHlwZUFuZExlbmd0aChhYS5rZXJuZWxTaXplLCJudW1iZXIiLDEsMSkpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYENvbnYxRCBleHBlY3RzIGNvbmZpZy5rZXJuZWxTaXplIHRvIGJlIG51bWJlciBvciBudW1iZXJbXSB3aXRoIGxlbmd0aCAxLCBidXQgcmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeShhYS5rZXJuZWxTaXplKX0uYCl9fUNvbnYxRC5jbGFzc05hbWU9IkNvbnYxRCIscmVnaXN0ZXJDbGFzcyQxKENvbnYxRCk7Y2xhc3MgQ3JvcHBpbmcyRCBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdHlwZW9mIGFhLmNyb3BwaW5nPT0ibnVtYmVyIj90aGlzLmNyb3BwaW5nPVtbYWEuY3JvcHBpbmcsYWEuY3JvcHBpbmddLFthYS5jcm9wcGluZyxhYS5jcm9wcGluZ11dOnR5cGVvZiBhYS5jcm9wcGluZ1swXT09Im51bWJlciI/dGhpcy5jcm9wcGluZz1bW2FhLmNyb3BwaW5nWzBdLGFhLmNyb3BwaW5nWzBdXSxbYWEuY3JvcHBpbmdbMV0sYWEuY3JvcHBpbmdbMV1dXTp0aGlzLmNyb3BwaW5nPWFhLmNyb3BwaW5nLHRoaXMuZGF0YUZvcm1hdD1hYS5kYXRhRm9ybWF0PT09dm9pZCAwPyJjaGFubmVsc0xhc3QiOmFhLmRhdGFGb3JtYXQsdGhpcy5pbnB1dFNwZWM9W3tuZGltOjR9XX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiB0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCI/W2FhWzBdLGFhWzFdLGFhWzJdLXRoaXMuY3JvcHBpbmdbMF1bMF0tdGhpcy5jcm9wcGluZ1swXVsxXSxhYVszXS10aGlzLmNyb3BwaW5nWzFdWzBdLXRoaXMuY3JvcHBpbmdbMV1bMV1dOlthYVswXSxhYVsxXS10aGlzLmNyb3BwaW5nWzBdWzBdLXRoaXMuY3JvcHBpbmdbMF1bMV0sYWFbMl0tdGhpcy5jcm9wcGluZ1sxXVswXS10aGlzLmNyb3BwaW5nWzFdWzFdLGFhWzNdXX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57aWYoYWE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSksdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCIpe2NvbnN0IGJhPXNsaWNlQWxvbmdBeGlzKGFhLHRoaXMuY3JvcHBpbmdbMF1bMF0sYWEuc2hhcGVbMV0tdGhpcy5jcm9wcGluZ1swXVswXS10aGlzLmNyb3BwaW5nWzBdWzFdLDIpO3JldHVybiBzbGljZUFsb25nQXhpcyhiYSx0aGlzLmNyb3BwaW5nWzFdWzBdLGFhLnNoYXBlWzJdLXRoaXMuY3JvcHBpbmdbMV1bMV0tdGhpcy5jcm9wcGluZ1sxXVswXSwzKX1lbHNle2NvbnN0IGJhPXNsaWNlQWxvbmdBeGlzKGFhLHRoaXMuY3JvcHBpbmdbMF1bMF0sYWEuc2hhcGVbMl0tdGhpcy5jcm9wcGluZ1swXVswXS10aGlzLmNyb3BwaW5nWzBdWzFdLDMpO3JldHVybiBzbGljZUFsb25nQXhpcyhiYSx0aGlzLmNyb3BwaW5nWzFdWzBdLGFhLnNoYXBlWzNdLXRoaXMuY3JvcHBpbmdbMV1bMV0tdGhpcy5jcm9wcGluZ1sxXVswXSw0KX19KX1nZXRDb25maWcoKXtjb25zdCBhYT17Y3JvcHBpbmc6dGhpcy5jcm9wcGluZyxkYXRhRm9ybWF0OnRoaXMuZGF0YUZvcm1hdH0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1Dcm9wcGluZzJELmNsYXNzTmFtZT0iQ3JvcHBpbmcyRCIscmVnaXN0ZXJDbGFzcyQxKENyb3BwaW5nMkQpO2NsYXNzIFVwU2FtcGxpbmcyRCBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5ERUZBVUxUX1NJWkU9WzIsMl0sdGhpcy5pbnB1dFNwZWM9W3tuZGltOjR9XSx0aGlzLnNpemU9YWEuc2l6ZT09bnVsbD90aGlzLkRFRkFVTFRfU0laRTphYS5zaXplLHRoaXMuZGF0YUZvcm1hdD1hYS5kYXRhRm9ybWF0PT1udWxsPyJjaGFubmVsc0xhc3QiOmFhLmRhdGFGb3JtYXQsY2hlY2tEYXRhRm9ybWF0KHRoaXMuZGF0YUZvcm1hdCksdGhpcy5pbnRlcnBvbGF0aW9uPWFhLmludGVycG9sYXRpb249PW51bGw/Im5lYXJlc3QiOmFhLmludGVycG9sYXRpb24sY2hlY2tJbnRlcnBvbGF0aW9uRm9ybWF0KHRoaXMuaW50ZXJwb2xhdGlvbil9Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXtpZih0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCIpe2NvbnN0IHhhPWFhWzJdPT1udWxsP251bGw6dGhpcy5zaXplWzBdKmFhWzJdLGJhPWFhWzNdPT1udWxsP251bGw6dGhpcy5zaXplWzFdKmFhWzNdO3JldHVyblthYVswXSxhYVsxXSx4YSxiYV19ZWxzZXtjb25zdCB4YT1hYVsxXT09bnVsbD9udWxsOnRoaXMuc2l6ZVswXSphYVsxXSxiYT1hYVsyXT09bnVsbD9udWxsOnRoaXMuc2l6ZVsxXSphYVsyXTtyZXR1cm5bYWFbMF0seGEsYmEsYWFbM11dfX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO2NvbnN0IFNhPWJhLnNoYXBlO2lmKHRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Iil7YmE9dHJhbnNwb3NlJDMoYmEsWzAsMiwzLDFdKTtjb25zdCBUYT10aGlzLnNpemVbMF0qU2FbMl0sd2E9dGhpcy5zaXplWzFdKlNhWzNdLEVhPXRoaXMuaW50ZXJwb2xhdGlvbj09PSJuZWFyZXN0Ij9pbWFnZSQxLnJlc2l6ZU5lYXJlc3ROZWlnaGJvcihiYSxbVGEsd2FdKTppbWFnZSQxLnJlc2l6ZUJpbGluZWFyKGJhLFtUYSx3YV0pO3JldHVybiB0cmFuc3Bvc2UkMyhFYSxbMCwzLDEsMl0pfWVsc2V7Y29uc3QgVGE9dGhpcy5zaXplWzBdKlNhWzFdLHdhPXRoaXMuc2l6ZVsxXSpTYVsyXTtyZXR1cm4gdGhpcy5pbnRlcnBvbGF0aW9uPT09Im5lYXJlc3QiP2ltYWdlJDEucmVzaXplTmVhcmVzdE5laWdoYm9yKGJhLFtUYSx3YV0pOmltYWdlJDEucmVzaXplQmlsaW5lYXIoYmEsW1RhLHdhXSl9fSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e3NpemU6dGhpcy5zaXplLGRhdGFGb3JtYXQ6dGhpcy5kYXRhRm9ybWF0LGludGVycG9sYXRpb246dGhpcy5pbnRlcnBvbGF0aW9ufSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9fVVwU2FtcGxpbmcyRC5jbGFzc05hbWU9IlVwU2FtcGxpbmcyRCIscmVnaXN0ZXJDbGFzcyQxKFVwU2FtcGxpbmcyRCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGVwdGh3aXNlQ29udjJkKGhhLGFhLHhhPVsxLDFdLGJhPSJ2YWxpZCIsU2EsVGEpe3JldHVybiB0aWR5JDEoKCk9PntTYT09bnVsbCYmKFNhPWltYWdlRGF0YUZvcm1hdCgpKSxjaGVja0RhdGFGb3JtYXQoU2EpO2xldCB3YT1wcmVwcm9jZXNzQ29udjJESW5wdXQoaGEsU2EpO2lmKGhhLnJhbmshPT00KXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbnB1dCBmb3IgZGVwdGh3aXNlQ29udjJkIGlzIHJlcXVpcmVkIHRvIGJlIDQtRCwgYnV0IGlzIGluc3RlYWQgJHtoYS5yYW5rfS1EYCk7aWYoYWEucmFuayE9PTQpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYGRlcHRod2lzZUtlcm5lbCBpcyByZXF1aXJlZCB0byBiZSA0LUQsIGJ1dCBpcyBpbnN0ZWFkICR7YWEucmFua30tRGApO3JldHVybiB3YT1kZXB0aHdpc2VDb252MmQkMih3YSxhYSx4YSxiYT09PSJzYW1lIj8ic2FtZSI6InZhbGlkIiwiTkhXQyIsVGEpLFNhPT09ImNoYW5uZWxzRmlyc3QiJiYod2E9dHJhbnNwb3NlJDMod2EsWzAsMywxLDJdKSksd2F9KX1jbGFzcyBEZXB0aHdpc2VDb252MkQgZXh0ZW5kcyBCYXNlQ29udntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoMixhYSksdGhpcy5kZXB0aHdpc2VLZXJuZWw9bnVsbCx0aGlzLmRlcHRoTXVsdGlwbGllcj1hYS5kZXB0aE11bHRpcGxpZXI9PW51bGw/MTphYS5kZXB0aE11bHRpcGxpZXIsdGhpcy5kZXB0aHdpc2VJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5kZXB0aHdpc2VJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX0tFUk5FTF9JTklUSUFMSVpFUiksdGhpcy5kZXB0aHdpc2VDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEuZGVwdGh3aXNlQ29uc3RyYWludCksdGhpcy5kZXB0aHdpc2VSZWd1bGFyaXplcj1nZXRSZWd1bGFyaXplcihhYS5kZXB0aHdpc2VSZWd1bGFyaXplcil9YnVpbGQoYWEpe2lmKGFhPWdldEV4YWN0bHlPbmVTaGFwZShhYSksYWEubGVuZ3RoPDQpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYElucHV0cyB0byBEZXB0aHdpc2VDb252MkQgc2hvdWxkIGhhdmUgcmFuayA0LiBSZWNlaXZlZCBpbnB1dCBzaGFwZTogJHtKU09OLnN0cmluZ2lmeShhYSl9LmApO2NvbnN0IHhhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij8xOjM7aWYoYWFbeGFdPT1udWxsfHxhYVt4YV08MCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgVGhlIGNoYW5uZWwgZGltZW5zaW9uIG9mIHRoZSBpbnB1dHMgdG8gRGVwdGh3aXNlQ29udjJEIHNob3VsZCBiZSBkZWZpbmVkLCBidXQgaXMgbm90ICgke2FhW3hhXX0pLmApO2NvbnN0IGJhPWFhW3hhXSxTYT1bdGhpcy5rZXJuZWxTaXplWzBdLHRoaXMua2VybmVsU2l6ZVsxXSxiYSx0aGlzLmRlcHRoTXVsdGlwbGllcl07dGhpcy5kZXB0aHdpc2VLZXJuZWw9dGhpcy5hZGRXZWlnaHQoImRlcHRod2lzZV9rZXJuZWwiLFNhLG51bGwsdGhpcy5kZXB0aHdpc2VJbml0aWFsaXplcix0aGlzLmRlcHRod2lzZVJlZ3VsYXJpemVyLCEwLHRoaXMuZGVwdGh3aXNlQ29uc3RyYWludCksdGhpcy51c2VCaWFzP3RoaXMuYmlhcz10aGlzLmFkZFdlaWdodCgiYmlhcyIsW2JhKnRoaXMuZGVwdGhNdWx0aXBsaWVyXSxudWxsLHRoaXMuYmlhc0luaXRpYWxpemVyLHRoaXMuYmlhc1JlZ3VsYXJpemVyLCEwLHRoaXMuYmlhc0NvbnN0cmFpbnQpOnRoaXMuYmlhcz1udWxsLHRoaXMuYnVpbHQ9ITB9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2FhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO2xldCBiYT1kZXB0aHdpc2VDb252MmQoYWEsdGhpcy5kZXB0aHdpc2VLZXJuZWwucmVhZCgpLHRoaXMuc3RyaWRlcyx0aGlzLnBhZGRpbmcsdGhpcy5kYXRhRm9ybWF0LG51bGwpO3JldHVybiB0aGlzLnVzZUJpYXMmJihiYT1iaWFzQWRkKGJhLHRoaXMuYmlhcy5yZWFkKCksdGhpcy5kYXRhRm9ybWF0KSksdGhpcy5hY3RpdmF0aW9uIT1udWxsJiYoYmE9dGhpcy5hY3RpdmF0aW9uLmFwcGx5KGJhKSksYmF9KX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9dGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiP2FhWzJdOmFhWzFdLGJhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij9hYVszXTphYVsyXSxTYT10aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCI/YWFbMV0qdGhpcy5kZXB0aE11bHRpcGxpZXI6YWFbM10qdGhpcy5kZXB0aE11bHRpcGxpZXIsVGE9Y29udk91dHB1dExlbmd0aCh4YSx0aGlzLmtlcm5lbFNpemVbMF0sdGhpcy5wYWRkaW5nLHRoaXMuc3RyaWRlc1swXSksd2E9Y29udk91dHB1dExlbmd0aChiYSx0aGlzLmtlcm5lbFNpemVbMV0sdGhpcy5wYWRkaW5nLHRoaXMuc3RyaWRlc1sxXSk7cmV0dXJuIHRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij9bYWFbMF0sU2EsVGEsd2FdOlthYVswXSxUYSx3YSxTYV19Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIGFhLmRlcHRoTXVsdGlwbGllcj10aGlzLmRlcHRoTXVsdGlwbGllcixhYS5kZXB0aHdpc2VJbml0aWFsaXplcj1zZXJpYWxpemVJbml0aWFsaXplcih0aGlzLmRlcHRod2lzZUluaXRpYWxpemVyKSxhYS5kZXB0aHdpc2VSZWd1bGFyaXplcj1zZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLmRlcHRod2lzZVJlZ3VsYXJpemVyKSxhYS5kZXB0aHdpc2VDb25zdHJhaW50PXNlcmlhbGl6ZUNvbnN0cmFpbnQodGhpcy5kZXB0aHdpc2VSZWd1bGFyaXplciksYWF9fURlcHRod2lzZUNvbnYyRC5jbGFzc05hbWU9IkRlcHRod2lzZUNvbnYyRCIscmVnaXN0ZXJDbGFzcyQxKERlcHRod2lzZUNvbnYyRCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RhbmRhcmRpemVBcmdzKGhhLGFhLHhhLGJhKXtpZihBcnJheS5pc0FycmF5KGhhKSl7aWYoYWEhPW51bGx8fHhhIT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJXaGVuIGlucHV0cyBpcyBhbiBhcnJheSwgbmVpdGhlciBpbml0aWFsU3RhdGUgb3IgY29uc3RhbnRzIHNob3VsZCBiZSBwcm92aWRlZCIpO2JhIT1udWxsJiYoeGE9aGEuc2xpY2UoaGEubGVuZ3RoLWJhLGhhLmxlbmd0aCksaGE9aGEuc2xpY2UoMCxoYS5sZW5ndGgtYmEpKSxoYS5sZW5ndGg+MSYmKGFhPWhhLnNsaWNlKDEsaGEubGVuZ3RoKSksaGE9aGFbMF19ZnVuY3Rpb24gU2EoVGEpe3JldHVybiBUYT09bnVsbHx8QXJyYXkuaXNBcnJheShUYSk/VGE6W1RhXX1yZXR1cm4gYWE9U2EoYWEpLHhhPVNhKHhhKSx7aW5wdXRzOmhhLGluaXRpYWxTdGF0ZTphYSxjb25zdGFudHM6eGF9fWZ1bmN0aW9uIHJubihoYSxhYSx4YSxiYT0hMSxTYSxUYSx3YT0hMSxFYT0hMSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IGthPWFhLnNoYXBlLmxlbmd0aDtpZihrYTwzKXRocm93IG5ldyBWYWx1ZUVycm9yKGBJbnB1dCBzaG91bGQgYmUgYXQgbGVhc3QgM0QsIGJ1dCBpcyAke2thfUQuYCk7Y29uc3QgQWE9WzEsMF0uY29uY2F0KHJhbmdlJDMoMixrYSkpO2FhPXRyYW5zcG9zZSQzKGFhLEFhKSx3YSYmY29uc29sZS53YXJuKCJCYWNrZW5kIHJubigpOiB0aGUgdW5yb2xsID0gdHJ1ZSBvcHRpb24gaXMgbm90IGFwcGxpY2FibGUgdG8gdGhlIGltcGVyYXRpdmUgZGVlcGxlYXJuLmpzIGJhY2tlbmQuIiksU2EhPW51bGwmJihTYT1jYXN0JDUoY2FzdCQ1KFNhLCJib29sIiksImZsb2F0MzIiKSxTYS5yYW5rPT09a2EtMSYmKFNhPWV4cGFuZERpbXMkNChTYSwtMSkpLFNhPXRyYW5zcG9zZSQzKFNhLEFhKSksYmEmJihhYT1yZXZlcnNlJDMoYWEsMCksU2EhPW51bGwmJihTYT1yZXZlcnNlJDMoU2EsMCkpKTtjb25zdCBGYT1bXTtsZXQgTGEsZWw9eGE7Y29uc3QgdGw9YWEuc2hhcGVbMF0sbmw9dW5zdGFjayhhYSk7bGV0IHNsO1NhIT1udWxsJiYoc2w9dW5zdGFjayhTYSkpO2ZvcihsZXQgb2w9MDtvbDx0bDsrK29sKXtjb25zdCBhbD1ubFtvbF0sbGw9dGlkeSQxKCgpPT5oYShhbCxlbCkpO2lmKFNhPT1udWxsKUxhPWxsWzBdLGVsPWxsWzFdO2Vsc2V7Y29uc3QgaWw9dGlkeSQxKCgpPT57Y29uc3QgY2w9c2xbb2xdLHVsPXN1YiQ0KG9uZXNMaWtlJDMoY2wpLGNsKSxkbD1hZGQkMyhtdWwkMShsbFswXSxjbCksbXVsJDEoZWxbMF0sdWwpKSxobD1lbC5tYXAoKHBsLGZsKT0+YWRkJDMobXVsJDEobGxbMV1bZmxdLGNsKSxtdWwkMShwbCx1bCkpKTtyZXR1cm57b3V0cHV0OmRsLG5ld1N0YXRlczpobH19KTtMYT1pbC5vdXRwdXQsZWw9aWwubmV3U3RhdGVzfUVhJiZGYS5wdXNoKExhKX1sZXQgcmw7cmV0dXJuIEVhJiYocmw9c3RhY2soRmEsMSkpLFtMYSxybCxlbF19KX1jbGFzcyBSTk4gZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpO2xldCB4YTtpZihhYS5jZWxsPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJjZWxsIHByb3BlcnR5IGlzIG1pc3NpbmcgZm9yIHRoZSBjb25zdHJ1Y3RvciBvZiBSTk4uIik7aWYoQXJyYXkuaXNBcnJheShhYS5jZWxsKT94YT1uZXcgU3RhY2tlZFJOTkNlbGxzKHtjZWxsczphYS5jZWxsfSk6eGE9YWEuY2VsbCx4YS5zdGF0ZVNpemU9PW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIlRoZSBSTk4gY2VsbCBzaG91bGQgaGF2ZSBhbiBhdHRyaWJ1dGUgYHN0YXRlU2l6ZWAgKHR1cGxlIG9mIGludGVnZXJzLCBvbmUgaW50ZWdlciBwZXIgUk5OIHN0YXRlKS4iKTt0aGlzLmNlbGw9eGEsdGhpcy5yZXR1cm5TZXF1ZW5jZXM9YWEucmV0dXJuU2VxdWVuY2VzPT1udWxsPyExOmFhLnJldHVyblNlcXVlbmNlcyx0aGlzLnJldHVyblN0YXRlPWFhLnJldHVyblN0YXRlPT1udWxsPyExOmFhLnJldHVyblN0YXRlLHRoaXMuZ29CYWNrd2FyZHM9YWEuZ29CYWNrd2FyZHM9PW51bGw/ITE6YWEuZ29CYWNrd2FyZHMsdGhpcy5fc3RhdGVmdWw9YWEuc3RhdGVmdWw9PW51bGw/ITE6YWEuc3RhdGVmdWwsdGhpcy51bnJvbGw9YWEudW5yb2xsPT1udWxsPyExOmFhLnVucm9sbCx0aGlzLnN1cHBvcnRzTWFza2luZz0hMCx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTozfSldLHRoaXMuc3RhdGVTcGVjPW51bGwsdGhpcy5zdGF0ZXNfPW51bGwsdGhpcy5udW1Db25zdGFudHM9bnVsbCx0aGlzLmtlcHRTdGF0ZXM9W119Z2V0U3RhdGVzKCl7aWYodGhpcy5zdGF0ZXNfPT1udWxsKXtjb25zdCBhYT1BcnJheS5pc0FycmF5KHRoaXMuY2VsbC5zdGF0ZVNpemUpP3RoaXMuY2VsbC5zdGF0ZVNpemUubGVuZ3RoOjE7cmV0dXJuIHJhbmdlJDMoMCxhYSkubWFwKHhhPT5udWxsKX1lbHNlIHJldHVybiB0aGlzLnN0YXRlc199c2V0U3RhdGVzKGFhKXt0aGlzLnN0YXRlc189YWF9Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXtpc0FycmF5T2ZTaGFwZXMoYWEpJiYoYWE9YWFbMF0pLGFhPWFhO2xldCB4YT10aGlzLmNlbGwuc3RhdGVTaXplO0FycmF5LmlzQXJyYXkoeGEpfHwoeGE9W3hhXSk7Y29uc3QgYmE9eGFbMF07bGV0IFNhO2lmKHRoaXMucmV0dXJuU2VxdWVuY2VzP1NhPVthYVswXSxhYVsxXSxiYV06U2E9W2FhWzBdLGJhXSx0aGlzLnJldHVyblN0YXRlKXtjb25zdCBUYT1bXTtmb3IoY29uc3Qgd2Egb2YgeGEpVGEucHVzaChbYWFbMF0sd2FdKTtyZXR1cm5bU2FdLmNvbmNhdChUYSl9ZWxzZSByZXR1cm4gU2F9Y29tcHV0ZU1hc2soYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PntBcnJheS5pc0FycmF5KHhhKSYmKHhhPXhhWzBdKTtjb25zdCBiYT10aGlzLnJldHVyblNlcXVlbmNlcz94YTpudWxsO2lmKHRoaXMucmV0dXJuU3RhdGUpe2NvbnN0IFNhPXRoaXMuc3RhdGVzLm1hcChUYT0+bnVsbCk7cmV0dXJuW2JhXS5jb25jYXQoU2EpfWVsc2UgcmV0dXJuIGJhfSl9Z2V0IHN0YXRlcygpe2lmKHRoaXMuc3RhdGVzXz09bnVsbCl7Y29uc3QgYWE9QXJyYXkuaXNBcnJheSh0aGlzLmNlbGwuc3RhdGVTaXplKT90aGlzLmNlbGwuc3RhdGVTaXplLmxlbmd0aDoxLHhhPVtdO2ZvcihsZXQgYmE9MDtiYTxhYTsrK2JhKXhhLnB1c2gobnVsbCk7cmV0dXJuIHhhfWVsc2UgcmV0dXJuIHRoaXMuc3RhdGVzX31zZXQgc3RhdGVzKGFhKXt0aGlzLnN0YXRlc189YWF9YnVpbGQoYWEpe2lmKHRoaXMubnVtQ29uc3RhbnRzIT1udWxsKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJDb25zdGFudHMgc3VwcG9ydCBpcyBub3QgaW1wbGVtZW50ZWQgaW4gUk5OIHlldC4iKTtpc0FycmF5T2ZTaGFwZXMoYWEpJiYoYWE9YWFbMF0pLGFhPWFhO2NvbnN0IHhhPXRoaXMuc3RhdGVmdWw/YWFbMF06bnVsbCxiYT1hYS5zbGljZSgyKTt0aGlzLmlucHV0U3BlY1swXT1uZXcgSW5wdXRTcGVjKHtzaGFwZTpbeGEsbnVsbCwuLi5iYV19KTtjb25zdCBTYT1bYWFbMF1dLmNvbmNhdChhYS5zbGljZSgyKSk7dGhpcy5jZWxsLmJ1aWxkKFNhKTtsZXQgVGE7aWYoQXJyYXkuaXNBcnJheSh0aGlzLmNlbGwuc3RhdGVTaXplKT9UYT10aGlzLmNlbGwuc3RhdGVTaXplOlRhPVt0aGlzLmNlbGwuc3RhdGVTaXplXSx0aGlzLnN0YXRlU3BlYyE9bnVsbCl7aWYoIWFycmF5c0VxdWFsJDEodGhpcy5zdGF0ZVNwZWMubWFwKHdhPT53YS5zaGFwZVt3YS5zaGFwZS5sZW5ndGgtMV0pLFRhKSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQW4gaW5pdGlhbFN0YXRlIHdhcyBwYXNzZWQgdGhhdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIGNlbGwuc3RhdGVTaXplLiBSZWNlaXZlZCBzdGF0ZVNwZWM9JHt0aGlzLnN0YXRlU3BlY307IEhvd2V2ZXIgY2VsbC5zdGF0ZVNpemUgaXMgJHt0aGlzLmNlbGwuc3RhdGVTaXplfWApfWVsc2UgdGhpcy5zdGF0ZVNwZWM9VGEubWFwKHdhPT5uZXcgSW5wdXRTcGVjKHtzaGFwZTpbbnVsbCx3YV19KSk7dGhpcy5zdGF0ZWZ1bCYmdGhpcy5yZXNldFN0YXRlcygpfXJlc2V0U3RhdGVzKGFhLHhhPSExKXt0aWR5JDEoKCk9PntpZighdGhpcy5zdGF0ZWZ1bCl0aHJvdyBuZXcgQXR0cmlidXRlRXJyb3IoIkNhbm5vdCBjYWxsIHJlc2V0U3RhdGVzKCkgb24gYW4gUk5OIExheWVyIHRoYXQgaXMgbm90IHN0YXRlZnVsLiIpO2NvbnN0IGJhPXRoaXMuaW5wdXRTcGVjWzBdLnNoYXBlWzBdO2lmKGJhPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKCJJZiBhbiBSTk4gaXMgc3RhdGVmdWwsIGl0IG5lZWRzIHRvIGtub3cgaXRzIGJhdGNoIHNpemUuIFNwZWNpZnkgdGhlIGJhdGNoIHNpemUgb2YgeW91ciBpbnB1dCB0ZW5zb3JzOiBcbi0gSWYgdXNpbmcgYSBTZXF1ZW50aWFsIG1vZGVsLCBzcGVjaWZ5IHRoZSBiYXRjaCBzaXplIGJ5IHBhc3NpbmcgYSBgYmF0Y2hJbnB1dFNoYXBlYCBvcHRpb24gdG8geW91ciBmaXJzdCBsYXllci5cbi0gSWYgdXNpbmcgdGhlIGZ1bmN0aW9uYWwgQVBJLCBzcGVjaWZ5IHRoZSBiYXRjaCBzaXplIGJ5IHBhc3NpbmcgYSBgYmF0Y2hTaGFwZWAgb3B0aW9uIHRvIHlvdXIgSW5wdXQgbGF5ZXIuIik7aWYodGhpcy5zdGF0ZXNfPT1udWxsKUFycmF5LmlzQXJyYXkodGhpcy5jZWxsLnN0YXRlU2l6ZSk/dGhpcy5zdGF0ZXNfPXRoaXMuY2VsbC5zdGF0ZVNpemUubWFwKFNhPT56ZXJvcyQyKFtiYSxTYV0pKTp0aGlzLnN0YXRlc189W3plcm9zJDIoW2JhLHRoaXMuY2VsbC5zdGF0ZVNpemVdKV07ZWxzZSBpZihhYT09bnVsbClkaXNwb3NlJDEodGhpcy5zdGF0ZXNfKSx0aGlzLmtlcHRTdGF0ZXMhPW51bGwmJihkaXNwb3NlJDEodGhpcy5rZXB0U3RhdGVzKSx0aGlzLmtlcHRTdGF0ZXM9W10pLEFycmF5LmlzQXJyYXkodGhpcy5jZWxsLnN0YXRlU2l6ZSk/dGhpcy5zdGF0ZXNfPXRoaXMuY2VsbC5zdGF0ZVNpemUubWFwKFNhPT56ZXJvcyQyKFtiYSxTYV0pKTp0aGlzLnN0YXRlc19bMF09emVyb3MkMihbYmEsdGhpcy5jZWxsLnN0YXRlU2l6ZV0pO2Vsc2V7aWYoQXJyYXkuaXNBcnJheShhYSl8fChhYT1bYWFdKSxhYS5sZW5ndGghPT10aGlzLnN0YXRlc18ubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBMYXllciAke3RoaXMubmFtZX0gZXhwZWN0cyAke3RoaXMuc3RhdGVzXy5sZW5ndGh9IHN0YXRlKHMpLCBidXQgaXQgcmVjZWl2ZWQgJHthYS5sZW5ndGh9IHN0YXRlIHZhbHVlKHMpLiBJbnB1dCByZWNlaXZlZDogJHthYX1gKTt4YT09PSEwP3RoaXMua2VwdFN0YXRlcy5wdXNoKHRoaXMuc3RhdGVzXy5zbGljZSgpKTpkaXNwb3NlJDEodGhpcy5zdGF0ZXNfKTtmb3IobGV0IFNhPTA7U2E8dGhpcy5zdGF0ZXNfLmxlbmd0aDsrK1NhKXtjb25zdCBUYT1hYVtTYV0sd2E9QXJyYXkuaXNBcnJheSh0aGlzLmNlbGwuc3RhdGVTaXplKT90aGlzLmNlbGwuc3RhdGVTaXplW1NhXTp0aGlzLmNlbGwuc3RhdGVTaXplLEVhPVtiYSx3YV07aWYoIWFycmF5c0VxdWFsJDEoVGEuc2hhcGUsRWEpKXRocm93IG5ldyBWYWx1ZUVycm9yKGBTdGF0ZSAke1NhfSBpcyBpbmNvbXBhdGlibGUgd2l0aCBsYXllciAke3RoaXMubmFtZX06IGV4cGVjdGVkIHNoYXBlPSR7RWF9LCByZWNlaXZlZCBzaGFwZT0ke1RhLnNoYXBlfWApO3RoaXMuc3RhdGVzX1tTYV09VGF9fXRoaXMuc3RhdGVzXz10aGlzLnN0YXRlc18ubWFwKFNhPT5rZWVwJDEoU2EuY2xvbmUoKSkpfSl9YXBwbHkoYWEseGEpe2xldCBiYT14YT09bnVsbD9udWxsOnhhLmluaXRpYWxTdGF0ZSxTYT14YT09bnVsbD9udWxsOnhhLmNvbnN0YW50czt4YT09bnVsbCYmKHhhPXt9KTtjb25zdCBUYT1zdGFuZGFyZGl6ZUFyZ3MoYWEsYmEsU2EsdGhpcy5udW1Db25zdGFudHMpO2FhPVRhLmlucHV0cyxiYT1UYS5pbml0aWFsU3RhdGUsU2E9VGEuY29uc3RhbnRzO2xldCB3YT1bXSxFYT1bXTtpZihiYSE9bnVsbCl7eGEuaW5pdGlhbFN0YXRlPWJhLHdhPXdhLmNvbmNhdChiYSksdGhpcy5zdGF0ZVNwZWM9W107Zm9yKGNvbnN0IEFhIG9mIGJhKXRoaXMuc3RhdGVTcGVjLnB1c2gobmV3IElucHV0U3BlYyh7c2hhcGU6QWEuc2hhcGV9KSk7RWE9RWEuY29uY2F0KHRoaXMuc3RhdGVTcGVjKX1pZihTYSE9bnVsbCYmKHhhLmNvbnN0YW50cz1TYSx3YT13YS5jb25jYXQoU2EpLHRoaXMubnVtQ29uc3RhbnRzPVNhLmxlbmd0aCksd2FbMF1pbnN0YW5jZW9mIFN5bWJvbGljVGVuc29yKXtjb25zdCBBYT1bYWFdLmNvbmNhdCh3YSksRmE9dGhpcy5pbnB1dFNwZWMuY29uY2F0KEVhKSxMYT10aGlzLmlucHV0U3BlYzt0aGlzLmlucHV0U3BlYz1GYTtjb25zdCBlbD1zdXBlci5hcHBseShBYSx4YSk7cmV0dXJuIHRoaXMuaW5wdXRTcGVjPUxhLGVsfWVsc2UgcmV0dXJuIHN1cGVyLmFwcGx5KGFhLHhhKX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgYmE9eGE9PW51bGw/bnVsbDp4YS5tYXNrLFNhPXhhPT1udWxsP251bGw6eGEudHJhaW5pbmc7bGV0IFRhPXhhPT1udWxsP251bGw6eGEuaW5pdGlhbFN0YXRlO2FhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLFRhPT1udWxsJiYodGhpcy5zdGF0ZWZ1bD9UYT10aGlzLnN0YXRlc186VGE9dGhpcy5nZXRJbml0aWFsU3RhdGUoYWEpKTtjb25zdCB3YT1BcnJheS5pc0FycmF5KHRoaXMuY2VsbC5zdGF0ZVNpemUpP3RoaXMuY2VsbC5zdGF0ZVNpemUubGVuZ3RoOjE7aWYoVGEubGVuZ3RoIT09d2EpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFJOTiBMYXllciBoYXMgJHt3YX0gc3RhdGUocykgYnV0IHdhcyBwYXNzZWQgJHtUYS5sZW5ndGh9IGluaXRpYWwgc3RhdGUocykuYCk7dGhpcy51bnJvbGwmJmNvbnNvbGUud2FybigiSWdub3JpbmcgdW5yb2xsID0gdHJ1ZSBmb3IgUk5OIGxheWVyLCBkdWUgdG8gaW1wZXJhdGl2ZSBiYWNrZW5kLiIpO2NvbnN0IEVhPXt0cmFpbmluZzpTYX0sQWE9cm5uKChubCxzbCk9Pntjb25zdCBybD10aGlzLmNlbGwuY2FsbChbbmxdLmNvbmNhdChzbCksRWEpO3JldHVybltybFswXSxybC5zbGljZSgxKV19LGFhLFRhLHRoaXMuZ29CYWNrd2FyZHMsYmEsbnVsbCx0aGlzLnVucm9sbCx0aGlzLnJldHVyblNlcXVlbmNlcyksRmE9QWFbMF0sTGE9QWFbMV0sZWw9QWFbMl07dGhpcy5zdGF0ZWZ1bCYmdGhpcy5yZXNldFN0YXRlcyhlbCxTYSk7Y29uc3QgdGw9dGhpcy5yZXR1cm5TZXF1ZW5jZXM/TGE6RmE7cmV0dXJuIHRoaXMucmV0dXJuU3RhdGU/W3RsXS5jb25jYXQoZWwpOnRsfSl9Z2V0SW5pdGlhbFN0YXRlKGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IHhhPXplcm9zJDIoYWEuc2hhcGUpO3JldHVybiB4YT1zdW0kNSh4YSxbMSwyXSkseGE9ZXhwYW5kRGltcyQzKHhhKSxBcnJheS5pc0FycmF5KHRoaXMuY2VsbC5zdGF0ZVNpemUpP3RoaXMuY2VsbC5zdGF0ZVNpemUubWFwKGJhPT5iYT4xP3RpbGUkMyh4YSxbMSxiYV0pOnhhKTp0aGlzLmNlbGwuc3RhdGVTaXplPjE/W3RpbGUkMyh4YSxbMSx0aGlzLmNlbGwuc3RhdGVTaXplXSldOlt4YV19KX1nZXQgdHJhaW5hYmxlV2VpZ2h0cygpe3JldHVybiB0aGlzLnRyYWluYWJsZT90aGlzLmNlbGwudHJhaW5hYmxlV2VpZ2h0czpbXX1nZXQgbm9uVHJhaW5hYmxlV2VpZ2h0cygpe3JldHVybiB0aGlzLnRyYWluYWJsZT90aGlzLmNlbGwubm9uVHJhaW5hYmxlV2VpZ2h0czp0aGlzLmNlbGwud2VpZ2h0c31zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKXtzdXBlci5zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKSx0aGlzLmNlbGwhPW51bGwmJnRoaXMuY2VsbC5zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKX1nZXRDb25maWcoKXtjb25zdCBhYT1zdXBlci5nZXRDb25maWcoKSx4YT17cmV0dXJuU2VxdWVuY2VzOnRoaXMucmV0dXJuU2VxdWVuY2VzLHJldHVyblN0YXRlOnRoaXMucmV0dXJuU3RhdGUsZ29CYWNrd2FyZHM6dGhpcy5nb0JhY2t3YXJkcyxzdGF0ZWZ1bDp0aGlzLnN0YXRlZnVsLHVucm9sbDp0aGlzLnVucm9sbH07dGhpcy5udW1Db25zdGFudHMhPW51bGwmJih4YS5udW1Db25zdGFudHM9dGhpcy5udW1Db25zdGFudHMpO2NvbnN0IGJhPXRoaXMuY2VsbC5nZXRDb25maWcoKTtyZXR1cm4gdGhpcy5nZXRDbGFzc05hbWUoKT09PVJOTi5jbGFzc05hbWUmJih4YS5jZWxsPXtjbGFzc05hbWU6dGhpcy5jZWxsLmdldENsYXNzTmFtZSgpLGNvbmZpZzpiYX0pLE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LGJhKSxhYSkseGEpfXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhLGJhPXt9KXtjb25zdCBTYT14YS5jZWxsLFRhPWRlc2VyaWFsaXplKFNhLGJhKTtyZXR1cm4gbmV3IGFhKE9iamVjdC5hc3NpZ24oeGEse2NlbGw6VGF9KSl9fVJOTi5jbGFzc05hbWU9IlJOTiIscmVnaXN0ZXJDbGFzcyQxKFJOTik7Y2xhc3MgUk5OQ2VsbCBleHRlbmRzIExheWVye31jbGFzcyBTaW1wbGVSTk5DZWxsIGV4dGVuZHMgUk5OQ2VsbHtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMuREVGQVVMVF9BQ1RJVkFUSU9OPSJ0YW5oIix0aGlzLkRFRkFVTFRfS0VSTkVMX0lOSVRJQUxJWkVSPSJnbG9yb3ROb3JtYWwiLHRoaXMuREVGQVVMVF9SRUNVUlJFTlRfSU5JVElBTElaRVI9Im9ydGhvZ29uYWwiLHRoaXMuREVGQVVMVF9CSUFTX0lOSVRJQUxJWkVSPSJ6ZXJvcyIsdGhpcy51bml0cz1hYS51bml0cyxhc3NlcnRQb3NpdGl2ZUludGVnZXIodGhpcy51bml0cywidW5pdHMiKSx0aGlzLmFjdGl2YXRpb249Z2V0QWN0aXZhdGlvbihhYS5hY3RpdmF0aW9uPT1udWxsP3RoaXMuREVGQVVMVF9BQ1RJVkFUSU9OOmFhLmFjdGl2YXRpb24pLHRoaXMudXNlQmlhcz1hYS51c2VCaWFzPT1udWxsPyEwOmFhLnVzZUJpYXMsdGhpcy5rZXJuZWxJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5rZXJuZWxJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX0tFUk5FTF9JTklUSUFMSVpFUiksdGhpcy5yZWN1cnJlbnRJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5yZWN1cnJlbnRJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX1JFQ1VSUkVOVF9JTklUSUFMSVpFUiksdGhpcy5iaWFzSW5pdGlhbGl6ZXI9Z2V0SW5pdGlhbGl6ZXIoYWEuYmlhc0luaXRpYWxpemVyfHx0aGlzLkRFRkFVTFRfQklBU19JTklUSUFMSVpFUiksdGhpcy5rZXJuZWxSZWd1bGFyaXplcj1nZXRSZWd1bGFyaXplcihhYS5rZXJuZWxSZWd1bGFyaXplciksdGhpcy5yZWN1cnJlbnRSZWd1bGFyaXplcj1nZXRSZWd1bGFyaXplcihhYS5yZWN1cnJlbnRSZWd1bGFyaXplciksdGhpcy5iaWFzUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEuYmlhc1JlZ3VsYXJpemVyKSx0aGlzLmtlcm5lbENvbnN0cmFpbnQ9Z2V0Q29uc3RyYWludChhYS5rZXJuZWxDb25zdHJhaW50KSx0aGlzLnJlY3VycmVudENvbnN0cmFpbnQ9Z2V0Q29uc3RyYWludChhYS5yZWN1cnJlbnRDb25zdHJhaW50KSx0aGlzLmJpYXNDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEuYmlhc0NvbnN0cmFpbnQpLHRoaXMuZHJvcG91dD1taW4kMyhbMSxtYXgkMyhbMCxhYS5kcm9wb3V0PT1udWxsPzA6YWEuZHJvcG91dF0pXSksdGhpcy5yZWN1cnJlbnREcm9wb3V0PW1pbiQzKFsxLG1heCQzKFswLGFhLnJlY3VycmVudERyb3BvdXQ9PW51bGw/MDphYS5yZWN1cnJlbnREcm9wb3V0XSldKSx0aGlzLmRyb3BvdXRGdW5jPWFhLmRyb3BvdXRGdW5jLHRoaXMuc3RhdGVTaXplPXRoaXMudW5pdHMsdGhpcy5kcm9wb3V0TWFzaz1udWxsLHRoaXMucmVjdXJyZW50RHJvcG91dE1hc2s9bnVsbH1idWlsZChhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKSx0aGlzLmtlcm5lbD10aGlzLmFkZFdlaWdodCgia2VybmVsIixbYWFbYWEubGVuZ3RoLTFdLHRoaXMudW5pdHNdLG51bGwsdGhpcy5rZXJuZWxJbml0aWFsaXplcix0aGlzLmtlcm5lbFJlZ3VsYXJpemVyLCEwLHRoaXMua2VybmVsQ29uc3RyYWludCksdGhpcy5yZWN1cnJlbnRLZXJuZWw9dGhpcy5hZGRXZWlnaHQoInJlY3VycmVudF9rZXJuZWwiLFt0aGlzLnVuaXRzLHRoaXMudW5pdHNdLG51bGwsdGhpcy5yZWN1cnJlbnRJbml0aWFsaXplcix0aGlzLnJlY3VycmVudFJlZ3VsYXJpemVyLCEwLHRoaXMucmVjdXJyZW50Q29uc3RyYWludCksdGhpcy51c2VCaWFzP3RoaXMuYmlhcz10aGlzLmFkZFdlaWdodCgiYmlhcyIsW3RoaXMudW5pdHNdLG51bGwsdGhpcy5iaWFzSW5pdGlhbGl6ZXIsdGhpcy5iaWFzUmVndWxhcml6ZXIsITAsdGhpcy5iaWFzQ29uc3RyYWludCk6dGhpcy5iaWFzPW51bGwsdGhpcy5idWlsdD0hMH1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57aWYoYWE9YWEsYWEubGVuZ3RoIT09Mil0aHJvdyBuZXcgVmFsdWVFcnJvcihgU2ltcGxlUk5OQ2VsbCBleHBlY3RzIDIgaW5wdXQgVGVuc29ycywgZ290ICR7YWEubGVuZ3RofS5gKTtsZXQgYmE9YWFbMV07YWE9YWFbMF07Y29uc3QgU2E9eGEudHJhaW5pbmc9PW51bGw/ITE6eGEudHJhaW5pbmc7MDx0aGlzLmRyb3BvdXQmJnRoaXMuZHJvcG91dDwxJiZ0aGlzLmRyb3BvdXRNYXNrPT1udWxsJiYodGhpcy5kcm9wb3V0TWFzaz1nZW5lcmF0ZURyb3BvdXRNYXNrKHtvbmVzOigpPT5vbmVzTGlrZSQzKGFhKSxyYXRlOnRoaXMuZHJvcG91dCx0cmFpbmluZzpTYSxkcm9wb3V0RnVuYzp0aGlzLmRyb3BvdXRGdW5jfSkpLDA8dGhpcy5yZWN1cnJlbnREcm9wb3V0JiZ0aGlzLnJlY3VycmVudERyb3BvdXQ8MSYmdGhpcy5yZWN1cnJlbnREcm9wb3V0TWFzaz09bnVsbCYmKHRoaXMucmVjdXJyZW50RHJvcG91dE1hc2s9Z2VuZXJhdGVEcm9wb3V0TWFzayh7b25lczooKT0+b25lc0xpa2UkMyhiYSkscmF0ZTp0aGlzLnJlY3VycmVudERyb3BvdXQsdHJhaW5pbmc6U2EsZHJvcG91dEZ1bmM6dGhpcy5kcm9wb3V0RnVuY30pKTtsZXQgVGE7Y29uc3Qgd2E9dGhpcy5kcm9wb3V0TWFzayxFYT10aGlzLnJlY3VycmVudERyb3BvdXRNYXNrO3dhIT1udWxsP1RhPWRvdChtdWwkMShhYSx3YSksdGhpcy5rZXJuZWwucmVhZCgpKTpUYT1kb3QoYWEsdGhpcy5rZXJuZWwucmVhZCgpKSx0aGlzLmJpYXMhPW51bGwmJihUYT1iaWFzQWRkKFRhLHRoaXMuYmlhcy5yZWFkKCkpKSxFYSE9bnVsbCYmKGJhPW11bCQxKGJhLEVhKSk7bGV0IGthPWFkZCQzKFRhLGRvdChiYSx0aGlzLnJlY3VycmVudEtlcm5lbC5yZWFkKCkpKTtyZXR1cm4gdGhpcy5hY3RpdmF0aW9uIT1udWxsJiYoa2E9dGhpcy5hY3RpdmF0aW9uLmFwcGx5KGthKSksW2thLGthXX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXN1cGVyLmdldENvbmZpZygpLHhhPXt1bml0czp0aGlzLnVuaXRzLGFjdGl2YXRpb246c2VyaWFsaXplQWN0aXZhdGlvbih0aGlzLmFjdGl2YXRpb24pLHVzZUJpYXM6dGhpcy51c2VCaWFzLGtlcm5lbEluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMua2VybmVsSW5pdGlhbGl6ZXIpLHJlY3VycmVudEluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMucmVjdXJyZW50SW5pdGlhbGl6ZXIpLGJpYXNJbml0aWFsaXplcjpzZXJpYWxpemVJbml0aWFsaXplcih0aGlzLmJpYXNJbml0aWFsaXplciksa2VybmVsUmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5rZXJuZWxSZWd1bGFyaXplcikscmVjdXJyZW50UmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5yZWN1cnJlbnRSZWd1bGFyaXplciksYmlhc1JlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuYmlhc1JlZ3VsYXJpemVyKSxhY3Rpdml0eVJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuYWN0aXZpdHlSZWd1bGFyaXplciksa2VybmVsQ29uc3RyYWludDpzZXJpYWxpemVDb25zdHJhaW50KHRoaXMua2VybmVsQ29uc3RyYWludCkscmVjdXJyZW50Q29uc3RyYWludDpzZXJpYWxpemVDb25zdHJhaW50KHRoaXMucmVjdXJyZW50Q29uc3RyYWludCksYmlhc0NvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmJpYXNDb25zdHJhaW50KSxkcm9wb3V0OnRoaXMuZHJvcG91dCxyZWN1cnJlbnREcm9wb3V0OnRoaXMucmVjdXJyZW50RHJvcG91dH07cmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxhYSkseGEpfX1TaW1wbGVSTk5DZWxsLmNsYXNzTmFtZT0iU2ltcGxlUk5OQ2VsbCIscmVnaXN0ZXJDbGFzcyQxKFNpbXBsZVJOTkNlbGwpO2NsYXNzIFNpbXBsZVJOTiBleHRlbmRzIFJOTntjb25zdHJ1Y3RvcihhYSl7YWEuY2VsbD1uZXcgU2ltcGxlUk5OQ2VsbChhYSksc3VwZXIoYWEpfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pnt0aGlzLmNlbGwuZHJvcG91dE1hc2shPW51bGwmJihkaXNwb3NlJDEodGhpcy5jZWxsLmRyb3BvdXRNYXNrKSx0aGlzLmNlbGwuZHJvcG91dE1hc2s9bnVsbCksdGhpcy5jZWxsLnJlY3VycmVudERyb3BvdXRNYXNrIT1udWxsJiYoZGlzcG9zZSQxKHRoaXMuY2VsbC5yZWN1cnJlbnREcm9wb3V0TWFzayksdGhpcy5jZWxsLnJlY3VycmVudERyb3BvdXRNYXNrPW51bGwpO2NvbnN0IGJhPXhhPT1udWxsP251bGw6eGEubWFzayxTYT14YT09bnVsbD9udWxsOnhhLnRyYWluaW5nLFRhPXhhPT1udWxsP251bGw6eGEuaW5pdGlhbFN0YXRlO3JldHVybiBzdXBlci5jYWxsKGFhLHttYXNrOmJhLHRyYWluaW5nOlNhLGluaXRpYWxTdGF0ZTpUYX0pfSl9c3RhdGljIGZyb21Db25maWcoYWEseGEpe3JldHVybiBuZXcgYWEoeGEpfX1TaW1wbGVSTk4uY2xhc3NOYW1lPSJTaW1wbGVSTk4iLHJlZ2lzdGVyQ2xhc3MkMShTaW1wbGVSTk4pO2NsYXNzIEdSVUNlbGwgZXh0ZW5kcyBSTk5DZWxse2NvbnN0cnVjdG9yKGFhKXtpZihzdXBlcihhYSksdGhpcy5ERUZBVUxUX0FDVElWQVRJT049InRhbmgiLHRoaXMuREVGQVVMVF9SRUNVUlJFTlRfQUNUSVZBVElPTj0iaGFyZFNpZ21vaWQiLHRoaXMuREVGQVVMVF9LRVJORUxfSU5JVElBTElaRVI9Imdsb3JvdE5vcm1hbCIsdGhpcy5ERUZBVUxUX1JFQ1VSUkVOVF9JTklUSUFMSVpFUj0ib3J0aG9nb25hbCIsdGhpcy5ERUZBVUxUX0JJQVNfSU5JVElBTElaRVI9Inplcm9zIixhYS5yZXNldEFmdGVyKXRocm93IG5ldyBWYWx1ZUVycm9yKCJHUlVDZWxsIGRvZXMgbm90IHN1cHBvcnQgcmVzZXRfYWZ0ZXIgcGFyYW1ldGVyIHNldCB0byB0cnVlLiIpO3RoaXMudW5pdHM9YWEudW5pdHMsYXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHRoaXMudW5pdHMsInVuaXRzIiksdGhpcy5hY3RpdmF0aW9uPWdldEFjdGl2YXRpb24oYWEuYWN0aXZhdGlvbj09PXZvaWQgMD90aGlzLkRFRkFVTFRfQUNUSVZBVElPTjphYS5hY3RpdmF0aW9uKSx0aGlzLnJlY3VycmVudEFjdGl2YXRpb249Z2V0QWN0aXZhdGlvbihhYS5yZWN1cnJlbnRBY3RpdmF0aW9uPT09dm9pZCAwP3RoaXMuREVGQVVMVF9SRUNVUlJFTlRfQUNUSVZBVElPTjphYS5yZWN1cnJlbnRBY3RpdmF0aW9uKSx0aGlzLnVzZUJpYXM9YWEudXNlQmlhcz09bnVsbD8hMDphYS51c2VCaWFzLHRoaXMua2VybmVsSW5pdGlhbGl6ZXI9Z2V0SW5pdGlhbGl6ZXIoYWEua2VybmVsSW5pdGlhbGl6ZXJ8fHRoaXMuREVGQVVMVF9LRVJORUxfSU5JVElBTElaRVIpLHRoaXMucmVjdXJyZW50SW5pdGlhbGl6ZXI9Z2V0SW5pdGlhbGl6ZXIoYWEucmVjdXJyZW50SW5pdGlhbGl6ZXJ8fHRoaXMuREVGQVVMVF9SRUNVUlJFTlRfSU5JVElBTElaRVIpLHRoaXMuYmlhc0luaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLmJpYXNJbml0aWFsaXplcnx8dGhpcy5ERUZBVUxUX0JJQVNfSU5JVElBTElaRVIpLHRoaXMua2VybmVsUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEua2VybmVsUmVndWxhcml6ZXIpLHRoaXMucmVjdXJyZW50UmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEucmVjdXJyZW50UmVndWxhcml6ZXIpLHRoaXMuYmlhc1JlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmJpYXNSZWd1bGFyaXplciksdGhpcy5rZXJuZWxDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEua2VybmVsQ29uc3RyYWludCksdGhpcy5yZWN1cnJlbnRDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEucmVjdXJyZW50Q29uc3RyYWludCksdGhpcy5iaWFzQ29uc3RyYWludD1nZXRDb25zdHJhaW50KGFhLmJpYXNDb25zdHJhaW50KSx0aGlzLmRyb3BvdXQ9bWluJDMoWzEsbWF4JDMoWzAsYWEuZHJvcG91dD09bnVsbD8wOmFhLmRyb3BvdXRdKV0pLHRoaXMucmVjdXJyZW50RHJvcG91dD1taW4kMyhbMSxtYXgkMyhbMCxhYS5yZWN1cnJlbnREcm9wb3V0PT1udWxsPzA6YWEucmVjdXJyZW50RHJvcG91dF0pXSksdGhpcy5kcm9wb3V0RnVuYz1hYS5kcm9wb3V0RnVuYyx0aGlzLmltcGxlbWVudGF0aW9uPWFhLmltcGxlbWVudGF0aW9uLHRoaXMuc3RhdGVTaXplPXRoaXMudW5pdHMsdGhpcy5kcm9wb3V0TWFzaz1udWxsLHRoaXMucmVjdXJyZW50RHJvcG91dE1hc2s9bnVsbH1idWlsZChhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKTtjb25zdCB4YT1hYVthYS5sZW5ndGgtMV07dGhpcy5rZXJuZWw9dGhpcy5hZGRXZWlnaHQoImtlcm5lbCIsW3hhLHRoaXMudW5pdHMqM10sbnVsbCx0aGlzLmtlcm5lbEluaXRpYWxpemVyLHRoaXMua2VybmVsUmVndWxhcml6ZXIsITAsdGhpcy5rZXJuZWxDb25zdHJhaW50KSx0aGlzLnJlY3VycmVudEtlcm5lbD10aGlzLmFkZFdlaWdodCgicmVjdXJyZW50X2tlcm5lbCIsW3RoaXMudW5pdHMsdGhpcy51bml0cyozXSxudWxsLHRoaXMucmVjdXJyZW50SW5pdGlhbGl6ZXIsdGhpcy5yZWN1cnJlbnRSZWd1bGFyaXplciwhMCx0aGlzLnJlY3VycmVudENvbnN0cmFpbnQpLHRoaXMudXNlQmlhcz90aGlzLmJpYXM9dGhpcy5hZGRXZWlnaHQoImJpYXMiLFt0aGlzLnVuaXRzKjNdLG51bGwsdGhpcy5iaWFzSW5pdGlhbGl6ZXIsdGhpcy5iaWFzUmVndWxhcml6ZXIsITAsdGhpcy5iaWFzQ29uc3RyYWludCk6dGhpcy5iaWFzPW51bGwsdGhpcy5idWlsdD0hMH1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57aWYoYWE9YWEsYWEubGVuZ3RoIT09Mil0aHJvdyBuZXcgVmFsdWVFcnJvcihgR1JVQ2VsbCBleHBlY3RzIDIgaW5wdXQgVGVuc29ycyAoaW5wdXRzLCBoLCBjKSwgZ290ICR7YWEubGVuZ3RofS5gKTtjb25zdCBiYT14YS50cmFpbmluZz09bnVsbD8hMTp4YS50cmFpbmluZztsZXQgU2E9YWFbMV07YWE9YWFbMF0sMDx0aGlzLmRyb3BvdXQmJnRoaXMuZHJvcG91dDwxJiZ0aGlzLmRyb3BvdXRNYXNrPT1udWxsJiYodGhpcy5kcm9wb3V0TWFzaz1nZW5lcmF0ZURyb3BvdXRNYXNrKHtvbmVzOigpPT5vbmVzTGlrZSQzKGFhKSxyYXRlOnRoaXMuZHJvcG91dCx0cmFpbmluZzpiYSxjb3VudDozLGRyb3BvdXRGdW5jOnRoaXMuZHJvcG91dEZ1bmN9KSksMDx0aGlzLnJlY3VycmVudERyb3BvdXQmJnRoaXMucmVjdXJyZW50RHJvcG91dDwxJiZ0aGlzLnJlY3VycmVudERyb3BvdXRNYXNrPT1udWxsJiYodGhpcy5yZWN1cnJlbnREcm9wb3V0TWFzaz1nZW5lcmF0ZURyb3BvdXRNYXNrKHtvbmVzOigpPT5vbmVzTGlrZSQzKFNhKSxyYXRlOnRoaXMucmVjdXJyZW50RHJvcG91dCx0cmFpbmluZzpiYSxjb3VudDozLGRyb3BvdXRGdW5jOnRoaXMuZHJvcG91dEZ1bmN9KSk7Y29uc3QgVGE9dGhpcy5kcm9wb3V0TWFzayx3YT10aGlzLnJlY3VycmVudERyb3BvdXRNYXNrO2xldCBFYSxrYSxBYTswPHRoaXMuZHJvcG91dCYmdGhpcy5kcm9wb3V0PDEmJihhYT1tdWwkMShhYSxUYVswXSkpO2xldCBGYT1kb3QoYWEsdGhpcy5rZXJuZWwucmVhZCgpKTt0aGlzLnVzZUJpYXMmJihGYT1iaWFzQWRkKEZhLHRoaXMuYmlhcy5yZWFkKCkpKSwwPHRoaXMucmVjdXJyZW50RHJvcG91dCYmdGhpcy5yZWN1cnJlbnREcm9wb3V0PDEmJihTYT1tdWwkMShTYSx3YVswXSkpO2NvbnN0IExhPXRoaXMucmVjdXJyZW50S2VybmVsLnJlYWQoKSxbZWwsdGxdPXNwbGl0JDMoTGEsWzIqdGhpcy51bml0cyx0aGlzLnVuaXRzXSxMYS5yYW5rLTEpLG5sPWRvdChTYSxlbCksW3NsLHJsLG9sXT1zcGxpdCQzKEZhLDMsRmEucmFuay0xKSxbYWwsbGxdPXNwbGl0JDMobmwsMixubC5yYW5rLTEpO0VhPXRoaXMucmVjdXJyZW50QWN0aXZhdGlvbi5hcHBseShhZGQkMyhzbCxhbCkpLGthPXRoaXMucmVjdXJyZW50QWN0aXZhdGlvbi5hcHBseShhZGQkMyhybCxsbCkpO2NvbnN0IGlsPWRvdChtdWwkMShrYSxTYSksdGwpO0FhPXRoaXMuYWN0aXZhdGlvbi5hcHBseShhZGQkMyhvbCxpbCkpO2NvbnN0IGNsPWFkZCQzKG11bCQxKEVhLFNhKSxtdWwkMShhZGQkMygxLG5lZyQzKEVhKSksQWEpKTtyZXR1cm5bY2wsY2xdfSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCkseGE9e3VuaXRzOnRoaXMudW5pdHMsYWN0aXZhdGlvbjpzZXJpYWxpemVBY3RpdmF0aW9uKHRoaXMuYWN0aXZhdGlvbikscmVjdXJyZW50QWN0aXZhdGlvbjpzZXJpYWxpemVBY3RpdmF0aW9uKHRoaXMucmVjdXJyZW50QWN0aXZhdGlvbiksdXNlQmlhczp0aGlzLnVzZUJpYXMsa2VybmVsSW5pdGlhbGl6ZXI6c2VyaWFsaXplSW5pdGlhbGl6ZXIodGhpcy5rZXJuZWxJbml0aWFsaXplcikscmVjdXJyZW50SW5pdGlhbGl6ZXI6c2VyaWFsaXplSW5pdGlhbGl6ZXIodGhpcy5yZWN1cnJlbnRJbml0aWFsaXplciksYmlhc0luaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuYmlhc0luaXRpYWxpemVyKSxrZXJuZWxSZWd1bGFyaXplcjpzZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLmtlcm5lbFJlZ3VsYXJpemVyKSxyZWN1cnJlbnRSZWd1bGFyaXplcjpzZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLnJlY3VycmVudFJlZ3VsYXJpemVyKSxiaWFzUmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5iaWFzUmVndWxhcml6ZXIpLGFjdGl2aXR5UmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5hY3Rpdml0eVJlZ3VsYXJpemVyKSxrZXJuZWxDb25zdHJhaW50OnNlcmlhbGl6ZUNvbnN0cmFpbnQodGhpcy5rZXJuZWxDb25zdHJhaW50KSxyZWN1cnJlbnRDb25zdHJhaW50OnNlcmlhbGl6ZUNvbnN0cmFpbnQodGhpcy5yZWN1cnJlbnRDb25zdHJhaW50KSxiaWFzQ29uc3RyYWludDpzZXJpYWxpemVDb25zdHJhaW50KHRoaXMuYmlhc0NvbnN0cmFpbnQpLGRyb3BvdXQ6dGhpcy5kcm9wb3V0LHJlY3VycmVudERyb3BvdXQ6dGhpcy5yZWN1cnJlbnREcm9wb3V0LGltcGxlbWVudGF0aW9uOnRoaXMuaW1wbGVtZW50YXRpb24scmVzZXRBZnRlcjohMX07cmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxhYSkseGEpfX1HUlVDZWxsLmNsYXNzTmFtZT0iR1JVQ2VsbCIscmVnaXN0ZXJDbGFzcyQxKEdSVUNlbGwpO2NsYXNzIEdSVSBleHRlbmRzIFJOTntjb25zdHJ1Y3RvcihhYSl7YWEuaW1wbGVtZW50YXRpb249PT0wJiZjb25zb2xlLndhcm4oImBpbXBsZW1lbnRhdGlvbj0wYCBoYXMgYmVlbiBkZXByZWNhdGVkLCBhbmQgbm93IGRlZmF1bHRzIHRvIGBpbXBsZW1lbnRhdGlvbj0xYC4gUGxlYXNlIHVwZGF0ZSB5b3VyIGxheWVyIGNhbGwuIiksYWEuY2VsbD1uZXcgR1JVQ2VsbChhYSksc3VwZXIoYWEpfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pnt0aGlzLmNlbGwuZHJvcG91dE1hc2shPW51bGwmJihkaXNwb3NlJDEodGhpcy5jZWxsLmRyb3BvdXRNYXNrKSx0aGlzLmNlbGwuZHJvcG91dE1hc2s9bnVsbCksdGhpcy5jZWxsLnJlY3VycmVudERyb3BvdXRNYXNrIT1udWxsJiYoZGlzcG9zZSQxKHRoaXMuY2VsbC5yZWN1cnJlbnREcm9wb3V0TWFzayksdGhpcy5jZWxsLnJlY3VycmVudERyb3BvdXRNYXNrPW51bGwpO2NvbnN0IGJhPXhhPT1udWxsP251bGw6eGEubWFzayxTYT14YT09bnVsbD9udWxsOnhhLnRyYWluaW5nLFRhPXhhPT1udWxsP251bGw6eGEuaW5pdGlhbFN0YXRlO3JldHVybiBzdXBlci5jYWxsKGFhLHttYXNrOmJhLHRyYWluaW5nOlNhLGluaXRpYWxTdGF0ZTpUYX0pfSl9c3RhdGljIGZyb21Db25maWcoYWEseGEpe3JldHVybiB4YS5pbXBsbWVudGF0aW9uPT09MCYmKHhhLmltcGxlbWVudGF0aW9uPTEpLG5ldyBhYSh4YSl9fUdSVS5jbGFzc05hbWU9IkdSVSIscmVnaXN0ZXJDbGFzcyQxKEdSVSk7Y2xhc3MgTFNUTUNlbGwgZXh0ZW5kcyBSTk5DZWxse2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5ERUZBVUxUX0FDVElWQVRJT049InRhbmgiLHRoaXMuREVGQVVMVF9SRUNVUlJFTlRfQUNUSVZBVElPTj0iaGFyZFNpZ21vaWQiLHRoaXMuREVGQVVMVF9LRVJORUxfSU5JVElBTElaRVI9Imdsb3JvdE5vcm1hbCIsdGhpcy5ERUZBVUxUX1JFQ1VSUkVOVF9JTklUSUFMSVpFUj0ib3J0aG9nb25hbCIsdGhpcy5ERUZBVUxUX0JJQVNfSU5JVElBTElaRVI9Inplcm9zIix0aGlzLnVuaXRzPWFhLnVuaXRzLGFzc2VydFBvc2l0aXZlSW50ZWdlcih0aGlzLnVuaXRzLCJ1bml0cyIpLHRoaXMuYWN0aXZhdGlvbj1nZXRBY3RpdmF0aW9uKGFhLmFjdGl2YXRpb249PT12b2lkIDA/dGhpcy5ERUZBVUxUX0FDVElWQVRJT046YWEuYWN0aXZhdGlvbiksdGhpcy5yZWN1cnJlbnRBY3RpdmF0aW9uPWdldEFjdGl2YXRpb24oYWEucmVjdXJyZW50QWN0aXZhdGlvbj09PXZvaWQgMD90aGlzLkRFRkFVTFRfUkVDVVJSRU5UX0FDVElWQVRJT046YWEucmVjdXJyZW50QWN0aXZhdGlvbiksdGhpcy51c2VCaWFzPWFhLnVzZUJpYXM9PW51bGw/ITA6YWEudXNlQmlhcyx0aGlzLmtlcm5lbEluaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLmtlcm5lbEluaXRpYWxpemVyfHx0aGlzLkRFRkFVTFRfS0VSTkVMX0lOSVRJQUxJWkVSKSx0aGlzLnJlY3VycmVudEluaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLnJlY3VycmVudEluaXRpYWxpemVyfHx0aGlzLkRFRkFVTFRfUkVDVVJSRU5UX0lOSVRJQUxJWkVSKSx0aGlzLmJpYXNJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5iaWFzSW5pdGlhbGl6ZXJ8fHRoaXMuREVGQVVMVF9CSUFTX0lOSVRJQUxJWkVSKSx0aGlzLnVuaXRGb3JnZXRCaWFzPWFhLnVuaXRGb3JnZXRCaWFzLHRoaXMua2VybmVsUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEua2VybmVsUmVndWxhcml6ZXIpLHRoaXMucmVjdXJyZW50UmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEucmVjdXJyZW50UmVndWxhcml6ZXIpLHRoaXMuYmlhc1JlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmJpYXNSZWd1bGFyaXplciksdGhpcy5rZXJuZWxDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEua2VybmVsQ29uc3RyYWludCksdGhpcy5yZWN1cnJlbnRDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEucmVjdXJyZW50Q29uc3RyYWludCksdGhpcy5iaWFzQ29uc3RyYWludD1nZXRDb25zdHJhaW50KGFhLmJpYXNDb25zdHJhaW50KSx0aGlzLmRyb3BvdXQ9bWluJDMoWzEsbWF4JDMoWzAsYWEuZHJvcG91dD09bnVsbD8wOmFhLmRyb3BvdXRdKV0pLHRoaXMucmVjdXJyZW50RHJvcG91dD1taW4kMyhbMSxtYXgkMyhbMCxhYS5yZWN1cnJlbnREcm9wb3V0PT1udWxsPzA6YWEucmVjdXJyZW50RHJvcG91dF0pXSksdGhpcy5kcm9wb3V0RnVuYz1hYS5kcm9wb3V0RnVuYyx0aGlzLmltcGxlbWVudGF0aW9uPWFhLmltcGxlbWVudGF0aW9uLHRoaXMuc3RhdGVTaXplPVt0aGlzLnVuaXRzLHRoaXMudW5pdHNdLHRoaXMuZHJvcG91dE1hc2s9bnVsbCx0aGlzLnJlY3VycmVudERyb3BvdXRNYXNrPW51bGx9YnVpbGQoYWEpe3ZhciB4YTthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IGJhPWFhW2FhLmxlbmd0aC0xXTt0aGlzLmtlcm5lbD10aGlzLmFkZFdlaWdodCgia2VybmVsIixbYmEsdGhpcy51bml0cyo0XSxudWxsLHRoaXMua2VybmVsSW5pdGlhbGl6ZXIsdGhpcy5rZXJuZWxSZWd1bGFyaXplciwhMCx0aGlzLmtlcm5lbENvbnN0cmFpbnQpLHRoaXMucmVjdXJyZW50S2VybmVsPXRoaXMuYWRkV2VpZ2h0KCJyZWN1cnJlbnRfa2VybmVsIixbdGhpcy51bml0cyx0aGlzLnVuaXRzKjRdLG51bGwsdGhpcy5yZWN1cnJlbnRJbml0aWFsaXplcix0aGlzLnJlY3VycmVudFJlZ3VsYXJpemVyLCEwLHRoaXMucmVjdXJyZW50Q29uc3RyYWludCk7bGV0IFNhO2lmKHRoaXMudXNlQmlhcyl7aWYodGhpcy51bml0Rm9yZ2V0Qmlhcyl7Y29uc3QgVGE9dGhpcy5iaWFzSW5pdGlhbGl6ZXIsd2E9dGhpcy51bml0cztTYT1uZXcoeGE9Y2xhc3MgZXh0ZW5kcyBJbml0aWFsaXplcnthcHBseShrYSxBYSl7Y29uc3QgRmE9VGEuYXBwbHkoW3dhXSksTGE9bmV3IE9uZXMoKS5hcHBseShbd2FdKSxlbD1UYS5hcHBseShbd2EqMl0pO3JldHVybiBjb25jYXRBbG9uZ0ZpcnN0QXhpcyhjb25jYXRBbG9uZ0ZpcnN0QXhpcyhGYSxMYSksZWwpfX0seGEuY2xhc3NOYW1lPSJDdXN0b21Jbml0Iix4YSl9ZWxzZSBTYT10aGlzLmJpYXNJbml0aWFsaXplcjt0aGlzLmJpYXM9dGhpcy5hZGRXZWlnaHQoImJpYXMiLFt0aGlzLnVuaXRzKjRdLG51bGwsU2EsdGhpcy5iaWFzUmVndWxhcml6ZXIsITAsdGhpcy5iaWFzQ29uc3RyYWludCl9ZWxzZSB0aGlzLmJpYXM9bnVsbDt0aGlzLmJ1aWx0PSEwfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT14YS50cmFpbmluZz09bnVsbD8hMTp4YS50cmFpbmluZztpZihhYT1hYSxhYS5sZW5ndGghPT0zKXRocm93IG5ldyBWYWx1ZUVycm9yKGBMU1RNQ2VsbCBleHBlY3RzIDMgaW5wdXQgVGVuc29ycyAoaW5wdXRzLCBoLCBjKSwgZ290ICR7YWEubGVuZ3RofS5gKTtsZXQgU2E9YWFbMV07Y29uc3QgVGE9YWFbMl07YWE9YWFbMF0sMDx0aGlzLmRyb3BvdXQmJnRoaXMuZHJvcG91dDwxJiZ0aGlzLmRyb3BvdXRNYXNrPT1udWxsJiYodGhpcy5kcm9wb3V0TWFzaz1nZW5lcmF0ZURyb3BvdXRNYXNrKHtvbmVzOigpPT5vbmVzTGlrZSQzKGFhKSxyYXRlOnRoaXMuZHJvcG91dCx0cmFpbmluZzpiYSxjb3VudDo0LGRyb3BvdXRGdW5jOnRoaXMuZHJvcG91dEZ1bmN9KSksMDx0aGlzLnJlY3VycmVudERyb3BvdXQmJnRoaXMucmVjdXJyZW50RHJvcG91dDwxJiZ0aGlzLnJlY3VycmVudERyb3BvdXRNYXNrPT1udWxsJiYodGhpcy5yZWN1cnJlbnREcm9wb3V0TWFzaz1nZW5lcmF0ZURyb3BvdXRNYXNrKHtvbmVzOigpPT5vbmVzTGlrZSQzKFNhKSxyYXRlOnRoaXMucmVjdXJyZW50RHJvcG91dCx0cmFpbmluZzpiYSxjb3VudDo0LGRyb3BvdXRGdW5jOnRoaXMuZHJvcG91dEZ1bmN9KSk7Y29uc3Qgd2E9dGhpcy5kcm9wb3V0TWFzayxFYT10aGlzLnJlY3VycmVudERyb3BvdXRNYXNrO2xldCBrYSxBYSxGYSxMYTswPHRoaXMuZHJvcG91dCYmdGhpcy5kcm9wb3V0PDEmJihhYT1tdWwkMShhYSx3YVswXSkpO2xldCBlbD1kb3QoYWEsdGhpcy5rZXJuZWwucmVhZCgpKTswPHRoaXMucmVjdXJyZW50RHJvcG91dCYmdGhpcy5yZWN1cnJlbnREcm9wb3V0PDEmJihTYT1tdWwkMShTYSxFYVswXSkpLGVsPWFkZCQzKGVsLGRvdChTYSx0aGlzLnJlY3VycmVudEtlcm5lbC5yZWFkKCkpKSx0aGlzLnVzZUJpYXMmJihlbD1iaWFzQWRkKGVsLHRoaXMuYmlhcy5yZWFkKCkpKTtjb25zdFt0bCxubCxzbCxybF09c3BsaXQkMyhlbCw0LGVsLnJhbmstMSk7a2E9dGhpcy5yZWN1cnJlbnRBY3RpdmF0aW9uLmFwcGx5KHRsKSxBYT10aGlzLnJlY3VycmVudEFjdGl2YXRpb24uYXBwbHkobmwpLEZhPWFkZCQzKG11bCQxKEFhLFRhKSxtdWwkMShrYSx0aGlzLmFjdGl2YXRpb24uYXBwbHkoc2wpKSksTGE9dGhpcy5yZWN1cnJlbnRBY3RpdmF0aW9uLmFwcGx5KHJsKTtjb25zdCBvbD1tdWwkMShMYSx0aGlzLmFjdGl2YXRpb24uYXBwbHkoRmEpKTtyZXR1cm5bb2wsb2wsRmFdfSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCkseGE9e3VuaXRzOnRoaXMudW5pdHMsYWN0aXZhdGlvbjpzZXJpYWxpemVBY3RpdmF0aW9uKHRoaXMuYWN0aXZhdGlvbikscmVjdXJyZW50QWN0aXZhdGlvbjpzZXJpYWxpemVBY3RpdmF0aW9uKHRoaXMucmVjdXJyZW50QWN0aXZhdGlvbiksdXNlQmlhczp0aGlzLnVzZUJpYXMsa2VybmVsSW5pdGlhbGl6ZXI6c2VyaWFsaXplSW5pdGlhbGl6ZXIodGhpcy5rZXJuZWxJbml0aWFsaXplcikscmVjdXJyZW50SW5pdGlhbGl6ZXI6c2VyaWFsaXplSW5pdGlhbGl6ZXIodGhpcy5yZWN1cnJlbnRJbml0aWFsaXplciksYmlhc0luaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuYmlhc0luaXRpYWxpemVyKSx1bml0Rm9yZ2V0Qmlhczp0aGlzLnVuaXRGb3JnZXRCaWFzLGtlcm5lbFJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMua2VybmVsUmVndWxhcml6ZXIpLHJlY3VycmVudFJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMucmVjdXJyZW50UmVndWxhcml6ZXIpLGJpYXNSZWd1bGFyaXplcjpzZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLmJpYXNSZWd1bGFyaXplciksYWN0aXZpdHlSZWd1bGFyaXplcjpzZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLmFjdGl2aXR5UmVndWxhcml6ZXIpLGtlcm5lbENvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmtlcm5lbENvbnN0cmFpbnQpLHJlY3VycmVudENvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLnJlY3VycmVudENvbnN0cmFpbnQpLGJpYXNDb25zdHJhaW50OnNlcmlhbGl6ZUNvbnN0cmFpbnQodGhpcy5iaWFzQ29uc3RyYWludCksZHJvcG91dDp0aGlzLmRyb3BvdXQscmVjdXJyZW50RHJvcG91dDp0aGlzLnJlY3VycmVudERyb3BvdXQsaW1wbGVtZW50YXRpb246dGhpcy5pbXBsZW1lbnRhdGlvbn07cmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxhYSkseGEpfX1MU1RNQ2VsbC5jbGFzc05hbWU9IkxTVE1DZWxsIixyZWdpc3RlckNsYXNzJDEoTFNUTUNlbGwpO2NsYXNzIExTVE0gZXh0ZW5kcyBSTk57Y29uc3RydWN0b3IoYWEpe2FhLmltcGxlbWVudGF0aW9uPT09MCYmY29uc29sZS53YXJuKCJgaW1wbGVtZW50YXRpb249MGAgaGFzIGJlZW4gZGVwcmVjYXRlZCwgYW5kIG5vdyBkZWZhdWx0cyB0byBgaW1wbGVtZW50YXRpb249MWAuIFBsZWFzZSB1cGRhdGUgeW91ciBsYXllciBjYWxsLiIpLGFhLmNlbGw9bmV3IExTVE1DZWxsKGFhKSxzdXBlcihhYSl9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e3RoaXMuY2VsbC5kcm9wb3V0TWFzayE9bnVsbCYmKGRpc3Bvc2UkMSh0aGlzLmNlbGwuZHJvcG91dE1hc2spLHRoaXMuY2VsbC5kcm9wb3V0TWFzaz1udWxsKSx0aGlzLmNlbGwucmVjdXJyZW50RHJvcG91dE1hc2shPW51bGwmJihkaXNwb3NlJDEodGhpcy5jZWxsLnJlY3VycmVudERyb3BvdXRNYXNrKSx0aGlzLmNlbGwucmVjdXJyZW50RHJvcG91dE1hc2s9bnVsbCk7Y29uc3QgYmE9eGE9PW51bGw/bnVsbDp4YS5tYXNrLFNhPXhhPT1udWxsP251bGw6eGEudHJhaW5pbmcsVGE9eGE9PW51bGw/bnVsbDp4YS5pbml0aWFsU3RhdGU7cmV0dXJuIHN1cGVyLmNhbGwoYWEse21hc2s6YmEsdHJhaW5pbmc6U2EsaW5pdGlhbFN0YXRlOlRhfSl9KX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIHhhLmltcGxtZW50YXRpb249PT0wJiYoeGEuaW1wbGVtZW50YXRpb249MSksbmV3IGFhKHhhKX19TFNUTS5jbGFzc05hbWU9IkxTVE0iLHJlZ2lzdGVyQ2xhc3MkMShMU1RNKTtjbGFzcyBTdGFja2VkUk5OQ2VsbHMgZXh0ZW5kcyBSTk5DZWxse2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5jZWxscz1hYS5jZWxsc31nZXQgc3RhdGVTaXplKCl7Y29uc3QgYWE9W107Zm9yKGNvbnN0IHhhIG9mIHRoaXMuY2VsbHMuc2xpY2UoKS5yZXZlcnNlKCkpQXJyYXkuaXNBcnJheSh4YS5zdGF0ZVNpemUpP2FhLnB1c2goLi4ueGEuc3RhdGVTaXplKTphYS5wdXNoKHhhLnN0YXRlU2l6ZSk7cmV0dXJuIGFhfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PnthYT1hYTtsZXQgYmE9YWEuc2xpY2UoMSk7Y29uc3QgU2E9W107Zm9yKGNvbnN0IEVhIG9mIHRoaXMuY2VsbHMuc2xpY2UoKS5yZXZlcnNlKCkpQXJyYXkuaXNBcnJheShFYS5zdGF0ZVNpemUpP1NhLnB1c2goYmEuc3BsaWNlKDAsRWEuc3RhdGVTaXplLmxlbmd0aCkpOlNhLnB1c2goYmEuc3BsaWNlKDAsMSkpO1NhLnJldmVyc2UoKTtjb25zdCBUYT1bXTtsZXQgd2E7Zm9yKGxldCBFYT0wO0VhPHRoaXMuY2VsbHMubGVuZ3RoOysrRWEpe2NvbnN0IGthPXRoaXMuY2VsbHNbRWFdO2JhPVNhW0VhXSxFYT09PTA/d2E9W2FhWzBdXS5jb25jYXQoYmEpOndhPVt3YVswXV0uY29uY2F0KGJhKSx3YT1rYS5jYWxsKHdhLHhhKSxUYS5wdXNoKHdhLnNsaWNlKDEpKX1iYT1bXTtmb3IoY29uc3QgRWEgb2YgVGEuc2xpY2UoKS5yZXZlcnNlKCkpYmEucHVzaCguLi5FYSk7cmV0dXJuW3dhWzBdXS5jb25jYXQoYmEpfSl9YnVpbGQoYWEpe2lzQXJyYXlPZlNoYXBlcyhhYSkmJihhYT1hYVswXSksYWE9YWE7bGV0IHhhO3RoaXMuY2VsbHMuZm9yRWFjaCgoYmEsU2EpPT57bmFtZVNjb3BlKGBSTk5DZWxsXyR7U2F9YCwoKT0+e2JhLmJ1aWxkKGFhKSxBcnJheS5pc0FycmF5KGJhLnN0YXRlU2l6ZSk/eGE9YmEuc3RhdGVTaXplWzBdOnhhPWJhLnN0YXRlU2l6ZSxhYT1bYWFbMF0seGFdfSl9KSx0aGlzLmJ1aWx0PSEwfWdldENvbmZpZygpe2NvbnN0IGFhPXN1cGVyLmdldENvbmZpZygpLHhhPVRhPT4oe2NsYXNzTmFtZTpUYS5nZXRDbGFzc05hbWUoKSxjb25maWc6VGEuZ2V0Q29uZmlnKCl9KSxTYT17Y2VsbHM6dGhpcy5jZWxscy5tYXAoeGEpfTtyZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LGFhKSxTYSl9c3RhdGljIGZyb21Db25maWcoYWEseGEsYmE9e30pe2NvbnN0IFNhPVtdO2Zvcihjb25zdCBUYSBvZiB4YS5jZWxscylTYS5wdXNoKGRlc2VyaWFsaXplKFRhLGJhKSk7cmV0dXJuIG5ldyBhYSh7Y2VsbHM6U2F9KX1nZXQgdHJhaW5hYmxlV2VpZ2h0cygpe2lmKCF0aGlzLnRyYWluYWJsZSlyZXR1cm5bXTtjb25zdCBhYT1bXTtmb3IoY29uc3QgeGEgb2YgdGhpcy5jZWxscylhYS5wdXNoKC4uLnhhLnRyYWluYWJsZVdlaWdodHMpO3JldHVybiBhYX1nZXQgbm9uVHJhaW5hYmxlV2VpZ2h0cygpe2NvbnN0IGFhPVtdO2Zvcihjb25zdCB4YSBvZiB0aGlzLmNlbGxzKWFhLnB1c2goLi4ueGEubm9uVHJhaW5hYmxlV2VpZ2h0cyk7aWYoIXRoaXMudHJhaW5hYmxlKXtjb25zdCB4YT1bXTtmb3IoY29uc3QgYmEgb2YgdGhpcy5jZWxscyl4YS5wdXNoKC4uLmJhLnRyYWluYWJsZVdlaWdodHMpO3JldHVybiB4YS5jb25jYXQoYWEpfXJldHVybiBhYX1nZXRXZWlnaHRzKCl7Y29uc3QgYWE9W107Zm9yKGNvbnN0IHhhIG9mIHRoaXMuY2VsbHMpYWEucHVzaCguLi54YS53ZWlnaHRzKTtyZXR1cm4gYmF0Y2hHZXRWYWx1ZShhYSl9c2V0V2VpZ2h0cyhhYSl7Y29uc3QgeGE9W107Zm9yKGNvbnN0IGJhIG9mIHRoaXMuY2VsbHMpe2NvbnN0IFNhPWJhLndlaWdodHMubGVuZ3RoLFRhPWFhLnNwbGljZShTYSk7Zm9yKGxldCB3YT0wO3dhPGJhLndlaWdodHMubGVuZ3RoOysrd2EpeGEucHVzaChbYmEud2VpZ2h0c1t3YV0sVGFbd2FdXSl9YmF0Y2hTZXRWYWx1ZSh4YSl9fVN0YWNrZWRSTk5DZWxscy5jbGFzc05hbWU9IlN0YWNrZWRSTk5DZWxscyIscmVnaXN0ZXJDbGFzcyQxKFN0YWNrZWRSTk5DZWxscyk7ZnVuY3Rpb24gZ2VuZXJhdGVEcm9wb3V0TWFzayhoYSl7Y29uc3R7b25lczphYSxyYXRlOnhhLHRyYWluaW5nOmJhPSExLGNvdW50OlNhPTEsZHJvcG91dEZ1bmM6VGF9PWhhLHdhPSgpPT5UYSE9bnVsbD9UYShhYSgpLHhhKTpkcm9wb3V0KGFhKCkseGEpLEVhPSgpPT5pblRyYWluUGhhc2Uod2EsYWEsYmEpO3JldHVybiFTYXx8U2E8PTE/a2VlcCQxKEVhKCkuY2xvbmUoKSk6QXJyYXkoU2EpLmZpbGwodm9pZCAwKS5tYXAoRWEpLm1hcChBYT0+a2VlcCQxKEFhLmNsb25lKCkpKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi92YXIgX19yZXN0PWZ1bmN0aW9uKGhhLGFhKXt2YXIgeGE9e307Zm9yKHZhciBiYSBpbiBoYSlPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaGEsYmEpJiZhYS5pbmRleE9mKGJhKTwwJiYoeGFbYmFdPWhhW2JhXSk7aWYoaGEhPW51bGwmJnR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzPT0iZnVuY3Rpb24iKWZvcih2YXIgU2E9MCxiYT1PYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKGhhKTtTYTxiYS5sZW5ndGg7U2ErKylhYS5pbmRleE9mKGJhW1NhXSk8MCYmT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGhhLGJhW1NhXSkmJih4YVtiYVtTYV1dPWhhW2JhW1NhXV0pO3JldHVybiB4YX07Y2xhc3MgQ29udlJOTjJEIGV4dGVuZHMgUk5Oe2NvbnN0cnVjdG9yKGFhKXtpZihhYS51bnJvbGwpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoIlVucm9sbGluZyBpcyBub3QgcG9zc2libGUgd2l0aCBjb252b2x1dGlvbmFsIFJOTnMuIik7aWYoQXJyYXkuaXNBcnJheShhYS5jZWxsKSl0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiSXQgaXMgbm90IHBvc3NpYmxlIGF0IHRoZSBtb21lbnQgdG8gc3RhY2sgY29udm9sdXRpb25hbCBjZWxscy4iKTtzdXBlcihhYSksdGhpcy5pbnB1dFNwZWM9W25ldyBJbnB1dFNwZWMoe25kaW06NX0pXX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57aWYodGhpcy5jZWxsLmRyb3BvdXRNYXNrIT1udWxsJiYoZGlzcG9zZSQxKHRoaXMuY2VsbC5kcm9wb3V0TWFzayksdGhpcy5jZWxsLmRyb3BvdXRNYXNrPW51bGwpLHRoaXMuY2VsbC5yZWN1cnJlbnREcm9wb3V0TWFzayE9bnVsbCYmKGRpc3Bvc2UkMSh0aGlzLmNlbGwucmVjdXJyZW50RHJvcG91dE1hc2spLHRoaXMuY2VsbC5yZWN1cnJlbnREcm9wb3V0TWFzaz1udWxsKSx4YSYmeGEuY29uc3RhbnRzKXRocm93IG5ldyBWYWx1ZUVycm9yKCJDb252Uk5OMkQgY2VsbCBkb2VzIG5vdCBzdXBwb3J0IGNvbnN0YW50cyIpO2NvbnN0IGJhPXhhPT1udWxsP251bGw6eGEubWFzayxTYT14YT09bnVsbD9udWxsOnhhLnRyYWluaW5nLFRhPXhhPT1udWxsP251bGw6eGEuaW5pdGlhbFN0YXRlO3JldHVybiBzdXBlci5jYWxsKGFhLHttYXNrOmJhLHRyYWluaW5nOlNhLGluaXRpYWxTdGF0ZTpUYX0pfSl9Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXtsZXQgeGE9dGhpcy5jb21wdXRlU2luZ2xlT3V0cHV0U2hhcGUoYWEpO3JldHVybiB0aGlzLnJldHVyblNlcXVlbmNlc3x8KHhhPVt4YVswXSwuLi54YS5zbGljZSgyKV0pLHRoaXMucmV0dXJuU3RhdGUmJih4YT1beGEsLi4uQXJyYXkoMikuZmlsbChbYWFbMF0sLi4ueGEuc2xpY2UoLTMpXSldKSx4YX1nZXRJbml0aWFsU3RhdGUoYWEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdHtzdGF0ZVNpemU6eGF9PXRoaXMuY2VsbCxiYT1hYS5zaGFwZSxTYT10aGlzLmNvbXB1dGVTaW5nbGVPdXRwdXRTaGFwZShiYSksVGE9W1NhWzBdLC4uLlNhLnNsaWNlKDIpXSx3YT16ZXJvcyQyKFRhKTtyZXR1cm4gQXJyYXkuaXNBcnJheSh4YSk/QXJyYXkoeGEubGVuZ3RoKS5maWxsKHdhKTpbd2FdfSl9cmVzZXRTdGF0ZXMoYWEseGE9ITEpe3RpZHkkMSgoKT0+e2lmKCF0aGlzLnN0YXRlZnVsKXRocm93IG5ldyBBdHRyaWJ1dGVFcnJvcigiQ2Fubm90IGNhbGwgcmVzZXRTdGF0ZXMoKSBvbiBhbiBSTk4gTGF5ZXIgdGhhdCBpcyBub3Qgc3RhdGVmdWwuIik7Y29uc3QgYmE9dGhpcy5pbnB1dFNwZWNbMF0uc2hhcGUsU2E9dGhpcy5jb21wdXRlU2luZ2xlT3V0cHV0U2hhcGUoYmEpLFRhPVtTYVswXSwuLi5TYS5zbGljZSgyKV07aWYoYmFbMF09PW51bGwpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIklmIGFuIFJOTiBpcyBzdGF0ZWZ1bCwgaXQgbmVlZHMgdG8ga25vdyBpdHMgYmF0Y2ggc2l6ZS4gU3BlY2lmeSB0aGUgYmF0Y2ggc2l6ZSBvZiB5b3VyIGlucHV0IHRlbnNvcnM6IFxuLSBJZiB1c2luZyBhIFNlcXVlbnRpYWwgbW9kZWwsIHNwZWNpZnkgdGhlIGJhdGNoIHNpemUgYnkgcGFzc2luZyBhIGBiYXRjaElucHV0U2hhcGVgIG9wdGlvbiB0byB5b3VyIGZpcnN0IGxheWVyLlxuLSBJZiB1c2luZyB0aGUgZnVuY3Rpb25hbCBBUEksIHNwZWNpZnkgdGhlIGJhdGNoIHNpemUgYnkgcGFzc2luZyBhIGBiYXRjaFNoYXBlYCBvcHRpb24gdG8geW91ciBJbnB1dCBsYXllci4iKTtpZih0aGlzLmdldFN0YXRlcygpPT1udWxsKUFycmF5LmlzQXJyYXkodGhpcy5jZWxsLnN0YXRlU2l6ZSk/dGhpcy5zdGF0ZXNfPXRoaXMuY2VsbC5zdGF0ZVNpemUubWFwKCgpPT56ZXJvcyQyKFRhKSk6dGhpcy5zdGF0ZXNfPVt6ZXJvcyQyKFRhKV07ZWxzZSBpZihhYT09bnVsbClkaXNwb3NlJDEodGhpcy5zdGF0ZXNfKSx0aGlzLmtlcHRTdGF0ZXMhPW51bGwmJihkaXNwb3NlJDEodGhpcy5rZXB0U3RhdGVzKSx0aGlzLmtlcHRTdGF0ZXM9W10pLEFycmF5LmlzQXJyYXkodGhpcy5jZWxsLnN0YXRlU2l6ZSk/dGhpcy5zdGF0ZXNfPXRoaXMuY2VsbC5zdGF0ZVNpemUubWFwKCgpPT56ZXJvcyQyKFRhKSk6dGhpcy5zdGF0ZXNfWzBdPXplcm9zJDIoVGEpO2Vsc2V7aWYoQXJyYXkuaXNBcnJheShhYSl8fChhYT1bYWFdKSxhYS5sZW5ndGghPT10aGlzLnN0YXRlc18ubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBMYXllciAke3RoaXMubmFtZX0gZXhwZWN0cyAke3RoaXMuc3RhdGVzXy5sZW5ndGh9IHN0YXRlKHMpLCBidXQgaXQgcmVjZWl2ZWQgJHthYS5sZW5ndGh9IHN0YXRlIHZhbHVlKHMpLiBJbnB1dCByZWNlaXZlZDogJHthYX1gKTt4YT90aGlzLmtlcHRTdGF0ZXMucHVzaCh0aGlzLnN0YXRlc18uc2xpY2UoKSk6ZGlzcG9zZSQxKHRoaXMuc3RhdGVzXyk7Zm9yKGxldCBFYT0wO0VhPHRoaXMuc3RhdGVzXy5sZW5ndGg7KytFYSl7Y29uc3Qga2E9YWFbRWFdLEFhPVRhO2lmKCFhcnJheXNFcXVhbCQxKGthLnNoYXBlLEFhKSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgU3RhdGUgJHtFYX0gaXMgaW5jb21wYXRpYmxlIHdpdGggbGF5ZXIgJHt0aGlzLm5hbWV9OiBleHBlY3RlZCBzaGFwZT0ke0FhfSwgcmVjZWl2ZWQgc2hhcGU9JHtrYS5zaGFwZX1gKTt0aGlzLnN0YXRlc19bRWFdPWthfX10aGlzLnN0YXRlc189dGhpcy5zdGF0ZXNfLm1hcChFYT0+a2VlcCQxKEVhLmNsb25lKCkpKX0pfWNvbXB1dGVTaW5nbGVPdXRwdXRTaGFwZShhYSl7Y29uc3R7ZGF0YUZvcm1hdDp4YSxmaWx0ZXJzOmJhLGtlcm5lbFNpemU6U2EscGFkZGluZzpUYSxzdHJpZGVzOndhLGRpbGF0aW9uUmF0ZTpFYX09dGhpcy5jZWxsLGthPXhhPT09ImNoYW5uZWxzRmlyc3QiLEFhPWFhW2thPzM6Ml0sRmE9YWFba2E/NDozXSxMYT1jb252T3V0cHV0TGVuZ3RoKEFhLFNhWzBdLFRhLHdhWzBdLEVhWzBdKSxlbD1jb252T3V0cHV0TGVuZ3RoKEZhLFNhWzFdLFRhLHdhWzFdLEVhWzFdKTtyZXR1cm5bLi4uYWEuc2xpY2UoMCwyKSwuLi5rYT9bYmEsTGEsZWxdOltMYSxlbCxiYV1dfX1Db252Uk5OMkQuY2xhc3NOYW1lPSJDb252Uk5OMkQiO2NsYXNzIENvbnZMU1RNMkRDZWxsIGV4dGVuZHMgTFNUTUNlbGx7Y29uc3RydWN0b3IoYWEpe2NvbnN0e2ZpbHRlcnM6eGEsa2VybmVsU2l6ZTpiYSxzdHJpZGVzOlNhLHBhZGRpbmc6VGEsZGF0YUZvcm1hdDp3YSxkaWxhdGlvblJhdGU6RWF9PWFhO3N1cGVyKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxhYSkse3VuaXRzOnhhfSkpLHRoaXMuZmlsdGVycz14YSxhc3NlcnRQb3NpdGl2ZUludGVnZXIodGhpcy5maWx0ZXJzLCJmaWx0ZXJzIiksdGhpcy5rZXJuZWxTaXplPW5vcm1hbGl6ZUFycmF5KGJhLDIsImtlcm5lbFNpemUiKSx0aGlzLmtlcm5lbFNpemUuZm9yRWFjaChrYT0+YXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKGthLCJrZXJuZWxTaXplIikpLHRoaXMuc3RyaWRlcz1ub3JtYWxpemVBcnJheShTYXx8MSwyLCJzdHJpZGVzIiksdGhpcy5zdHJpZGVzLmZvckVhY2goa2E9PmFzc2VydFBvc2l0aXZlSW50ZWdlcihrYSwic3RyaWRlcyIpKSx0aGlzLnBhZGRpbmc9VGF8fCJ2YWxpZCIsY2hlY2tQYWRkaW5nTW9kZSh0aGlzLnBhZGRpbmcpLHRoaXMuZGF0YUZvcm1hdD13YXx8ImNoYW5uZWxzTGFzdCIsY2hlY2tEYXRhRm9ybWF0KHRoaXMuZGF0YUZvcm1hdCksdGhpcy5kaWxhdGlvblJhdGU9bm9ybWFsaXplQXJyYXkoRWF8fDEsMiwiZGlsYXRpb25SYXRlIiksdGhpcy5kaWxhdGlvblJhdGUuZm9yRWFjaChrYT0+YXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKGthLCJkaWxhdGlvblJhdGUiKSl9YnVpbGQoYWEpe3ZhciB4YTthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IGJhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij8xOmFhLmxlbmd0aC0xO2lmKGFhW2JhXT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgVGhlIGNoYW5uZWwgZGltZW5zaW9uIG9mIHRoZSBpbnB1dCBzaG91bGQgYmUgZGVmaW5lZC4gRm91bmQgJHthYVtiYV19YCk7Y29uc3QgU2E9YWFbYmFdLFRhPTQsd2E9dGhpcy5rZXJuZWxTaXplLmNvbmNhdChbU2EsdGhpcy5maWx0ZXJzKlRhXSk7dGhpcy5rZXJuZWw9dGhpcy5hZGRXZWlnaHQoImtlcm5lbCIsd2EsbnVsbCx0aGlzLmtlcm5lbEluaXRpYWxpemVyLHRoaXMua2VybmVsUmVndWxhcml6ZXIsITAsdGhpcy5rZXJuZWxDb25zdHJhaW50KTtjb25zdCBFYT10aGlzLmtlcm5lbFNpemUuY29uY2F0KFt0aGlzLmZpbHRlcnMsdGhpcy5maWx0ZXJzKlRhXSk7aWYodGhpcy5yZWN1cnJlbnRLZXJuZWw9dGhpcy5hZGRXZWlnaHQoInJlY3VycmVudF9rZXJuZWwiLEVhLG51bGwsdGhpcy5yZWN1cnJlbnRJbml0aWFsaXplcix0aGlzLnJlY3VycmVudFJlZ3VsYXJpemVyLCEwLHRoaXMucmVjdXJyZW50Q29uc3RyYWludCksdGhpcy51c2VCaWFzKXtsZXQga2E7aWYodGhpcy51bml0Rm9yZ2V0Qmlhcyl7Y29uc3QgQWE9dGhpcy5iaWFzSW5pdGlhbGl6ZXIsRmE9dGhpcy5maWx0ZXJzO2thPW5ldyh4YT1jbGFzcyBleHRlbmRzIEluaXRpYWxpemVye2FwcGx5KGVsLHRsKXtjb25zdCBubD1BYS5hcHBseShbRmFdKSxzbD1vbmVzJDEoW0ZhXSkscmw9QWEuYXBwbHkoW0ZhKjJdKTtyZXR1cm4gY29uY2F0ZW5hdGUoW25sLHNsLHJsXSl9fSx4YS5jbGFzc05hbWU9IkN1c3RvbUluaXQiLHhhKX1lbHNlIGthPXRoaXMuYmlhc0luaXRpYWxpemVyO3RoaXMuYmlhcz10aGlzLmFkZFdlaWdodCgiYmlhcyIsW3RoaXMuZmlsdGVycypUYV0sbnVsbCxrYSx0aGlzLmJpYXNSZWd1bGFyaXplciwhMCx0aGlzLmJpYXNDb25zdHJhaW50KX10aGlzLmJ1aWx0PSEwfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PntpZihhYS5sZW5ndGghPT0zKXRocm93IG5ldyBWYWx1ZUVycm9yKGBDb252TFNUTTJEQ2VsbCBleHBlY3RzIDMgaW5wdXQgVGVuc29ycyAoaW5wdXRzLCBoLCBjKSwgZ290ICR7YWEubGVuZ3RofS5gKTtjb25zdCBiYT14YS50cmFpbmluZ3x8ITEsU2E9YWFbMF0sVGE9YWFbMV0sd2E9YWFbMl0sRWE9NDswPHRoaXMuZHJvcG91dCYmdGhpcy5kcm9wb3V0PDEmJnRoaXMuZHJvcG91dE1hc2s9PW51bGwmJih0aGlzLmRyb3BvdXRNYXNrPWdlbmVyYXRlRHJvcG91dE1hc2soe29uZXM6KCk9Pm9uZXNMaWtlJDMoU2EpLHJhdGU6dGhpcy5kcm9wb3V0LHRyYWluaW5nOmJhLGNvdW50OkVhLGRyb3BvdXRGdW5jOnRoaXMuZHJvcG91dEZ1bmN9KSk7Y29uc3Qga2E9dGhpcy5kcm9wb3V0TWFzayxBYT0od2wsSWwsTmwpPT4hSWx8fCFJbFtObF0/d2w6bXVsJDEoSWxbTmxdLHdsKTtsZXQgRmE9QWEoU2Esa2EsMCksTGE9QWEoU2Esa2EsMSksZWw9QWEoU2Esa2EsMiksdGw9QWEoU2Esa2EsMyk7MDx0aGlzLnJlY3VycmVudERyb3BvdXQmJnRoaXMucmVjdXJyZW50RHJvcG91dDwxJiZ0aGlzLnJlY3VycmVudERyb3BvdXRNYXNrPT1udWxsJiYodGhpcy5yZWN1cnJlbnREcm9wb3V0TWFzaz1nZW5lcmF0ZURyb3BvdXRNYXNrKHtvbmVzOigpPT5vbmVzTGlrZSQzKFRhKSxyYXRlOnRoaXMucmVjdXJyZW50RHJvcG91dCx0cmFpbmluZzpiYSxjb3VudDpFYSxkcm9wb3V0RnVuYzp0aGlzLmRyb3BvdXRGdW5jfSkpO2NvbnN0IG5sPXRoaXMucmVjdXJyZW50RHJvcG91dE1hc2s7bGV0IHNsPUFhKFRhLG5sLDApLHJsPUFhKFRhLG5sLDEpLG9sPUFhKFRhLG5sLDIpLGFsPUFhKFRhLG5sLDMpO2NvbnN0IGxsPTMsW2lsLGNsLHVsLGRsXT1zcGxpdCQzKHRoaXMua2VybmVsLnJlYWQoKSxFYSxsbCksW2hsLHBsLGZsLG1sXT10aGlzLnVzZUJpYXM/c3BsaXQkMyh0aGlzLmJpYXMucmVhZCgpLEVhKTpbbnVsbCxudWxsLG51bGwsbnVsbF07RmE9dGhpcy5pbnB1dENvbnYoRmEsaWwsaGwsdGhpcy5wYWRkaW5nKSxMYT10aGlzLmlucHV0Q29udihMYSxjbCxwbCx0aGlzLnBhZGRpbmcpLGVsPXRoaXMuaW5wdXRDb252KGVsLHVsLGZsLHRoaXMucGFkZGluZyksdGw9dGhpcy5pbnB1dENvbnYodGwsZGwsbWwsdGhpcy5wYWRkaW5nKTtjb25zdFtnbCwkbCx4bCx5bF09c3BsaXQkMyh0aGlzLnJlY3VycmVudEtlcm5lbC5yZWFkKCksRWEsbGwpO3NsPXRoaXMucmVjdXJyZW50Q29udihzbCxnbCkscmw9dGhpcy5yZWN1cnJlbnRDb252KHJsLCRsKSxvbD10aGlzLnJlY3VycmVudENvbnYob2wseGwpLGFsPXRoaXMucmVjdXJyZW50Q29udihhbCx5bCk7Y29uc3QgYmw9dGhpcy5yZWN1cnJlbnRBY3RpdmF0aW9uLmFwcGx5KGFkZCQzKEZhLHNsKSksU2w9dGhpcy5yZWN1cnJlbnRBY3RpdmF0aW9uLmFwcGx5KGFkZCQzKExhLHJsKSksQ2w9YWRkJDMobXVsJDEoU2wsd2EpLG11bCQxKGJsLHRoaXMuYWN0aXZhdGlvbi5hcHBseShhZGQkMyhlbCxvbCkpKSksVGw9bXVsJDEodGhpcy5yZWN1cnJlbnRBY3RpdmF0aW9uLmFwcGx5KGFkZCQzKHRsLGFsKSksdGhpcy5hY3RpdmF0aW9uLmFwcGx5KENsKSk7cmV0dXJuW1RsLFRsLENsXX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXN1cGVyLmdldENvbmZpZygpLHhhPV9fcmVzdChhYSxbInVuaXRzIl0pLGJhPXtmaWx0ZXJzOnRoaXMuZmlsdGVycyxrZXJuZWxTaXplOnRoaXMua2VybmVsU2l6ZSxwYWRkaW5nOnRoaXMucGFkZGluZyxkYXRhRm9ybWF0OnRoaXMuZGF0YUZvcm1hdCxkaWxhdGlvblJhdGU6dGhpcy5kaWxhdGlvblJhdGUsc3RyaWRlczp0aGlzLnN0cmlkZXN9O3JldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30seGEpLGJhKX1pbnB1dENvbnYoYWEseGEsYmEsU2Epe2NvbnN0IFRhPWNvbnYyZCQzKGFhLHhhLHRoaXMuc3RyaWRlcyxTYXx8InZhbGlkIix0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCI/Ik5DSFciOiJOSFdDIix0aGlzLmRpbGF0aW9uUmF0ZSk7cmV0dXJuIGJhP2JpYXNBZGQoVGEsYmEsdGhpcy5kYXRhRm9ybWF0KTpUYX1yZWN1cnJlbnRDb252KGFhLHhhKXtyZXR1cm4gY29udjJkJDMoYWEseGEsMSwic2FtZSIsdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiPyJOQ0hXIjoiTkhXQyIpfX1Db252TFNUTTJEQ2VsbC5jbGFzc05hbWU9IkNvbnZMU1RNMkRDZWxsIixyZWdpc3RlckNsYXNzJDEoQ29udkxTVE0yRENlbGwpO2NsYXNzIENvbnZMU1RNMkQgZXh0ZW5kcyBDb252Uk5OMkR7Y29uc3RydWN0b3IoYWEpe2NvbnN0IHhhPW5ldyBDb252TFNUTTJEQ2VsbChhYSk7c3VwZXIoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LGFhKSx7Y2VsbDp4YX0pKX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YSl9fUNvbnZMU1RNMkQuY2xhc3NOYW1lPSJDb252TFNUTTJEIixyZWdpc3RlckNsYXNzJDEoQ29udkxTVE0yRCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMKICoKICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlCiAqIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBvciBhdAogKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgRHJvcG91dCBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5yYXRlPU1hdGgubWF4KE1hdGgubWluKGFhLnJhdGUsMSksMCksdGhpcy5ub2lzZVNoYXBlPWFhLm5vaXNlU2hhcGUsdGhpcy5zZWVkPWFhLnNlZWQsdGhpcy5zdXBwb3J0c01hc2tpbmc9ITB9Z2V0Tm9pc2VTaGFwZShhYSl7aWYodGhpcy5ub2lzZVNoYXBlPT1udWxsKXJldHVybiB0aGlzLm5vaXNlU2hhcGU7Y29uc3QgeGE9YWEuc2hhcGUsYmE9W107Zm9yKGxldCBTYT0wO1NhPHRoaXMubm9pc2VTaGFwZS5sZW5ndGg7KytTYSliYS5wdXNoKHRoaXMubm9pc2VTaGFwZVtTYV09PW51bGw/eGFbU2FdOnRoaXMubm9pc2VTaGFwZVtTYV0pO3JldHVybiBiYX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57dGhpcy5pbnZva2VDYWxsSG9vayhhYSx4YSk7Y29uc3QgYmE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSk7aWYoMDx0aGlzLnJhdGUmJnRoaXMucmF0ZTwxKXtjb25zdCBTYT14YS50cmFpbmluZz09bnVsbD8hMTp4YS50cmFpbmluZyxUYT10aGlzLmdldE5vaXNlU2hhcGUoYmEpO3JldHVybiBpblRyYWluUGhhc2UoKCk9PmRyb3BvdXQoYmEsdGhpcy5yYXRlLFRhLHRoaXMuc2VlZCksKCk9PmJhLFNhKX1yZXR1cm4gYWF9KX1nZXRDb25maWcoKXtjb25zdCBhYT17cmF0ZTp0aGlzLnJhdGUsbm9pc2VTaGFwZTp0aGlzLm5vaXNlU2hhcGUsc2VlZDp0aGlzLnNlZWR9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX1kaXNwb3NlKCl7cmV0dXJuIHN1cGVyLmRpc3Bvc2UoKX19RHJvcG91dC5jbGFzc05hbWU9IkRyb3BvdXQiLHJlZ2lzdGVyQ2xhc3MkMShEcm9wb3V0KTtjbGFzcyBTcGF0aWFsRHJvcG91dDFEIGV4dGVuZHMgRHJvcG91dHtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMuaW5wdXRTcGVjPVt7bmRpbTozfV19Z2V0Tm9pc2VTaGFwZShhYSl7Y29uc3QgeGE9YWEuc2hhcGU7cmV0dXJuW3hhWzBdLDEseGFbMl1dfX1TcGF0aWFsRHJvcG91dDFELmNsYXNzTmFtZT0iU3BhdGlhbERyb3BvdXQxRCIscmVnaXN0ZXJDbGFzcyQxKFNwYXRpYWxEcm9wb3V0MUQpO2NsYXNzIERlbnNlIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKHN1cGVyKGFhKSx0aGlzLmFjdGl2YXRpb249bnVsbCx0aGlzLnVzZUJpYXM9ITAsdGhpcy5rZXJuZWw9bnVsbCx0aGlzLmJpYXM9bnVsbCx0aGlzLkRFRkFVTFRfS0VSTkVMX0lOSVRJQUxJWkVSPSJnbG9yb3ROb3JtYWwiLHRoaXMuREVGQVVMVF9CSUFTX0lOSVRJQUxJWkVSPSJ6ZXJvcyIsYWEuYmF0Y2hJbnB1dFNoYXBlPT1udWxsJiZhYS5pbnB1dFNoYXBlPT1udWxsJiZhYS5pbnB1dERpbSE9bnVsbCl7bGV0IHhhPW51bGw7YWEuYmF0Y2hTaXplIT1udWxsJiYoeGE9YWEuYmF0Y2hTaXplKSx0aGlzLmJhdGNoSW5wdXRTaGFwZT1beGEsYWEuaW5wdXREaW1dfXRoaXMudW5pdHM9YWEudW5pdHMsYXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHRoaXMudW5pdHMsInVuaXRzIiksdGhpcy5hY3RpdmF0aW9uPWdldEFjdGl2YXRpb24oYWEuYWN0aXZhdGlvbiksYWEudXNlQmlhcyE9bnVsbCYmKHRoaXMudXNlQmlhcz1hYS51c2VCaWFzKSx0aGlzLmtlcm5lbEluaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLmtlcm5lbEluaXRpYWxpemVyfHx0aGlzLkRFRkFVTFRfS0VSTkVMX0lOSVRJQUxJWkVSKSx0aGlzLmJpYXNJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5iaWFzSW5pdGlhbGl6ZXJ8fHRoaXMuREVGQVVMVF9CSUFTX0lOSVRJQUxJWkVSKSx0aGlzLmtlcm5lbENvbnN0cmFpbnQ9Z2V0Q29uc3RyYWludChhYS5rZXJuZWxDb25zdHJhaW50KSx0aGlzLmJpYXNDb25zdHJhaW50PWdldENvbnN0cmFpbnQoYWEuYmlhc0NvbnN0cmFpbnQpLHRoaXMua2VybmVsUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEua2VybmVsUmVndWxhcml6ZXIpLHRoaXMuYmlhc1JlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmJpYXNSZWd1bGFyaXplciksdGhpcy5hY3Rpdml0eVJlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmFjdGl2aXR5UmVndWxhcml6ZXIpLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwLHRoaXMuaW5wdXRTcGVjPVt7bWluTkRpbToyfV19YnVpbGQoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9YWFbYWEubGVuZ3RoLTFdO3RoaXMua2VybmVsPT1udWxsJiYodGhpcy5rZXJuZWw9dGhpcy5hZGRXZWlnaHQoImtlcm5lbCIsW3hhLHRoaXMudW5pdHNdLG51bGwsdGhpcy5rZXJuZWxJbml0aWFsaXplcix0aGlzLmtlcm5lbFJlZ3VsYXJpemVyLCEwLHRoaXMua2VybmVsQ29uc3RyYWludCksdGhpcy51c2VCaWFzJiYodGhpcy5iaWFzPXRoaXMuYWRkV2VpZ2h0KCJiaWFzIixbdGhpcy51bml0c10sbnVsbCx0aGlzLmJpYXNJbml0aWFsaXplcix0aGlzLmJpYXNSZWd1bGFyaXplciwhMCx0aGlzLmJpYXNDb25zdHJhaW50KSkpLHRoaXMuaW5wdXRTcGVjPVt7bWluTkRpbToyLGF4ZXM6e1stMV06eGF9fV0sdGhpcy5idWlsdD0hMH1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9YWEuc2xpY2UoKTtyZXR1cm4geGFbeGEubGVuZ3RoLTFdPXRoaXMudW5pdHMseGF9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e3RoaXMuaW52b2tlQ2FsbEhvb2soYWEseGEpO2NvbnN0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLFNhPW1hcEFjdGl2YXRpb25Ub0Z1c2VkS2VybmVsKHRoaXMuYWN0aXZhdGlvbi5nZXRDbGFzc05hbWUoKSk7bGV0IFRhO3JldHVybiBTYSE9bnVsbD9UYT1kb3QoYmEsdGhpcy5rZXJuZWwucmVhZCgpLFNhLHRoaXMuYmlhcz90aGlzLmJpYXMucmVhZCgpOm51bGwpOihUYT1kb3QoYmEsdGhpcy5rZXJuZWwucmVhZCgpKSx0aGlzLmJpYXMhPW51bGwmJihUYT1iaWFzQWRkKFRhLHRoaXMuYmlhcy5yZWFkKCkpKSx0aGlzLmFjdGl2YXRpb24hPW51bGwmJihUYT10aGlzLmFjdGl2YXRpb24uYXBwbHkoVGEpKSksVGF9KX1nZXRDb25maWcoKXtjb25zdCBhYT17dW5pdHM6dGhpcy51bml0cyxhY3RpdmF0aW9uOnNlcmlhbGl6ZUFjdGl2YXRpb24odGhpcy5hY3RpdmF0aW9uKSx1c2VCaWFzOnRoaXMudXNlQmlhcyxrZXJuZWxJbml0aWFsaXplcjpzZXJpYWxpemVJbml0aWFsaXplcih0aGlzLmtlcm5lbEluaXRpYWxpemVyKSxiaWFzSW5pdGlhbGl6ZXI6c2VyaWFsaXplSW5pdGlhbGl6ZXIodGhpcy5iaWFzSW5pdGlhbGl6ZXIpLGtlcm5lbFJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMua2VybmVsUmVndWxhcml6ZXIpLGJpYXNSZWd1bGFyaXplcjpzZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLmJpYXNSZWd1bGFyaXplciksYWN0aXZpdHlSZWd1bGFyaXplcjpzZXJpYWxpemVSZWd1bGFyaXplcih0aGlzLmFjdGl2aXR5UmVndWxhcml6ZXIpLGtlcm5lbENvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmtlcm5lbENvbnN0cmFpbnQpLGJpYXNDb25zdHJhaW50OnNlcmlhbGl6ZUNvbnN0cmFpbnQodGhpcy5iaWFzQ29uc3RyYWludCl9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19RGVuc2UuY2xhc3NOYW1lPSJEZW5zZSIscmVnaXN0ZXJDbGFzcyQxKERlbnNlKTtjbGFzcyBGbGF0dGVuIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2FhPWFhfHx7fSxzdXBlcihhYSksdGhpcy5pbnB1dFNwZWM9W3ttaW5ORGltOjN9XSx0aGlzLmRhdGFGb3JtYXQ9YWEuZGF0YUZvcm1hdH1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Zm9yKGNvbnN0IHhhIG9mIGFhLnNsaWNlKDEpKWlmKHhhPT1udWxsKXRocm93IG5ldyBWYWx1ZUVycm9yKGBUaGUgc2hhcGUgb2YgdGhlIGlucHV0IHRvICJGbGF0dGVuIiBpcyBub3QgZnVsbHkgZGVmaW5lZCAoZ290ICR7YWEuc2xpY2UoMSl9KS4gTWFrZSBzdXJlIHRvIHBhc3MgYSBjb21wbGV0ZSAiaW5wdXRfc2hhcGUiIG9yICJiYXRjaF9pbnB1dF9zaGFwZSIgYXJndW1lbnQgdG8gdGhlIGZpcnN0IGxheWVyIGluIHlvdXIgbW9kZWwuYCk7cmV0dXJuW2FhWzBdLGFycmF5UHJvZChhYSwxKV19Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e3RoaXMuaW52b2tlQ2FsbEhvb2soYWEseGEpO2xldCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtpZih0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCImJmJhLnJhbms+MSl7Y29uc3QgU2E9WzBdO2ZvcihsZXQgVGE9MjtUYTxiYS5yYW5rOysrVGEpU2EucHVzaChUYSk7U2EucHVzaCgxKSxiYT10cmFuc3Bvc2UkMyhiYSxTYSl9cmV0dXJuIGJhdGNoRmxhdHRlbihiYSl9KX1nZXRDb25maWcoKXtjb25zdCBhYT17fTt0aGlzLmRhdGFGb3JtYXQhPW51bGwmJihhYS5kYXRhRm9ybWF0PXRoaXMuZGF0YUZvcm1hdCk7Y29uc3QgeGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1GbGF0dGVuLmNsYXNzTmFtZT0iRmxhdHRlbiIscmVnaXN0ZXJDbGFzcyQxKEZsYXR0ZW4pO2NsYXNzIEFjdGl2YXRpb24gZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwLHRoaXMuYWN0aXZhdGlvbj1nZXRBY3RpdmF0aW9uKGFhLmFjdGl2YXRpb24pfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pnt0aGlzLmludm9rZUNhbGxIb29rKGFhLHhhKTtjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtyZXR1cm4gdGhpcy5hY3RpdmF0aW9uLmFwcGx5KGJhKX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXthY3RpdmF0aW9uOnNlcmlhbGl6ZUFjdGl2YXRpb24odGhpcy5hY3RpdmF0aW9uKX0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1BY3RpdmF0aW9uLmNsYXNzTmFtZT0iQWN0aXZhdGlvbiIscmVnaXN0ZXJDbGFzcyQxKEFjdGl2YXRpb24pO2NsYXNzIFJlcGVhdFZlY3RvciBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5uPWFhLm4sdGhpcy5pbnB1dFNwZWM9W3tuZGltOjJ9XX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVyblthYVswXSx0aGlzLm4sYWFbMV1dfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PihhYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKSxyZXBlYXQoYWEsdGhpcy5uKSkpfWdldENvbmZpZygpe2NvbnN0IGFhPXtuOnRoaXMubn0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1SZXBlYXRWZWN0b3IuY2xhc3NOYW1lPSJSZXBlYXRWZWN0b3IiLHJlZ2lzdGVyQ2xhc3MkMShSZXBlYXRWZWN0b3IpO2xldCBSZXNoYXBlJDE9Y2xhc3MgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMudGFyZ2V0U2hhcGU9YWEudGFyZ2V0U2hhcGU7Zm9yKGxldCB4YT0wO3hhPHRoaXMudGFyZ2V0U2hhcGUubGVuZ3RoOysreGEpdGhpcy5pc1Vua25vd24odGhpcy50YXJnZXRTaGFwZVt4YV0pJiYodGhpcy50YXJnZXRTaGFwZVt4YV09bnVsbCl9aXNVbmtub3duKGFhKXtyZXR1cm4gYWE8MHx8YWE9PW51bGx9Zml4VW5rbm93bkRpbWVuc2lvbihhYSx4YSl7Y29uc3QgYmE9IlRvdGFsIHNpemUgb2YgbmV3IGFycmF5IG11c3QgYmUgdW5jaGFuZ2VkLiIsU2E9eGEuc2xpY2UoKTtsZXQgVGE9MSx3YT1udWxsO2ZvcihsZXQga2E9MDtrYTxTYS5sZW5ndGg7KytrYSl7Y29uc3QgQWE9U2Fba2FdO2lmKHRoaXMuaXNVbmtub3duKEFhKSlpZih3YT09PW51bGwpd2E9a2E7ZWxzZSB0aHJvdyBuZXcgVmFsdWVFcnJvcigiQ2FuIG9ubHkgc3BlY2lmaXkgb25lIHVua25vd24gZGltZW5zaW9uLiIpO2Vsc2UgVGEqPUFhfWNvbnN0IEVhPWFycmF5UHJvZChhYSk7aWYod2EhPT1udWxsKXtpZihUYT09PTB8fEVhJVRhIT09MCl0aHJvdyBuZXcgVmFsdWVFcnJvcihiYSk7U2Fbd2FdPUVhL1RhfWVsc2UgaWYoRWEhPT1UYSl0aHJvdyBuZXcgVmFsdWVFcnJvcihiYSk7cmV0dXJuIFNhfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7bGV0IHhhPSExO2ZvcihsZXQgYmE9MDtiYTxhYS5sZW5ndGg7KytiYSlpZih0aGlzLmlzVW5rbm93bihhYVtiYV0pKXt4YT0hMDticmVha31yZXR1cm4geGE/YWEuc2xpY2UoMCwxKS5jb25jYXQodGhpcy50YXJnZXRTaGFwZSk6YWEuc2xpY2UoMCwxKS5jb25jYXQodGhpcy5maXhVbmtub3duRGltZW5zaW9uKGFhLnNsaWNlKDEpLHRoaXMudGFyZ2V0U2hhcGUpKX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57dGhpcy5pbnZva2VDYWxsSG9vayhhYSx4YSk7Y29uc3QgYmE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSksU2E9YmEuc2hhcGUsVGE9U2Euc2xpY2UoMCwxKS5jb25jYXQodGhpcy5maXhVbmtub3duRGltZW5zaW9uKFNhLnNsaWNlKDEpLHRoaXMudGFyZ2V0U2hhcGUpKTtyZXR1cm4gcmVzaGFwZSQ0KGJhLFRhKX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXt0YXJnZXRTaGFwZTp0aGlzLnRhcmdldFNoYXBlfSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9fTtSZXNoYXBlJDEuY2xhc3NOYW1lPSJSZXNoYXBlIixyZWdpc3RlckNsYXNzJDEoUmVzaGFwZSQxKTtjbGFzcyBQZXJtdXRlIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKHN1cGVyKGFhKSxhYS5kaW1zPT1udWxsKXRocm93IG5ldyBFcnJvcigiUmVxdWlyZWQgY29uZmlndXJhdGlvbiBmaWVsZCBgZGltc2AgaXMgbWlzc2luZyBkdXJpbmcgUGVybXV0ZSBjb25zdHJ1Y3RvciBjYWxsLiIpO2lmKCFBcnJheS5pc0FycmF5KGFhLmRpbXMpKXRocm93IG5ldyBFcnJvcihgUGVybXV0ZSBjb25zdHJ1Y3RvciByZXF1aXJlcyBcYGRpbXNcYCB0byBiZSBhbiBBcnJheSwgYnV0IHJlY2VpdmVkICR7YWEuZGltc30gaW5zdGVhZC5gKTtjb25zdCB4YT1yYW5nZSQzKDEsYWEuZGltcy5sZW5ndGgrMSk7aWYoIWFycmF5c0VxdWFsJDEoYWEuZGltcy5zbGljZSgpLnNvcnQoKSx4YSkpdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIHBlcm11dGF0aW9uIGBkaW1zYDogIitKU09OLnN0cmluZ2lmeShhYS5kaW1zKSsiIGBkaW1zYCBtdXN0IGNvbnRhaW4gY29uc2VjdXRpdmUgaW50ZWdlcnMgc3RhcnRpbmcgZnJvbSAxLiIpO3RoaXMuZGltcz1hYS5kaW1zLHRoaXMuZGltc0luY2x1ZGluZ0JhdGNoPVswXS5jb25jYXQodGhpcy5kaW1zKSx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTp0aGlzLmRpbXMubGVuZ3RoKzF9KV19Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IHhhPWFhLnNsaWNlKCk7cmV0dXJuIHRoaXMuZGltcy5mb3JFYWNoKChiYSxTYSk9Pnt4YVtTYSsxXT1hYVtiYV19KSx4YX1jYWxsKGFhLHhhKXtyZXR1cm4gdHJhbnNwb3NlJDMoZ2V0RXhhY3RseU9uZVRlbnNvcihhYSksdGhpcy5kaW1zSW5jbHVkaW5nQmF0Y2gpfWdldENvbmZpZygpe2NvbnN0IGFhPXtkaW1zOnRoaXMuZGltc30seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1QZXJtdXRlLmNsYXNzTmFtZT0iUGVybXV0ZSIscmVnaXN0ZXJDbGFzcyQxKFBlcm11dGUpO2NsYXNzIE1hc2tpbmcgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWE/P3t9KSx0aGlzLnN1cHBvcnRzTWFza2luZz0hMCxhYSE9bnVsbD90aGlzLm1hc2tWYWx1ZT1hYS5tYXNrVmFsdWU9PW51bGw/MDphYS5tYXNrVmFsdWU6dGhpcy5tYXNrVmFsdWU9MH1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYX1nZXRDb25maWcoKXtjb25zdCBhYT1zdXBlci5nZXRDb25maWcoKSx4YT17bWFza1ZhbHVlOnRoaXMubWFza1ZhbHVlfTtyZXR1cm4gT2JqZWN0LmFzc2lnbih4YSxhYSkseGF9Y29tcHV0ZU1hc2soYWEseGEpe2NvbnN0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO3JldHVybiBhbnkkMyhub3RFcXVhbCQzKGJhLHRoaXMubWFza1ZhbHVlKSwtMSl9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e3RoaXMuaW52b2tlQ2FsbEhvb2soYWEseGEpO2NvbnN0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLHdhPWFueSQzKG5vdEVxdWFsJDMoYmEsdGhpcy5tYXNrVmFsdWUpLC0xLCEwKTtyZXR1cm4gbXVsJDEoYmEsY2FzdCQ1KHdhLGJhLmR0eXBlKSl9KX19TWFza2luZy5jbGFzc05hbWU9Ik1hc2tpbmciLHJlZ2lzdGVyQ2xhc3MkMShNYXNraW5nKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBFbWJlZGRpbmcgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7aWYoc3VwZXIoYWEpLHRoaXMuZW1iZWRkaW5ncz1udWxsLHRoaXMuREVGQVVMVF9FTUJFRERJTkdTX0lOSVRJQUxJWkVSPSJyYW5kb21Vbmlmb3JtIixhYS5iYXRjaElucHV0U2hhcGU9PW51bGwmJmFhLmlucHV0U2hhcGU9PW51bGwpe2xldCB4YT1udWxsO2FhLmJhdGNoU2l6ZSE9bnVsbCYmKHhhPWFhLmJhdGNoU2l6ZSksYWEuaW5wdXRMZW5ndGg9PW51bGw/dGhpcy5iYXRjaElucHV0U2hhcGU9W3hhLG51bGxdOnRoaXMuYmF0Y2hJbnB1dFNoYXBlPVt4YV0uY29uY2F0KHRvTGlzdChhYS5pbnB1dExlbmd0aCkpfXRoaXMuaW5wdXREaW09YWEuaW5wdXREaW0sYXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHRoaXMuaW5wdXREaW0sImlucHV0RGltIiksdGhpcy5vdXRwdXREaW09YWEub3V0cHV0RGltLGFzc2VydFBvc2l0aXZlSW50ZWdlcih0aGlzLm91dHB1dERpbSwib3V0cHV0RGltIiksdGhpcy5lbWJlZGRpbmdzSW5pdGlhbGl6ZXI9Z2V0SW5pdGlhbGl6ZXIoYWEuZW1iZWRkaW5nc0luaXRpYWxpemVyfHx0aGlzLkRFRkFVTFRfRU1CRURESU5HU19JTklUSUFMSVpFUiksdGhpcy5lbWJlZGRpbmdzUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEuZW1iZWRkaW5nc1JlZ3VsYXJpemVyKSx0aGlzLmFjdGl2aXR5UmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEuYWN0aXZpdHlSZWd1bGFyaXplciksdGhpcy5lbWJlZGRpbmdzQ29uc3RyYWludD1nZXRDb25zdHJhaW50KGFhLmVtYmVkZGluZ3NDb25zdHJhaW50KSx0aGlzLm1hc2taZXJvPWFhLm1hc2taZXJvLHRoaXMuc3VwcG9ydHNNYXNraW5nPWFhLm1hc2taZXJvLHRoaXMuaW5wdXRMZW5ndGg9YWEuaW5wdXRMZW5ndGh9YnVpbGQoYWEpe3RoaXMuZW1iZWRkaW5ncz10aGlzLmFkZFdlaWdodCgiZW1iZWRkaW5ncyIsW3RoaXMuaW5wdXREaW0sdGhpcy5vdXRwdXREaW1dLHRoaXMuZHR5cGUsdGhpcy5lbWJlZGRpbmdzSW5pdGlhbGl6ZXIsdGhpcy5lbWJlZGRpbmdzUmVndWxhcml6ZXIsITAsdGhpcy5lbWJlZGRpbmdzQ29uc3RyYWludCksdGhpcy5idWlsdD0hMH13YXJuT25JbmNvbXBhdGlibGVJbnB1dFNoYXBlKGFhKXt9Y29tcHV0ZU1hc2soYWEseGEpe3JldHVybiB0aWR5JDEoKCk9PnRoaXMubWFza1plcm8/KGFhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLG5vdEVxdWFsJDMoYWEsemVyb3NMaWtlJDQoYWEpKSk6bnVsbCl9Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXtpZihhYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpLHRoaXMuaW5wdXRMZW5ndGg9PW51bGwpcmV0dXJuWy4uLmFhLHRoaXMub3V0cHV0RGltXTtjb25zdCB4YT10b0xpc3QodGhpcy5pbnB1dExlbmd0aCk7aWYoeGEubGVuZ3RoIT09YWEubGVuZ3RoLTEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYCJpbnB1dExlbmd0aCIgaXMgJHt0aGlzLmlucHV0TGVuZ3RofSwgYnV0IHJlY2VpdmVkIGlucHV0IHNoYXBlIGhhcyBzaGFwZSAke2FhfWApO3tsZXQgYmE9MDtmb3IobGV0IFNhPTA7U2E8eGEubGVuZ3RoOysrU2Epe2NvbnN0IFRhPXhhW1NhXSx3YT1hYVtTYSsxXTtpZihUYSE9bnVsbCYmd2EhPW51bGwmJlRhIT09d2EpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYCJpbnB1dExlbmd0aCIgaXMgJHt0aGlzLmlucHV0TGVuZ3RofSwgYnV0IHJlY2VpdmVkIGlucHV0IHNoYXBlIGhhcyBzaGFwZSAke2FhfWApO1RhPT1udWxsJiYoeGFbYmFdPXdhKSxiYSsrfX1yZXR1cm5bYWFbMF0sLi4ueGEsdGhpcy5vdXRwdXREaW1dfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pnt0aGlzLmludm9rZUNhbGxIb29rKGFhLHhhKTtsZXQgYmE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSk7YmEuZHR5cGUhPT0iaW50MzIiJiYoYmE9Y2FzdCQ0KGJhLCJpbnQzMiIpKTtjb25zdCBTYT1nYXRoZXIodGhpcy5lbWJlZGRpbmdzLnJlYWQoKSxyZXNoYXBlJDQoYmEsW2JhLnNpemVdKSk7cmV0dXJuIHJlc2hhcGUkNChTYSxnZXRFeGFjdGx5T25lU2hhcGUodGhpcy5jb21wdXRlT3V0cHV0U2hhcGUoYmEuc2hhcGUpKSl9KX1nZXRDb25maWcoKXtjb25zdCBhYT17aW5wdXREaW06dGhpcy5pbnB1dERpbSxvdXRwdXREaW06dGhpcy5vdXRwdXREaW0sZW1iZWRkaW5nc0luaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuZW1iZWRkaW5nc0luaXRpYWxpemVyKSxlbWJlZGRpbmdzUmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5lbWJlZGRpbmdzUmVndWxhcml6ZXIpLGFjdGl2aXR5UmVndWxhcml6ZXI6c2VyaWFsaXplUmVndWxhcml6ZXIodGhpcy5hY3Rpdml0eVJlZ3VsYXJpemVyKSxlbWJlZGRpbmdzQ29uc3RyYWludDpzZXJpYWxpemVDb25zdHJhaW50KHRoaXMuZW1iZWRkaW5nc0NvbnN0cmFpbnQpLG1hc2taZXJvOnRoaXMubWFza1plcm8saW5wdXRMZW5ndGg6dGhpcy5pbnB1dExlbmd0aH0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1FbWJlZGRpbmcuY2xhc3NOYW1lPSJFbWJlZGRpbmciLHJlZ2lzdGVyQ2xhc3MkMShFbWJlZGRpbmcpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIE1lcmdlIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhfHx7fSksdGhpcy5zdXBwb3J0c01hc2tpbmc9ITB9bWVyZ2VGdW5jdGlvbihhYSl7dGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3J9Y29tcHV0ZUVsZW1lbnR3aXNlT3BPdXRwdXRTaGFwZShhYSx4YSl7aWYoYWE9PW51bGx8fHhhPT1udWxsKXJldHVybiBudWxsO2lmKGFhLmxlbmd0aDx4YS5sZW5ndGgpcmV0dXJuIHRoaXMuY29tcHV0ZUVsZW1lbnR3aXNlT3BPdXRwdXRTaGFwZSh4YSxhYSk7aWYoeGEubGVuZ3RoPT09MClyZXR1cm4gYWE7Y29uc3QgYmE9YWEuc2xpY2UoMCxhYS5sZW5ndGgteGEubGVuZ3RoKTtmb3IobGV0IFNhPTA7U2E8eGEubGVuZ3RoOysrU2Epe2NvbnN0IFRhPWFhW2FhLmxlbmd0aC14YS5sZW5ndGgrU2FdLHdhPXhhW1NhXTtpZihUYT09bnVsbHx8d2E9PW51bGx8fFRhPDB8fHdhPDApYmEucHVzaChudWxsKTtlbHNlIGlmKFRhPT09MSliYS5wdXNoKHdhKTtlbHNlIGlmKHdhPT09MSliYS5wdXNoKFRhKTtlbHNle2lmKFRhIT09d2EpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIk9wZXJhbmRzIGNvdWxkIG5vdCBiZSBicm9hZGNhc3QgdG9nZXRoZXIgd2l0aCBzaGFwZXMgIitKU09OLnN0cmluZ2lmeShhYSkrIiAiK0pTT04uc3RyaW5naWZ5KHhhKSk7YmEucHVzaChUYSl9fXJldHVybiBiYX1idWlsZChhYSl7aWYoQXJyYXkuaXNBcnJheShhYSkmJiFBcnJheS5pc0FycmF5KGFhWzBdKSYmKGFhPVtnZXRFeGFjdGx5T25lU2hhcGUoYWEpXSksYWE9YWEsYWEubGVuZ3RoPDIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEEgbWVyZ2UgbGF5ZXIgc2hvdWxkIGJlIGNhbGxlZCBvbiBhbiBBcnJheSBvZiBhdCBsZWFzdCAyIGlucHV0cy4gR290ICR7YWEubGVuZ3RofSBpbnB1dChzKS5gKTtsZXQgeGE9W107Zm9yKGNvbnN0IFRhIG9mIGFhKVRhIT1udWxsJiZUYVswXSE9PW51bGwmJnhhLnB1c2goVGFbMF0pO2lmKHhhPXVuaXF1ZSQzKHhhKSx4YS5sZW5ndGg+MSl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQ2FuIG5vdCBtZXJnZSB0ZW5zb3JzIHdpdGggZGlmZmVyZW50IGJhdGNoIHNpemVzLiBHb3QgdGVuc29ycyB3aXRoIHNoYXBlczogJHtKU09OLnN0cmluZ2lmeShhYSl9LmApO2xldCBiYT1hYVswXT09bnVsbD9udWxsOmFhWzBdLnNsaWNlKDEpO2ZvcihsZXQgVGE9MTtUYTxhYS5sZW5ndGg7KytUYSl7Y29uc3Qgd2E9YWFbVGFdPT1udWxsP251bGw6YWFbVGFdLnNsaWNlKDEpO2JhPXRoaXMuY29tcHV0ZUVsZW1lbnR3aXNlT3BPdXRwdXRTaGFwZShiYSx3YSl9Y29uc3QgU2E9YWEubWFwKFRhPT5UYS5sZW5ndGgpO2FhLmluZGV4T2YobnVsbCk9PT0tMSYmdW5pcXVlJDMoU2EpLmxlbmd0aD09PTE/dGhpcy5yZXNoYXBlUmVxdWlyZWQ9ITE6dGhpcy5yZXNoYXBlUmVxdWlyZWQ9ITB9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2lmKGFhPWFhLHRoaXMucmVzaGFwZVJlcXVpcmVkKXtjb25zdCBiYT1bXSxTYT1hYS5tYXAoVGE9PlRhLnJhbmspO2lmKFNhLmluZGV4T2YobnVsbCk9PT0tMSl7Y29uc3QgVGE9bWF4JDMoU2EpO2ZvcihsZXQgd2Egb2YgYWEpe2NvbnN0IEVhPXdhLnJhbms7Zm9yKGxldCBrYT0wO2thPFRhLUVhOysra2Epd2E9ZXhwYW5kRGltcyQzKHdhLDEpO2JhLnB1c2god2EpfXJldHVybiB0aGlzLm1lcmdlRnVuY3Rpb24oYmEpfWVsc2V7bGV0IFRhPSExO2Zvcihjb25zdCBrYSBvZiBhYSl7Y29uc3QgQWE9a2EucmFuaztpZihBYT09bnVsbCl7Y29uc3QgRmE9a2Euc2hhcGUsTGE9RmFbMF0sZWw9RmEuc2xpY2UoMSkuY29uY2F0KFtMYV0pO2xldCB0bD1yZXNoYXBlJDQoa2EsW0xhXS5jb25jYXQoYXJyYXlQcm9kKEZhLnNsaWNlKDEpKSkpO3RsPXRyYW5zcG9zZSQzKHRsLFsxLDBdKSx0bD1yZXNoYXBlJDQodGwsZWwpLGJhLnB1c2godGwpLFRhPSEwfWVsc2UgaWYoQWE+MSl7Y29uc3QgRmE9cmFuZ2UkMygxLEFhKS5jb25jYXQoWzBdKTtiYS5wdXNoKHRyYW5zcG9zZSQzKGthLEZhKSksVGE9ITB9ZWxzZSBiYS5wdXNoKGthKX1sZXQgd2E9dGhpcy5tZXJnZUZ1bmN0aW9uKGJhKTtjb25zdCBFYT13YS5yYW5rO2lmKFRhKXtpZihFYT09bnVsbCl7Y29uc3Qga2E9d2Euc2hhcGUsQWE9a2EubGVuZ3RoLEZhPWthW0FhLTFdLExhPVtGYV0uY29uY2F0KGthLnNsaWNlKDAsa2EubGVuZ3RoLTEpKTt3YT1yZXNoYXBlJDQodHJhbnNwb3NlJDMocmVzaGFwZSQ0KHdhLFstMSxGYV0pLFsxLDBdKSxMYSl9ZWxzZSBpZihFYT4xKXtjb25zdCBrYT1bRWEtMV0uY29uY2F0KHJhbmdlJDMoMCxFYS0xKSk7d2E9dHJhbnNwb3NlJDMod2Esa2EpfX1yZXR1cm4gd2F9fWVsc2UgcmV0dXJuIHRoaXMubWVyZ2VGdW5jdGlvbihhYSl9KX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2FhPWFhO2xldCB4YTthYVswXT09bnVsbD94YT1udWxsOnhhPWFhWzBdLnNsaWNlKDEpO2ZvcihsZXQgU2E9MTtTYTxhYS5sZW5ndGg7KytTYSl7Y29uc3QgVGE9YWFbU2FdPT1udWxsP251bGw6YWFbU2FdLnNsaWNlKDEpO3hhPXRoaXMuY29tcHV0ZUVsZW1lbnR3aXNlT3BPdXRwdXRTaGFwZSh4YSxUYSl9bGV0IGJhPVtdO2Zvcihjb25zdCBTYSBvZiBhYSlTYSE9bnVsbCYmU2FbMF0hPT1udWxsJiZiYS5wdXNoKFNhWzBdKTtyZXR1cm4gYmE9dW5pcXVlJDMoYmEpLGJhLmxlbmd0aD09PTE/eGE9YmEuY29uY2F0KHhhKTp4YT1bbnVsbF0uY29uY2F0KHhhKSx4YX1jb21wdXRlTWFzayhhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2lmKHhhPT1udWxsKXJldHVybiBudWxsO2lmKCFBcnJheS5pc0FycmF5KHhhKSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiYG1hc2tgIHNob3VsZCBiZSBhbiBBcnJheSIpO2lmKCFBcnJheS5pc0FycmF5KGFhKSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiYGlucHV0c2Agc2hvdWxkIGJlIGFuIEFycmF5Iik7aWYoeGEubGVuZ3RoIT09YWEubGVuZ3RoKXRocm93IG5ldyBWYWx1ZUVycm9yKGBUaGUgQXJyYXkgJ2lucHV0cycgYW5kICdtYXNrJyBhcmUgZXhwZWN0ZWQgdG8gaGF2ZSB0aGUgc2FtZSBsZW5ndGgsIGJ1dCBoYXZlIGRpZmZlcmVudCBsZW5ndGhzICgke2FhLmxlbmd0aH0gdnMgJHt4YS5sZW5ndGh9KWApO2lmKHhhLmV2ZXJ5KFNhPT5TYT09bnVsbCkpcmV0dXJuIG51bGw7eGE9eGEubWFwKFNhPT5TYT09bnVsbD9TYTpleHBhbmREaW1zJDQoU2EsMCkpO2xldCBiYT14YVswXTtmb3IobGV0IFNhPTE7U2E8eGEubGVuZ3RoLTE7KytTYSliYT1sb2dpY2FsQW5kJDMoYmEseGFbU2FdKTtyZXR1cm4gYmF9KX19bGV0IEFkZCQxPWNsYXNzIGV4dGVuZHMgTWVyZ2V7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKX1tZXJnZUZ1bmN0aW9uKGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IHhhPWFhWzBdLmNsb25lKCk7Zm9yKGxldCBiYT0xO2JhPGFhLmxlbmd0aDsrK2JhKXhhPWFkZCQzKHhhLGFhW2JhXSk7cmV0dXJuIHhhfSl9fTtBZGQkMS5jbGFzc05hbWU9IkFkZCIscmVnaXN0ZXJDbGFzcyQxKEFkZCQxKTtsZXQgTXVsdGlwbHkkMT1jbGFzcyBleHRlbmRzIE1lcmdle2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSl9bWVyZ2VGdW5jdGlvbihhYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2xldCB4YT1hYVswXS5jbG9uZSgpO2ZvcihsZXQgYmE9MTtiYTxhYS5sZW5ndGg7KytiYSl4YT1tdWwkMSh4YSxhYVtiYV0pO3JldHVybiB4YX0pfX07TXVsdGlwbHkkMS5jbGFzc05hbWU9Ik11bHRpcGx5IixyZWdpc3RlckNsYXNzJDEoTXVsdGlwbHkkMSk7Y2xhc3MgQXZlcmFnZSBleHRlbmRzIE1lcmdle2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSl9bWVyZ2VGdW5jdGlvbihhYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2xldCB4YT1hYVswXS5jbG9uZSgpO2ZvcihsZXQgYmE9MTtiYTxhYS5sZW5ndGg7KytiYSl4YT1hZGQkMyh4YSxhYVtiYV0pO3JldHVybiBtdWwkMSgxL2FhLmxlbmd0aCx4YSl9KX19QXZlcmFnZS5jbGFzc05hbWU9IkF2ZXJhZ2UiLHJlZ2lzdGVyQ2xhc3MkMShBdmVyYWdlKTtsZXQgTWF4aW11bSQxPWNsYXNzIGV4dGVuZHMgTWVyZ2V7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKX1tZXJnZUZ1bmN0aW9uKGFhKXtyZXR1cm4gdGlkeSQxKCgpPT57bGV0IHhhPWFhWzBdO2ZvcihsZXQgYmE9MTtiYTxhYS5sZW5ndGg7KytiYSl4YT1tYXhpbXVtJDQoeGEsYWFbYmFdKTtyZXR1cm4geGF9KX19O01heGltdW0kMS5jbGFzc05hbWU9Ik1heGltdW0iLHJlZ2lzdGVyQ2xhc3MkMShNYXhpbXVtJDEpO2xldCBNaW5pbXVtJDE9Y2xhc3MgZXh0ZW5kcyBNZXJnZXtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpfW1lcmdlRnVuY3Rpb24oYWEpe3JldHVybiB0aWR5JDEoKCk9PntsZXQgeGE9YWFbMF07Zm9yKGxldCBiYT0xO2JhPGFhLmxlbmd0aDsrK2JhKXhhPW1pbmltdW0kMyh4YSxhYVtiYV0pO3JldHVybiB4YX0pfX07TWluaW11bSQxLmNsYXNzTmFtZT0iTWluaW11bSIscmVnaXN0ZXJDbGFzcyQxKE1pbmltdW0kMSk7Y2xhc3MgQ29uY2F0ZW5hdGUgZXh0ZW5kcyBNZXJnZXtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMuREVGQVVMVF9BWElTPS0xLGFhPT1udWxsJiYoYWE9e30pLHRoaXMuYXhpcz1hYS5heGlzPT1udWxsP3RoaXMuREVGQVVMVF9BWElTOmFhLmF4aXMsdGhpcy5zdXBwb3J0c01hc2tpbmc9ITAsdGhpcy5yZXNoYXBlUmVxdWlyZWQ9ITF9YnVpbGQoYWEpe2lmKCEoQXJyYXkuaXNBcnJheShhYSkmJkFycmF5LmlzQXJyYXkoYWFbMF0pKXx8YWEubGVuZ3RoPT09MSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQSBgQ29uY2F0ZW5hdGVgIGxheWVyIHNob3VsZCBiZSBjYWxsZWQgb24gYSBsaXN0IG9mIGF0IGxlYXN0IDIgaW5wdXRzIik7YWE9YWE7bGV0IHhhPSEwO2Zvcihjb25zdCBTYSBvZiBhYSlpZihTYSE9bnVsbCl7eGE9ITE7YnJlYWt9aWYoeGEpcmV0dXJuO2NvbnN0IGJhPVtdO2ZvcihsZXQgU2E9MDtTYTxhYS5sZW5ndGg7KytTYSl7Y29uc3QgVGE9YWFbU2FdLnNsaWNlKCk7VGEuc3BsaWNlKHRoaXMuYXhpcywxKTtsZXQgd2E9ITE7Zm9yKGNvbnN0IEVhIG9mIGJhKWlmKGFycmF5c0VxdWFsJDEoRWEsVGEpKXt3YT0hMDticmVha313YXx8YmEucHVzaChUYSl9aWYoYmEubGVuZ3RoPjEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoIkEgYENvbmNhdGVuYXRlYCBsYXllciByZXF1aXJlcyBpbnB1dHMgd2l0aCBtYXRjaGluZyBzaGFwZXMgZXhjZXB0IGZvciB0aGUgY29uY2F0IGF4aXMuIEdvdCBpbnB1dCBzaGFwZXM6ICIrSlNPTi5zdHJpbmdpZnkoYWEpKX1tZXJnZUZ1bmN0aW9uKGFhKXtyZXR1cm4gdGlkeSQxKCgpPT5jb25jYXRlbmF0ZShhYSx0aGlzLmF4aXMpKX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2lmKCEoQXJyYXkuaXNBcnJheShhYSkmJkFycmF5LmlzQXJyYXkoYWFbMF0pKSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiQSBgQ29uY2F0ZW5hdGVgIGxheWVyIHNob3VsZCBiZSBjYWxsZWQgb24gYSBsaXN0IG9mIGlucHV0cy4iKTtjb25zdCB4YT1hYSxiYT14YVswXS5zbGljZSgpLFNhPXRoaXMuYXhpczwwP2JhLmxlbmd0aCt0aGlzLmF4aXM6dGhpcy5heGlzO2Zvcihjb25zdCBUYSBvZiB4YS5zbGljZSgxKSl7aWYoYmFbU2FdPT1udWxsfHxUYVtTYV09PW51bGwpe2JhW1NhXT1udWxsO2JyZWFrfWJhW1NhXSs9VGFbU2FdfXJldHVybiBiYX1jb21wdXRlTWFzayhhYSx4YSl7aWYoeGE9PW51bGwpcmV0dXJuIG51bGw7aWYoIUFycmF5LmlzQXJyYXkoeGEpKXRocm93IG5ldyBWYWx1ZUVycm9yKCJgbWFza2Agc2hvdWxkIGJlIGFuIGFycmF5IGZvciBDb25jYXRlbmF0ZSIpO2lmKCFBcnJheS5pc0FycmF5KGFhKSl0aHJvdyBuZXcgVmFsdWVFcnJvcigiYGlucHV0c2Agc2hvdWxkIGJlIGFuIGFycmF5IGZvciBDb25jYXRlbmF0ZSIpO2lmKHhhLmxlbmd0aCE9PWFhLmxlbmd0aCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgTWlzbWF0Y2ggaW4gdGhlIGxlbmd0aCBvZiBtYXNrICgke3hhLmxlbmd0aH0pIGFuZCB0aGUgbGVnbnRoIG9mIGlucHV0cyAoJHthYS5sZW5ndGh9KWApO3JldHVybiB0aWR5JDEoKCk9PntsZXQgYmE9ITA7aWYoeGEuZm9yRWFjaCh3YT0+e2lmKHdhIT1udWxsKXtiYT0hMTtyZXR1cm59fSksYmEpcmV0dXJuIG51bGw7Y29uc3QgU2E9W107Zm9yKGxldCB3YT0wO3dhPGFhLmxlbmd0aDsrK3dhKXhhW3dhXT09bnVsbD9TYS5wdXNoKGNhc3QkNShvbmVzTGlrZSQzKGFhW3dhXSksImJvb2wiKSk6eGFbd2FdLnJhbms8YWFbd2FdLnJhbms/U2EucHVzaChleHBhbmREaW1zJDQoeGFbd2FdLC0xKSk6U2EucHVzaCh4YVt3YV0pO2NvbnN0IFRhPWNvbmNhdCQzKFNhLHRoaXMuYXhpcyk7cmV0dXJuIGFsbCQzKFRhLC0xLCExKX0pfWdldENvbmZpZygpe2NvbnN0IGFhPXtheGlzOnRoaXMuYXhpc30seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1Db25jYXRlbmF0ZS5jbGFzc05hbWU9IkNvbmNhdGVuYXRlIixyZWdpc3RlckNsYXNzJDEoQ29uY2F0ZW5hdGUpO2Z1bmN0aW9uIGludGVycHJldEF4aXMoaGEsYWEpe2Zvcig7aGE8MDspaGErPWFhO3JldHVybiBoYX1mdW5jdGlvbiBiYXRjaERvdChoYSxhYSx4YSl7aWYoaGEuc2hhcGUubGVuZ3RoPjN8fGFhLnNoYXBlLmxlbmd0aD4zKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJiYXRjaERvdCBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIHRlbnNvcnMgb2YgNEQgb3IgaGlnaGVyIHJhbmsgeWV0Iik7aWYoYXNzZXJ0JDIoaGEuc2hhcGUubGVuZ3RoPj0yLCgpPT5gYmF0Y2hEb3QgcmVxdWlyZXMgdGhlIHJhbmsgb2YgeCB0byBiZSA+PSAyLCBidXQgZ290ICR7aGEuc2hhcGUubGVuZ3RofWApLGFzc2VydCQyKGhhLnNoYXBlLmxlbmd0aD49MiwoKT0+YGJhdGNoRG90IHJlcXVpcmVzIHRoZSByYW5rIG9mIHkgdG8gYmUgPj0gMiwgYnV0IGdvdCAke2FhLnNoYXBlLmxlbmd0aH1gKSx0eXBlb2YgeGE9PSJudW1iZXIiJiYoeGE9W3hhLHhhXSksaGEuZHR5cGU9PT0iY29tcGxleDY0Inx8YWEuZHR5cGU9PT0iY29tcGxleDY0Iil0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiYmF0Y2hEb3QgaXMgbm90IGltcGxlbWVudGVkIGZvciBjb21wbGV4NjQtdHlwZSBUZW5zb3JzIHlldC4iKTtjb25zdCBiYT1oYS5zaGFwZS5sZW5ndGgsU2E9YWEuc2hhcGUubGVuZ3RoO3hhPT1udWxsJiYoeGE9W2JhLTEsU2EtMl0pO2NvbnN0IFRhPXhhO3JldHVybiB0aWR5JDEoKCk9PntsZXQgd2E7aWYoYmE+U2Epe3dhPWJhLVNhO2NvbnN0IGthPVtdO2ZvcihsZXQgQWE9MDtBYTx3YTsrK0FhKWthLnB1c2goMSk7YWE9cmVzaGFwZSQ0KGFhLGFhLnNoYXBlLmNvbmNhdChrYSkpfWVsc2UgaWYoU2E+YmEpe3dhPVNhLWJhO2NvbnN0IGthPVtdO2ZvcihsZXQgQWE9MDtBYTx3YTsrK0FhKWthLnB1c2goMSk7aGE9cmVzaGFwZSQ0KGhhLGhhLnNoYXBlLmNvbmNhdChrYSkpfWVsc2Ugd2E9MDtsZXQgRWE7aWYoaGEuc2hhcGUubGVuZ3RoPT09MiYmYWEuc2hhcGUubGVuZ3RoPT09MilUYVswXT09PVRhWzFdP0VhPXN1bSQ1KG11bCQxKGhhLGFhKSxUYVswXSk6RWE9c3VtJDUobXVsJDEodHJhbnNwb3NlJDMoaGEsWzEsMF0pLGFhKSxUYVsxXSk7ZWxzZXtjb25zdCBrYT1UYVswXSE9PWhhLnNoYXBlLmxlbmd0aC0xLEFhPVRhWzFdPT09YWEuc2hhcGUubGVuZ3RoLTE7RWE9bWF0TXVsJDEoaGEsYWEsa2EsQWEpfWlmKHdhPjApe2xldCBrYTtiYT5TYT9rYT1iYStTYS0zOmthPWJhLTE7Y29uc3QgQWE9W107Zm9yKGxldCBGYT1rYTtGYTxrYSt3YTsrK0ZhKUFhLnB1c2goRmEpO0VhPXNxdWVlemUoRWEsQWEpfXJldHVybiBFYS5zaGFwZS5sZW5ndGg9PT0xJiYoRWE9ZXhwYW5kRGltcyQ0KEVhLDEpKSxFYX0pfWNsYXNzIERvdCBleHRlbmRzIE1lcmdle2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5heGVzPWFhLmF4ZXMsdGhpcy5ub3JtYWxpemU9YWEubm9ybWFsaXplPT1udWxsPyExOmFhLm5vcm1hbGl6ZSx0aGlzLnN1cHBvcnRzTWFza2luZz0hMCx0aGlzLnJlc2hhcGVSZXF1aXJlZD0hMX1idWlsZChhYSl7YXNzZXJ0JDIoQXJyYXkuaXNBcnJheShhYSkmJmFhLmxlbmd0aD09PTImJkFycmF5LmlzQXJyYXkoYWFbMF0pJiZBcnJheS5pc0FycmF5KGFhWzFdKSwoKT0+IkEgYERvdGAgbGF5ZXIgc2hvdWxkIGJlIGNhbGxlZCBvbiBhIGxpc3Qgb2YgZXhhY3RseSAyIGlucHV0cy4iKTtjb25zdCB4YT1hYVswXSxiYT1hYVsxXTtpZih4YS5sZW5ndGg+M3x8YmEubGVuZ3RoPjMpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoIkRvdCBsYXllciBkb2VzIG5vdCBzdXBwb3J0IHRlbnNvcnMgb2YgNEQgb3IgaGlnaGVyIHJhbmsgeWV0LiIpO2NvbnN0IFNhPXRoaXMuaW50ZXJwcmV0QXhlcyh4YSxiYSk7aWYoeGFbU2FbMF1dIT09YmFbU2FbMV1dKXRocm93IG5ldyBWYWx1ZUVycm9yKGBEaW1lbnNpb24gaW5jb21wYXRpYmlsaXR5OiAke3hhW1NhWzBdXX0gIT09ICR7YmFbU2FbMV1dfWApfW1lcmdlRnVuY3Rpb24oYWEpe2lmKGFhLmxlbmd0aCE9PTIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEEgXGBEb3RcYCBsYXllciBtdXN0IGJlIGNhbGxlZCBvbiBleGFjdGx5IDIgaW5wdXRzLCBidXQgcmVjZWl2ZWQgJHthYS5sZW5ndGh9IGlucHV0KHMpLmApO2xldCB4YT1hYVswXSxiYT1hYVsxXSxTYTtyZXR1cm4gQXJyYXkuaXNBcnJheSh0aGlzLmF4ZXMpP1NhPXRoaXMuYXhlcy5tYXAoKFRhLHdhKT0+aW50ZXJwcmV0QXhpcyhUYSxhYVt3YV0uc2hhcGUubGVuZ3RoKSk6U2E9W2ludGVycHJldEF4aXModGhpcy5heGVzLHhhLnNoYXBlLmxlbmd0aCksaW50ZXJwcmV0QXhpcyh0aGlzLmF4ZXMsYmEuc2hhcGUubGVuZ3RoKV0sdGhpcy5ub3JtYWxpemUmJih4YT1sMk5vcm1hbGl6ZSh4YSxTYVswXSksYmE9bDJOb3JtYWxpemUoYmEsU2FbMV0pKSxiYXRjaERvdCh4YSxiYSxTYSl9aW50ZXJwcmV0QXhlcyhhYSx4YSl7bGV0IGJhO3JldHVybiBBcnJheS5pc0FycmF5KHRoaXMuYXhlcyk/YmE9dGhpcy5heGVzOmJhPVtpbnRlcnByZXRBeGlzKHRoaXMuYXhlcyxhYS5sZW5ndGgpLGludGVycHJldEF4aXModGhpcy5heGVzLHhhLmxlbmd0aCldLGJhfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7YXNzZXJ0JDIoQXJyYXkuaXNBcnJheShhYSkmJmFhLmxlbmd0aD09PTImJkFycmF5LmlzQXJyYXkoYWFbMF0pJiZBcnJheS5pc0FycmF5KGFhWzFdKSwoKT0+IkEgYERvdGAgbGF5ZXIgc2hvdWxkIGJlIGNhbGxlZCBvbiBhIGxpc3Qgb2YgZXhhY3RseSAyIGlucHV0cy4iKTtjb25zdCB4YT1hYVswXS5zbGljZSgpLGJhPWFhWzFdLnNsaWNlKCk7aWYoeGEubGVuZ3RoPjN8fGJhLmxlbmd0aD4zKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJEb3QgbGF5ZXIgZG9lcyBub3Qgc3VwcG9ydCB0ZW5zb3JzIG9mIDREIG9yIGhpZ2hlciByYW5rIHlldC4iKTtjb25zdCBTYT10aGlzLmludGVycHJldEF4ZXMoeGEsYmEpO3hhLnNwbGljZShTYVswXSwxKSxiYS5zcGxpY2UoU2FbMV0sMSksYmEuc3BsaWNlKDAsMSk7Y29uc3QgVGE9eGEuY29uY2F0KGJhKTtyZXR1cm4gVGEubGVuZ3RoPT09MSYmVGEucHVzaCgxKSxUYX1jb21wdXRlTWFzayhhYSx4YSl7cmV0dXJuIG51bGx9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e2F4ZXM6dGhpcy5heGVzLG5vcm1hbGl6ZTp0aGlzLm5vcm1hbGl6ZX0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1Eb3QuY2xhc3NOYW1lPSJEb3QiLHJlZ2lzdGVyQ2xhc3MkMShEb3QpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEdhdXNzaWFuTm9pc2UgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwLHRoaXMuc3RkZGV2PWFhLnN0ZGRldn1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYX1nZXRDb25maWcoKXtjb25zdCBhYT1zdXBlci5nZXRDb25maWcoKSx4YT17c3RkZGV2OnRoaXMuc3RkZGV2fTtyZXR1cm4gT2JqZWN0LmFzc2lnbih4YSxhYSkseGF9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e3RoaXMuaW52b2tlQ2FsbEhvb2soYWEseGEpO2NvbnN0IGJhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpO3JldHVybiBpblRyYWluUGhhc2UoKCk9PmFkZCQzKHJhbmRvbU5vcm1hbChiYS5zaGFwZSwwLHRoaXMuc3RkZGV2KSxiYSksKCk9PmJhLHhhLnRyYWluaW5nfHwhMSl9KX19R2F1c3NpYW5Ob2lzZS5jbGFzc05hbWU9IkdhdXNzaWFuTm9pc2UiLHJlZ2lzdGVyQ2xhc3MkMShHYXVzc2lhbk5vaXNlKTtjbGFzcyBHYXVzc2lhbkRyb3BvdXQgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwLHRoaXMucmF0ZT1hYS5yYXRlfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7cmV0dXJuIGFhfWdldENvbmZpZygpe2NvbnN0IGFhPXN1cGVyLmdldENvbmZpZygpLHhhPXtyYXRlOnRoaXMucmF0ZX07cmV0dXJuIE9iamVjdC5hc3NpZ24oeGEsYWEpLHhhfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pnt0aGlzLmludm9rZUNhbGxIb29rKGFhLHhhKTtjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtyZXR1cm4gdGhpcy5yYXRlPjAmJnRoaXMucmF0ZTwxP2luVHJhaW5QaGFzZSgoKT0+e2NvbnN0IFRhPU1hdGguc3FydCh0aGlzLnJhdGUvKDEtdGhpcy5yYXRlKSk7cmV0dXJuIG11bCQxKGJhLHJhbmRvbU5vcm1hbChiYS5zaGFwZSwxLFRhKSl9LCgpPT5iYSx4YS50cmFpbmluZ3x8ITEpOmJhfSl9fUdhdXNzaWFuRHJvcG91dC5jbGFzc05hbWU9IkdhdXNzaWFuRHJvcG91dCIscmVnaXN0ZXJDbGFzcyQxKEdhdXNzaWFuRHJvcG91dCk7Y2xhc3MgQWxwaGFEcm9wb3V0IGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSx0aGlzLnN1cHBvcnRzTWFza2luZz0hMCx0aGlzLnJhdGU9YWEucmF0ZSx0aGlzLm5vaXNlU2hhcGU9YWEubm9pc2VTaGFwZX1fZ2V0Tm9pc2VTaGFwZShhYSl7cmV0dXJuIHRoaXMubm9pc2VTaGFwZXx8Z2V0RXhhY3RseU9uZVRlbnNvcihhYSkuc2hhcGV9Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXtyZXR1cm4gYWF9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9c3VwZXIuZ2V0Q29uZmlnKCkseGE9e3JhdGU6dGhpcy5yYXRlfTtyZXR1cm4gT2JqZWN0LmFzc2lnbih4YSxhYSkseGF9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2lmKHRoaXMucmF0ZTwxJiZ0aGlzLnJhdGU+MCl7Y29uc3QgYmE9dGhpcy5fZ2V0Tm9pc2VTaGFwZShhYSk7cmV0dXJuIGluVHJhaW5QaGFzZSgoKT0+e2NvbnN0IFRhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLGthPS0xLjY3MzI2MzI0MjM1NDM3NzIqMS4wNTA3MDA5ODczNTU0ODA1O2xldCBBYT1ncmVhdGVyRXF1YWwkMyhyYW5kb21Vbmlmb3JtKGJhKSx0aGlzLnJhdGUpO0FhPWNhc3QkNChBYSwiZmxvYXQzMiIpO2NvbnN0IEZhPSgoMS10aGlzLnJhdGUpKigxK3RoaXMucmF0ZSprYSoqMikpKiotLjUsTGE9LUZhKmthKnRoaXMucmF0ZSxlbD1hZGQkMyhtdWwkMShUYSxBYSksbXVsJDEoYWRkJDMoQWEsLTEpLGthKSk7cmV0dXJuIGFkZCQzKG11bCQxKGVsLEZhKSxMYSl9LCgpPT5nZXRFeGFjdGx5T25lVGVuc29yKGFhKSx4YS50cmFpbmluZ3x8ITEpfXJldHVybiBhYX0pfX1BbHBoYURyb3BvdXQuY2xhc3NOYW1lPSJBbHBoYURyb3BvdXQiLHJlZ2lzdGVyQ2xhc3MkMShBbHBoYURyb3BvdXQpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJhdGNoTm9ybWFsaXphdGlvbihoYSxhYSx4YSxiYSxTYSxUYT0uMDAxKXtsZXQgd2E7aWYoaGEucmFuaz09PTIpd2E9YmF0Y2hOb3JtMmQoaGEsYWEseGEsYmEsU2EsVGEpO2Vsc2UgaWYoaGEucmFuaz09PTMpd2E9YmF0Y2hOb3JtM2QoaGEsYWEseGEsYmEsU2EsVGEpO2Vsc2UgaWYoaGEucmFuaz09PTQpd2E9YmF0Y2hOb3JtNGQoaGEsYWEseGEsYmEsU2EsVGEpO2Vsc2UgdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoYGJhdGNoTm9ybWFsaXphdGlvbiBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIGFycmF5IG9mIHJhbmsgJHtoYS5yYW5rfSB5ZXRgKTtyZXR1cm4gd2F9ZnVuY3Rpb24gcmVndWxhck5vcm1hbGl6ZUJhdGNoSW5UcmFpbmluZyhoYSxhYSx4YSxiYSxTYT0uMDAxKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgVGE9bW9tZW50cyhoYSxiYSksd2E9VGEubWVhbixFYT1UYS52YXJpYW5jZTtyZXR1cm5bYmF0Y2hOb3JtYWxpemF0aW9uKGhhLHdhLEVhLHhhLGFhLFNhKSx3YSxFYV19KX1mdW5jdGlvbiBicm9hZGNhc3ROb3JtYWxpemVCYXRjaEluVHJhaW5pbmcoaGEsYWEseGEsYmEsU2E9LjAwMSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IFRhPW1vbWVudHMoaGEsYmEpLHdhPVRhLm1lYW4sRWE9VGEudmFyaWFuY2Usa2E9W107Zm9yKGNvbnN0IG5sIG9mIHJhbmdlJDMoMCxoYS5yYW5rKSliYS5pbmRleE9mKG5sKSE9PS0xP2thLnB1c2goMSk6a2EucHVzaChoYS5zaGFwZVtubF0pO2NvbnN0IEFhPXJlc2hhcGUkNCh3YSxrYSksRmE9cmVzaGFwZSQ0KEVhLGthKSxMYT1hYT09bnVsbD9udWxsOnJlc2hhcGUkNChhYSxrYSksZWw9eGE9PW51bGw/bnVsbDpyZXNoYXBlJDQoeGEsa2EpO3JldHVybltiYXRjaE5vcm1hbGl6YXRpb24oaGEsQWEsRmEsZWwsTGEsU2EpLHdhLEVhXX0pfWZ1bmN0aW9uIG5vcm1hbGl6ZUJhdGNoSW5UcmFpbmluZyhoYSxhYSx4YSxiYSxTYT0uMDAxKXtyZXR1cm4gYXJyYXlzRXF1YWwkMShiYS5zbGljZSgpLnNvcnQoKSxyYW5nZSQzKDAsaGEucmFuay0xKSk/cmVndWxhck5vcm1hbGl6ZUJhdGNoSW5UcmFpbmluZyhoYSxhYSx4YSxiYSxTYSk6YnJvYWRjYXN0Tm9ybWFsaXplQmF0Y2hJblRyYWluaW5nKGhhLGFhLHhhLGJhLFNhKX1jbGFzcyBCYXRjaE5vcm1hbGl6YXRpb24gZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7YWE9PW51bGwmJihhYT17fSksc3VwZXIoYWEpLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwLHRoaXMuYXhpcz1hYS5heGlzPT1udWxsPy0xOmFhLmF4aXMsdGhpcy5tb21lbnR1bT1hYS5tb21lbnR1bT09bnVsbD8uOTk6YWEubW9tZW50dW0sdGhpcy5lcHNpbG9uPWFhLmVwc2lsb249PW51bGw/LjAwMTphYS5lcHNpbG9uLHRoaXMuY2VudGVyPWFhLmNlbnRlcj09bnVsbD8hMDphYS5jZW50ZXIsdGhpcy5zY2FsZT1hYS5zY2FsZT09bnVsbD8hMDphYS5zY2FsZSx0aGlzLmJldGFJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5iZXRhSW5pdGlhbGl6ZXJ8fCJ6ZXJvcyIpLHRoaXMuZ2FtbWFJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5nYW1tYUluaXRpYWxpemVyfHwib25lcyIpLHRoaXMubW92aW5nTWVhbkluaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLm1vdmluZ01lYW5Jbml0aWFsaXplcnx8Inplcm9zIiksdGhpcy5tb3ZpbmdWYXJpYW5jZUluaXRpYWxpemVyPWdldEluaXRpYWxpemVyKGFhLm1vdmluZ1ZhcmlhbmNlSW5pdGlhbGl6ZXJ8fCJvbmVzIiksdGhpcy5iZXRhQ29uc3RyYWludD1nZXRDb25zdHJhaW50KGFhLmJldGFDb25zdHJhaW50KSx0aGlzLmdhbW1hQ29uc3RyYWludD1nZXRDb25zdHJhaW50KGFhLmdhbW1hQ29uc3RyYWludCksdGhpcy5iZXRhUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEuYmV0YVJlZ3VsYXJpemVyKSx0aGlzLmdhbW1hUmVndWxhcml6ZXI9Z2V0UmVndWxhcml6ZXIoYWEuZ2FtbWFSZWd1bGFyaXplcil9YnVpbGQoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9dGhpcy5heGlzPj0wP3RoaXMuYXhpczp0aGlzLmF4aXMrYWEubGVuZ3RoLGJhPWFhW3hhXTtpZihiYT09bnVsbCl0aHJvdyBuZXcgVmFsdWVFcnJvcihgQXhpcyAke3hhfSBvZiBpbnB1dCB0ZW5zb3Igc2hvdWxkIGhhdmUgYSBkZWZpbmVkIGRpbWVuc2lvbiBidXQgdGhlIGxheWVyIHJlY2VpdmVkIGFuIGlucHV0IHdpdGggc2hhcGUgJHtKU09OLnN0cmluZ2lmeShhYSl9LmApO3RoaXMuaW5wdXRTcGVjPVtuZXcgSW5wdXRTcGVjKHtuZGltOmFhLmxlbmd0aCxheGVzOntbeGFdOmJhfX0pXTtjb25zdCBTYT1bYmFdO3RoaXMuc2NhbGUmJih0aGlzLmdhbW1hPXRoaXMuYWRkV2VpZ2h0KCJnYW1tYSIsU2EsbnVsbCx0aGlzLmdhbW1hSW5pdGlhbGl6ZXIsdGhpcy5nYW1tYVJlZ3VsYXJpemVyLCEwLHRoaXMuZ2FtbWFDb25zdHJhaW50KSksdGhpcy5jZW50ZXImJih0aGlzLmJldGE9dGhpcy5hZGRXZWlnaHQoImJldGEiLFNhLG51bGwsdGhpcy5iZXRhSW5pdGlhbGl6ZXIsdGhpcy5iZXRhUmVndWxhcml6ZXIsITAsdGhpcy5iZXRhQ29uc3RyYWludCkpLHRoaXMubW92aW5nTWVhbj10aGlzLmFkZFdlaWdodCgibW92aW5nX21lYW4iLFNhLG51bGwsdGhpcy5tb3ZpbmdNZWFuSW5pdGlhbGl6ZXIsbnVsbCwhMSksdGhpcy5tb3ZpbmdWYXJpYW5jZT10aGlzLmFkZFdlaWdodCgibW92aW5nX3ZhcmlhbmNlIixTYSxudWxsLHRoaXMubW92aW5nVmFyaWFuY2VJbml0aWFsaXplcixudWxsLCExKSx0aGlzLmJ1aWx0PSEwfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT14YS50cmFpbmluZz09bnVsbD8hMTp4YS50cmFpbmluZyxTYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKSxUYT1TYS5zaGFwZSx3YT1UYS5sZW5ndGgsRWE9cmFuZ2UkMygwLHdhKSxrYT10aGlzLmF4aXM+PTA/dGhpcy5heGlzOnRoaXMuYXhpcyt3YTtFYS5zcGxpY2Uoa2EsMSk7Y29uc3QgQWE9cHlMaXN0UmVwZWF0KDEsd2EpO0FhW2thXT1UYVtrYV07Y29uc3QgRmE9RWEuc2xpY2UoKTtGYS5zb3J0KCk7Y29uc3QgTGE9IWFycmF5c0VxdWFsJDEoRmEscmFuZ2UkMygwLHdhKS5zbGljZSgwLHdhLTEpKSxlbD0oKT0+e2lmKExhKXtjb25zdCBhbD1yZXNoYXBlJDQodGhpcy5tb3ZpbmdNZWFuLnJlYWQoKSxBYSksbGw9cmVzaGFwZSQ0KHRoaXMubW92aW5nVmFyaWFuY2UucmVhZCgpLEFhKSxpbD10aGlzLmNlbnRlcj9yZXNoYXBlJDQodGhpcy5iZXRhLnJlYWQoKSxBYSk6bnVsbCxjbD10aGlzLnNjYWxlP3Jlc2hhcGUkNCh0aGlzLmdhbW1hLnJlYWQoKSxBYSk6bnVsbDtyZXR1cm4gYmF0Y2hOb3JtYWxpemF0aW9uKFNhLGFsLGxsLGlsLGNsLHRoaXMuZXBzaWxvbil9ZWxzZSByZXR1cm4gYmF0Y2hOb3JtYWxpemF0aW9uKFNhLHRoaXMubW92aW5nTWVhbi5yZWFkKCksdGhpcy5tb3ZpbmdWYXJpYW5jZS5yZWFkKCksdGhpcy5iZXRhPT1udWxsP251bGw6dGhpcy5iZXRhLnJlYWQoKSx0aGlzLmdhbW1hPT1udWxsP251bGw6dGhpcy5nYW1tYS5yZWFkKCksdGhpcy5lcHNpbG9uKX07aWYoIWJhKXJldHVybiBlbCgpO2NvbnN0W3RsLG5sLHNsXT1ub3JtYWxpemVCYXRjaEluVHJhaW5pbmcoU2EsdGhpcy5nYW1tYS5yZWFkKCksdGhpcy5iZXRhLnJlYWQoKSxFYSx0aGlzLmVwc2lsb24pLHJsPShhbCxsbCxpbCk9Pnt0aWR5JDEoKCk9Pntjb25zdCBjbD0xLWlsLHVsPWFsLnJlYWQoKSxkbD1tdWwkMShzdWIkNCh1bCxsbCksY2wpO2FsLndyaXRlKHN1YiQ0KHVsLGRsKSl9KX07cmV0dXJuKCgpPT57cmwodGhpcy5tb3ZpbmdNZWFuLG5sLHRoaXMubW9tZW50dW0pLHJsKHRoaXMubW92aW5nVmFyaWFuY2Usc2wsdGhpcy5tb21lbnR1bSl9KSgpLHRsfSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e2F4aXM6dGhpcy5heGlzLG1vbWVudHVtOnRoaXMubW9tZW50dW0sZXBzaWxvbjp0aGlzLmVwc2lsb24sY2VudGVyOnRoaXMuY2VudGVyLHNjYWxlOnRoaXMuc2NhbGUsYmV0YUluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuYmV0YUluaXRpYWxpemVyKSxnYW1tYUluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuZ2FtbWFJbml0aWFsaXplciksbW92aW5nTWVhbkluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMubW92aW5nTWVhbkluaXRpYWxpemVyKSxtb3ZpbmdWYXJpYW5jZUluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMubW92aW5nVmFyaWFuY2VJbml0aWFsaXplciksYmV0YVJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuYmV0YVJlZ3VsYXJpemVyKSxnYW1tYVJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuZ2FtbWFSZWd1bGFyaXplciksYmV0YUNvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmJldGFDb25zdHJhaW50KSxnYW1tYUNvbnN0cmFpbnQ6c2VyaWFsaXplQ29uc3RyYWludCh0aGlzLmdhbW1hQ29uc3RyYWludCl9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19QmF0Y2hOb3JtYWxpemF0aW9uLmNsYXNzTmFtZT0iQmF0Y2hOb3JtYWxpemF0aW9uIixyZWdpc3RlckNsYXNzJDEoQmF0Y2hOb3JtYWxpemF0aW9uKTtjbGFzcyBMYXllck5vcm1hbGl6YXRpb24gZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7aWYoYWE9PW51bGwmJihhYT17fSksc3VwZXIoYWEpLHRoaXMuYXhpcz1hYS5heGlzPT1udWxsPy0xOmFhLmF4aXMsdHlwZW9mIHRoaXMuYXhpcz09Im51bWJlciIpe2lmKCFOdW1iZXIuaXNJbnRlZ2VyKHRoaXMuYXhpcykpdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBheGlzIHRvIGJlIGFuIGludGVnZXIsIGJ1dCByZWNlaXZlZCAke3RoaXMuYXhpc31gKX1lbHNlIGlmKEFycmF5LmlzQXJyYXkodGhpcy5heGlzKSl7Zm9yKGNvbnN0IHhhIG9mIHRoaXMuYXhpcylpZighTnVtYmVyLmlzSW50ZWdlcih4YSkpdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBheGlzIHRvIGJlIGFuIGFycmF5IG9mIGludGVnZXJzLCBidXQgcmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeSh0aGlzLmF4aXMpfWApfWVsc2UgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBheGlzIHRvIGJlIGFuIGludGVnZXIgb3IgYW4gYXJyYXkgb2YgaW50ZWdlcnMsIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KHRoaXMuYXhpcyl9YCk7dGhpcy5lcHNpbG9uPWFhLmVwc2lsb249PW51bGw/LjAwMTphYS5lcHNpbG9uLHRoaXMuY2VudGVyPWFhLmNlbnRlcj09bnVsbD8hMDphYS5jZW50ZXIsdGhpcy5zY2FsZT1hYS5zY2FsZT09bnVsbD8hMDphYS5zY2FsZSx0aGlzLmJldGFJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5iZXRhSW5pdGlhbGl6ZXJ8fCJ6ZXJvcyIpLHRoaXMuZ2FtbWFJbml0aWFsaXplcj1nZXRJbml0aWFsaXplcihhYS5nYW1tYUluaXRpYWxpemVyfHwib25lcyIpLHRoaXMuYmV0YVJlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmJldGFSZWd1bGFyaXplciksdGhpcy5nYW1tYVJlZ3VsYXJpemVyPWdldFJlZ3VsYXJpemVyKGFhLmdhbW1hUmVndWxhcml6ZXIpLHRoaXMuc3VwcG9ydHNNYXNraW5nPSEwfWJ1aWxkKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IHhhPWFhLmxlbmd0aDt0eXBlb2YgdGhpcy5heGlzPT0ibnVtYmVyIiYmKHRoaXMuYXhpcz1bdGhpcy5heGlzXSk7Zm9yKGxldCBUYT0wO1RhPHRoaXMuYXhpcy5sZW5ndGg7KytUYSl0aGlzLmF4aXNbVGFdPDAmJih0aGlzLmF4aXNbVGFdKz14YSk7Zm9yKGNvbnN0IFRhIG9mIHRoaXMuYXhpcylpZihUYTwwfHxUYT49eGEpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGF4aXM6ICR7VGF9YCk7aWYodGhpcy5heGlzLmxlbmd0aCE9PXVuaXF1ZSQzKHRoaXMuYXhpcykubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgRm91bmQgZHVwbGljYXRlIGF4ZXMgaW46ICR7dGhpcy5heGlzfWApO2NvbnN0IGJhPXRoaXMuYXhpcy5tYXAoVGE9PmFhW1RhXSksU2E9ITA7dGhpcy5zY2FsZT90aGlzLmdhbW1hPXRoaXMuYWRkV2VpZ2h0KCJnYW1tYSIsYmEsImZsb2F0MzIiLHRoaXMuZ2FtbWFJbml0aWFsaXplcix0aGlzLmdhbW1hUmVndWxhcml6ZXIsU2EpOnRoaXMuZ2FtbWE9bnVsbCx0aGlzLmNlbnRlcj90aGlzLmJldGE9dGhpcy5hZGRXZWlnaHQoImJldGEiLGJhLCJmbG9hdDMyIix0aGlzLmJldGFJbml0aWFsaXplcix0aGlzLmJldGFSZWd1bGFyaXplcixTYSk6dGhpcy5iZXRhPW51bGwsdGhpcy5idWlsdD0hMH1jYWxsKGFhLHhhKXtjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKSxTYT1iYS5zaGFwZSxUYT1TYS5sZW5ndGg7cmV0dXJuIHRpZHkkMSgoKT0+e2xldHttZWFuOkVhLHZhcmlhbmNlOmthfT1tb21lbnRzKGJhLHRoaXMuYXhpcywhMCk7Y29uc3QgQWE9cHlMaXN0UmVwZWF0KDEsVGEpO2Zvcihjb25zdCBzbCBvZiB0aGlzLmF4aXMpQWFbc2xdPVNhW3NsXTtjb25zdCBGYT1zbD0+c2whPW51bGwmJnNsLnNoYXBlLmxlbmd0aCE9PVRhP3Jlc2hhcGUkNChzbCxBYSk6c2w7bGV0IExhPXRoaXMuc2NhbGU/RmEodGhpcy5nYW1tYS5yZWFkKCkpOm51bGwsZWw9dGhpcy5jZW50ZXI/RmEodGhpcy5iZXRhLnJlYWQoKSk6bnVsbDtjb25zdCB0bD1bXSxubD1bXTtmb3IobGV0IHNsPTA7c2w8VGE7KytzbCl0aGlzLmF4aXMuaW5kZXhPZihzbCkhPT0tMT8odGwucHVzaChTYVtzbF0pLG5sLnB1c2goMSkpOih0bC5wdXNoKDEpLG5sLnB1c2goU2Fbc2xdKSk7cmV0dXJuIEVhPXRpbGUkNChFYSx0bCksa2E9dGlsZSQ0KGthLHRsKSxMYSE9bnVsbCYmKExhPXRpbGUkNChMYSxubCkpLGVsIT1udWxsJiYoZWw9dGlsZSQ0KGVsLG5sKSksYmF0Y2hOb3JtYWxpemF0aW9uKGJhLEVhLGthLGVsLExhLHRoaXMuZXBzaWxvbil9KX1nZXRDb25maWcoKXtjb25zdCBhYT17YXhpczp0aGlzLmF4aXMsZXBzaWxvbjp0aGlzLmVwc2lsb24sY2VudGVyOnRoaXMuY2VudGVyLHNjYWxlOnRoaXMuc2NhbGUsYmV0YUluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuYmV0YUluaXRpYWxpemVyKSxnYW1tYUluaXRpYWxpemVyOnNlcmlhbGl6ZUluaXRpYWxpemVyKHRoaXMuZ2FtbWFJbml0aWFsaXplciksYmV0YVJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuYmV0YVJlZ3VsYXJpemVyKSxnYW1tYVJlZ3VsYXJpemVyOnNlcmlhbGl6ZVJlZ3VsYXJpemVyKHRoaXMuZ2FtbWFSZWd1bGFyaXplcil9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19TGF5ZXJOb3JtYWxpemF0aW9uLmNsYXNzTmFtZT0iTGF5ZXJOb3JtYWxpemF0aW9uIixyZWdpc3RlckNsYXNzJDEoTGF5ZXJOb3JtYWxpemF0aW9uKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGF0aWFsMmRQYWRkaW5nKGhhLGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57aWYoaGEucmFuayE9PTQpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYHRlbXBvcmFsUGFkZGluZyBleHBlY3RzIGlucHV0IHRlbnNvciB0byBiZSA0LUQsIGJ1dCByZWNlaXZlZCBhICR7aGEucmFua30tRCB0ZW5zb3IuYCk7aWYoYWE9PW51bGwmJihhYT1bWzEsMV0sWzEsMV1dKSxhYS5sZW5ndGghPT0yfHxhYVswXS5sZW5ndGghPT0yfHxhYVsxXS5sZW5ndGghPT0yKXRocm93IG5ldyBWYWx1ZUVycm9yKCJzcGF0aWFsMmRQYWRkaW5nIGV4cGVjdHMgYHBhZGRpbmdgIHRvIGJlIGFuIEFycmF5IG9mIHR3byBBcnJheXMsIGVhY2ggb2Ygd2hpY2ggaXMgYW4gQXJyYXkgb2YgdHdvIGludGVnZXJzLiIpO2lmKHhhPT1udWxsJiYoeGE9aW1hZ2VEYXRhRm9ybWF0KCkpLHhhIT09ImNoYW5uZWxzTGFzdCImJnhhIT09ImNoYW5uZWxzRmlyc3QiKXRocm93IG5ldyBWYWx1ZUVycm9yKGBVbmtub3duIGRhdGEgZm9ybWF0OiAke3hhfS4gU3VwcG9ydGVkIGRhdGEgZm9ybWF0cyBhcmUgJ2NoYW5uZWxzTGFzdCcgYW5kICdjaGFubmVsc0ZpcnN0LmApO2xldCBiYTtyZXR1cm4geGE9PT0iY2hhbm5lbHNGaXJzdCI/YmE9W1swLDBdLFswLDBdLGFhWzBdLGFhWzFdXTpiYT1bWzAsMF0sYWFbMF0sYWFbMV0sWzAsMF1dLHBhZChoYSxiYSl9KX1jbGFzcyBaZXJvUGFkZGluZzJEIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKGFhPT1udWxsJiYoYWE9e30pLHN1cGVyKGFhKSx0aGlzLmRhdGFGb3JtYXQ9YWEuZGF0YUZvcm1hdD09bnVsbD9pbWFnZURhdGFGb3JtYXQoKTphYS5kYXRhRm9ybWF0LGFhLnBhZGRpbmc9PW51bGwpdGhpcy5wYWRkaW5nPVtbMSwxXSxbMSwxXV07ZWxzZSBpZih0eXBlb2YgYWEucGFkZGluZz09Im51bWJlciIpdGhpcy5wYWRkaW5nPVtbYWEucGFkZGluZyxhYS5wYWRkaW5nXSxbYWEucGFkZGluZyxhYS5wYWRkaW5nXV07ZWxzZXtpZihhYS5wYWRkaW5nPWFhLnBhZGRpbmcsYWEucGFkZGluZy5sZW5ndGghPT0yKXRocm93IG5ldyBWYWx1ZUVycm9yKGBaZXJvUGFkZGluZzJEIGV4cGVjdHMgcGFkZGluZyB0byBiZSBhIGxlbmd0aC0yIGFycmF5LCBidXQgcmVjZWl2ZWQgYSBsZW5ndGgtJHthYS5wYWRkaW5nLmxlbmd0aH0gYXJyYXkuYCk7bGV0IHhhLGJhO2lmKHR5cGVvZiBhYS5wYWRkaW5nWzBdPT0ibnVtYmVyIil4YT1bYWEucGFkZGluZ1swXSxhYS5wYWRkaW5nWzBdXSxiYT1bYWEucGFkZGluZ1sxXSxhYS5wYWRkaW5nWzFdXTtlbHNle2lmKGFhLnBhZGRpbmc9YWEucGFkZGluZyxhYS5wYWRkaW5nWzBdLmxlbmd0aCE9PTIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFplcm9QYWRkaW5nMkQgZXhwZWN0cyBoZWlnaHQgcGFkZGluZyB0byBiZSBhIGxlbmd0aC0yIGFycmF5LCBidXQgcmVjZWl2ZWQgYSBsZW5ndGgtJHthYS5wYWRkaW5nWzBdLmxlbmd0aH0gYXJyYXkuYCk7aWYoeGE9YWEucGFkZGluZ1swXSxhYS5wYWRkaW5nWzFdLmxlbmd0aCE9PTIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFplcm9QYWRkaW5nMkQgZXhwZWN0cyB3aWR0aCBwYWRkaW5nIHRvIGJlIGEgbGVuZ3RoLTIgYXJyYXksIGJ1dCByZWNlaXZlZCBhIGxlbmd0aC0ke2FhLnBhZGRpbmdbMV0ubGVuZ3RofSBhcnJheS5gKTtiYT1hYS5wYWRkaW5nWzFdfXRoaXMucGFkZGluZz1beGEsYmFdfXRoaXMuaW5wdXRTcGVjPVtuZXcgSW5wdXRTcGVjKHtuZGltOjR9KV19Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2xldCB4YSxiYTtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiPyhhYVsyXSE9bnVsbCYmYWFbMl0+PTA/eGE9YWFbMl0rdGhpcy5wYWRkaW5nWzBdWzBdK3RoaXMucGFkZGluZ1swXVsxXTp4YT1udWxsLGFhWzNdIT1udWxsJiZhYVszXT49MD9iYT1hYVszXSt0aGlzLnBhZGRpbmdbMV1bMF0rdGhpcy5wYWRkaW5nWzFdWzFdOmJhPW51bGwsW2FhWzBdLGFhWzFdLHhhLGJhXSk6KGFhWzFdIT1udWxsJiZhYVsxXT49MD94YT1hYVsxXSt0aGlzLnBhZGRpbmdbMF1bMF0rdGhpcy5wYWRkaW5nWzBdWzFdOnhhPW51bGwsYWFbMl0hPW51bGwmJmFhWzJdPj0wP2JhPWFhWzJdK3RoaXMucGFkZGluZ1sxXVswXSt0aGlzLnBhZGRpbmdbMV1bMV06YmE9bnVsbCxbYWFbMF0seGEsYmEsYWFbM11dKX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT5zcGF0aWFsMmRQYWRkaW5nKGdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLHRoaXMucGFkZGluZyx0aGlzLmRhdGFGb3JtYXQpKX1nZXRDb25maWcoKXtjb25zdCBhYT17cGFkZGluZzp0aGlzLnBhZGRpbmcsZGF0YUZvcm1hdDp0aGlzLmRhdGFGb3JtYXR9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19WmVyb1BhZGRpbmcyRC5jbGFzc05hbWU9Ilplcm9QYWRkaW5nMkQiLHJlZ2lzdGVyQ2xhc3MkMShaZXJvUGFkZGluZzJEKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwb29sMmQoaGEsYWEseGEsYmEsU2EsVGEpe3JldHVybiB0aWR5JDEoKCk9PntjaGVja0RhdGFGb3JtYXQoU2EpLGNoZWNrUG9vbE1vZGUoVGEpLGNoZWNrUGFkZGluZ01vZGUoYmEpLHhhPT1udWxsJiYoeGE9WzEsMV0pLGJhPT1udWxsJiYoYmE9InZhbGlkIiksU2E9PW51bGwmJihTYT1pbWFnZURhdGFGb3JtYXQoKSksVGE9PW51bGwmJihUYT0ibWF4IiksaGE9cHJlcHJvY2Vzc0NvbnYyRElucHV0KGhhLFNhKTtsZXQgd2E7Y29uc3QgRWE9YmE9PT0ic2FtZSI/InNhbWUiOiJ2YWxpZCI7cmV0dXJuIFRhPT09Im1heCI/d2E9bWF4UG9vbCQzKGhhLGFhLHhhLEVhKTp3YT1hdmdQb29sJDMoaGEsYWEseGEsRWEpLFNhPT09ImNoYW5uZWxzRmlyc3QiJiYod2E9dHJhbnNwb3NlJDMod2EsWzAsMywxLDJdKSksd2F9KX1mdW5jdGlvbiBwb29sM2QkMShoYSxhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NoZWNrRGF0YUZvcm1hdChTYSksY2hlY2tQb29sTW9kZShUYSksY2hlY2tQYWRkaW5nTW9kZShiYSkseGE9PW51bGwmJih4YT1bMSwxLDFdKSxiYT09bnVsbCYmKGJhPSJ2YWxpZCIpLFNhPT1udWxsJiYoU2E9aW1hZ2VEYXRhRm9ybWF0KCkpLFRhPT1udWxsJiYoVGE9Im1heCIpLGhhPXByZXByb2Nlc3NDb252M0RJbnB1dChoYSxTYSk7bGV0IHdhO2NvbnN0IEVhPWJhPT09InNhbWUiPyJzYW1lIjoidmFsaWQiO3JldHVybiBUYT09PSJtYXgiP3dhPW1heFBvb2wzZCQyKGhhLGFhLHhhLEVhKTp3YT1hdmdQb29sM2QoaGEsYWEseGEsRWEpLFNhPT09ImNoYW5uZWxzRmlyc3QiJiYod2E9dHJhbnNwb3NlJDMod2EsWzAsNCwxLDIsM10pKSx3YX0pfWNsYXNzIFBvb2xpbmcxRCBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtpZihhYS5wb29sU2l6ZT09bnVsbCYmKGFhLnBvb2xTaXplPTIpLHN1cGVyKGFhKSx0eXBlb2YgYWEucG9vbFNpemU9PSJudW1iZXIiKXRoaXMucG9vbFNpemU9W2FhLnBvb2xTaXplXTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoYWEucG9vbFNpemUpJiZhYS5wb29sU2l6ZS5sZW5ndGg9PT0xJiZ0eXBlb2YgYWEucG9vbFNpemVbMF09PSJudW1iZXIiKXRoaXMucG9vbFNpemU9YWEucG9vbFNpemU7ZWxzZSB0aHJvdyBuZXcgVmFsdWVFcnJvcihgcG9vbFNpemUgZm9yIDFEIGNvbnZvbHV0aW9uYWwgbGF5ZXIgbXVzdCBiZSBhIG51bWJlciBvciBhbiBBcnJheSBvZiBhIHNpbmdsZSBudW1iZXIsIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KGFhLnBvb2xTaXplKX1gKTtpZihhc3NlcnRQb3NpdGl2ZUludGVnZXIodGhpcy5wb29sU2l6ZSwicG9vbFNpemUiKSxhYS5zdHJpZGVzPT1udWxsKXRoaXMuc3RyaWRlcz10aGlzLnBvb2xTaXplO2Vsc2UgaWYodHlwZW9mIGFhLnN0cmlkZXM9PSJudW1iZXIiKXRoaXMuc3RyaWRlcz1bYWEuc3RyaWRlc107ZWxzZSBpZihBcnJheS5pc0FycmF5KGFhLnN0cmlkZXMpJiZhYS5zdHJpZGVzLmxlbmd0aD09PTEmJnR5cGVvZiBhYS5zdHJpZGVzWzBdPT0ibnVtYmVyIil0aGlzLnN0cmlkZXM9YWEuc3RyaWRlcztlbHNlIHRocm93IG5ldyBWYWx1ZUVycm9yKGBzdHJpZGVzIGZvciAxRCBjb252b2x1dGlvbmFsIGxheWVyIG11c3QgYmUgYSBudW1iZXIgb3IgYW4gQXJyYXkgb2YgYSBzaW5nbGUgbnVtYmVyLCBidXQgcmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeShhYS5zdHJpZGVzKX1gKTthc3NlcnRQb3NpdGl2ZUludGVnZXIodGhpcy5zdHJpZGVzLCJzdHJpZGVzIiksdGhpcy5wYWRkaW5nPWFhLnBhZGRpbmc9PW51bGw/InZhbGlkIjphYS5wYWRkaW5nLGNoZWNrUGFkZGluZ01vZGUodGhpcy5wYWRkaW5nKSx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTozfSldfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKTtjb25zdCB4YT1jb252T3V0cHV0TGVuZ3RoKGFhWzFdLHRoaXMucG9vbFNpemVbMF0sdGhpcy5wYWRkaW5nLHRoaXMuc3RyaWRlc1swXSk7cmV0dXJuW2FhWzBdLHhhLGFhWzJdXX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57dGhpcy5pbnZva2VDYWxsSG9vayhhYSx4YSksYWE9ZXhwYW5kRGltcyQzKGdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLDIpO2NvbnN0IGJhPXRoaXMucG9vbGluZ0Z1bmN0aW9uKGdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLFt0aGlzLnBvb2xTaXplWzBdLDFdLFt0aGlzLnN0cmlkZXNbMF0sMV0sdGhpcy5wYWRkaW5nLCJjaGFubmVsc0xhc3QiKTtyZXR1cm4gc3F1ZWV6ZShiYSxbMl0pfSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e3Bvb2xTaXplOnRoaXMucG9vbFNpemUscGFkZGluZzp0aGlzLnBhZGRpbmcsc3RyaWRlczp0aGlzLnN0cmlkZXN9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX19Y2xhc3MgTWF4UG9vbGluZzFEIGV4dGVuZHMgUG9vbGluZzFEe2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSl9cG9vbGluZ0Z1bmN0aW9uKGFhLHhhLGJhLFNhLFRhKXtyZXR1cm4gY2hlY2tEYXRhRm9ybWF0KFRhKSxjaGVja1BhZGRpbmdNb2RlKFNhKSxwb29sMmQoYWEseGEsYmEsU2EsVGEsIm1heCIpfX1NYXhQb29saW5nMUQuY2xhc3NOYW1lPSJNYXhQb29saW5nMUQiLHJlZ2lzdGVyQ2xhc3MkMShNYXhQb29saW5nMUQpO2NsYXNzIEF2ZXJhZ2VQb29saW5nMUQgZXh0ZW5kcyBQb29saW5nMUR7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKX1wb29saW5nRnVuY3Rpb24oYWEseGEsYmEsU2EsVGEpe3JldHVybiBjaGVja0RhdGFGb3JtYXQoVGEpLGNoZWNrUGFkZGluZ01vZGUoU2EpLHBvb2wyZChhYSx4YSxiYSxTYSxUYSwiYXZnIil9fUF2ZXJhZ2VQb29saW5nMUQuY2xhc3NOYW1lPSJBdmVyYWdlUG9vbGluZzFEIixyZWdpc3RlckNsYXNzJDEoQXZlcmFnZVBvb2xpbmcxRCk7Y2xhc3MgUG9vbGluZzJEIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe2lmKGFhLnBvb2xTaXplPT1udWxsJiYoYWEucG9vbFNpemU9WzIsMl0pLHN1cGVyKGFhKSx0aGlzLnBvb2xTaXplPUFycmF5LmlzQXJyYXkoYWEucG9vbFNpemUpP2FhLnBvb2xTaXplOlthYS5wb29sU2l6ZSxhYS5wb29sU2l6ZV0sYWEuc3RyaWRlcz09bnVsbCl0aGlzLnN0cmlkZXM9dGhpcy5wb29sU2l6ZTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoYWEuc3RyaWRlcykpe2lmKGFhLnN0cmlkZXMubGVuZ3RoIT09Mil0aHJvdyBuZXcgVmFsdWVFcnJvcihgSWYgdGhlIHN0cmlkZXMgcHJvcGVydHkgb2YgYSAyRCBwb29saW5nIGxheWVyIGlzIGFuIEFycmF5LCBpdCBpcyBleHBlY3RlZCB0byBoYXZlIGEgbGVuZ3RoIG9mIDIsIGJ1dCByZWNlaXZlZCBsZW5ndGggJHthYS5zdHJpZGVzLmxlbmd0aH0uYCk7dGhpcy5zdHJpZGVzPWFhLnN0cmlkZXN9ZWxzZSB0aGlzLnN0cmlkZXM9W2FhLnN0cmlkZXMsYWEuc3RyaWRlc107YXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHRoaXMucG9vbFNpemUsInBvb2xTaXplIiksYXNzZXJ0UG9zaXRpdmVJbnRlZ2VyKHRoaXMuc3RyaWRlcywic3RyaWRlcyIpLHRoaXMucGFkZGluZz1hYS5wYWRkaW5nPT1udWxsPyJ2YWxpZCI6YWEucGFkZGluZyx0aGlzLmRhdGFGb3JtYXQ9YWEuZGF0YUZvcm1hdD09bnVsbD8iY2hhbm5lbHNMYXN0IjphYS5kYXRhRm9ybWF0LGNoZWNrRGF0YUZvcm1hdCh0aGlzLmRhdGFGb3JtYXQpLGNoZWNrUGFkZGluZ01vZGUodGhpcy5wYWRkaW5nKSx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTo0fSldfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKTtsZXQgeGE9dGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiP2FhWzJdOmFhWzFdLGJhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij9hYVszXTphYVsyXTtyZXR1cm4geGE9Y29udk91dHB1dExlbmd0aCh4YSx0aGlzLnBvb2xTaXplWzBdLHRoaXMucGFkZGluZyx0aGlzLnN0cmlkZXNbMF0pLGJhPWNvbnZPdXRwdXRMZW5ndGgoYmEsdGhpcy5wb29sU2l6ZVsxXSx0aGlzLnBhZGRpbmcsdGhpcy5zdHJpZGVzWzFdKSx0aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCI/W2FhWzBdLGFhWzFdLHhhLGJhXTpbYWFbMF0seGEsYmEsYWFbM11dfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pih0aGlzLmludm9rZUNhbGxIb29rKGFhLHhhKSx0aGlzLnBvb2xpbmdGdW5jdGlvbihnZXRFeGFjdGx5T25lVGVuc29yKGFhKSx0aGlzLnBvb2xTaXplLHRoaXMuc3RyaWRlcyx0aGlzLnBhZGRpbmcsdGhpcy5kYXRhRm9ybWF0KSkpfWdldENvbmZpZygpe2NvbnN0IGFhPXtwb29sU2l6ZTp0aGlzLnBvb2xTaXplLHBhZGRpbmc6dGhpcy5wYWRkaW5nLHN0cmlkZXM6dGhpcy5zdHJpZGVzLGRhdGFGb3JtYXQ6dGhpcy5kYXRhRm9ybWF0fSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9fWNsYXNzIE1heFBvb2xpbmcyRCBleHRlbmRzIFBvb2xpbmcyRHtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpfXBvb2xpbmdGdW5jdGlvbihhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIGNoZWNrRGF0YUZvcm1hdChUYSksY2hlY2tQYWRkaW5nTW9kZShTYSkscG9vbDJkKGFhLHhhLGJhLFNhLFRhLCJtYXgiKX19TWF4UG9vbGluZzJELmNsYXNzTmFtZT0iTWF4UG9vbGluZzJEIixyZWdpc3RlckNsYXNzJDEoTWF4UG9vbGluZzJEKTtjbGFzcyBBdmVyYWdlUG9vbGluZzJEIGV4dGVuZHMgUG9vbGluZzJEe2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSl9cG9vbGluZ0Z1bmN0aW9uKGFhLHhhLGJhLFNhLFRhKXtyZXR1cm4gY2hlY2tEYXRhRm9ybWF0KFRhKSxjaGVja1BhZGRpbmdNb2RlKFNhKSxwb29sMmQoYWEseGEsYmEsU2EsVGEsImF2ZyIpfX1BdmVyYWdlUG9vbGluZzJELmNsYXNzTmFtZT0iQXZlcmFnZVBvb2xpbmcyRCIscmVnaXN0ZXJDbGFzcyQxKEF2ZXJhZ2VQb29saW5nMkQpO2NsYXNzIFBvb2xpbmczRCBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtpZihhYS5wb29sU2l6ZT09bnVsbCYmKGFhLnBvb2xTaXplPVsyLDIsMl0pLHN1cGVyKGFhKSx0aGlzLnBvb2xTaXplPUFycmF5LmlzQXJyYXkoYWEucG9vbFNpemUpP2FhLnBvb2xTaXplOlthYS5wb29sU2l6ZSxhYS5wb29sU2l6ZSxhYS5wb29sU2l6ZV0sYWEuc3RyaWRlcz09bnVsbCl0aGlzLnN0cmlkZXM9dGhpcy5wb29sU2l6ZTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoYWEuc3RyaWRlcykpe2lmKGFhLnN0cmlkZXMubGVuZ3RoIT09Myl0aHJvdyBuZXcgVmFsdWVFcnJvcihgSWYgdGhlIHN0cmlkZXMgcHJvcGVydHkgb2YgYSAzRCBwb29saW5nIGxheWVyIGlzIGFuIEFycmF5LCBpdCBpcyBleHBlY3RlZCB0byBoYXZlIGEgbGVuZ3RoIG9mIDMsIGJ1dCByZWNlaXZlZCBsZW5ndGggJHthYS5zdHJpZGVzLmxlbmd0aH0uYCk7dGhpcy5zdHJpZGVzPWFhLnN0cmlkZXN9ZWxzZSB0aGlzLnN0cmlkZXM9W2FhLnN0cmlkZXMsYWEuc3RyaWRlcyxhYS5zdHJpZGVzXTthc3NlcnRQb3NpdGl2ZUludGVnZXIodGhpcy5wb29sU2l6ZSwicG9vbFNpemUiKSxhc3NlcnRQb3NpdGl2ZUludGVnZXIodGhpcy5zdHJpZGVzLCJzdHJpZGVzIiksdGhpcy5wYWRkaW5nPWFhLnBhZGRpbmc9PW51bGw/InZhbGlkIjphYS5wYWRkaW5nLHRoaXMuZGF0YUZvcm1hdD1hYS5kYXRhRm9ybWF0PT1udWxsPyJjaGFubmVsc0xhc3QiOmFhLmRhdGFGb3JtYXQsY2hlY2tEYXRhRm9ybWF0KHRoaXMuZGF0YUZvcm1hdCksY2hlY2tQYWRkaW5nTW9kZSh0aGlzLnBhZGRpbmcpLHRoaXMuaW5wdXRTcGVjPVtuZXcgSW5wdXRTcGVjKHtuZGltOjV9KV19Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2xldCB4YT10aGlzLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNGaXJzdCI/YWFbMl06YWFbMV0sYmE9dGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiP2FhWzNdOmFhWzJdLFNhPXRoaXMuZGF0YUZvcm1hdD09PSJjaGFubmVsc0ZpcnN0Ij9hYVs0XTphYVszXTtyZXR1cm4geGE9Y29udk91dHB1dExlbmd0aCh4YSx0aGlzLnBvb2xTaXplWzBdLHRoaXMucGFkZGluZyx0aGlzLnN0cmlkZXNbMF0pLGJhPWNvbnZPdXRwdXRMZW5ndGgoYmEsdGhpcy5wb29sU2l6ZVsxXSx0aGlzLnBhZGRpbmcsdGhpcy5zdHJpZGVzWzFdKSxTYT1jb252T3V0cHV0TGVuZ3RoKFNhLHRoaXMucG9vbFNpemVbMl0sdGhpcy5wYWRkaW5nLHRoaXMuc3RyaWRlc1syXSksdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzRmlyc3QiP1thYVswXSxhYVsxXSx4YSxiYSxTYV06W2FhWzBdLHhhLGJhLFNhLGFhWzRdXX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT4odGhpcy5pbnZva2VDYWxsSG9vayhhYSx4YSksdGhpcy5wb29saW5nRnVuY3Rpb24oZ2V0RXhhY3RseU9uZVRlbnNvcihhYSksdGhpcy5wb29sU2l6ZSx0aGlzLnN0cmlkZXMsdGhpcy5wYWRkaW5nLHRoaXMuZGF0YUZvcm1hdCkpKX1nZXRDb25maWcoKXtjb25zdCBhYT17cG9vbFNpemU6dGhpcy5wb29sU2l6ZSxwYWRkaW5nOnRoaXMucGFkZGluZyxzdHJpZGVzOnRoaXMuc3RyaWRlcyxkYXRhRm9ybWF0OnRoaXMuZGF0YUZvcm1hdH0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1jbGFzcyBNYXhQb29saW5nM0QgZXh0ZW5kcyBQb29saW5nM0R7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKX1wb29saW5nRnVuY3Rpb24oYWEseGEsYmEsU2EsVGEpe3JldHVybiBjaGVja0RhdGFGb3JtYXQoVGEpLGNoZWNrUGFkZGluZ01vZGUoU2EpLHBvb2wzZCQxKGFhLHhhLGJhLFNhLFRhLCJtYXgiKX19TWF4UG9vbGluZzNELmNsYXNzTmFtZT0iTWF4UG9vbGluZzNEIixyZWdpc3RlckNsYXNzJDEoTWF4UG9vbGluZzNEKTtjbGFzcyBBdmVyYWdlUG9vbGluZzNEIGV4dGVuZHMgUG9vbGluZzNEe2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSl9cG9vbGluZ0Z1bmN0aW9uKGFhLHhhLGJhLFNhLFRhKXtyZXR1cm4gY2hlY2tEYXRhRm9ybWF0KFRhKSxjaGVja1BhZGRpbmdNb2RlKFNhKSxwb29sM2QkMShhYSx4YSxiYSxTYSxUYSwiYXZnIil9fUF2ZXJhZ2VQb29saW5nM0QuY2xhc3NOYW1lPSJBdmVyYWdlUG9vbGluZzNEIixyZWdpc3RlckNsYXNzJDEoQXZlcmFnZVBvb2xpbmczRCk7Y2xhc3MgR2xvYmFsUG9vbGluZzFEIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSx0aGlzLmlucHV0U3BlYz1bbmV3IElucHV0U3BlYyh7bmRpbTozfSldfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7cmV0dXJuW2FhWzBdLGFhWzJdXX1jYWxsKGFhLHhhKXt0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcn19Y2xhc3MgR2xvYmFsQXZlcmFnZVBvb2xpbmcxRCBleHRlbmRzIEdsb2JhbFBvb2xpbmcxRHtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWF8fHt9KX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgYmE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSk7cmV0dXJuIG1lYW4kMShiYSwxKX0pfX1HbG9iYWxBdmVyYWdlUG9vbGluZzFELmNsYXNzTmFtZT0iR2xvYmFsQXZlcmFnZVBvb2xpbmcxRCIscmVnaXN0ZXJDbGFzcyQxKEdsb2JhbEF2ZXJhZ2VQb29saW5nMUQpO2NsYXNzIEdsb2JhbE1heFBvb2xpbmcxRCBleHRlbmRzIEdsb2JhbFBvb2xpbmcxRHtjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWF8fHt9KX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgYmE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSk7cmV0dXJuIG1heCQ0KGJhLDEpfSl9fUdsb2JhbE1heFBvb2xpbmcxRC5jbGFzc05hbWU9Ikdsb2JhbE1heFBvb2xpbmcxRCIscmVnaXN0ZXJDbGFzcyQxKEdsb2JhbE1heFBvb2xpbmcxRCk7Y2xhc3MgR2xvYmFsUG9vbGluZzJEIGV4dGVuZHMgTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSx0aGlzLmRhdGFGb3JtYXQ9YWEuZGF0YUZvcm1hdD09bnVsbD8iY2hhbm5lbHNMYXN0IjphYS5kYXRhRm9ybWF0LGNoZWNrRGF0YUZvcm1hdCh0aGlzLmRhdGFGb3JtYXQpLHRoaXMuaW5wdXRTcGVjPVtuZXcgSW5wdXRTcGVjKHtuZGltOjR9KV19Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXtyZXR1cm4gYWE9YWEsdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCI/W2FhWzBdLGFhWzNdXTpbYWFbMF0sYWFbMV1dfWNhbGwoYWEseGEpe3Rocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yfWdldENvbmZpZygpe2NvbnN0IGFhPXtkYXRhRm9ybWF0OnRoaXMuZGF0YUZvcm1hdH0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1jbGFzcyBHbG9iYWxBdmVyYWdlUG9vbGluZzJEIGV4dGVuZHMgR2xvYmFsUG9vbGluZzJEe2NhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCI/bWVhbiQxKGJhLFsxLDJdKTptZWFuJDEoYmEsWzIsM10pfSl9fUdsb2JhbEF2ZXJhZ2VQb29saW5nMkQuY2xhc3NOYW1lPSJHbG9iYWxBdmVyYWdlUG9vbGluZzJEIixyZWdpc3RlckNsYXNzJDEoR2xvYmFsQXZlcmFnZVBvb2xpbmcyRCk7Y2xhc3MgR2xvYmFsTWF4UG9vbGluZzJEIGV4dGVuZHMgR2xvYmFsUG9vbGluZzJEe2NhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCI/bWF4JDQoYmEsWzEsMl0pOm1heCQ0KGJhLFsyLDNdKX0pfX1HbG9iYWxNYXhQb29saW5nMkQuY2xhc3NOYW1lPSJHbG9iYWxNYXhQb29saW5nMkQiLHJlZ2lzdGVyQ2xhc3MkMShHbG9iYWxNYXhQb29saW5nMkQpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFdyYXBwZXIgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMubGF5ZXI9YWEubGF5ZXJ9YnVpbGQoYWEpe3RoaXMuYnVpbHQ9ITB9Z2V0IHRyYWluYWJsZSgpe3JldHVybiB0aGlzLmxheWVyIT1udWxsP3RoaXMubGF5ZXIudHJhaW5hYmxlOiExfXNldCB0cmFpbmFibGUoYWEpe3RoaXMubGF5ZXIhPW51bGwmJih0aGlzLmxheWVyLnRyYWluYWJsZT1hYSl9Z2V0IHRyYWluYWJsZVdlaWdodHMoKXtyZXR1cm4gdGhpcy5sYXllci50cmFpbmFibGVXZWlnaHRzfWdldCBub25UcmFpbmFibGVXZWlnaHRzKCl7cmV0dXJuIHRoaXMubGF5ZXIubm9uVHJhaW5hYmxlV2VpZ2h0c31nZXQgdXBkYXRlcygpe3JldHVybiB0aGlzLmxheWVyLl91cGRhdGVzfWdldCBsb3NzZXMoKXtyZXR1cm4gdGhpcy5sYXllci5sb3NzZXN9Z2V0V2VpZ2h0cygpe3JldHVybiB0aGlzLmxheWVyLmdldFdlaWdodHMoKX1zZXRXZWlnaHRzKGFhKXt0aGlzLmxheWVyLnNldFdlaWdodHMoYWEpfWdldENvbmZpZygpe2NvbnN0IGFhPXtsYXllcjp7Y2xhc3NOYW1lOnRoaXMubGF5ZXIuZ2V0Q2xhc3NOYW1lKCksY29uZmlnOnRoaXMubGF5ZXIuZ2V0Q29uZmlnKCl9fSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9c2V0RmFzdFdlaWdodEluaXREdXJpbmdCdWlsZChhYSl7c3VwZXIuc2V0RmFzdFdlaWdodEluaXREdXJpbmdCdWlsZChhYSksdGhpcy5sYXllciE9bnVsbCYmdGhpcy5sYXllci5zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSxiYT17fSl7Y29uc3QgU2E9eGEubGF5ZXIsVGE9ZGVzZXJpYWxpemUoU2EsYmEpO2RlbGV0ZSB4YS5sYXllcjtjb25zdCB3YT17bGF5ZXI6VGF9O3JldHVybiBPYmplY3QuYXNzaWduKHdhLHhhKSxuZXcgYWEod2EpfX1jbGFzcyBUaW1lRGlzdHJpYnV0ZWQgZXh0ZW5kcyBXcmFwcGVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5zdXBwb3J0c01hc2tpbmc9ITB9YnVpbGQoYWEpe2lmKGFhPWdldEV4YWN0bHlPbmVTaGFwZShhYSksYWEubGVuZ3RoPDMpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYFRpbWVEaXN0cmlidXRlZCBsYXllciBleHBlY3RzIGFuIGlucHV0IHNoYXBlID49IDNELCBidXQgcmVjZWl2ZWQgaW5wdXQgc2hhcGUgJHtKU09OLnN0cmluZ2lmeShhYSl9YCk7dGhpcy5pbnB1dFNwZWM9W3tzaGFwZTphYX1dO2NvbnN0IHhhPVthYVswXV0uY29uY2F0KGFhLnNsaWNlKDIpKTt0aGlzLmxheWVyLmJ1aWx0fHwodGhpcy5sYXllci5idWlsZCh4YSksdGhpcy5sYXllci5idWlsdD0hMCksc3VwZXIuYnVpbGQoYWEpfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKTtjb25zdCB4YT1bYWFbMF1dLmNvbmNhdChhYS5zbGljZSgyKSksYmE9dGhpcy5sYXllci5jb21wdXRlT3V0cHV0U2hhcGUoeGEpLFNhPWFhWzFdO3JldHVybltiYVswXSxTYV0uY29uY2F0KGJhLnNsaWNlKDEpKX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT4oYWE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSkscm5uKCh3YSxFYSk9PltnZXRFeGFjdGx5T25lVGVuc29yKHRoaXMubGF5ZXIuY2FsbCh3YSx4YSkpLFtdXSxhYSxbXSwhMSxudWxsLG51bGwsITEsITApWzFdKSl9fVRpbWVEaXN0cmlidXRlZC5jbGFzc05hbWU9IlRpbWVEaXN0cmlidXRlZCIscmVnaXN0ZXJDbGFzcyQxKFRpbWVEaXN0cmlidXRlZCk7ZnVuY3Rpb24gY2hlY2tCaWRpcmVjdGlvbmFsTWVyZ2VNb2RlKGhhKXtjaGVja1N0cmluZ1R5cGVVbmlvblZhbHVlKFZBTElEX0JJRElSRUNUSU9OQUxfTUVSR0VfTU9ERVMsIkJpZGlyZWN0aW9uYWxNZXJnZU1vZGUiLGhhKX1jb25zdCBERUZBVUxUX0JJRElSRUNUSU9OQUxfTUVSR0VfTU9ERT0iY29uY2F0IjtjbGFzcyBCaWRpcmVjdGlvbmFsIGV4dGVuZHMgV3JhcHBlcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpO2NvbnN0IHhhPWFhLmxheWVyLmdldENvbmZpZygpLGJhPXt9O2JhLmNsYXNzTmFtZT1hYS5sYXllci5nZXRDbGFzc05hbWUoKSxiYS5jb25maWc9eGEsdGhpcy5mb3J3YXJkTGF5ZXI9ZGVzZXJpYWxpemUoYmEpLHhhLmdvQmFja3dhcmRzPXhhLmdvQmFja3dhcmRzIT09ITA7Y29uc3QgU2E9e307aWYoU2EuY2xhc3NOYW1lPWFhLmxheWVyLmdldENsYXNzTmFtZSgpLFNhLmNvbmZpZz14YSx0aGlzLmJhY2t3YXJkTGF5ZXI9ZGVzZXJpYWxpemUoU2EpLHRoaXMuZm9yd2FyZExheWVyLm5hbWU9ImZvcndhcmRfIit0aGlzLmZvcndhcmRMYXllci5uYW1lLHRoaXMuYmFja3dhcmRMYXllci5uYW1lPSJiYWNrd2FyZF8iK3RoaXMuYmFja3dhcmRMYXllci5uYW1lLHRoaXMubWVyZ2VNb2RlPWFhLm1lcmdlTW9kZT09PXZvaWQgMD9ERUZBVUxUX0JJRElSRUNUSU9OQUxfTUVSR0VfTU9ERTphYS5tZXJnZU1vZGUsY2hlY2tCaWRpcmVjdGlvbmFsTWVyZ2VNb2RlKHRoaXMubWVyZ2VNb2RlKSxhYS53ZWlnaHRzKXRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCJ3ZWlnaHRzIHN1cHBvcnQgaXMgbm90IGltcGxlbWVudGVkIGZvciBCaWRpcmVjdGlvbmFsIGxheWVyIHlldC4iKTt0aGlzLl9zdGF0ZWZ1bD1hYS5sYXllci5zdGF0ZWZ1bCx0aGlzLnJldHVyblNlcXVlbmNlcz1hYS5sYXllci5yZXR1cm5TZXF1ZW5jZXMsdGhpcy5yZXR1cm5TdGF0ZT1hYS5sYXllci5yZXR1cm5TdGF0ZSx0aGlzLnN1cHBvcnRzTWFza2luZz0hMCx0aGlzLl90cmFpbmFibGU9ITAsdGhpcy5pbnB1dFNwZWM9YWEubGF5ZXIuaW5wdXRTcGVjLHRoaXMubnVtQ29uc3RhbnRzPW51bGx9Z2V0IHRyYWluYWJsZSgpe3JldHVybiB0aGlzLl90cmFpbmFibGV9c2V0IHRyYWluYWJsZShhYSl7dGhpcy5fdHJhaW5hYmxlPWFhLHRoaXMuZm9yd2FyZExheWVyIT1udWxsJiYodGhpcy5mb3J3YXJkTGF5ZXIudHJhaW5hYmxlPWFhKSx0aGlzLmJhY2t3YXJkTGF5ZXIhPW51bGwmJih0aGlzLmJhY2t3YXJkTGF5ZXIudHJhaW5hYmxlPWFhKX1nZXRXZWlnaHRzKCl7cmV0dXJuIHRoaXMuZm9yd2FyZExheWVyLmdldFdlaWdodHMoKS5jb25jYXQodGhpcy5iYWNrd2FyZExheWVyLmdldFdlaWdodHMoKSl9c2V0V2VpZ2h0cyhhYSl7Y29uc3QgeGE9YWEubGVuZ3RoLGJhPU1hdGguZmxvb3IoeGEvMik7dGhpcy5mb3J3YXJkTGF5ZXIuc2V0V2VpZ2h0cyhhYS5zbGljZSgwLGJhKSksdGhpcy5iYWNrd2FyZExheWVyLnNldFdlaWdodHMoYWEuc2xpY2UoYmEpKX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2xldCB4YT10aGlzLmZvcndhcmRMYXllci5jb21wdXRlT3V0cHV0U2hhcGUoYWEpO0FycmF5LmlzQXJyYXkoeGEpJiZBcnJheS5pc0FycmF5KHhhWzBdKXx8KHhhPVt4YV0pLHhhPXhhO2xldCBiYSxTYSxUYTtyZXR1cm4gdGhpcy5yZXR1cm5TdGF0ZSYmKFRhPXhhLnNsaWNlKDEpKSxiYT14YVswXSxiYT1iYSx0aGlzLm1lcmdlTW9kZT09PSJjb25jYXQiPyhiYVtiYS5sZW5ndGgtMV0qPTIsU2E9W2JhXSk6dGhpcy5tZXJnZU1vZGU9PW51bGw/U2E9W2JhLGJhLnNsaWNlKCldOlNhPVtiYV0sdGhpcy5yZXR1cm5TdGF0ZT90aGlzLm1lcmdlTW9kZT09bnVsbD9TYS5jb25jYXQoVGEpLmNvbmNhdChUYS5zbGljZSgpKTpbYmFdLmNvbmNhdChUYSkuY29uY2F0KFRhLnNsaWNlKCkpOnNpbmdsZXRvbk9yQXJyYXkoU2EpfWFwcGx5KGFhLHhhKXtsZXQgYmE9eGE9PW51bGw/bnVsbDp4YS5pbml0aWFsU3RhdGUsU2E9eGE9PW51bGw/bnVsbDp4YS5jb25zdGFudHM7eGE9PW51bGwmJih4YT17fSk7Y29uc3QgVGE9c3RhbmRhcmRpemVBcmdzKGFhLGJhLFNhLHRoaXMubnVtQ29uc3RhbnRzKTtpZihhYT1UYS5pbnB1dHMsYmE9VGEuaW5pdGlhbFN0YXRlLFNhPVRhLmNvbnN0YW50cyxBcnJheS5pc0FycmF5KGFhKSYmKGJhPWFhLnNsaWNlKDEpLGFhPWFhWzBdKSwoYmE9PW51bGx8fGJhLmxlbmd0aD09PTApJiZTYT09bnVsbClyZXR1cm4gc3VwZXIuYXBwbHkoYWEseGEpO2NvbnN0IHdhPVtdLEVhPVtdO2lmKGJhIT1udWxsKXtjb25zdCBBYT1iYS5sZW5ndGg7aWYoQWElMj4wKXRocm93IG5ldyBWYWx1ZUVycm9yKCJXaGVuIHBhc3NpbmcgYGluaXRpYWxTdGF0ZWAgdG8gYSBCaWRyZWN0aW9uYWwgUk5OLCB0aGUgc3RhdGUgc2hvdWxkIGJlIGFuIEFycmF5IGNvbnRhaW5pbmcgdGhlIHN0YXRlcyBvZiB0aGUgdW5kZXJseWluZyBSTk5zLiIpO3hhLmluaXRpYWxTdGF0ZT1iYSx3YS5wdXNoKC4uLmJhKTtjb25zdCBGYT1iYS5tYXAoTGE9Pm5ldyBJbnB1dFNwZWMoe3NoYXBlOkxhLnNoYXBlfSkpO3RoaXMuZm9yd2FyZExheWVyLnN0YXRlU3BlYz1GYS5zbGljZSgwLEFhLzIpLHRoaXMuYmFja3dhcmRMYXllci5zdGF0ZVNwZWM9RmEuc2xpY2UoQWEvMiksRWEucHVzaCguLi5GYSl9aWYoU2EhPW51bGwpdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoIlN1cHBvcnQgZm9yIGNvbnN0YW50cyBpbiBCaWRpcmVjdGlvbmFsIGxheWVycyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIpO2NvbnN0IGthPXdhWzBdaW5zdGFuY2VvZiBTeW1ib2xpY1RlbnNvcjtmb3IoY29uc3QgQWEgb2Ygd2EpaWYoQWEgaW5zdGFuY2VvZiBTeW1ib2xpY1RlbnNvciE9PWthKXRocm93IG5ldyBWYWx1ZUVycm9yKCJUaGUgaW5pdGlhbCBzdGF0ZSBvZiBhIEJpZGlyZWN0aW9uYWwgbGF5ZXIgY2Fubm90IGJlIHNwZWNpZmllZCBhcyBhIG1peCBvZiBzeW1ib2xpYyBhbmQgbm9uLXN5bWJvbGljIHRlbnNvcnMiKTtpZihrYSl7Y29uc3QgQWE9W2FhXS5jb25jYXQod2EpLEZhPXRoaXMuaW5wdXRTcGVjLmNvbmNhdChFYSksTGE9dGhpcy5pbnB1dFNwZWM7dGhpcy5pbnB1dFNwZWM9RmE7Y29uc3QgZWw9c3VwZXIuYXBwbHkoQWEseGEpO3JldHVybiB0aGlzLmlucHV0U3BlYz1MYSxlbH1lbHNlIHJldHVybiBzdXBlci5hcHBseShhYSx4YSl9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IGJhPXhhLmluaXRpYWxTdGF0ZTtsZXQgU2EsVGE7aWYoYmE9PW51bGwpU2E9dGhpcy5mb3J3YXJkTGF5ZXIuY2FsbChhYSx4YSksVGE9dGhpcy5iYWNrd2FyZExheWVyLmNhbGwoYWEseGEpO2Vsc2V7Y29uc3Qga2E9YmEuc2xpY2UoMCxiYS5sZW5ndGgvMiksQWE9YmEuc2xpY2UoYmEubGVuZ3RoLzIpO1NhPXRoaXMuZm9yd2FyZExheWVyLmNhbGwoYWEsT2JqZWN0LmFzc2lnbih4YSx7aW5pdGlhbFN0YXRlOmthfSkpLFRhPXRoaXMuYmFja3dhcmRMYXllci5jYWxsKGFhLE9iamVjdC5hc3NpZ24oeGEse2luaXRpYWxTdGF0ZTpBYX0pKX1sZXQgd2E7dGhpcy5yZXR1cm5TdGF0ZSYmKEFycmF5LmlzQXJyYXkoU2EpJiYod2E9U2Euc2xpY2UoMSkuY29uY2F0KFRhLnNsaWNlKDEpKSksU2E9U2FbMF0sVGE9VGFbMF0pLHRoaXMucmV0dXJuU2VxdWVuY2VzJiYoVGE9cmV2ZXJzZSQzKFRhLDEpKTtsZXQgRWE7cmV0dXJuIHRoaXMubWVyZ2VNb2RlPT09ImNvbmNhdCI/RWE9Y29uY2F0ZW5hdGUoW1NhLFRhXSk6dGhpcy5tZXJnZU1vZGU9PT0ic3VtIj9FYT1hZGQkMyhTYSxUYSk6dGhpcy5tZXJnZU1vZGU9PT0iYXZlIj9FYT1tdWwkMSguNSxhZGQkMyhTYSxUYSkpOnRoaXMubWVyZ2VNb2RlPT09Im11bCI/RWE9bXVsJDEoU2EsVGEpOnRoaXMubWVyZ2VNb2RlPT1udWxsJiYoRWE9W1NhLFRhXSksdGhpcy5yZXR1cm5TdGF0ZT90aGlzLm1lcmdlTW9kZT09bnVsbD9FYS5jb25jYXQod2EpOltFYV0uY29uY2F0KHdhKTpFYX0pfXJlc2V0U3RhdGVzKGFhKXt0aGlzLmZvcndhcmRMYXllci5yZXNldFN0YXRlcygpLHRoaXMuYmFja3dhcmRMYXllci5yZXNldFN0YXRlcygpfWJ1aWxkKGFhKXtuYW1lU2NvcGUodGhpcy5mb3J3YXJkTGF5ZXIubmFtZSwoKT0+e3RoaXMuZm9yd2FyZExheWVyLmJ1aWxkKGFhKX0pLG5hbWVTY29wZSh0aGlzLmJhY2t3YXJkTGF5ZXIubmFtZSwoKT0+e3RoaXMuYmFja3dhcmRMYXllci5idWlsZChhYSl9KSx0aGlzLmJ1aWx0PSEwfWNvbXB1dGVNYXNrKGFhLHhhKXtBcnJheS5pc0FycmF5KHhhKSYmKHhhPXhhWzBdKTtsZXQgYmE7aWYodGhpcy5yZXR1cm5TZXF1ZW5jZXM/dGhpcy5tZXJnZU1vZGU9PW51bGw/YmE9W3hhLHhhXTpiYT14YTp0aGlzLm1lcmdlTW9kZT09bnVsbD9iYT1bbnVsbCxudWxsXTpiYT1udWxsLHRoaXMucmV0dXJuU3RhdGUpe2NvbnN0IFRhPXRoaXMuZm9yd2FyZExheWVyLnN0YXRlcy5tYXAod2E9Pm51bGwpO3JldHVybiBBcnJheS5pc0FycmF5KGJhKT9iYS5jb25jYXQoVGEpLmNvbmNhdChUYSk6W2JhXS5jb25jYXQoVGEpLmNvbmNhdChUYSl9ZWxzZSByZXR1cm4gYmF9Z2V0IHRyYWluYWJsZVdlaWdodHMoKXtyZXR1cm4gdGhpcy5mb3J3YXJkTGF5ZXIudHJhaW5hYmxlV2VpZ2h0cy5jb25jYXQodGhpcy5iYWNrd2FyZExheWVyLnRyYWluYWJsZVdlaWdodHMpfWdldCBub25UcmFpbmFibGVXZWlnaHRzKCl7cmV0dXJuIHRoaXMuZm9yd2FyZExheWVyLm5vblRyYWluYWJsZVdlaWdodHMuY29uY2F0KHRoaXMuYmFja3dhcmRMYXllci5ub25UcmFpbmFibGVXZWlnaHRzKX1zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKXtzdXBlci5zZXRGYXN0V2VpZ2h0SW5pdER1cmluZ0J1aWxkKGFhKSx0aGlzLmZvcndhcmRMYXllciE9bnVsbCYmdGhpcy5mb3J3YXJkTGF5ZXIuc2V0RmFzdFdlaWdodEluaXREdXJpbmdCdWlsZChhYSksdGhpcy5iYWNrd2FyZExheWVyIT1udWxsJiZ0aGlzLmJhY2t3YXJkTGF5ZXIuc2V0RmFzdFdlaWdodEluaXREdXJpbmdCdWlsZChhYSl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e21lcmdlTW9kZTp0aGlzLm1lcmdlTW9kZX0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtjb25zdCBiYT1kZXNlcmlhbGl6ZSh4YS5sYXllcik7aWYoZGVsZXRlIHhhLmxheWVyLHhhLm51bUNvbnN0YW50cyE9bnVsbCl0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcigiRGVzZXJpYWxpemF0aW9uIG9mIGEgQmlkaXJlY3Rpb25hbCBsYXllciB3aXRoIG51bUNvbnN0YW50cyBwcmVzZW50IGlzIG5vdCBzdXBwb3J0ZWQgeWV0LiIpO2NvbnN0IFNhPXhhO3JldHVybiBTYS5sYXllcj1iYSxuZXcgYWEoU2EpfX1CaWRpcmVjdGlvbmFsLmNsYXNzTmFtZT0iQmlkaXJlY3Rpb25hbCIscmVnaXN0ZXJDbGFzcyQxKEJpZGlyZWN0aW9uYWwpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFJlc2NhbGluZyBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5zY2FsZT1hYS5zY2FsZSxhYS5vZmZzZXQ/dGhpcy5vZmZzZXQ9YWEub2Zmc2V0OnRoaXMub2Zmc2V0PTB9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e3NjYWxlOnRoaXMuc2NhbGUsb2Zmc2V0OnRoaXMub2Zmc2V0fSx4YT1zdXBlci5nZXRDb25maWcoKTtyZXR1cm4gT2JqZWN0LmFzc2lnbihhYSx4YSksYWF9Y2FsbChhYSx4YSl7cmV0dXJuIHRpZHkkMSgoKT0+KGFhPWdldEV4YWN0bHlPbmVUZW5zb3IoYWEpLGFhLmR0eXBlIT09ImZsb2F0MzIiJiYoYWE9Y2FzdCQ0KGFhLCJmbG9hdDMyIikpLGFkZCQzKG11bCQxKGFhLHRoaXMuc2NhbGUpLHRoaXMub2Zmc2V0KSkpfX1SZXNjYWxpbmcuY2xhc3NOYW1lPSJSZXNjYWxpbmciLHJlZ2lzdGVyQ2xhc3MkMShSZXNjYWxpbmcpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0e3Jlc2l6ZUJpbGluZWFyOnJlc2l6ZUJpbGluZWFyJDMsY3JvcEFuZFJlc2l6ZTpjcm9wQW5kUmVzaXplJDN9PWltYWdlJDE7Y2xhc3MgQ2VudGVyQ3JvcCBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5oZWlnaHQ9YWEuaGVpZ2h0LHRoaXMud2lkdGg9YWEud2lkdGh9Y2VudGVyQ3JvcChhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2xldCBBYSxGYT0hMTtjb25zdCBMYT14YS93YSxlbD1iYS9FYSx0bD0oU2EreGEpL3dhLG5sPShUYStiYSkvRWEsc2w9W0xhLGVsLHRsLG5sXSxybD1bXTthYS5yYW5rPT09Mz8oRmE9ITAsQWE9c3RhY2soW2FhXSkpOkFhPWFhO2ZvcihsZXQgY2w9MDtjbDxBYS5zaGFwZVswXTtjbCsrKXJsLnB1c2goc2wpO2NvbnN0IG9sPXRlbnNvcihybCxbcmwubGVuZ3RoLDRdKSxhbD1yYW5nZSQ0KDAscmwubGVuZ3RoLDEsImludDMyIiksaWw9Y3JvcEFuZFJlc2l6ZSQzKEFhLG9sLGFsLFtTYSxUYV0sIm5lYXJlc3QiKTtyZXR1cm4gY2FzdCQ0KEZhP2dldEV4YWN0bHlPbmVUZW5zb3IodW5zdGFjayhpbCkpOmlsLGthKX0pfXVwc2l6ZShhYSx4YSxiYSxTYSl7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IFRhPXJlc2l6ZUJpbGluZWFyJDMoYWEsW3hhLGJhXSk7cmV0dXJuIGNhc3QkNChUYSxTYSl9KX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57Y29uc3QgYmE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSksU2E9YmEuZHR5cGUsVGE9YmEuc2hhcGUsd2E9VGFbVGEubGVuZ3RoLTNdLEVhPVRhW1RhLmxlbmd0aC0yXTtsZXQga2E9MDt3YSE9PXRoaXMuaGVpZ2h0JiYoa2E9TWF0aC5mbG9vcigod2EtdGhpcy5oZWlnaHQpLzIpKTtsZXQgQWE9MDtyZXR1cm4gRWEhPT10aGlzLndpZHRoJiYoQWE9TWF0aC5mbG9vcigoRWEtdGhpcy53aWR0aCkvMiksQWE9PT0wJiYoQWE9MSkpLGthPj0wJiZBYT49MD90aGlzLmNlbnRlckNyb3AoYmEsa2EsQWEsdGhpcy5oZWlnaHQsdGhpcy53aWR0aCx3YSxFYSxTYSk6dGhpcy51cHNpemUoYWEsdGhpcy5oZWlnaHQsdGhpcy53aWR0aCxTYSl9KX1nZXRDb25maWcoKXtjb25zdCBhYT17aGVpZ2h0OnRoaXMuaGVpZ2h0LHdpZHRoOnRoaXMud2lkdGh9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe2FhPWdldEV4YWN0bHlPbmVTaGFwZShhYSk7Y29uc3QgeGE9YWEubGVuZ3RoLTMsYmE9YWEubGVuZ3RoLTI7cmV0dXJuIGFhW3hhXT10aGlzLmhlaWdodCxhYVtiYV09dGhpcy53aWR0aCxhYX19Q2VudGVyQ3JvcC5jbGFzc05hbWU9IkNlbnRlckNyb3AiLHJlZ2lzdGVyQ2xhc3MkMShDZW50ZXJDcm9wKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgQ29kZVNtaXRoIExMQwogKgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUKICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0CiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlULgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBlbmNvZGVDYXRlZ29yaWNhbElucHV0cyhoYSxhYSx4YSxiYSl7bGV0IFNhPWdldEV4YWN0bHlPbmVUZW5zb3IoaGEpO2lmKFNhLmR0eXBlIT09ImludDMyIiYmKFNhPWNhc3QkNChTYSwiaW50MzIiKSksYWE9PT0iaW50IilyZXR1cm4gU2E7Y29uc3QgVGE9U2Euc2hhcGU7aWYoU2EucmFuaz09PTAmJihTYT1leHBhbmREaW1zJDQoU2EsLTEpKSxhYT09PSJvbmVIb3QiJiZTYS5zaGFwZVtTYS5zaGFwZS5sZW5ndGgtMV0hPT0xJiYoU2E9ZXhwYW5kRGltcyQ0KFNhLC0xKSksU2EucmFuaz4yKXRocm93IG5ldyBWYWx1ZUVycm9yKGBXaGVuIG91dHB1dE1vZGUgaXMgbm90IGludCwgbWF4aW11bSBvdXRwdXQgcmFuayBpcyAyIFJlY2VpdmVkIG91dHB1dE1vZGUgJHthYX0gYW5kIGlucHV0IHNoYXBlICR7VGF9IHdoaWNoIHdvdWxkIHJlc3VsdCBpbiBvdXRwdXQgcmFuayAke1NhLnJhbmt9LmApO2NvbnN0IHdhPVsibXVsdGlIb3QiLCJvbmVIb3QiXS5pbmNsdWRlcyhhYSksRWE9U2E7bGV0IGthO2lmKHR5cGVvZiBiYTwidSImJmFhPT09ImNvdW50Ij9rYT1kZW5zZUJpbmNvdW50JDMoRWEsYmEseGEsd2EpOmthPWRlbnNlQmluY291bnQkMyhFYSxbXSx4YSx3YSksYWEhPT0idGZJZGYiKXJldHVybiBrYTtpZihiYSlyZXR1cm4gbXVsJDEoa2EsYmEpO3Rocm93IG5ldyBWYWx1ZUVycm9yKCJXaGVuIG91dHB1dE1vZGUgaXMgJ3RmSWRmJywgd2VpZ2h0cyBtdXN0IGJlIHByb3ZpZGVkLiIpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIENhdGVnb3J5RW5jb2RpbmcgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEpLHRoaXMubnVtVG9rZW5zPWFhLm51bVRva2VucyxhYS5vdXRwdXRNb2RlP3RoaXMub3V0cHV0TW9kZT1hYS5vdXRwdXRNb2RlOnRoaXMub3V0cHV0TW9kZT0ibXVsdGlIb3QifWdldENvbmZpZygpe2NvbnN0IGFhPXtudW1Ub2tlbnM6dGhpcy5udW1Ub2tlbnMsb3V0cHV0TW9kZTp0aGlzLm91dHB1dE1vZGV9LHhhPXN1cGVyLmdldENvbmZpZygpO3JldHVybiBPYmplY3QuYXNzaWduKGFhLHhhKSxhYX1jb21wdXRlT3V0cHV0U2hhcGUoYWEpe3JldHVybiBhYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpLGFhPT1udWxsP1t0aGlzLm51bVRva2Vuc106dGhpcy5vdXRwdXRNb2RlPT09Im9uZUhvdCImJmFhW2FhLmxlbmd0aC0xXSE9PTE/KGFhLnB1c2godGhpcy5udW1Ub2tlbnMpLGFhKTooYWFbYWEubGVuZ3RoLTFdPXRoaXMubnVtVG9rZW5zLGFhKX1jYWxsKGFhLHhhKXtyZXR1cm4gdGlkeSQxKCgpPT57YWE9Z2V0RXhhY3RseU9uZVRlbnNvcihhYSksYWEuZHR5cGUhPT0iaW50MzIiJiYoYWE9Y2FzdCQ0KGFhLCJpbnQzMiIpKTtsZXQgYmE7aWYodHlwZW9mIHhhLmNvdW50V2VpZ2h0czwidSIpe2lmKHRoaXMub3V0cHV0TW9kZSE9PSJjb3VudCIpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYGNvdW50V2VpZ2h0cyBpcyBub3QgdXNlZCB3aGVuIG91dHB1dE1vZGUgIT09IGNvdW50LgogICAgICAgICAgICAgIFJlY2VpdmVkIGNvdW50V2VpZ2h0cz0ke3hhLmNvdW50V2VpZ2h0c31gKTtiYT1nZXRFeGFjdGx5T25lVGVuc29yKHhhLmNvdW50V2VpZ2h0cyl9Y29uc3QgU2E9bWF4JDQoYWEpLFRhPW1pbiQ0KGFhKSx3YT1ncmVhdGVyJDModGhpcy5udW1Ub2tlbnMsU2EpLmJ1ZmZlclN5bmMoKS5nZXQoMCksRWE9Z3JlYXRlckVxdWFsJDMoVGEsMCkuYnVmZmVyU3luYygpLmdldCgwKTtpZighKHdhJiZFYSkpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYElucHV0IHZhbHVlcyBtdXN0IGJlIGJldHdlZW4gMCA8IHZhbHVlcyA8PSBudW1Ub2tlbnMgd2l0aCBudW1Ub2tlbnM9JHt0aGlzLm51bVRva2Vuc31gKTtyZXR1cm4gZW5jb2RlQ2F0ZWdvcmljYWxJbnB1dHMoYWEsdGhpcy5vdXRwdXRNb2RlLHRoaXMubnVtVG9rZW5zLGJhKX0pfX1DYXRlZ29yeUVuY29kaW5nLmNsYXNzTmFtZT0iQ2F0ZWdvcnlFbmNvZGluZyIscmVnaXN0ZXJDbGFzcyQxKENhdGVnb3J5RW5jb2RpbmcpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IElOVEVSUE9MQVRJT05fS0VZUyQxPVsiYmlsaW5lYXIiLCJuZWFyZXN0Il0sSU5URVJQT0xBVElPTl9NRVRIT0RTJDE9bmV3IFNldChJTlRFUlBPTEFUSU9OX0tFWVMkMSk7Y2xhc3MgUmVzaXppbmcgZXh0ZW5kcyBMYXllcntjb25zdHJ1Y3RvcihhYSl7aWYoc3VwZXIoYWEpLHRoaXMuaGVpZ2h0PWFhLmhlaWdodCx0aGlzLndpZHRoPWFhLndpZHRoLGFhLmludGVycG9sYXRpb24paWYoSU5URVJQT0xBVElPTl9NRVRIT0RTJDEuaGFzKGFhLmludGVycG9sYXRpb24pKXRoaXMuaW50ZXJwb2xhdGlvbj1hYS5pbnRlcnBvbGF0aW9uO2Vsc2UgdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEludmFsaWQgaW50ZXJwb2xhdGlvbiBwYXJhbWV0ZXI6ICR7YWEuaW50ZXJwb2xhdGlvbn0gaXMgbm90IGltcGxlbWVudGVkYCk7ZWxzZSB0aGlzLmludGVycG9sYXRpb249ImJpbGluZWFyIjt0aGlzLmNyb3BUb0FzcGVjdFJhdGlvPSEhYWEuY3JvcFRvQXNwZWN0UmF0aW99Y29tcHV0ZU91dHB1dFNoYXBlKGFhKXthYT1nZXRFeGFjdGx5T25lU2hhcGUoYWEpO2NvbnN0IHhhPWFhWzJdO3JldHVyblt0aGlzLmhlaWdodCx0aGlzLndpZHRoLHhhXX1nZXRDb25maWcoKXtjb25zdCBhYT17aGVpZ2h0OnRoaXMuaGVpZ2h0LHdpZHRoOnRoaXMud2lkdGgsaW50ZXJwb2xhdGlvbjp0aGlzLmludGVycG9sYXRpb24sY3JvcFRvQXNwZWN0UmF0aW86dGhpcy5jcm9wVG9Bc3BlY3RSYXRpb30seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT1bdGhpcy5oZWlnaHQsdGhpcy53aWR0aF07aWYodGhpcy5pbnRlcnBvbGF0aW9uPT09ImJpbGluZWFyIilyZXR1cm4gaW1hZ2UkMS5yZXNpemVCaWxpbmVhcihhYSxiYSwhdGhpcy5jcm9wVG9Bc3BlY3RSYXRpbyk7aWYodGhpcy5pbnRlcnBvbGF0aW9uPT09Im5lYXJlc3QiKXJldHVybiBpbWFnZSQxLnJlc2l6ZU5lYXJlc3ROZWlnaGJvcihhYSxiYSwhdGhpcy5jcm9wVG9Bc3BlY3RSYXRpbyk7dGhyb3cgbmV3IEVycm9yKGBJbnRlcnBvbGF0aW9uIGlzICR7dGhpcy5pbnRlcnBvbGF0aW9ufSBidXQgb25seSAke1suLi5JTlRFUlBPTEFUSU9OX01FVEhPRFMkMV19IGFyZSBzdXBwb3J0ZWRgKX0pfX1SZXNpemluZy5jbGFzc05hbWU9IlJlc2l6aW5nIixyZWdpc3RlckNsYXNzJDEoUmVzaXppbmcpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFJhbmRvbVNlZWR7Y29uc3RydWN0b3IoYWEpe3RoaXMuc2VlZD1hYX1uZXh0KCl7aWYodGhpcy5zZWVkIT09dm9pZCAwKXJldHVybiB0aGlzLnNlZWQrK319UmFuZG9tU2VlZC5jbGFzc05hbWU9IlJhbmRvbVNlZWQiOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEJhc2VSYW5kb21MYXllciBleHRlbmRzIExheWVye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSksdGhpcy5yYW5kb21HZW5lcmF0b3I9bmV3IFJhbmRvbVNlZWQoYWEuc2VlZCl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e3NlZWQ6dGhpcy5yYW5kb21HZW5lcmF0b3Iuc2VlZH0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfX1CYXNlUmFuZG9tTGF5ZXIuY2xhc3NOYW1lPSJCYXNlUmFuZG9tTGF5ZXIiOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBDb2RlU21pdGggTExDCiAqCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZQogKiBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgb3IgYXQKICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IElOVEVSUE9MQVRJT05fS0VZUz1bImJpbGluZWFyIiwibmVhcmVzdCJdLElOVEVSUE9MQVRJT05fTUVUSE9EUz1uZXcgU2V0KElOVEVSUE9MQVRJT05fS0VZUyk7Y2xhc3MgUmFuZG9tV2lkdGggZXh0ZW5kcyBCYXNlUmFuZG9tTGF5ZXJ7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKTtjb25zdHtmYWN0b3I6eGEsaW50ZXJwb2xhdGlvbjpiYT0iYmlsaW5lYXIifT1hYTtpZih0aGlzLmZhY3Rvcj14YSxBcnJheS5pc0FycmF5KHRoaXMuZmFjdG9yKSYmdGhpcy5mYWN0b3IubGVuZ3RoPT09Mil0aGlzLndpZHRoTG93ZXI9dGhpcy5mYWN0b3JbMF0sdGhpcy53aWR0aFVwcGVyPXRoaXMuZmFjdG9yWzFdO2Vsc2UgaWYoIUFycmF5LmlzQXJyYXkodGhpcy5mYWN0b3IpJiZ0aGlzLmZhY3Rvcj4wKXRoaXMud2lkdGhMb3dlcj0tdGhpcy5mYWN0b3IsdGhpcy53aWR0aFVwcGVyPXRoaXMuZmFjdG9yO2Vsc2UgdGhyb3cgbmV3IFZhbHVlRXJyb3IoYEludmFsaWQgZmFjdG9yOiAke3RoaXMuZmFjdG9yfS4gTXVzdCBiZSBwb3NpdGl2ZSBudW1iZXIgb3IgdHVwbGUgb2YgMiBudW1iZXJzYCk7aWYodGhpcy53aWR0aExvd2VyPC0xfHx0aGlzLndpZHRoVXBwZXI8LTEpdGhyb3cgbmV3IFZhbHVlRXJyb3IoYGZhY3RvciBtdXN0IGhhdmUgdmFsdWVzIGxhcmdlciB0aGFuIC0xLiBHb3Q6ICR7dGhpcy5mYWN0b3J9YCk7aWYodGhpcy53aWR0aFVwcGVyPHRoaXMud2lkdGhMb3dlcil0aHJvdyBuZXcgVmFsdWVFcnJvcihgZmFjdG9yIGNhbm5vdCBoYXZlIHVwcGVyIGJvdW5kIGxlc3MgdGhhbiBsb3dlciBib3VuZC4KICAgICAgICBHb3QgdXBwZXIgYm91bmQ6ICR7dGhpcy53aWR0aFVwcGVyfS4KICAgICAgICBHb3QgbG93ZXIgYm91bmQ6ICR7dGhpcy53aWR0aExvd2VyfQogICAgICBgKTtpZihiYSlpZihJTlRFUlBPTEFUSU9OX01FVEhPRFMuaGFzKGJhKSl0aGlzLmludGVycG9sYXRpb249YmE7ZWxzZSB0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW52YWxpZCBpbnRlcnBvbGF0aW9uIHBhcmFtZXRlcjogJHtiYX0gaXMgbm90IGltcGxlbWVudGVkYCl9Z2V0Q29uZmlnKCl7Y29uc3QgYWE9e2ZhY3Rvcjp0aGlzLmZhY3RvcixpbnRlcnBvbGF0aW9uOnRoaXMuaW50ZXJwb2xhdGlvbn0seGE9c3VwZXIuZ2V0Q29uZmlnKCk7cmV0dXJuIE9iamVjdC5hc3NpZ24oYWEseGEpLGFhfWNvbXB1dGVPdXRwdXRTaGFwZShhYSl7YWE9Z2V0RXhhY3RseU9uZVNoYXBlKGFhKTtjb25zdCB4YT1hYVsyXTtyZXR1cm5bdGhpcy5pbWdIZWlnaHQsLTEseGFdfWNhbGwoYWEseGEpe3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBiYT1nZXRFeGFjdGx5T25lVGVuc29yKGFhKTt0aGlzLmltZ0hlaWdodD1iYS5zaGFwZVtiYS5zaGFwZS5sZW5ndGgtM107Y29uc3QgU2E9YmEuc2hhcGVbYmEuc2hhcGUubGVuZ3RoLTJdO3RoaXMud2lkdGhGYWN0b3I9cmFuZG9tVW5pZm9ybShbMV0sMSt0aGlzLndpZHRoTG93ZXIsMSt0aGlzLndpZHRoVXBwZXIsImZsb2F0MzIiLHRoaXMucmFuZG9tR2VuZXJhdG9yLm5leHQoKSk7bGV0IFRhPXRoaXMud2lkdGhGYWN0b3IuZGF0YVN5bmMoKVswXSpTYTtUYT1NYXRoLnJvdW5kKFRhKTtjb25zdCB3YT1bdGhpcy5pbWdIZWlnaHQsVGFdO3N3aXRjaCh0aGlzLmludGVycG9sYXRpb24pe2Nhc2UiYmlsaW5lYXIiOnJldHVybiBpbWFnZSQxLnJlc2l6ZUJpbGluZWFyKGFhLHdhKTtjYXNlIm5lYXJlc3QiOnJldHVybiBpbWFnZSQxLnJlc2l6ZU5lYXJlc3ROZWlnaGJvcihhYSx3YSk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYEludGVycG9sYXRpb24gaXMgJHt0aGlzLmludGVycG9sYXRpb259CiAgICAgICAgICBidXQgb25seSAke1suLi5JTlRFUlBPTEFUSU9OX01FVEhPRFNdfSBhcmUgc3VwcG9ydGVkYCl9fSl9fVJhbmRvbVdpZHRoLmNsYXNzTmFtZT0iUmFuZG9tV2lkdGgiLHJlZ2lzdGVyQ2xhc3MkMShSYW5kb21XaWR0aCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRU5WJDQ9ZW52JDEoKTtFTlYkNC5yZWdpc3RlckZsYWcoIktFRVBfSU5URVJNRURJQVRFX1RFTlNPUlMiLCgpPT4hMSxoYT0+e2hhJiZjb25zb2xlLndhcm4oIktlZXAgaW50ZXJtZWRpYXRlIHRlbnNvcnMgaXMgT04uIFRoaXMgd2lsbCBwcmludCB0aGUgdmFsdWVzIG9mIGFsbCBpbnRlcm1lZGlhdGUgdGVuc29ycyBkdXJpbmcgbW9kZWwgaW5mZXJlbmNlLiBOb3QgYWxsIG1vZGVscyBzdXBwb3J0IHRoaXMgbW9kZS4gRm9yIGRldGFpbHMsIGNoZWNrIGUyZS9iZW5jaG1hcmtzLyBtb2RlbF9jb25maWcuanMuIFRoaXMgc2lnbmlmaWNhbnRseSBpbXBhY3RzIHBlcmZvcm1hbmNlLiIpfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICoKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovdmFyIERhdGFUeXBlOyhmdW5jdGlvbihoYSl7aGFbaGEuRFRfSU5WQUxJRD0wXT0iRFRfSU5WQUxJRCIsaGFbaGEuRFRfRkxPQVQ9MV09IkRUX0ZMT0FUIixoYVtoYS5EVF9ET1VCTEU9Ml09IkRUX0RPVUJMRSIsaGFbaGEuRFRfSU5UMzI9M109IkRUX0lOVDMyIixoYVtoYS5EVF9VSU5UOD00XT0iRFRfVUlOVDgiLGhhW2hhLkRUX0lOVDE2PTVdPSJEVF9JTlQxNiIsaGFbaGEuRFRfSU5UOD02XT0iRFRfSU5UOCIsaGFbaGEuRFRfU1RSSU5HPTddPSJEVF9TVFJJTkciLGhhW2hhLkRUX0NPTVBMRVg2ND04XT0iRFRfQ09NUExFWDY0IixoYVtoYS5EVF9JTlQ2ND05XT0iRFRfSU5UNjQiLGhhW2hhLkRUX0JPT0w9MTBdPSJEVF9CT09MIixoYVtoYS5EVF9RSU5UOD0xMV09IkRUX1FJTlQ4IixoYVtoYS5EVF9RVUlOVDg9MTJdPSJEVF9RVUlOVDgiLGhhW2hhLkRUX1FJTlQzMj0xM109IkRUX1FJTlQzMiIsaGFbaGEuRFRfQkZMT0FUMTY9MTRdPSJEVF9CRkxPQVQxNiIsaGFbaGEuRFRfUUlOVDE2PTE1XT0iRFRfUUlOVDE2IixoYVtoYS5EVF9RVUlOVDE2PTE2XT0iRFRfUVVJTlQxNiIsaGFbaGEuRFRfVUlOVDE2PTE3XT0iRFRfVUlOVDE2IixoYVtoYS5EVF9DT01QTEVYMTI4PTE4XT0iRFRfQ09NUExFWDEyOCIsaGFbaGEuRFRfSEFMRj0xOV09IkRUX0hBTEYiLGhhW2hhLkRUX1JFU09VUkNFPTIwXT0iRFRfUkVTT1VSQ0UiLGhhW2hhLkRUX1ZBUklBTlQ9MjFdPSJEVF9WQVJJQU5UIixoYVtoYS5EVF9VSU5UMzI9MjJdPSJEVF9VSU5UMzIiLGhhW2hhLkRUX1VJTlQ2ND0yM109IkRUX1VJTlQ2NCIsaGFbaGEuRFRfRkxPQVRfUkVGPTEwMV09IkRUX0ZMT0FUX1JFRiIsaGFbaGEuRFRfRE9VQkxFX1JFRj0xMDJdPSJEVF9ET1VCTEVfUkVGIixoYVtoYS5EVF9JTlQzMl9SRUY9MTAzXT0iRFRfSU5UMzJfUkVGIixoYVtoYS5EVF9VSU5UOF9SRUY9MTA0XT0iRFRfVUlOVDhfUkVGIixoYVtoYS5EVF9JTlQxNl9SRUY9MTA1XT0iRFRfSU5UMTZfUkVGIixoYVtoYS5EVF9JTlQ4X1JFRj0xMDZdPSJEVF9JTlQ4X1JFRiIsaGFbaGEuRFRfU1RSSU5HX1JFRj0xMDddPSJEVF9TVFJJTkdfUkVGIixoYVtoYS5EVF9DT01QTEVYNjRfUkVGPTEwOF09IkRUX0NPTVBMRVg2NF9SRUYiLGhhW2hhLkRUX0lOVDY0X1JFRj0xMDldPSJEVF9JTlQ2NF9SRUYiLGhhW2hhLkRUX0JPT0xfUkVGPTExMF09IkRUX0JPT0xfUkVGIixoYVtoYS5EVF9RSU5UOF9SRUY9MTExXT0iRFRfUUlOVDhfUkVGIixoYVtoYS5EVF9RVUlOVDhfUkVGPTExMl09IkRUX1FVSU5UOF9SRUYiLGhhW2hhLkRUX1FJTlQzMl9SRUY9MTEzXT0iRFRfUUlOVDMyX1JFRiIsaGFbaGEuRFRfQkZMT0FUMTZfUkVGPTExNF09IkRUX0JGTE9BVDE2X1JFRiIsaGFbaGEuRFRfUUlOVDE2X1JFRj0xMTVdPSJEVF9RSU5UMTZfUkVGIixoYVtoYS5EVF9RVUlOVDE2X1JFRj0xMTZdPSJEVF9RVUlOVDE2X1JFRiIsaGFbaGEuRFRfVUlOVDE2X1JFRj0xMTddPSJEVF9VSU5UMTZfUkVGIixoYVtoYS5EVF9DT01QTEVYMTI4X1JFRj0xMThdPSJEVF9DT01QTEVYMTI4X1JFRiIsaGFbaGEuRFRfSEFMRl9SRUY9MTE5XT0iRFRfSEFMRl9SRUYiLGhhW2hhLkRUX1JFU09VUkNFX1JFRj0xMjBdPSJEVF9SRVNPVVJDRV9SRUYiLGhhW2hhLkRUX1ZBUklBTlRfUkVGPTEyMV09IkRUX1ZBUklBTlRfUkVGIixoYVtoYS5EVF9VSU5UMzJfUkVGPTEyMl09IkRUX1VJTlQzMl9SRUYiLGhhW2hhLkRUX1VJTlQ2NF9SRUY9MTIzXT0iRFRfVUlOVDY0X1JFRiJ9KShEYXRhVHlwZXx8KERhdGFUeXBlPXt9KSk7dmFyIFNhdmVyRGVmOyhmdW5jdGlvbihoYSl7KGZ1bmN0aW9uKGFhKXthYVthYS5MRUdBQ1k9MF09IkxFR0FDWSIsYWFbYWEuVjE9MV09IlYxIixhYVthYS5WMj0yXT0iVjIifSkoaGEuQ2hlY2twb2ludEZvcm1hdFZlcnNpb258fChoYS5DaGVja3BvaW50Rm9ybWF0VmVyc2lvbj17fSkpfSkoU2F2ZXJEZWZ8fChTYXZlckRlZj17fSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IENVU1RPTV9PUFM9e307ZnVuY3Rpb24gZ2V0UmVnaXN0ZXJlZE9wKGhhKXtyZXR1cm4gQ1VTVE9NX09QU1toYV19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0UGFyYW1WYWx1ZShoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9YWEuaW5wdXRQYXJhbXNbaGFdO2lmKFRhJiZUYS5pbnB1dEluZGV4U3RhcnQhPT12b2lkIDApe2NvbnN0IEVhPVRhLmlucHV0SW5kZXhTdGFydCxrYT1UYS5pbnB1dEluZGV4RW5kPT09MD92b2lkIDA6VGEuaW5wdXRJbmRleEVuZD09PXZvaWQgMD9FYSsxOlRhLmlucHV0SW5kZXhFbmQsQWE9RWE8MD9hYS5pbnB1dE5hbWVzLmxlbmd0aCtFYTpFYTtpZihUYS50eXBlPT09InRlbnNvciIpcmV0dXJuIGdldFRlbnNvcihhYS5pbnB1dE5hbWVzW0FhXSx4YSxiYSxTYSk7aWYoVGEudHlwZT09PSJ0ZW5zb3JzIil7Y29uc3QgZWw9YWEuaW5wdXRzLnNsaWNlKEVhLGthKTtyZXR1cm4gYWEuaW5wdXROYW1lcy5zbGljZShFYSxrYSkuZmlsdGVyKChubCxzbCk9Pnt2YXIgcmw7cmV0dXJuKChybD1lbFtzbF0pPT09bnVsbHx8cmw9PT12b2lkIDA/dm9pZCAwOnJsLm9wKSE9PSJOb09wIn0pLm1hcChubD0+Z2V0VGVuc29yKG5sLHhhLGJhLFNhKSl9Y29uc3QgRmE9Z2V0VGVuc29yKGFhLmlucHV0TmFtZXNbQWFdLHhhLGJhLFNhKSxMYT1GYS5kYXRhU3luYygpO3JldHVybiBUYS50eXBlPT09Im51bWJlciI/TGFbMF06dG9OZXN0ZWRBcnJheSQxKEZhLnNoYXBlLExhKX1jb25zdCB3YT1hYS5hdHRyUGFyYW1zW2hhXTtyZXR1cm4gd2EmJndhLnZhbHVlfWZ1bmN0aW9uIGdldFRlbnNvcihoYSxhYSx4YSxiYSl7Y29uc3RbU2EsVGFdPXBhcnNlTm9kZU5hbWUoaGEseGEpO2lmKGJhIT1udWxsKXtjb25zdCBFYT1iYS5nZXRIYXNoVGFibGVIYW5kbGVCeU5hbWUoU2EpO2lmKEVhIT1udWxsKXJldHVybiBFYX1jb25zdCB3YT14YS5jdXJyZW50Q29udGV4dElkcy5maW5kKEVhPT4hIWFhW2dldE5vZGVOYW1lV2l0aENvbnRleHRJZChTYSxFYSldKTtyZXR1cm4gd2EhPT12b2lkIDA/YWFbZ2V0Tm9kZU5hbWVXaXRoQ29udGV4dElkKFNhLHdhKV1bVGFdOnZvaWQgMH1mdW5jdGlvbiBnZXRUZW5zb3JzRm9yQ3VycmVudENvbnRleHQoaGEsYWEseGEpe3JldHVybiBhYVtnZXROb2RlTmFtZVdpdGhDb250ZXh0SWQoaGEseGEuY3VycmVudENvbnRleHRJZCldfWZ1bmN0aW9uIGdldE5vZGVOYW1lQW5kSW5kZXgoaGEsYWEpe2NvbnN0W3hhLGJhLFNhXT1wYXJzZU5vZGVOYW1lKGhhLGFhKTtyZXR1cm5bZ2V0Tm9kZU5hbWVXaXRoQ29udGV4dElkKHhhLGFhJiZhYS5jdXJyZW50Q29udGV4dElkKSxiYSxTYV19ZnVuY3Rpb24gZ2V0Tm9kZU5hbWVXaXRoQ29udGV4dElkKGhhLGFhKXtyZXR1cm4gYWE/YCR7aGF9LSR7YWF9YDpoYX1mdW5jdGlvbiBwYXJzZU5vZGVOYW1lKGhhLGFhKXtpZihoYT09PSIiKXJldHVyblsiIiwwLHZvaWQgMF07Y29uc3QgeGE9YWEhPW51bGwmJmFhLnBhcnNlTm9kZU5hbWVDYWNoZSE9bnVsbDtpZih4YSl7Y29uc3QgVGE9YWEucGFyc2VOb2RlTmFtZUNhY2hlLmdldChoYSk7aWYoVGEhPW51bGwpcmV0dXJuIFRhfWNvbnN0IGJhPWhhLnNwbGl0KCI6Iik7bGV0IFNhO2lmKGJhLmxlbmd0aD09PTEpU2E9W2hhLDAsdm9pZCAwXTtlbHNle2NvbnN0IFRhPWJhWzBdLHdhPWJhLmxlbmd0aD09PTM/YmFbMV06dm9pZCAwLEVhPU51bWJlcihiYVtiYS5sZW5ndGgtMV0pO1NhPVtUYSxFYSx3YV19cmV0dXJuIHhhJiZhYS5wYXJzZU5vZGVOYW1lQ2FjaGUuc2V0KGhhLFNhKSxTYX1mdW5jdGlvbiBnZXRQYWRkaW5nKGhhLGFhLHhhKXtsZXQgYmE9Z2V0UGFyYW1WYWx1ZSgicGFkIixoYSxhYSx4YSk7aWYoYmE9PT0iZXhwbGljaXQiKXtiYT1nZXRQYXJhbVZhbHVlKCJleHBsaWNpdFBhZGRpbmdzIixoYSxhYSx4YSk7Y29uc3QgU2E9W1swLDBdLFswLDBdLFswLDBdLFswLDBdXTtmb3IobGV0IFRhPTA7VGE8NDtUYSsrKVNhW1RhXVswXT1iYVtUYSoyXSxTYVtUYV1bMV09YmFbVGEqMisxXTtyZXR1cm4gU2F9cmV0dXJuIGJhfWZ1bmN0aW9uIGNsb25lVGVuc29yKGhhKXtyZXR1cm4gaGEua2VwdD9oYTpjbG9uZSQxKGhhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJGk9W3t0Zk9wTmFtZToiQWRkIixjYXRlZ29yeToiYXJpdGhtZXRpYyIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiQWRkVjIiLGNhdGVnb3J5OiJhcml0aG1ldGljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJBZGROIixjYXRlZ29yeToiYXJpdGhtZXRpYyIsaW5wdXRzOlt7c3RhcnQ6MCxlbmQ6MCxuYW1lOiJ0ZW5zb3JzIix0eXBlOiJ0ZW5zb3JzIn1dfSx7dGZPcE5hbWU6IkJpYXNBZGQiLGNhdGVnb3J5OiJhcml0aG1ldGljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImRhdGFfZm9ybWF0IixuYW1lOiJkYXRhRm9ybWF0Iix0eXBlOiJzdHJpbmciLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlN1YiIsY2F0ZWdvcnk6ImFyaXRobWV0aWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlJlYWxEaXYiLGNhdGVnb3J5OiJhcml0aG1ldGljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJEaXYiLGNhdGVnb3J5OiJhcml0aG1ldGljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJEaXZOb05hbiIsY2F0ZWdvcnk6ImFyaXRobWV0aWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkZsb29yRGl2IixjYXRlZ29yeToiYXJpdGhtZXRpYyIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTXVsIixjYXRlZ29yeToiYXJpdGhtZXRpYyIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTWF4aW11bSIsY2F0ZWdvcnk6ImFyaXRobWV0aWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ik1pbmltdW0iLGNhdGVnb3J5OiJhcml0aG1ldGljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJQb3ciLGNhdGVnb3J5OiJhcml0aG1ldGljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJTcXVhcmVkRGlmZmVyZW5jZSIsY2F0ZWdvcnk6ImFyaXRobWV0aWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ik1vZCIsY2F0ZWdvcnk6ImFyaXRobWV0aWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkZsb29yTW9kIixjYXRlZ29yeToiYXJpdGhtZXRpYyIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19XTt2YXIgYXJpdGhtZXRpYz1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29uOmpzb24kaX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGpzb24kaD1be3RmT3BOYW1lOiJBYnMiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJBY29zIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiQXNpbiIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkF0YW4iLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJBdGFuMiIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToieSIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkNlaWwiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJDbGlwQnlWYWx1ZSIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiY2xpcFZhbHVlTWluIix0eXBlOiJudW1iZXIifSx7c3RhcnQ6MixuYW1lOiJjbGlwVmFsdWVNYXgiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJDb21wbGV4IixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJyZWFsIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbWFnIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiQ29tcGxleEFicyIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkNvcyIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkNvc2giLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJFbHUiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJFeHAiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJGbG9vciIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkxvZyIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkltYWciLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IlRvdXQiLG5hbWU6Im91dHB1dFR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJOZWciLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJSZWFsIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfSx7dGZOYW1lOiJUb3V0IixuYW1lOiJvdXRwdXRUeXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiUHJlbHUiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImFscGhhIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiUmVsdSIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlJlbHU2IixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiU2VsdSIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlNpZ21vaWQiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJTaW4iLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJTaW5oIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiU3FydCIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlJzcXJ0IixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiU3F1YXJlIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiVGFuIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiVGFuaCIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlNpZ24iLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJSb3VuZCIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkV4cG0xIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTG9nMXAiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJSZWNpcHJvY2FsIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiU29mdHBsdXMiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJBc2luaCIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkFjb3NoIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiQXRhbmgiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJFcmYiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJMZWFreVJlbHUiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiYWxwaGEiLG5hbWU6ImFscGhhIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTouMn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJJc05hbiIsY2F0ZWdvcnk6ImJhc2ljX21hdGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IklzRmluaXRlIixjYXRlZ29yeToiYmFzaWNfbWF0aCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiSXNJbmYiLGNhdGVnb3J5OiJiYXNpY19tYXRoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX1dO3ZhciBiYXNpY01hdGg9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJGh9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJGc9W3t0Zk9wTmFtZToiRW1wdHlUZW5zb3JMaXN0IixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJlbGVtZW50U2hhcGUiLHR5cGU6InNoYXBlIn0se3N0YXJ0OjEsbmFtZToibWF4TnVtRWxlbWVudHMiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9kdHlwZSIsbmFtZToiZWxlbWVudERUeXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJMb29wQ29uZCIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToicHJlZCIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IlN3aXRjaCIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiZGF0YSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToicHJlZCIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6Ik1lcmdlIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxlbmQ6MCxuYW1lOiJ0ZW5zb3JzIix0eXBlOiJ0ZW5zb3JzIn1dfSx7dGZPcE5hbWU6IkVudGVyIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3IiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImZyYW1lX25hbWUiLG5hbWU6ImZyYW1lTmFtZSIsdHlwZToic3RyaW5nIn0se3RmTmFtZToiaXNfY29uc3RhbnQiLG5hbWU6ImlzQ29uc3RhbnQiLHR5cGU6ImJvb2wifV19LHt0Zk9wTmFtZToiRXhpdCIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTmV4dEl0ZXJhdGlvbiIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiVGVuc29yQXJyYXlWMyIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToic2l6ZSIsdHlwZToibnVtYmVyIn1dLGF0dHJzOlt7dGZOYW1lOiJkdHlwZSIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIn0se3RmTmFtZToiZWxlbWVudF9zaGFwZSIsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9LHt0Zk5hbWU6ImR5bmFtaWNfc2l6ZSIsbmFtZToiZHluYW1pY1NpemUiLHR5cGU6ImJvb2wifSx7dGZOYW1lOiJjbGVhcl9hZnRlcl9yZWFkIixuYW1lOiJjbGVhckFmdGVyUmVhZCIsdHlwZToiYm9vbCJ9LHt0Zk5hbWU6ImlkZW50aWNhbF9lbGVtZW50X3NoYXBlcyIsbmFtZToiaWRlbnRpY2FsRWxlbWVudFNoYXBlcyIsdHlwZToiYm9vbCJ9LHt0Zk5hbWU6InRlbnNvcl9hcnJheV9uYW1lIixuYW1lOiJuYW1lIix0eXBlOiJzdHJpbmcifV19LHt0Zk9wTmFtZToiVGVuc29yQXJyYXlXcml0ZVYzIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3JBcnJheUlkIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbmRleCIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjIsbmFtZToidGVuc29yIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MyxuYW1lOiJmbG93SW4iLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJUZW5zb3JBcnJheVJlYWRWMyIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yQXJyYXlJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kZXgiLHR5cGU6Im51bWJlciJ9LHtzdGFydDoyLG5hbWU6ImZsb3dJbiIsdHlwZToibnVtYmVyIn1dLGF0dHJzOlt7dGZOYW1lOiJkdHlwZSIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJUZW5zb3JBcnJheUdhdGhlclYzIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3JBcnJheUlkIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbmRpY2VzIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoyLG5hbWU6ImZsb3dJbiIsdHlwZToibnVtYmVyIn1dLGF0dHJzOlt7dGZOYW1lOiJkdHlwZSIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIn0se3RmTmFtZToiZWxlbWVudF9zaGFwZSIsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9XX0se3RmT3BOYW1lOiJUZW5zb3JBcnJheVNjYXR0ZXJWMyIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yQXJyYXlJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kaWNlcyIsdHlwZToibnVtYmVyW10ifSx7c3RhcnQ6MixuYW1lOiJ0ZW5zb3IiLHR5cGU6InRlbnNvciJ9LHtzdGFydDozLG5hbWU6ImZsb3dJbiIsdHlwZToibnVtYmVyIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yQXJyYXlDb25jYXRWMyIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yQXJyYXlJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZmxvd0luIix0eXBlOiJudW1iZXIifV0sYXR0cnM6W3t0Zk5hbWU6ImR0eXBlIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifSx7dGZOYW1lOiJlbGVtZW50X3NoYXBlX2V4Y2VwdDAiLG5hbWU6ImVsZW1lbnRTaGFwZUV4Y2VwdDAiLHR5cGU6InNoYXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJUZW5zb3JBcnJheVNwbGl0VjMiLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvckFycmF5SWQiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InRlbnNvciIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToibGVuZ3RocyIsdHlwZToibnVtYmVyW10ifSx7c3RhcnQ6MyxuYW1lOiJmbG93SW4iLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIn1dfSx7dGZPcE5hbWU6IlRlbnNvckFycmF5U2l6ZVYzIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3JBcnJheUlkIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJmbG93SW4iLHR5cGU6Im51bWJlciJ9XX0se3RmT3BOYW1lOiJUZW5zb3JBcnJheUNsb3NlVjMiLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvckFycmF5SWQiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJTdGF0ZWxlc3NJZiIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiY29uZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsZW5kOjAsbmFtZToiYXJncyIsdHlwZToidGVuc29ycyJ9XSxhdHRyczpbe3RmTmFtZToidGhlbl9icmFuY2giLG5hbWU6InRoZW5CcmFuY2giLHR5cGU6ImZ1bmMifSx7dGZOYW1lOiJlbHNlX2JyYW5jaCIsbmFtZToiZWxzZUJyYW5jaCIsdHlwZToiZnVuYyJ9XX0se3RmT3BOYW1lOiJJZiIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiY29uZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsZW5kOjAsbmFtZToiYXJncyIsdHlwZToidGVuc29ycyJ9XSxhdHRyczpbe3RmTmFtZToidGhlbl9icmFuY2giLG5hbWU6InRoZW5CcmFuY2giLHR5cGU6ImZ1bmMifSx7dGZOYW1lOiJlbHNlX2JyYW5jaCIsbmFtZToiZWxzZUJyYW5jaCIsdHlwZToiZnVuYyJ9XX0se3RmT3BOYW1lOiJTdGF0ZWxlc3NXaGlsZSIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsZW5kOjAsbmFtZToiYXJncyIsdHlwZToidGVuc29ycyJ9XSxhdHRyczpbe3RmTmFtZToiY29uZCIsbmFtZToiY29uZCIsdHlwZToiZnVuYyJ9LHt0Zk5hbWU6ImJvZHkiLG5hbWU6ImJvZHkiLHR5cGU6ImZ1bmMifV19LHt0Zk9wTmFtZToiV2hpbGUiLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLGVuZDowLG5hbWU6ImFyZ3MiLHR5cGU6InRlbnNvcnMifV0sYXR0cnM6W3t0Zk5hbWU6ImNvbmQiLG5hbWU6ImNvbmQiLHR5cGU6ImZ1bmMifSx7dGZOYW1lOiJib2R5IixuYW1lOiJib2R5Iix0eXBlOiJmdW5jIn1dfSx7dGZPcE5hbWU6IlRlbnNvckxpc3RTY2F0dGVyIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3IiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImluZGljZXMiLHR5cGU6Im51bWJlcltdIn0se3N0YXJ0OjIsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9kdHlwZSIsbmFtZToiZWxlbWVudERUeXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJUZW5zb3JMaXN0U2NhdHRlclYyIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3IiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImluZGljZXMiLHR5cGU6Im51bWJlcltdIn0se3N0YXJ0OjIsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9LHtzdGFydDozLG5hbWU6Im51bUVsZW1lbnRzIix0eXBlOiJudW1iZXIifV0sYXR0cnM6W3t0Zk5hbWU6ImVsZW1lbnRfZHR5cGUiLG5hbWU6ImVsZW1lbnREVHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdEdhdGhlciIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yTGlzdElkIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbmRpY2VzIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoyLG5hbWU6ImVsZW1lbnRTaGFwZSIsdHlwZToic2hhcGUifV0sYXR0cnM6W3t0Zk5hbWU6ImVsZW1lbnRfZHR5cGUiLG5hbWU6ImVsZW1lbnREVHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdEdldEl0ZW0iLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvckxpc3RJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kZXgiLHR5cGU6Im51bWJlciJ9LHtzdGFydDoyLG5hbWU6ImVsZW1lbnRTaGFwZSIsdHlwZToic2hhcGUifV0sYXR0cnM6W3t0Zk5hbWU6ImVsZW1lbnRfZHR5cGUiLG5hbWU6ImVsZW1lbnREVHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdFNldEl0ZW0iLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvckxpc3RJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kZXgiLHR5cGU6Im51bWJlciJ9LHtzdGFydDoyLG5hbWU6InRlbnNvciIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJlbGVtZW50X2R0eXBlIixuYW1lOiJlbGVtZW50RFR5cGUiLHR5cGU6ImR0eXBlIn1dfSx7dGZPcE5hbWU6IlRlbnNvckxpc3RSZXNlcnZlIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJlbGVtZW50U2hhcGUiLHR5cGU6InNoYXBlIn0se3N0YXJ0OjEsbmFtZToibnVtRWxlbWVudHMiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9kdHlwZSIsbmFtZToiZWxlbWVudERUeXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJUZW5zb3JMaXN0RnJvbVRlbnNvciIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJlbGVtZW50U2hhcGUiLHR5cGU6InNoYXBlIn1dLGF0dHJzOlt7dGZOYW1lOiJlbGVtZW50X2R0eXBlIixuYW1lOiJlbGVtZW50RFR5cGUiLHR5cGU6ImR0eXBlIn1dfSx7dGZPcE5hbWU6IlRlbnNvckxpc3RTdGFjayIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yTGlzdElkIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJlbGVtZW50U2hhcGUiLHR5cGU6InNoYXBlIn1dLGF0dHJzOlt7dGZOYW1lOiJlbGVtZW50X2R0eXBlIixuYW1lOiJlbGVtZW50RFR5cGUiLHR5cGU6ImR0eXBlIn0se3RmTmFtZToibnVtX2VsZW1lbnRzIixuYW1lOiJudW1FbGVtZW50cyIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdFNwbGl0IixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3IiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImVsZW1lbnRTaGFwZSIsdHlwZToic2hhcGUifSx7c3RhcnQ6MixuYW1lOiJsZW5ndGhzIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9kdHlwZSIsbmFtZToiZWxlbWVudERUeXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJUZW5zb3JMaXN0Q29uY2F0IixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3JMaXN0SWQiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9zaGFwZSIsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9LHt0Zk5hbWU6ImVsZW1lbnRfZHR5cGUiLG5hbWU6ImVsZW1lbnREVHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdENvbmNhdFYyIixjYXRlZ29yeToiY29udHJvbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3JMaXN0SWQiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9zaGFwZSIsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9LHt0Zk5hbWU6ImVsZW1lbnRfZHR5cGUiLG5hbWU6ImVsZW1lbnREVHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdFBvcEJhY2siLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvckxpc3RJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZWxlbWVudFNoYXBlIix0eXBlOiJzaGFwZSJ9XSxhdHRyczpbe3RmTmFtZToiZWxlbWVudF9kdHlwZSIsbmFtZToiZWxlbWVudERUeXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJUZW5zb3JMaXN0UHVzaEJhY2siLGNhdGVnb3J5OiJjb250cm9sIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvckxpc3RJZCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToidGVuc29yIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6ImVsZW1lbnRfZHR5cGUiLG5hbWU6ImVsZW1lbnREVHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdExlbmd0aCIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yTGlzdElkIix0eXBlOiJ0ZW5zb3IifV19LHt0Zk9wTmFtZToiVGVuc29yTGlzdFJlc2l6ZSIsY2F0ZWdvcnk6ImNvbnRyb2wiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGVuc29yTGlzdElkIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJzaXplIix0eXBlOiJudW1iZXIifV19XTt2YXIgY29udHJvbD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29uOmpzb24kZ30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGpzb24kZj1be3RmT3BOYW1lOiJBdmdQb29sIixjYXRlZ29yeToiY29udm9sdXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJzdHJpZGVzIixuYW1lOiJzdHJpZGVzIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6InBhZGRpbmciLG5hbWU6InBhZCIsdHlwZToic3RyaW5nIn0se3RmTmFtZToiZGF0YV9mb3JtYXQiLG5hbWU6ImRhdGFGb3JtYXQiLHR5cGU6InN0cmluZyIsbm90U3VwcG9ydGVkOiEwfSx7dGZOYW1lOiJrc2l6ZSIsbmFtZToia2VybmVsU2l6ZSIsdHlwZToibnVtYmVyW10ifSx7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ik1heFBvb2wiLGNhdGVnb3J5OiJjb252b2x1dGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6InN0cmlkZXMiLG5hbWU6InN0cmlkZXMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToicGFkZGluZyIsbmFtZToicGFkIix0eXBlOiJzdHJpbmcifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImtzaXplIixuYW1lOiJrZXJuZWxTaXplIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6ImV4cGxpY2l0X3BhZGRpbmdzIixuYW1lOiJleHBsaWNpdFBhZGRpbmdzIix0eXBlOiJudW1iZXJbXSIsZGVmYXVsdFZhbHVlOltdLG5vdFN1cHBvcnRlZDohMH0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJNYXhQb29sV2l0aEFyZ21heCIsY2F0ZWdvcnk6ImNvbnZvbHV0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToic3RyaWRlcyIsbmFtZToic3RyaWRlcyIsdHlwZToibnVtYmVyW10ifSx7dGZOYW1lOiJwYWRkaW5nIixuYW1lOiJwYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6ImtzaXplIixuYW1lOiJrZXJuZWxTaXplIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6ImluY2x1ZGVfYmF0Y2hfaW5faW5kZXgiLG5hbWU6ImluY2x1ZGVCYXRjaEluSW5kZXgiLHR5cGU6ImJvb2wifSx7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkF2Z1Bvb2wzRCIsY2F0ZWdvcnk6ImNvbnZvbHV0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToic3RyaWRlcyIsbmFtZToic3RyaWRlcyIsdHlwZToibnVtYmVyW10ifSx7dGZOYW1lOiJwYWRkaW5nIixuYW1lOiJwYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6ImRhdGFfZm9ybWF0IixuYW1lOiJkYXRhRm9ybWF0Iix0eXBlOiJzdHJpbmciLG5vdFN1cHBvcnRlZDohMH0se3RmTmFtZToia3NpemUiLG5hbWU6Imtlcm5lbFNpemUiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJNYXhQb29sM0QiLGNhdGVnb3J5OiJjb252b2x1dGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6InN0cmlkZXMiLG5hbWU6InN0cmlkZXMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToicGFkZGluZyIsbmFtZToicGFkIix0eXBlOiJzdHJpbmcifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImtzaXplIixuYW1lOiJrZXJuZWxTaXplIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiQ29udjFEIixjYXRlZ29yeToiY29udm9sdXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZmlsdGVyIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6InN0cmlkZSIsbmFtZToic3RyaWRlIix0eXBlOiJudW1iZXIifSx7dGZOYW1lOiJwYWRkaW5nIixuYW1lOiJwYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6ImRhdGFfZm9ybWF0IixuYW1lOiJkYXRhRm9ybWF0Iix0eXBlOiJzdHJpbmciLGRlZmF1bHRWYWx1ZToiTldDIn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImRpbGF0aW9uIixuYW1lOiJkaWxhdGlvbiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MX1dfSx7dGZPcE5hbWU6IkNvbnYyRCIsY2F0ZWdvcnk6ImNvbnZvbHV0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImZpbHRlciIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH0se3RmTmFtZToic3RyaWRlcyIsbmFtZToic3RyaWRlcyIsdHlwZToibnVtYmVyW10ifSx7dGZOYW1lOiJwYWRkaW5nIixuYW1lOiJwYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6InVzZUN1ZG5uT25HcHUiLG5hbWU6InVzZUN1ZG5uT25HcHUiLHR5cGU6ImJvb2wifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixkZWZhdWx0VmFsdWU6Ik5IV0MifSx7dGZOYW1lOiJleHBsaWNpdF9wYWRkaW5ncyIsbmFtZToiZXhwbGljaXRQYWRkaW5ncyIsdHlwZToibnVtYmVyW10iLGRlZmF1bHRWYWx1ZTpbXX0se3RmTmFtZToiZGlsYXRpb25zIixuYW1lOiJkaWxhdGlvbnMiLHR5cGU6Im51bWJlcltdIn1dfSx7dGZPcE5hbWU6Il9GdXNlZENvbnYyRCIsY2F0ZWdvcnk6ImNvbnZvbHV0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImZpbHRlciIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsZW5kOjAsbmFtZToiYXJncyIsdHlwZToidGVuc29ycyJ9XSxhdHRyczpbe3RmTmFtZToibnVtX2FyZ3MiLG5hbWU6Im51bUFyZ3MiLHR5cGU6Im51bWJlciJ9LHt0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfSx7dGZOYW1lOiJzdHJpZGVzIixuYW1lOiJzdHJpZGVzIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6InBhZGRpbmciLG5hbWU6InBhZCIsdHlwZToic3RyaW5nIn0se3RmTmFtZToiZXhwbGljaXRfcGFkZGluZ3MiLG5hbWU6ImV4cGxpY2l0UGFkZGluZ3MiLHR5cGU6Im51bWJlcltdIixkZWZhdWx0VmFsdWU6W119LHt0Zk5hbWU6InVzZV9jdWRubl9vbl9ncHUiLG5hbWU6InVzZUN1ZG5uT25HcHUiLHR5cGU6ImJvb2wiLGRlZmF1bHRWYWx1ZTohMH0se3RmTmFtZToiZGF0YV9mb3JtYXQiLG5hbWU6ImRhdGFGb3JtYXQiLHR5cGU6InN0cmluZyIsZGVmYXVsdFZhbHVlOiJOSFdDIn0se3RmTmFtZToiZGlsYXRpb25zIixuYW1lOiJkaWxhdGlvbnMiLHR5cGU6Im51bWJlcltdIixkZWZhdWx0VmFsdWU6WzEsMSwxLDFdfSx7dGZOYW1lOiJmdXNlZF9vcHMiLG5hbWU6ImZ1c2VkT3BzIix0eXBlOiJzdHJpbmdbXSIsZGVmYXVsdFZhbHVlOltdfSx7dGZOYW1lOiJlcHNpbG9uIixuYW1lOiJlcHNpbG9uIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZToxZS00fSx7dGZOYW1lOiJsZWFreXJlbHVfYWxwaGEiLG5hbWU6ImxlYWt5cmVsdUFscGhhIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTouMn1dfSx7dGZPcE5hbWU6IkNvbnYyREJhY2twcm9wSW5wdXQiLGNhdGVnb3J5OiJjb252b2x1dGlvbiIsaW5wdXRzOlt7c3RhcnQ6MixuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJmaWx0ZXIiLHR5cGU6InRlbnNvciJ9LHtzdGFydDowLG5hbWU6Im91dHB1dFNoYXBlIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToic3RyaWRlcyIsbmFtZToic3RyaWRlcyIsdHlwZToibnVtYmVyW10ifSx7dGZOYW1lOiJwYWRkaW5nIixuYW1lOiJwYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6ImRhdGFfZm9ybWF0IixuYW1lOiJkYXRhRm9ybWF0Iix0eXBlOiJzdHJpbmciLG5vdFN1cHBvcnRlZDohMH0se3RmTmFtZToiZXhwbGljaXRfcGFkZGluZ3MiLG5hbWU6ImV4cGxpY2l0UGFkZGluZ3MiLHR5cGU6Im51bWJlcltdIixkZWZhdWx0VmFsdWU6W119LHt0Zk5hbWU6ImRpbGF0aW9ucyIsbmFtZToiZGlsYXRpb25zIix0eXBlOiJudW1iZXJbXSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiRGVwdGh3aXNlQ29udjJkIixjYXRlZ29yeToiY29udm9sdXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiaW5wdXQiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImZpbHRlciIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJzdHJpZGVzIixuYW1lOiJzdHJpZGVzIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6InBhZGRpbmciLG5hbWU6InBhZCIsdHlwZToic3RyaW5nIn0se3RmTmFtZToiZGF0YV9mb3JtYXQiLG5hbWU6ImRhdGFGb3JtYXQiLHR5cGU6InN0cmluZyIsZGVmYXVsdFZhbHVlOiJOSFdDIn0se3RmTmFtZToiZXhwbGljaXRfcGFkZGluZ3MiLG5hbWU6ImV4cGxpY2l0UGFkZGluZ3MiLHR5cGU6Im51bWJlcltdIixkZWZhdWx0VmFsdWU6W119LHt0Zk5hbWU6ImRpbGF0aW9ucyIsbmFtZToiZGlsYXRpb25zIix0eXBlOiJudW1iZXJbXSJ9XX0se3RmT3BOYW1lOiJEZXB0aHdpc2VDb252MmROYXRpdmUiLGNhdGVnb3J5OiJjb252b2x1dGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJpbnB1dCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZmlsdGVyIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6InN0cmlkZXMiLG5hbWU6InN0cmlkZXMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToicGFkZGluZyIsbmFtZToicGFkIix0eXBlOiJzdHJpbmcifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixkZWZhdWx0VmFsdWU6Ik5IV0MifSx7dGZOYW1lOiJleHBsaWNpdF9wYWRkaW5ncyIsbmFtZToiZXhwbGljaXRQYWRkaW5ncyIsdHlwZToibnVtYmVyW10iLGRlZmF1bHRWYWx1ZTpbXX0se3RmTmFtZToiZGlsYXRpb25zIixuYW1lOiJkaWxhdGlvbnMiLHR5cGU6Im51bWJlcltdIn1dfSx7dGZPcE5hbWU6IkZ1c2VkRGVwdGh3aXNlQ29udjJkTmF0aXZlIixjYXRlZ29yeToiY29udm9sdXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZmlsdGVyIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixlbmQ6MCxuYW1lOiJhcmdzIix0eXBlOiJ0ZW5zb3JzIn1dLGF0dHJzOlt7dGZOYW1lOiJudW1fYXJncyIsbmFtZToibnVtQXJncyIsdHlwZToibnVtYmVyIn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6InN0cmlkZXMiLG5hbWU6InN0cmlkZXMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToicGFkZGluZyIsbmFtZToicGFkIix0eXBlOiJzdHJpbmcifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixkZWZhdWx0VmFsdWU6Ik5IV0MifSx7dGZOYW1lOiJkaWxhdGlvbnMiLG5hbWU6ImRpbGF0aW9ucyIsdHlwZToibnVtYmVyW10iLGRlZmF1bHRWYWx1ZTpbMSwxLDEsMV19LHt0Zk5hbWU6ImZ1c2VkX29wcyIsbmFtZToiZnVzZWRPcHMiLHR5cGU6InN0cmluZ1tdIixkZWZhdWx0VmFsdWU6W119LHt0Zk5hbWU6ImV4cGxpY2l0X3BhZGRpbmdzIixuYW1lOiJleHBsaWNpdFBhZGRpbmdzIix0eXBlOiJudW1iZXJbXSIsZGVmYXVsdFZhbHVlOltdfV19LHt0Zk9wTmFtZToiQ29udjNEIixjYXRlZ29yeToiY29udm9sdXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZmlsdGVyIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6InN0cmlkZXMiLG5hbWU6InN0cmlkZXMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToicGFkZGluZyIsbmFtZToicGFkIix0eXBlOiJzdHJpbmcifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixkZWZhdWx0VmFsdWU6Ik5IV0MifSx7dGZOYW1lOiJkaWxhdGlvbnMiLG5hbWU6ImRpbGF0aW9ucyIsdHlwZToibnVtYmVyW10ifV19LHt0Zk9wTmFtZToiRGlsYXRpb24yRCIsY2F0ZWdvcnk6ImNvbnZvbHV0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImZpbHRlciIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJzdHJpZGVzIixuYW1lOiJzdHJpZGVzIix0eXBlOiJudW1iZXJbXSJ9LHt0Zk5hbWU6InJhdGVzIixuYW1lOiJkaWxhdGlvbnMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToicGFkZGluZyIsbmFtZToicGFkIix0eXBlOiJzdHJpbmcifV19XTt2YXIgY29udm9sdXRpb249T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJGZ9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJGU9W3t0Zk9wTmFtZToiRmlsbCIsY2F0ZWdvcnk6ImNyZWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InNoYXBlIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoxLG5hbWU6InZhbHVlIix0eXBlOiJudW1iZXIifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJMaW5TcGFjZSIsY2F0ZWdvcnk6ImNyZWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InN0YXJ0Iix0eXBlOiJudW1iZXIifSx7c3RhcnQ6MSxuYW1lOiJzdG9wIix0eXBlOiJudW1iZXIifSx7c3RhcnQ6MixuYW1lOiJudW0iLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJPbmVIb3QiLGNhdGVnb3J5OiJjcmVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJpbmRpY2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJkZXB0aCIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjIsbmFtZToib25WYWx1ZSIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MX0se3N0YXJ0OjMsbmFtZToib2ZmVmFsdWUiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9XSxhdHRyczpbe3RmTmFtZToiYXhpcyIsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJPbmVzIixjYXRlZ29yeToiY3JlYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToic2hhcGUiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiT25lc0xpa2UiLGNhdGVnb3J5OiJjcmVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6ImR0eXBlIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiUmFuZG9tU3RhbmRhcmROb3JtYWwiLGNhdGVnb3J5OiJjcmVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJzaGFwZSIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6InNlZWQiLG5hbWU6InNlZWQiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9LHt0Zk5hbWU6InNlZWQyIixuYW1lOiJzZWVkMiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MCxub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImR0eXBlIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifSx7dGZOYW1lOiJUIixuYW1lOiJUIix0eXBlOiJudW1iZXIiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlJhbmRvbVVuaWZvcm0iLGNhdGVnb3J5OiJjcmVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJzaGFwZSIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6Im1pbnZhbCIsbmFtZToibWludmFsIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfSx7dGZOYW1lOiJtYXh2YWwiLG5hbWU6Im1heHZhbCIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MX0se3RmTmFtZToiZHR5cGUiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSJ9LHt0Zk5hbWU6InNlZWQiLG5hbWU6InNlZWQiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9LHt0Zk5hbWU6InNlZWQyIixuYW1lOiJzZWVkMiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MCxub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IlQiLG5hbWU6IlQiLHR5cGU6Im51bWJlciIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiUmFuZG9tVW5pZm9ybUludCIsY2F0ZWdvcnk6ImNyZWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InNoYXBlIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToibWludmFsIixuYW1lOiJtaW52YWwiLHR5cGU6Im51bWJlciJ9LHt0Zk5hbWU6Im1heHZhbCIsbmFtZToibWF4dmFsIix0eXBlOiJudW1iZXIifSx7dGZOYW1lOiJzZWVkIixuYW1lOiJzZWVkIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfSx7dGZOYW1lOiJzZWVkMiIsbmFtZToic2VlZDIiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjAsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiUmFuZ2UiLGNhdGVnb3J5OiJjcmVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJzdGFydCIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjEsbmFtZToic3RvcCIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjIsbmFtZToic3RlcCIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MH1dLGF0dHJzOlt7dGZOYW1lOiJUaWR4IixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiVHJ1bmNhdGVkTm9ybWFsIixjYXRlZ29yeToiY3JlYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToic2hhcGUiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJtZWFucyIsbmFtZToibWVhbiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MH0se3RmTmFtZToic3RkZGV2IixuYW1lOiJzdGREZXYiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjF9LHt0Zk5hbWU6InNlZWQiLG5hbWU6InNlZWQiLHR5cGU6Im51bWJlciJ9LHt0Zk5hbWU6InNlZWQyIixuYW1lOiJzZWVkMiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MCxub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6ImR0eXBlIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifSx7dGZOYW1lOiJUIixuYW1lOiJUIix0eXBlOiJudW1iZXIiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ilplcm9zIixjYXRlZ29yeToiY3JlYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToic2hhcGUiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiWmVyb3NMaWtlIixjYXRlZ29yeToiY3JlYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiTXVsdGlub21pYWwiLGNhdGVnb3J5OiJjcmVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJsb2dpdHMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6Im51bVNhbXBsZXMiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToic2VlZCIsbmFtZToic2VlZCIsdHlwZToibnVtYmVyIn0se3RmTmFtZToic2VlZDIiLG5hbWU6InNlZWQyIix0eXBlOiJudW1iZXIifSx7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifSx7dGZOYW1lOiJvdXRwdXRfZHR5cGUiLG5hbWU6Im91dHB1dF9kdHlwZSIsdHlwZToiZHR5cGUifV19XTt2YXIgY3JlYXRpb249T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJGV9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJGQ9W3t0Zk9wTmFtZToiTm9uTWF4U3VwcHJlc3Npb25WMiIsY2F0ZWdvcnk6ImR5bmFtaWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYm94ZXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InNjb3JlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToibWF4T3V0cHV0U2l6ZSIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjMsbmFtZToiaW91VGhyZXNob2xkIix0eXBlOiJudW1iZXIifV19LHt0Zk9wTmFtZToiTm9uTWF4U3VwcHJlc3Npb25WMyIsY2F0ZWdvcnk6ImR5bmFtaWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYm94ZXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InNjb3JlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToibWF4T3V0cHV0U2l6ZSIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjMsbmFtZToiaW91VGhyZXNob2xkIix0eXBlOiJudW1iZXIifSx7c3RhcnQ6NCxuYW1lOiJzY29yZVRocmVzaG9sZCIsdHlwZToibnVtYmVyIn1dfSx7dGZPcE5hbWU6Ik5vbk1heFN1cHByZXNzaW9uVjQiLGNhdGVnb3J5OiJkeW5hbWljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImJveGVzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJzY29yZXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoyLG5hbWU6Im1heE91dHB1dFNpemUiLHR5cGU6Im51bWJlciJ9LHtzdGFydDozLG5hbWU6ImlvdVRocmVzaG9sZCIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjQsbmFtZToic2NvcmVUaHJlc2hvbGQiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IlRfdGhyZXNob2xkIixuYW1lOiJ0aHJlc2hvbGQiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6InBhZF90b19tYXhfb3V0cHV0X3NpemUiLG5hbWU6InBhZFRvTWF4T3V0cHV0U2l6ZSIsdHlwZToiYm9vbCJ9XX0se3RmT3BOYW1lOiJOb25NYXhTdXBwcmVzc2lvblY1IixjYXRlZ29yeToiZHluYW1pYyIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJib3hlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2NvcmVzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJtYXhPdXRwdXRTaXplIix0eXBlOiJudW1iZXIifSx7c3RhcnQ6MyxuYW1lOiJpb3VUaHJlc2hvbGQiLHR5cGU6Im51bWJlciJ9LHtzdGFydDo0LG5hbWU6InNjb3JlVGhyZXNob2xkIix0eXBlOiJudW1iZXIifSx7c3RhcnQ6NSxuYW1lOiJzb2Z0Tm1zU2lnbWEiLHR5cGU6Im51bWJlciJ9XX0se3RmT3BOYW1lOiJXaGVyZSIsY2F0ZWdvcnk6ImR5bmFtaWMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiY29uZGl0aW9uIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTGlzdERpZmYiLGNhdGVnb3J5OiJkeW5hbWljIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InkiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX1dO3ZhciBkeW5hbWljPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGpzb246anNvbiRkfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QganNvbiRjPVt7dGZPcE5hbWU6Ikxvd2VyQm91bmQiLGNhdGVnb3J5OiJldmFsdWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InNvcnRlZFNlcXVlbmNlIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJ2YWx1ZXMiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJUb3BLVjIiLGNhdGVnb3J5OiJldmFsdWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImsiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToic29ydGVkIixuYW1lOiJzb3J0ZWQiLHR5cGU6ImJvb2wifV19LHt0Zk9wTmFtZToiVXBwZXJCb3VuZCIsY2F0ZWdvcnk6ImV2YWx1YXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToic29ydGVkU2VxdWVuY2UiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InZhbHVlcyIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IlVuaXF1ZSIsY2F0ZWdvcnk6ImV2YWx1YXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IlVuaXF1ZVYyIixjYXRlZ29yeToiZXZhbHVhdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJheGlzIix0eXBlOiJudW1iZXIifV19XTt2YXIgZXZhbHVhdGlvbj1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29uOmpzb24kY30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGpzb24kYj1be3RmT3BOYW1lOiJQbGFjZWhvbGRlcldpdGhEZWZhdWx0IixjYXRlZ29yeToiZ3JhcGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiZGVmYXVsdCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJzaGFwZSIsbmFtZToic2hhcGUiLHR5cGU6InNoYXBlIn0se3RmTmFtZToiZHR5cGUiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJQbGFjZWhvbGRlciIsY2F0ZWdvcnk6ImdyYXBoIixhdHRyczpbe3RmTmFtZToic2hhcGUiLG5hbWU6InNoYXBlIix0eXBlOiJzaGFwZSJ9LHt0Zk5hbWU6ImR0eXBlIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUifV19LHt0Zk9wTmFtZToiQ29uc3QiLGNhdGVnb3J5OiJncmFwaCJ9LHt0Zk9wTmFtZToiSWRlbnRpdHkiLGNhdGVnb3J5OiJncmFwaCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV19LHt0Zk9wTmFtZToiSWRlbnRpdHlOIixjYXRlZ29yeToiZ3JhcGgiLGlucHV0czpbe3N0YXJ0OjAsZW5kOjAsbmFtZToieCIsdHlwZToidGVuc29ycyJ9XX0se3RmT3BOYW1lOiJTbmFwc2hvdCIsY2F0ZWdvcnk6ImdyYXBoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJSYW5rIixjYXRlZ29yeToiZ3JhcGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IlNpemUiLGNhdGVnb3J5OiJncmFwaCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV19LHt0Zk9wTmFtZToiU2hhcGUiLGNhdGVnb3J5OiJncmFwaCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV19LHt0Zk9wTmFtZToiU2hhcGVOIixjYXRlZ29yeToiZ3JhcGgiLGlucHV0czpbe3N0YXJ0OjAsZW5kOjAsbmFtZToieCIsdHlwZToidGVuc29ycyJ9XX0se3RmT3BOYW1lOiJQcmludCIsY2F0ZWdvcnk6ImdyYXBoIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImRhdGEiLHR5cGU6InRlbnNvcnMifV0sYXR0cnM6W3t0Zk5hbWU6Im1lc3NhZ2UiLG5hbWU6Im1lc3NhZ2UiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6ImZpcnN0X24iLG5hbWU6ImZpcnN0TiIsdHlwZToibnVtYmVyIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6InN1bW1hcml6ZSIsbmFtZToic3VtbWFyaXplIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTozfV19LHt0Zk9wTmFtZToiTm9PcCIsY2F0ZWdvcnk6ImdyYXBoIixpbnB1dHM6W119LHt0Zk9wTmFtZToiU3RvcEdyYWRpZW50IixjYXRlZ29yeToiZ3JhcGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IkZha2VRdWFudFdpdGhNaW5NYXhWYXJzIixjYXRlZ29yeToiZ3JhcGgiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJtaW4iLG5hbWU6Im1pbiIsdHlwZToibnVtYmVyIn0se3RmTmFtZToibWF4IixuYW1lOiJtYXgiLHR5cGU6Im51bWJlciJ9XX1dO3ZhciBncmFwaD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29uOmpzb24kYn0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGpzb24kYT1be3RmT3BOYW1lOiJIYXNoVGFibGUiLGNhdGVnb3J5OiJoYXNoX3RhYmxlIixpbnB1dHM6W10sYXR0cnM6W3t0Zk5hbWU6InNoYXJlZF9uYW1lIixuYW1lOiJzaGFyZWROYW1lIix0eXBlOiJzdHJpbmcifSx7dGZOYW1lOiJ1c2Vfbm9kZV9uYW1lX3NoYXJpbmciLG5hbWU6InVzZU5vZGVOYW1lU2hhcmluZyIsdHlwZToiYm9vbCJ9LHt0Zk5hbWU6ImtleV9kdHlwZSIsbmFtZToia2V5RFR5cGUiLHR5cGU6ImR0eXBlIn0se3RmTmFtZToidmFsdWVfZHR5cGUiLG5hbWU6InZhbHVlRFR5cGUiLHR5cGU6ImR0eXBlIn1dfSx7dGZPcE5hbWU6Ikhhc2hUYWJsZVYyIixjYXRlZ29yeToiaGFzaF90YWJsZSIsaW5wdXRzOltdLGF0dHJzOlt7dGZOYW1lOiJzaGFyZWRfbmFtZSIsbmFtZToic2hhcmVkTmFtZSIsdHlwZToic3RyaW5nIn0se3RmTmFtZToidXNlX25vZGVfbmFtZV9zaGFyaW5nIixuYW1lOiJ1c2VOb2RlTmFtZVNoYXJpbmciLHR5cGU6ImJvb2wifSx7dGZOYW1lOiJrZXlfZHR5cGUiLG5hbWU6ImtleURUeXBlIix0eXBlOiJkdHlwZSJ9LHt0Zk5hbWU6InZhbHVlX2R0eXBlIixuYW1lOiJ2YWx1ZURUeXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJMb29rdXBUYWJsZUltcG9ydCIsY2F0ZWdvcnk6Imhhc2hfdGFibGUiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGFibGVIYW5kbGUiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImtleXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoyLG5hbWU6InZhbHVlcyIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUaW4iLG5hbWU6InRJbiIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH0se3RmTmFtZToiVG91dCIsbmFtZToidE91dCIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ikxvb2t1cFRhYmxlSW1wb3J0VjIiLGNhdGVnb3J5OiJoYXNoX3RhYmxlIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRhYmxlSGFuZGxlIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJrZXlzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJ2YWx1ZXMiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVGluIixuYW1lOiJ0SW4iLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IlRvdXQiLG5hbWU6InRPdXQiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJMb29rdXBUYWJsZUZpbmQiLGNhdGVnb3J5OiJoYXNoX3RhYmxlIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRhYmxlSGFuZGxlIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJrZXlzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJkZWZhdWx0VmFsdWUiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVGluIixuYW1lOiJ0SW4iLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IlRvdXQiLG5hbWU6InRPdXQiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJMb29rdXBUYWJsZUZpbmRWMiIsY2F0ZWdvcnk6Imhhc2hfdGFibGUiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGFibGVIYW5kbGUiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImtleXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoyLG5hbWU6ImRlZmF1bHRWYWx1ZSIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUaW4iLG5hbWU6InRJbiIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH0se3RmTmFtZToiVG91dCIsbmFtZToidE91dCIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ikxvb2t1cFRhYmxlU2l6ZSIsY2F0ZWdvcnk6Imhhc2hfdGFibGUiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGFibGVIYW5kbGUiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJMb29rdXBUYWJsZVNpemVWMiIsY2F0ZWdvcnk6Imhhc2hfdGFibGUiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGFibGVIYW5kbGUiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJJbml0aWFsaXplVGFibGUiLGNhdGVnb3J5OiJoYXNoX3RhYmxlIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRhYmxlSGFuZGxlIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJrZXlzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJ2YWx1ZXMiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJJbml0aWFsaXplVGFibGVWMiIsY2F0ZWdvcnk6Imhhc2hfdGFibGUiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToidGFibGVIYW5kbGUiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImtleXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoyLG5hbWU6InZhbHVlcyIsdHlwZToidGVuc29yIn1dfV07dmFyIGhhc2hUYWJsZT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29uOmpzb24kYX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGpzb24kOT1be3RmT3BOYW1lOiJSZXNpemVCaWxpbmVhciIsY2F0ZWdvcnk6ImltYWdlIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImltYWdlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2l6ZSIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6ImFsaWduX2Nvcm5lcnMiLG5hbWU6ImFsaWduQ29ybmVycyIsdHlwZToiYm9vbCJ9LHt0Zk5hbWU6ImhhbGZfcGl4ZWxfY2VudGVycyIsbmFtZToiaGFsZlBpeGVsQ2VudGVycyIsdHlwZToiYm9vbCJ9LHt0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiUmVzaXplTmVhcmVzdE5laWdoYm9yIixjYXRlZ29yeToiaW1hZ2UiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiaW1hZ2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJzaXplIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToiYWxpZ25fY29ybmVycyIsbmFtZToiYWxpZ25Db3JuZXJzIix0eXBlOiJib29sIn0se3RmTmFtZToiaGFsZl9waXhlbF9jZW50ZXJzIixuYW1lOiJoYWxmUGl4ZWxDZW50ZXJzIix0eXBlOiJib29sIn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJDcm9wQW5kUmVzaXplIixjYXRlZ29yeToiaW1hZ2UiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiaW1hZ2UiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImJveGVzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJib3hJbmQiLHR5cGU6InRlbnNvciJ9LHtzdGFydDozLG5hbWU6ImNyb3BTaXplIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToibWV0aG9kIixuYW1lOiJtZXRob2QiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6ImV4dHJhcG9sYXRpb25fdmFsdWUiLG5hbWU6ImV4dHJhcG9sYXRpb25WYWx1ZSIsdHlwZToibnVtYmVyIn1dfSx7dGZPcE5hbWU6IkltYWdlUHJvamVjdGl2ZVRyYW5zZm9ybVYzIixjYXRlZ29yeToiaW1hZ2UiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiaW1hZ2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJ0cmFuc2Zvcm1zIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJvdXRwdXRTaGFwZSIsdHlwZToibnVtYmVyW10ifSx7c3RhcnQ6MyxuYW1lOiJmaWxsVmFsdWUiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiaW50ZXJwb2xhdGlvbiIsbmFtZToiaW50ZXJwb2xhdGlvbiIsdHlwZToic3RyaW5nIn0se3RmTmFtZToiZmlsbF9tb2RlIixuYW1lOiJmaWxsTW9kZSIsdHlwZToic3RyaW5nIn1dfV07dmFyIGltYWdlPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGpzb246anNvbiQ5fSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QganNvbiQ4PVt7dGZPcE5hbWU6IkVxdWFsIixjYXRlZ29yeToibG9naWNhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTm90RXF1YWwiLGNhdGVnb3J5OiJsb2dpY2FsIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJHcmVhdGVyIixjYXRlZ29yeToibG9naWNhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiR3JlYXRlckVxdWFsIixjYXRlZ29yeToibG9naWNhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTGVzcyIsY2F0ZWdvcnk6ImxvZ2ljYWwiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ikxlc3NFcXVhbCIsY2F0ZWdvcnk6ImxvZ2ljYWwiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkxvZ2ljYWxBbmQiLGNhdGVnb3J5OiJsb2dpY2FsIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJMb2dpY2FsTm90IixjYXRlZ29yeToibG9naWNhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiTG9naWNhbE9yIixjYXRlZ29yeToibG9naWNhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiU2VsZWN0IixjYXRlZ29yeToibG9naWNhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJjb25kaXRpb24iLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoyLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJTZWxlY3RWMiIsY2F0ZWdvcnk6ImxvZ2ljYWwiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiY29uZGl0aW9uIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJiIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6IlQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSIsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiQml0d2lzZUFuZCIsY2F0ZWdvcnk6ImxvZ2ljYWwiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToieSIsdHlwZToidGVuc29yIn1dfV07dmFyIGxvZ2ljYWw9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJDh9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJDc9W3t0Zk9wTmFtZToiX0Z1c2VkTWF0TXVsIixjYXRlZ29yeToibWF0cmljZXMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsZW5kOjAsbmFtZToiYXJncyIsdHlwZToidGVuc29ycyJ9XSxhdHRyczpbe3RmTmFtZToibnVtX2FyZ3MiLG5hbWU6Im51bUFyZ3MiLHR5cGU6Im51bWJlciJ9LHt0Zk5hbWU6ImZ1c2VkX29wcyIsbmFtZToiZnVzZWRPcHMiLHR5cGU6InN0cmluZ1tdIixkZWZhdWx0VmFsdWU6W119LHt0Zk5hbWU6ImVwc2lsb24iLG5hbWU6ImVwc2lsb24iLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjFlLTR9LHt0Zk5hbWU6InRyYW5zcG9zZV9hIixuYW1lOiJ0cmFuc3Bvc2VBIix0eXBlOiJib29sIixkZWZhdWx0VmFsdWU6ITF9LHt0Zk5hbWU6InRyYW5zcG9zZV9iIixuYW1lOiJ0cmFuc3Bvc2VCIix0eXBlOiJib29sIixkZWZhdWx0VmFsdWU6ITF9LHt0Zk5hbWU6ImxlYWt5cmVsdV9hbHBoYSIsbmFtZToibGVha3lyZWx1QWxwaGEiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOi4yfSx7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6Ik1hdE11bCIsY2F0ZWdvcnk6Im1hdHJpY2VzIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToidHJhbnNwb3NlX2EiLG5hbWU6InRyYW5zcG9zZUEiLHR5cGU6ImJvb2wiLGRlZmF1bHRWYWx1ZTohMX0se3RmTmFtZToidHJhbnNwb3NlX2IiLG5hbWU6InRyYW5zcG9zZUIiLHR5cGU6ImJvb2wiLGRlZmF1bHRWYWx1ZTohMX0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJCYXRjaE1hdE11bCIsY2F0ZWdvcnk6Im1hdHJpY2VzIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiYWRqX3giLG5hbWU6InRyYW5zcG9zZUEiLHR5cGU6ImJvb2wiLGRlZmF1bHRWYWx1ZTohMX0se3RmTmFtZToiYWRqX3kiLG5hbWU6InRyYW5zcG9zZUIiLHR5cGU6ImJvb2wiLGRlZmF1bHRWYWx1ZTohMX0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJCYXRjaE1hdE11bFYyIixjYXRlZ29yeToibWF0cmljZXMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYiIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJhZGpfeCIsbmFtZToidHJhbnNwb3NlQSIsdHlwZToiYm9vbCIsZGVmYXVsdFZhbHVlOiExfSx7dGZOYW1lOiJhZGpfeSIsbmFtZToidHJhbnNwb3NlQiIsdHlwZToiYm9vbCIsZGVmYXVsdFZhbHVlOiExfSx7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlRyYW5zcG9zZSIsY2F0ZWdvcnk6Im1hdHJpY2VzIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InBlcm0iLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJUIixuYW1lOiJkdHlwZSIsdHlwZToiZHR5cGUiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IkVpbnN1bSIsY2F0ZWdvcnk6Im1hdHJpY2VzIixpbnB1dHM6W3tzdGFydDowLGVuZDowLG5hbWU6InRlbnNvcnMiLHR5cGU6InRlbnNvcnMifV0sYXR0cnM6W3t0Zk5hbWU6ImVxdWF0aW9uIixuYW1lOiJlcXVhdGlvbiIsdHlwZToic3RyaW5nIn0se3RmTmFtZToiTiIsbmFtZToibiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6Mn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIn1dfSx7dGZPcE5hbWU6Ik1hdHJpeEJhbmRQYXJ0IixjYXRlZ29yeToibWF0cmljZXMiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiYSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToibnVtTG93ZXIiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6Im51bVVwcGVyIix0eXBlOiJ0ZW5zb3IifV19XTt2YXIgbWF0cmljZXM9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJDd9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJDY9W3t0Zk9wTmFtZToiRXVjbGlkZWFuTm9ybSIsY2F0ZWdvcnk6Im5vcm1hbGl6YXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6ImtlZXBfZGltcyIsbmFtZToia2VlcERpbXMiLHR5cGU6ImJvb2wiLGRlZmF1bHRWYWx1ZTohMX1dfSx7dGZPcE5hbWU6IkZ1c2VkQmF0Y2hOb3JtIixjYXRlZ29yeToibm9ybWFsaXphdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJzY2FsZSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToib2Zmc2V0Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MyxuYW1lOiJtZWFuIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6NCxuYW1lOiJ2YXJpYW5jZSIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJlcHNpbG9uIixuYW1lOiJlcHNpbG9uIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTouMDAxfSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJGdXNlZEJhdGNoTm9ybVYyIixjYXRlZ29yeToibm9ybWFsaXphdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJzY2FsZSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToib2Zmc2V0Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MyxuYW1lOiJtZWFuIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6NCxuYW1lOiJ2YXJpYW5jZSIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJlcHNpbG9uIixuYW1lOiJlcHNpbG9uIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTouMDAxfSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJGdXNlZEJhdGNoTm9ybVYzIixjYXRlZ29yeToibm9ybWFsaXphdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJzY2FsZSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToib2Zmc2V0Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MyxuYW1lOiJtZWFuIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6NCxuYW1lOiJ2YXJpYW5jZSIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJlcHNpbG9uIixuYW1lOiJlcHNpbG9uIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTouMDAxfSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJMUk4iLGNhdGVnb3J5OiJub3JtYWxpemF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiZGVwdGhfcmFkaXVzIixuYW1lOiJyYWRpdXMiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjV9LHt0Zk5hbWU6ImJpYXMiLG5hbWU6ImJpYXMiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjF9LHt0Zk5hbWU6ImFscGhhIixuYW1lOiJhbHBoYSIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MX0se3RmTmFtZToiYmV0YSIsbmFtZToiYmV0YSIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6LjV9XX0se3RmT3BOYW1lOiJTb2Z0bWF4IixjYXRlZ29yeToibm9ybWFsaXphdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV19LHt0Zk9wTmFtZToiTG9nU29mdG1heCIsY2F0ZWdvcnk6Im5vcm1hbGl6YXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dfV07dmFyIG5vcm1hbGl6YXRpb249T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJDZ9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJDU9W3t0Zk9wTmFtZToiQmluY291bnQiLGNhdGVnb3J5OiJyZWR1Y3Rpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2l6ZSIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjIsbmFtZToid2VpZ2h0cyIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IkRlbnNlQmluY291bnQiLGNhdGVnb3J5OiJyZWR1Y3Rpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2l6ZSIsdHlwZToibnVtYmVyIn0se3N0YXJ0OjIsbmFtZToid2VpZ2h0cyIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJiaW5hcnlfb3V0cHV0IixuYW1lOiJiaW5hcnlPdXRwdXQiLHR5cGU6ImJvb2wifV19LHt0Zk9wTmFtZToiTWF4IixjYXRlZ29yeToicmVkdWN0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJrZWVwX2RpbXMiLG5hbWU6ImtlZXBEaW1zIix0eXBlOiJib29sIn1dfSx7dGZPcE5hbWU6Ik1lYW4iLGNhdGVnb3J5OiJyZWR1Y3Rpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6ImtlZXBfZGltcyIsbmFtZToia2VlcERpbXMiLHR5cGU6ImJvb2wifV19LHt0Zk9wTmFtZToiTWluIixjYXRlZ29yeToicmVkdWN0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJrZWVwX2RpbXMiLG5hbWU6ImtlZXBEaW1zIix0eXBlOiJib29sIn1dfSx7dGZPcE5hbWU6IlN1bSIsY2F0ZWdvcnk6InJlZHVjdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJheGlzIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToia2VlcF9kaW1zIixuYW1lOiJrZWVwRGltcyIsdHlwZToiYm9vbCJ9XX0se3RmT3BOYW1lOiJBbGwiLGNhdGVnb3J5OiJyZWR1Y3Rpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6ImtlZXBfZGltcyIsbmFtZToia2VlcERpbXMiLHR5cGU6ImJvb2wifV19LHt0Zk9wTmFtZToiQW55IixjYXRlZ29yeToicmVkdWN0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJrZWVwX2RpbXMiLG5hbWU6ImtlZXBEaW1zIix0eXBlOiJib29sIn1dfSx7dGZPcE5hbWU6IkFyZ01heCIsY2F0ZWdvcnk6InJlZHVjdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJheGlzIix0eXBlOiJudW1iZXIifV19LHt0Zk9wTmFtZToiQXJnTWluIixjYXRlZ29yeToicmVkdWN0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlciJ9XX0se3RmT3BOYW1lOiJQcm9kIixjYXRlZ29yeToicmVkdWN0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJrZWVwX2RpbXMiLG5hbWU6ImtlZXBEaW1zIix0eXBlOiJib29sIn0se3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJDdW1wcm9kIixjYXRlZ29yeToicmVkdWN0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiZXhjbHVzaXZlIixuYW1lOiJleGNsdXNpdmUiLHR5cGU6ImJvb2wifSx7dGZOYW1lOiJyZXZlcnNlIixuYW1lOiJyZXZlcnNlIix0eXBlOiJib29sIn1dfSx7dGZPcE5hbWU6IkN1bXN1bSIsY2F0ZWdvcnk6InJlZHVjdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJheGlzIix0eXBlOiJudW1iZXIifV0sYXR0cnM6W3t0Zk5hbWU6ImV4Y2x1c2l2ZSIsbmFtZToiZXhjbHVzaXZlIix0eXBlOiJib29sIn0se3RmTmFtZToicmV2ZXJzZSIsbmFtZToicmV2ZXJzZSIsdHlwZToiYm9vbCJ9XX1dO3ZhciByZWR1Y3Rpb249T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsanNvbjpqc29uJDV9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBqc29uJDQ9W3t0Zk9wTmFtZToiQ29uY2F0VjIiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLGVuZDotMSxuYW1lOiJ0ZW5zb3JzIix0eXBlOiJ0ZW5zb3JzIn0se3N0YXJ0Oi0xLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiTiIsbmFtZToibiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6Mn1dfSx7dGZPcE5hbWU6IkNvbmNhdCIsY2F0ZWdvcnk6InNsaWNlX2pvaW4iLGlucHV0czpbe3N0YXJ0OjEsZW5kOjAsbmFtZToidGVuc29ycyIsdHlwZToidGVuc29ycyJ9LHtzdGFydDowLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlciJ9XSxhdHRyczpbe3RmTmFtZToiTiIsbmFtZToibiIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6Mn1dfSx7dGZPcE5hbWU6IkdhdGhlclYyIixjYXRlZ29yeToic2xpY2Vfam9pbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbmRpY2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJheGlzIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfV0sYXR0cnM6W3t0Zk5hbWU6ImJhdGNoX2RpbXMiLG5hbWU6ImJhdGNoRGltcyIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MH1dfSx7dGZPcE5hbWU6IkdhdGhlciIsY2F0ZWdvcnk6InNsaWNlX2pvaW4iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kaWNlcyIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJ2YWxpZGF0ZV9pbmRpY2VzIixuYW1lOiJ2YWxpZGF0ZUluZGljZXMiLHR5cGU6ImJvb2wiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlJldmVyc2UiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImRpbXMiLHR5cGU6ImJvb2xbXSJ9XX0se3RmT3BOYW1lOiJSZXZlcnNlVjIiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlcltdIn1dfSx7dGZPcE5hbWU6IlNsaWNlIixjYXRlZ29yeToic2xpY2Vfam9pbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJiZWdpbiIsdHlwZToibnVtYmVyW10ifSx7c3RhcnQ6MixuYW1lOiJzaXplIix0eXBlOiJudW1iZXJbXSJ9XX0se3RmT3BOYW1lOiJTdHJpZGVkU2xpY2UiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImJlZ2luIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoyLG5hbWU6ImVuZCIsdHlwZToibnVtYmVyW10ifSx7c3RhcnQ6MyxuYW1lOiJzdHJpZGVzIix0eXBlOiJudW1iZXJbXSJ9XSxhdHRyczpbe3RmTmFtZToiYmVnaW5fbWFzayIsbmFtZToiYmVnaW5NYXNrIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfSx7dGZOYW1lOiJlbmRfbWFzayIsbmFtZToiZW5kTWFzayIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MH0se3RmTmFtZToibmV3X2F4aXNfbWFzayIsbmFtZToibmV3QXhpc01hc2siLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9LHt0Zk5hbWU6ImVsbGlwc2lzX21hc2siLG5hbWU6ImVsbGlwc2lzTWFzayIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MH0se3RmTmFtZToic2hyaW5rX2F4aXNfbWFzayIsbmFtZToic2hyaW5rQXhpc01hc2siLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9XX0se3RmT3BOYW1lOiJQYWNrIixjYXRlZ29yeToic2xpY2Vfam9pbiIsaW5wdXRzOlt7c3RhcnQ6MCxlbmQ6MCxuYW1lOiJ0ZW5zb3JzIix0eXBlOiJ0ZW5zb3JzIn1dLGF0dHJzOlt7dGZOYW1lOiJheGlzIixuYW1lOiJheGlzIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfV19LHt0Zk9wTmFtZToiVW5wYWNrIixjYXRlZ29yeToic2xpY2Vfam9pbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ0ZW5zb3IiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiYXhpcyIsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyIixkZWZhdWx0VmFsdWU6MH0se3RmTmFtZToibnVtIixuYW1lOiJudW0iLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjAsbm90U3VwcG9ydGVkOiEwfV19LHt0Zk9wTmFtZToiVGlsZSIsY2F0ZWdvcnk6InNsaWNlX2pvaW4iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToicmVwcyIsdHlwZToibnVtYmVyW10ifV19LHt0Zk9wTmFtZToiU3BsaXQiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImF4aXMiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9LHtzdGFydDoxLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToibnVtX3NwbGl0IixuYW1lOiJudW1PclNpemVTcGxpdHMiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjF9XX0se3RmT3BOYW1lOiJTcGxpdFYiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6Im51bU9yU2l6ZVNwbGl0cyIsdHlwZToibnVtYmVyW10ifSx7c3RhcnQ6MixuYW1lOiJheGlzIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfV19LHt0Zk9wTmFtZToiU2NhdHRlck5kIixjYXRlZ29yeToic2xpY2Vfam9pbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJpbmRpY2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJ2YWx1ZXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoyLG5hbWU6InNoYXBlIix0eXBlOiJudW1iZXJbXSJ9XX0se3RmT3BOYW1lOiJHYXRoZXJOZCIsY2F0ZWdvcnk6InNsaWNlX2pvaW4iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kaWNlcyIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IlNwYXJzZVRvRGVuc2UiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InNwYXJzZUluZGljZXMiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6Im91dHB1dFNoYXBlIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoyLG5hbWU6InNwYXJzZVZhbHVlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjMsbmFtZToiZGVmYXVsdFZhbHVlIix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6InZhbGlkYXRlX2luZGljZXMiLG5hbWU6InZhbGlkYXRlSW5kaWNlcyIsdHlwZToiYm9vbCIsZGVmYXVsdFZhbHVlOiExLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IlRlbnNvclNjYXR0ZXJVcGRhdGUiLGNhdGVnb3J5OiJzbGljZV9qb2luIixpbnB1dHM6W3tzdGFydDowLG5hbWU6InRlbnNvciIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5kaWNlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToidmFsdWVzIix0eXBlOiJ0ZW5zb3IifV19XTt2YXIgc2xpY2VKb2luPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGpzb246anNvbiQ0fSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QganNvbiQzPVt7dGZPcE5hbWU6IlNwYXJzZUZpbGxFbXB0eVJvd3MiLGNhdGVnb3J5OiJzcGFyc2UiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiaW5kaWNlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToidmFsdWVzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJkZW5zZVNoYXBlIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MyxuYW1lOiJkZWZhdWx0VmFsdWUiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJTcGFyc2VSZXNoYXBlIixjYXRlZ29yeToic3BhcnNlIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImlucHV0SW5kaWNlcyIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiaW5wdXRTaGFwZSIsdHlwZToidGVuc29yIn0se3N0YXJ0OjIsbmFtZToibmV3U2hhcGUiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiVCIsbmFtZToiZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9XX0se3RmT3BOYW1lOiJTcGFyc2VTZWdtZW50TWVhbiIsY2F0ZWdvcnk6InNwYXJzZSIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJkYXRhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbmRpY2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJzZWdtZW50SWRzIix0eXBlOiJ0ZW5zb3IifV19LHt0Zk9wTmFtZToiU3BhcnNlU2VnbWVudFN1bSIsY2F0ZWdvcnk6InNwYXJzZSIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJkYXRhIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJpbmRpY2VzIix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MixuYW1lOiJzZWdtZW50SWRzIix0eXBlOiJ0ZW5zb3IifV19XTt2YXIgc3BhcnNlPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGpzb246anNvbiQzfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QganNvbiQyPVt7dGZPcE5hbWU6IkZGVCIsY2F0ZWdvcnk6InNwZWN0cmFsIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XX0se3RmT3BOYW1lOiJJRkZUIixjYXRlZ29yeToic3BlY3RyYWwiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dfSx7dGZPcE5hbWU6IlJGRlQiLGNhdGVnb3J5OiJzcGVjdHJhbCIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJmZnRfbGVuZ3RoIix0eXBlOiJudW1iZXIiLG5vdFN1cHBvcnRlZDohMH1dfSx7dGZPcE5hbWU6IklSRkZUIixjYXRlZ29yeToic3BlY3RyYWwiLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiZmZ0X2xlbmd0aCIsdHlwZToibnVtYmVyIixub3RTdXBwb3J0ZWQ6ITB9XX1dO3ZhciBzcGVjdHJhbD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29uOmpzb24kMn0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGpzb24kMT1be3RmT3BOYW1lOiJTdGF0aWNSZWdleFJlcGxhY2UiLGNhdGVnb3J5OiJzdHJpbmciLGlucHV0czpbe3N0YXJ0OjAsbmFtZToiaW5wdXQiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToicGF0dGVybiIsbmFtZToicGF0dGVybiIsdHlwZToic3RyaW5nIn0se3RmTmFtZToicmV3cml0ZSIsbmFtZToicmV3cml0ZSIsdHlwZToic3RyaW5nIn0se3RmTmFtZToicmVwbGFjZV9nbG9iYWwiLG5hbWU6InJlcGxhY2VHbG9iYWwiLHR5cGU6ImJvb2wifV19LHt0Zk9wTmFtZToiU3RyaW5nTkdyYW1zIixjYXRlZ29yeToic3RyaW5nIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImRhdGEiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImRhdGFTcGxpdHMiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToic2VwYXJhdG9yIixuYW1lOiJzZXBhcmF0b3IiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6Im5ncmFtX3dpZHRocyIsbmFtZToibkdyYW1XaWR0aHMiLHR5cGU6Im51bWJlcltdIn0se3RmTmFtZToibGVmdF9wYWQiLG5hbWU6ImxlZnRQYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6InJpZ2h0X3BhZCIsbmFtZToicmlnaHRQYWQiLHR5cGU6InN0cmluZyJ9LHt0Zk5hbWU6InBhZF93aWR0aCIsbmFtZToicGFkV2lkdGgiLHR5cGU6Im51bWJlciJ9LHt0Zk5hbWU6InByZXNlcnZlX3Nob3J0X3NlcXVlbmNlcyIsbmFtZToicHJlc2VydmVTaG9ydFNlcXVlbmNlcyIsdHlwZToiYm9vbCJ9XSxvdXRwdXRzOlsibmdyYW1zIiwibmdyYW1zX3NwbGl0cyJdfSx7dGZPcE5hbWU6IlN0cmluZ1NwbGl0IixjYXRlZ29yeToic3RyaW5nIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImlucHV0Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJkZWxpbWl0ZXIiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToic2tpcF9lbXB0eSIsbmFtZToic2tpcEVtcHR5Iix0eXBlOiJib29sIn1dLG91dHB1dHM6WyJpbmRpY2VzIiwidmFsdWVzIiwic2hhcGUiXX0se3RmT3BOYW1lOiJTdHJpbmdUb0hhc2hCdWNrZXRGYXN0IixjYXRlZ29yeToic3RyaW5nIixpbnB1dHM6W3tzdGFydDowLG5hbWU6ImlucHV0Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6Im51bV9idWNrZXRzIixuYW1lOiJudW1CdWNrZXRzIix0eXBlOiJudW1iZXIifV19XTt2YXIgc3RyaW5nPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGpzb246anNvbiQxfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QganNvbj1be3RmT3BOYW1lOiJDYXN0IixjYXRlZ29yeToidHJhbnNmb3JtYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn1dLGF0dHJzOlt7dGZOYW1lOiJTcmNUIixuYW1lOiJzZHR5cGUiLHR5cGU6ImR0eXBlIixub3RTdXBwb3J0ZWQ6ITB9LHt0Zk5hbWU6IkRzdFQiLG5hbWU6ImR0eXBlIix0eXBlOiJkdHlwZSJ9XX0se3RmT3BOYW1lOiJFeHBhbmREaW1zIixjYXRlZ29yeToidHJhbnNmb3JtYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyIn1dfSx7dGZPcE5hbWU6Ik1pcnJvclBhZCIsY2F0ZWdvcnk6InRyYW5zZm9ybWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6InBhZGRpbmciLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOlt7dGZOYW1lOiJtb2RlIixuYW1lOiJtb2RlIix0eXBlOiJzdHJpbmcifV19LHt0Zk9wTmFtZToiUGFkIixjYXRlZ29yeToidHJhbnNmb3JtYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToicGFkZGluZyIsdHlwZToibnVtYmVyW10ifV0sYXR0cnM6W3t0Zk5hbWU6ImNvbnN0YW50X3ZhbHVlIixuYW1lOiJjb25zdGFudFZhbHVlIix0eXBlOiJudW1iZXIiLGRlZmF1bHRWYWx1ZTowfV19LHt0Zk9wTmFtZToiUGFkVjIiLGNhdGVnb3J5OiJ0cmFuc2Zvcm1hdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJwYWRkaW5nIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoyLG5hbWU6ImNvbnN0YW50VmFsdWUiLHR5cGU6Im51bWJlciIsZGVmYXVsdFZhbHVlOjB9XX0se3RmT3BOYW1lOiJSZXNoYXBlIixjYXRlZ29yeToidHJhbnNmb3JtYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2hhcGUiLHR5cGU6Im51bWJlcltdIn1dfSx7dGZPcE5hbWU6IkVuc3VyZVNoYXBlIixjYXRlZ29yeToidHJhbnNmb3JtYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2hhcGUiLHR5cGU6Im51bWJlcltdIn1dfSx7dGZPcE5hbWU6IlNxdWVlemUiLGNhdGVnb3J5OiJ0cmFuc2Zvcm1hdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifV0sYXR0cnM6W3t0Zk5hbWU6ImF4aXMiLHRmRGVwcmVjYXRlZE5hbWU6InNxdWVlemVfZGltcyIsbmFtZToiYXhpcyIsdHlwZToibnVtYmVyW10ifV19LHt0Zk9wTmFtZToiU3BhY2VUb0JhdGNoTkQiLGNhdGVnb3J5OiJ0cmFuc2Zvcm1hdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJ4Iix0eXBlOiJ0ZW5zb3IifSx7c3RhcnQ6MSxuYW1lOiJibG9ja1NoYXBlIix0eXBlOiJudW1iZXJbXSJ9LHtzdGFydDoyLG5hbWU6InBhZGRpbmdzIix0eXBlOiJudW1iZXJbXSJ9XX0se3RmT3BOYW1lOiJCYXRjaFRvU3BhY2VORCIsY2F0ZWdvcnk6InRyYW5zZm9ybWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9LHtzdGFydDoxLG5hbWU6ImJsb2NrU2hhcGUiLHR5cGU6Im51bWJlcltdIn0se3N0YXJ0OjIsbmFtZToiY3JvcHMiLHR5cGU6Im51bWJlcltdIn1dfSx7dGZPcE5hbWU6IkRlcHRoVG9TcGFjZSIsY2F0ZWdvcnk6InRyYW5zZm9ybWF0aW9uIixpbnB1dHM6W3tzdGFydDowLG5hbWU6IngiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbe3RmTmFtZToiYmxvY2tfc2l6ZSIsbmFtZToiYmxvY2tTaXplIix0eXBlOiJudW1iZXIifSx7dGZOYW1lOiJkYXRhX2Zvcm1hdCIsbmFtZToiZGF0YUZvcm1hdCIsdHlwZToic3RyaW5nIn1dfSx7dGZPcE5hbWU6IkJyb2FkY2FzdFRvIixjYXRlZ29yeToidHJhbnNmb3JtYXRpb24iLGlucHV0czpbe3N0YXJ0OjAsbmFtZToieCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToic2hhcGUiLHR5cGU6Im51bWJlcltdIn1dLGF0dHJzOltdfSx7dGZPcE5hbWU6IkJyb2FkY2FzdEFyZ3MiLGNhdGVnb3J5OiJ0cmFuc2Zvcm1hdGlvbiIsaW5wdXRzOlt7c3RhcnQ6MCxuYW1lOiJzMCIsdHlwZToidGVuc29yIn0se3N0YXJ0OjEsbmFtZToiczEiLHR5cGU6InRlbnNvciJ9XSxhdHRyczpbXX1dO3ZhciB0cmFuc2Zvcm1hdGlvbj1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxqc29ufSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgT3BlcmF0aW9uTWFwcGVye3N0YXRpYyBnZXQgSW5zdGFuY2UoKXtyZXR1cm4gdGhpcy5faW5zdGFuY2V8fCh0aGlzLl9pbnN0YW5jZT1uZXcgdGhpcyl9Y29uc3RydWN0b3IoKXtjb25zdCBhYT1bYXJpdGhtZXRpYyxiYXNpY01hdGgsY29udHJvbCxjb252b2x1dGlvbixjcmVhdGlvbixkeW5hbWljLGV2YWx1YXRpb24sZ3JhcGgsaGFzaFRhYmxlLGltYWdlLGxvZ2ljYWwsbWF0cmljZXMsbm9ybWFsaXphdGlvbixyZWR1Y3Rpb24sc2xpY2VKb2luLHNwYXJzZSxzcGVjdHJhbCxzdHJpbmcsdHJhbnNmb3JtYXRpb25dLHhhPVtdLmNvbmNhdCguLi5hYS5tYXAoYmE9PmJhLmpzb24pKTt0aGlzLm9wTWFwcGVycz14YS5yZWR1Y2UoKGJhLFNhKT0+KGJhW1NhLnRmT3BOYW1lXT1TYSxiYSkse30pfXRyYW5zZm9ybUdyYXBoKGFhLHhhPXt9KXtjb25zdCBiYT1hYS5ub2RlLFNhPVtdLFRhPVtdLHdhPVtdLEVhPWJhLnJlZHVjZSgoc2wscmwpPT4oc2xbcmwubmFtZV09dGhpcy5tYXBOb2RlKHJsKSxybC5vcC5zdGFydHNXaXRoKCJQbGFjZWhvbGRlciIpP1NhLnB1c2goc2xbcmwubmFtZV0pOnJsLm9wPT09IkNvbnN0Ij9UYS5wdXNoKHNsW3JsLm5hbWVdKToocmwuaW5wdXQ9PW51bGx8fHJsLmlucHV0Lmxlbmd0aD09PTApJiZ3YS5wdXNoKHNsW3JsLm5hbWVdKSxzbCkse30pO2xldCBrYT1bXTtjb25zdCBBYT1bXTtsZXQgRmE9e30sTGE9e307eGEhPW51bGwmJihGYT10aGlzLm1hcFNpZ25hdHVyZUVudHJpZXMoeGEuaW5wdXRzKSxMYT10aGlzLm1hcFNpZ25hdHVyZUVudHJpZXMoeGEub3V0cHV0cykpO2NvbnN0IGVsPU9iamVjdC5rZXlzKEVhKTtlbC5mb3JFYWNoKHNsPT57Y29uc3Qgcmw9RWFbc2xdO3JsLmlucHV0TmFtZXMuZm9yRWFjaCgob2wsYWwpPT57Y29uc3RbbGwsLGlsXT1nZXROb2RlTmFtZUFuZEluZGV4KG9sKSxjbD1FYVtsbF07aWYoY2wub3V0cHV0cyE9bnVsbCl7Y29uc3QgdWw9Y2wub3V0cHV0cy5pbmRleE9mKGlsKTtpZih1bCE9PS0xKXtjb25zdCBkbD1gJHtsbH06JHt1bH1gO3JsLmlucHV0TmFtZXNbYWxdPWRsfX1ybC5pbnB1dHMucHVzaChjbCksY2wuY2hpbGRyZW4ucHVzaChybCl9KX0pLE9iamVjdC5rZXlzKExhKS5sZW5ndGg9PT0wP2VsLmZvckVhY2goc2w9Pntjb25zdCBybD1FYVtzbF07cmwuY2hpbGRyZW4ubGVuZ3RoPT09MCYmQWEucHVzaChybCl9KTpPYmplY3Qua2V5cyhMYSkuZm9yRWFjaChzbD0+e2NvbnN0W3JsXT1nZXROb2RlTmFtZUFuZEluZGV4KHNsKSxvbD1FYVtybF07b2whPW51bGwmJihvbC5zaWduYXR1cmVLZXk9TGFbc2xdLEFhLnB1c2gob2wpKX0pLE9iamVjdC5rZXlzKEZhKS5sZW5ndGg+MD9PYmplY3Qua2V5cyhGYSkuZm9yRWFjaChzbD0+e2NvbnN0W3JsXT1nZXROb2RlTmFtZUFuZEluZGV4KHNsKSxvbD1FYVtybF07b2wmJihvbC5zaWduYXR1cmVLZXk9RmFbc2xdLGthLnB1c2gob2wpKX0pOmthPVNhO2xldCB0bD17fTthYS5saWJyYXJ5IT1udWxsJiZhYS5saWJyYXJ5LmZ1bmN0aW9uIT1udWxsJiYodGw9YWEubGlicmFyeS5mdW5jdGlvbi5yZWR1Y2UoKHNsLHJsKT0+KHNsW3JsLnNpZ25hdHVyZS5uYW1lXT10aGlzLm1hcEZ1bmN0aW9uKHJsKSxzbCkse30pKTtjb25zdCBubD17bm9kZXM6RWEsaW5wdXRzOmthLG91dHB1dHM6QWEsd2VpZ2h0czpUYSxwbGFjZWhvbGRlcnM6U2Esc2lnbmF0dXJlOnhhLGZ1bmN0aW9uczp0bH07cmV0dXJuIHdhLmxlbmd0aD4wJiYobmwuaW5pdE5vZGVzPXdhKSxubH1tYXBTaWduYXR1cmVFbnRyaWVzKGFhKXtyZXR1cm4gT2JqZWN0LmtleXMoYWF8fHt9KS5yZWR1Y2UoKHhhLGJhKT0+KHhhW2FhW2JhXS5uYW1lXT1iYSx4YSkse30pfW1hcE5vZGUoYWEpe2NvbnN0IHhhPWdldFJlZ2lzdGVyZWRPcChhYS5vcCl8fHRoaXMub3BNYXBwZXJzW2FhLm9wXXx8e307YWEuYXR0cj09bnVsbCYmKGFhLmF0dHI9e30pO2NvbnN0IGJhPXtuYW1lOmFhLm5hbWUsb3A6YWEub3AsY2F0ZWdvcnk6eGEuY2F0ZWdvcnksaW5wdXROYW1lczooYWEuaW5wdXR8fFtdKS5tYXAoU2E9PlNhLnN0YXJ0c1dpdGgoIl4iKT9TYS5zbGljZSgxKTpTYSksaW5wdXRzOltdLGNoaWxkcmVuOltdLGlucHV0UGFyYW1zOnt9LGF0dHJQYXJhbXM6e30scmF3QXR0cnM6YWEuYXR0cixvdXRwdXRzOnhhLm91dHB1dHN9O3JldHVybiB4YS5pbnB1dHMhPW51bGwmJihiYS5pbnB1dFBhcmFtcz14YS5pbnB1dHMucmVkdWNlKChTYSxUYSk9PihTYVtUYS5uYW1lXT17dHlwZTpUYS50eXBlLGlucHV0SW5kZXhTdGFydDpUYS5zdGFydCxpbnB1dEluZGV4RW5kOlRhLmVuZH0sU2EpLHt9KSkseGEuYXR0cnMhPW51bGwmJihiYS5hdHRyUGFyYW1zPXhhLmF0dHJzLnJlZHVjZSgoU2EsVGEpPT57Y29uc3Qgd2E9VGEudHlwZTtsZXQgRWE7c3dpdGNoKFRhLnR5cGUpe2Nhc2Uic3RyaW5nIjpFYT1nZXRTdHJpbmdQYXJhbShhYS5hdHRyLFRhLnRmTmFtZSxUYS5kZWZhdWx0VmFsdWUpLEVhPT09dm9pZCAwJiZUYS50ZkRlcHJlY2F0ZWROYW1lJiYoRWE9Z2V0U3RyaW5nUGFyYW0oYWEuYXR0cixUYS50ZkRlcHJlY2F0ZWROYW1lLFRhLmRlZmF1bHRWYWx1ZSkpO2JyZWFrO2Nhc2Uic3RyaW5nW10iOkVhPWdldFN0cmluZ0FycmF5UGFyYW0oYWEuYXR0cixUYS50Zk5hbWUsVGEuZGVmYXVsdFZhbHVlKSxFYT09PXZvaWQgMCYmVGEudGZEZXByZWNhdGVkTmFtZSYmKEVhPWdldFN0cmluZ0FycmF5UGFyYW0oYWEuYXR0cixUYS50ZkRlcHJlY2F0ZWROYW1lLFRhLmRlZmF1bHRWYWx1ZSkpO2JyZWFrO2Nhc2UibnVtYmVyIjpFYT1nZXROdW1iZXJQYXJhbShhYS5hdHRyLFRhLnRmTmFtZSxUYS5kZWZhdWx0VmFsdWV8fDApLEVhPT09dm9pZCAwJiZUYS50ZkRlcHJlY2F0ZWROYW1lJiYoRWE9Z2V0TnVtYmVyUGFyYW0oYWEuYXR0cixUYS50ZkRlcHJlY2F0ZWROYW1lLFRhLmRlZmF1bHRWYWx1ZSkpO2JyZWFrO2Nhc2UibnVtYmVyW10iOkVhPWdldE51bWVyaWNBcnJheVBhcmFtKGFhLmF0dHIsVGEudGZOYW1lLFRhLmRlZmF1bHRWYWx1ZSksRWE9PT12b2lkIDAmJlRhLnRmRGVwcmVjYXRlZE5hbWUmJihFYT1nZXROdW1lcmljQXJyYXlQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJib29sIjpFYT1nZXRCb29sUGFyYW0oYWEuYXR0cixUYS50Zk5hbWUsVGEuZGVmYXVsdFZhbHVlKSxFYT09PXZvaWQgMCYmVGEudGZEZXByZWNhdGVkTmFtZSYmKEVhPWdldEJvb2xQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJib29sW10iOkVhPWdldEJvb2xBcnJheVBhcmFtKGFhLmF0dHIsVGEudGZOYW1lLFRhLmRlZmF1bHRWYWx1ZSksRWE9PT12b2lkIDAmJlRhLnRmRGVwcmVjYXRlZE5hbWUmJihFYT1nZXRCb29sQXJyYXlQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJzaGFwZSI6RWE9Z2V0VGVuc29yU2hhcGVQYXJhbShhYS5hdHRyLFRhLnRmTmFtZSxUYS5kZWZhdWx0VmFsdWUpLEVhPT09dm9pZCAwJiZUYS50ZkRlcHJlY2F0ZWROYW1lJiYoRWE9Z2V0VGVuc29yU2hhcGVQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJzaGFwZVtdIjpFYT1nZXRUZW5zb3JTaGFwZUFycmF5UGFyYW0oYWEuYXR0cixUYS50Zk5hbWUsVGEuZGVmYXVsdFZhbHVlKSxFYT09PXZvaWQgMCYmVGEudGZEZXByZWNhdGVkTmFtZSYmKEVhPWdldFRlbnNvclNoYXBlQXJyYXlQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJkdHlwZSI6RWE9Z2V0RHR5cGVQYXJhbShhYS5hdHRyLFRhLnRmTmFtZSxUYS5kZWZhdWx0VmFsdWUpLEVhPT09dm9pZCAwJiZUYS50ZkRlcHJlY2F0ZWROYW1lJiYoRWE9Z2V0RHR5cGVQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJkdHlwZVtdIjpFYT1nZXREdHlwZUFycmF5UGFyYW0oYWEuYXR0cixUYS50Zk5hbWUsVGEuZGVmYXVsdFZhbHVlKSxFYT09PXZvaWQgMCYmVGEudGZEZXByZWNhdGVkTmFtZSYmKEVhPWdldER0eXBlQXJyYXlQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJmdW5jIjpFYT1nZXRGdW5jUGFyYW0oYWEuYXR0cixUYS50Zk5hbWUsVGEuZGVmYXVsdFZhbHVlKSxFYT09PXZvaWQgMCYmVGEudGZEZXByZWNhdGVkTmFtZSYmKEVhPWdldEZ1bmNQYXJhbShhYS5hdHRyLFRhLnRmRGVwcmVjYXRlZE5hbWUsVGEuZGVmYXVsdFZhbHVlKSk7YnJlYWs7Y2FzZSJ0ZW5zb3IiOmNhc2UidGVuc29ycyI6YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcmFtIHR5cGU6ICR7VGEudHlwZX0gZm9yIG9wOiAke2FhLm9wfWApfXJldHVybiBTYVtUYS5uYW1lXT17dmFsdWU6RWEsdHlwZTp3YX0sU2F9LHt9KSksYmF9bWFwRnVuY3Rpb24oYWEpe2NvbnN0IHhhPWFhLm5vZGVEZWYsYmE9W10sU2E9W107bGV0IFRhPXt9O3hhIT1udWxsJiYoVGE9eGEucmVkdWNlKChMYSxlbCk9PihMYVtlbC5uYW1lXT10aGlzLm1hcE5vZGUoZWwpLGVsLm9wPT09IkNvbnN0IiYmU2EucHVzaChMYVtlbC5uYW1lXSksTGEpLHt9KSk7Y29uc3Qgd2E9W10sRWE9W107YWEuc2lnbmF0dXJlLmlucHV0QXJnLmZvckVhY2goTGE9Pntjb25zdFtlbF09Z2V0Tm9kZU5hbWVBbmRJbmRleChMYS5uYW1lKSx0bD17bmFtZTplbCxvcDoiUGxhY2Vob2xkZXIiLGlucHV0czpbXSxpbnB1dE5hbWVzOltdLGNhdGVnb3J5OiJncmFwaCIsaW5wdXRQYXJhbXM6e30sYXR0clBhcmFtczp7ZHR5cGU6e3ZhbHVlOnBhcnNlRHR5cGVQYXJhbShMYS50eXBlKSx0eXBlOiJkdHlwZSJ9fSxjaGlsZHJlbjpbXX07dGwuc2lnbmF0dXJlS2V5PUxhLm5hbWUsd2EucHVzaCh0bCksVGFbZWxdPXRsfSksT2JqZWN0LmtleXMoVGEpLmZvckVhY2goTGE9Pntjb25zdCBlbD1UYVtMYV07ZWwuaW5wdXROYW1lcy5mb3JFYWNoKCh0bCxubCk9Pntjb25zdFtzbCwscmxdPWdldE5vZGVOYW1lQW5kSW5kZXgodGwpLG9sPVRhW3NsXTtpZihvbC5vdXRwdXRzIT1udWxsKXtjb25zdCBhbD1vbC5vdXRwdXRzLmluZGV4T2YocmwpO2lmKGFsIT09LTEpe2NvbnN0IGxsPWAke3NsfToke2FsfWA7ZWwuaW5wdXROYW1lc1tubF09bGx9fWVsLmlucHV0cy5wdXNoKG9sKSxvbC5jaGlsZHJlbi5wdXNoKGVsKX0pfSk7Y29uc3QgQWE9YWEucmV0O2FhLnNpZ25hdHVyZS5vdXRwdXRBcmcuZm9yRWFjaChMYT0+e2NvbnN0W2VsLHRsXT1nZXROb2RlTmFtZUFuZEluZGV4KEFhW0xhLm5hbWVdKSxubD1UYVtlbF07bmwhPW51bGwmJihubC5kZWZhdWx0T3V0cHV0PXRsLEVhLnB1c2gobmwpKX0pO2NvbnN0IEZhPXRoaXMubWFwQXJnc1RvU2lnbmF0dXJlKGFhKTtyZXR1cm57bm9kZXM6VGEsaW5wdXRzOndhLG91dHB1dHM6RWEsd2VpZ2h0czpTYSxwbGFjZWhvbGRlcnM6YmEsc2lnbmF0dXJlOkZhfX1tYXBBcmdzVG9TaWduYXR1cmUoYWEpe3JldHVybnttZXRob2ROYW1lOmFhLnNpZ25hdHVyZS5uYW1lLGlucHV0czphYS5zaWduYXR1cmUuaW5wdXRBcmcucmVkdWNlKCh4YSxiYSk9Pih4YVtiYS5uYW1lXT10aGlzLm1hcEFyZ1RvVGVuc29ySW5mbyhiYSkseGEpLHt9KSxvdXRwdXRzOmFhLnNpZ25hdHVyZS5vdXRwdXRBcmcucmVkdWNlKCh4YSxiYSk9Pih4YVtiYS5uYW1lXT10aGlzLm1hcEFyZ1RvVGVuc29ySW5mbyhiYSxhYS5yZXQpLHhhKSx7fSl9fW1hcEFyZ1RvVGVuc29ySW5mbyhhYSx4YSl7bGV0IGJhPWFhLm5hbWU7cmV0dXJuIHhhIT1udWxsJiYoYmE9eGFbYmFdKSx7bmFtZTpiYSxkdHlwZTphYS50eXBlfX19ZnVuY3Rpb24gZGVjb2RlQmFzZTY0KGhhKXtjb25zdCBhYT1lbnYkMSgpLmdsb2JhbDtpZih0eXBlb2YgYWEuYXRvYjwidSIpcmV0dXJuIGFhLmF0b2IoaGEpO2lmKHR5cGVvZiBCdWZmZXI8InUiKXJldHVybiBuZXcgQnVmZmVyKGhhLCJiYXNlNjQiKS50b1N0cmluZygpO3Rocm93IG5ldyBFcnJvcigiVW5hYmxlIHRvIGRlY29kZSBiYXNlNjQgaW4gdGhpcyBlbnZpcm9ubWVudC4gTWlzc2luZyBidWlsdC1pbiBhdG9iKCkgb3IgQnVmZmVyKCkiKX1mdW5jdGlvbiBwYXJzZVN0cmluZ1BhcmFtKGhhLGFhKXtjb25zdCB4YT1BcnJheS5pc0FycmF5KGhhKT9TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsaGEpOmRlY29kZUJhc2U2NChoYSk7cmV0dXJuIGFhP3hhOnhhLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gZ2V0U3RyaW5nUGFyYW0oaGEsYWEseGEsYmE9ITEpe2NvbnN0IFNhPWhhW2FhXTtyZXR1cm4gU2EhPW51bGw/cGFyc2VTdHJpbmdQYXJhbShTYS5zLGJhKTp4YX1mdW5jdGlvbiBnZXRCb29sUGFyYW0oaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtyZXR1cm4gYmE/YmEuYjp4YX1mdW5jdGlvbiBnZXROdW1iZXJQYXJhbShoYSxhYSx4YSl7Y29uc3QgYmE9aGFbYWFdfHx7fSxTYT1iYS5pIT1udWxsP2JhLmk6YmEuZiE9bnVsbD9iYS5mOnhhO3JldHVybiB0eXBlb2YgU2E9PSJudW1iZXIiP1NhOnBhcnNlSW50KFNhLDEwKX1mdW5jdGlvbiBwYXJzZUR0eXBlUGFyYW0oaGEpe3N3aXRjaCh0eXBlb2YgaGE9PSJzdHJpbmciJiYoaGE9RGF0YVR5cGVbaGFdKSxoYSl7Y2FzZSBEYXRhVHlwZS5EVF9GTE9BVDpjYXNlIERhdGFUeXBlLkRUX0hBTEY6cmV0dXJuImZsb2F0MzIiO2Nhc2UgRGF0YVR5cGUuRFRfSU5UMzI6Y2FzZSBEYXRhVHlwZS5EVF9JTlQ2NDpjYXNlIERhdGFUeXBlLkRUX0lOVDg6Y2FzZSBEYXRhVHlwZS5EVF9VSU5UODpyZXR1cm4iaW50MzIiO2Nhc2UgRGF0YVR5cGUuRFRfQk9PTDpyZXR1cm4iYm9vbCI7Y2FzZSBEYXRhVHlwZS5EVF9ET1VCTEU6cmV0dXJuImZsb2F0MzIiO2Nhc2UgRGF0YVR5cGUuRFRfU1RSSU5HOnJldHVybiJzdHJpbmciO2Nhc2UgRGF0YVR5cGUuRFRfQ09NUExFWDY0OmNhc2UgRGF0YVR5cGUuRFRfQ09NUExFWDEyODpyZXR1cm4iY29tcGxleDY0IjtkZWZhdWx0OnJldHVybiBudWxsfX1mdW5jdGlvbiBnZXRGdW5jUGFyYW0oaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtyZXR1cm4gYmEmJmJhLmZ1bmM/YmEuZnVuYy5uYW1lOnhhfWZ1bmN0aW9uIGdldER0eXBlUGFyYW0oaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtyZXR1cm4gYmEmJmJhLnR5cGU/cGFyc2VEdHlwZVBhcmFtKGJhLnR5cGUpOnhhfWZ1bmN0aW9uIGdldER0eXBlQXJyYXlQYXJhbShoYSxhYSx4YSl7Y29uc3QgYmE9aGFbYWFdO3JldHVybiBiYSYmYmEubGlzdCYmYmEubGlzdC50eXBlP2JhLmxpc3QudHlwZS5tYXAoU2E9PnBhcnNlRHR5cGVQYXJhbShTYSkpOnhhfWZ1bmN0aW9uIHBhcnNlVGVuc29yU2hhcGVQYXJhbShoYSl7aWYoIWhhLnVua25vd25SYW5rKXJldHVybiBoYS5kaW0hPW51bGw/aGEuZGltLm1hcChhYT0+dHlwZW9mIGFhLnNpemU9PSJudW1iZXIiP2FhLnNpemU6cGFyc2VJbnQoYWEuc2l6ZSwxMCkpOltdfWZ1bmN0aW9uIGdldFRlbnNvclNoYXBlUGFyYW0oaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtyZXR1cm4gYmEmJmJhLnNoYXBlP3BhcnNlVGVuc29yU2hhcGVQYXJhbShiYS5zaGFwZSk6eGF9ZnVuY3Rpb24gZ2V0TnVtZXJpY0FycmF5UGFyYW0oaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtyZXR1cm4gYmE/KChiYS5saXN0LmYmJmJhLmxpc3QuZi5sZW5ndGg/YmEubGlzdC5mOmJhLmxpc3QuaSl8fFtdKS5tYXAoU2E9PnR5cGVvZiBTYT09Im51bWJlciI/U2E6cGFyc2VJbnQoU2EsMTApKTp4YX1mdW5jdGlvbiBnZXRTdHJpbmdBcnJheVBhcmFtKGhhLGFhLHhhLGJhPSExKXtjb25zdCBTYT1oYVthYV07cmV0dXJuIFNhJiZTYS5saXN0JiZTYS5saXN0LnM/U2EubGlzdC5zLm1hcChUYT0+cGFyc2VTdHJpbmdQYXJhbShUYSxiYSkpOnhhfWZ1bmN0aW9uIGdldFRlbnNvclNoYXBlQXJyYXlQYXJhbShoYSxhYSx4YSl7Y29uc3QgYmE9aGFbYWFdO3JldHVybiBiYSYmYmEubGlzdCYmYmEubGlzdC5zaGFwZT9iYS5saXN0LnNoYXBlLm1hcChTYT0+cGFyc2VUZW5zb3JTaGFwZVBhcmFtKFNhKSk6eGF9ZnVuY3Rpb24gZ2V0Qm9vbEFycmF5UGFyYW0oaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtyZXR1cm4gYmEmJmJhLmxpc3QmJmJhLmxpc3QuYj9iYS5saXN0LmI6eGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgTm9kZVZhbHVlSW1wbHtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy5ub2RlPWFhLHRoaXMudGVuc29yTWFwPXhhLHRoaXMuY29udGV4dD1iYSx0aGlzLmlucHV0cz1bXSx0aGlzLmF0dHJzPXt9LHRoaXMuaW5wdXRzPWFhLmlucHV0TmFtZXMubWFwKFNhPT50aGlzLmdldElucHV0KFNhKSksYWEucmF3QXR0cnMhPW51bGwmJih0aGlzLmF0dHJzPU9iamVjdC5rZXlzKGFhLnJhd0F0dHJzKS5yZWR1Y2UoKFNhLFRhKT0+KFNhW1RhXT10aGlzLmdldEF0dHIoVGEpLFNhKSx7fSkpfWdldElucHV0KGFhKXtyZXR1cm4gZ2V0VGVuc29yKGFhLHRoaXMudGVuc29yTWFwLHRoaXMuY29udGV4dCl9Z2V0QXR0cihhYSx4YSl7Y29uc3QgYmE9dGhpcy5ub2RlLnJhd0F0dHJzW2FhXTtpZihiYS50ZW5zb3IhPW51bGwpcmV0dXJuIGdldFRlbnNvcihhYSx0aGlzLnRlbnNvck1hcCx0aGlzLmNvbnRleHQpO2lmKGJhLmkhPW51bGx8fGJhLmYhPW51bGwpcmV0dXJuIGdldE51bWJlclBhcmFtKHRoaXMubm9kZS5yYXdBdHRycyxhYSx4YSk7aWYoYmEucyE9bnVsbClyZXR1cm4gZ2V0U3RyaW5nUGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKTtpZihiYS5iIT1udWxsKXJldHVybiBnZXRCb29sUGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKTtpZihiYS5zaGFwZSE9bnVsbClyZXR1cm4gZ2V0VGVuc29yU2hhcGVQYXJhbSh0aGlzLm5vZGUucmF3QXR0cnMsYWEseGEpO2lmKGJhLnR5cGUhPW51bGwpcmV0dXJuIGdldER0eXBlUGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKTtpZihiYS5saXN0IT1udWxsKXtpZihiYS5saXN0LmkhPW51bGx8fGJhLmxpc3QuZiE9bnVsbClyZXR1cm4gZ2V0TnVtZXJpY0FycmF5UGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKTtpZihiYS5saXN0LnMhPW51bGwpcmV0dXJuIGdldFN0cmluZ0FycmF5UGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKTtpZihiYS5saXN0LnNoYXBlIT1udWxsKXJldHVybiBnZXRUZW5zb3JTaGFwZUFycmF5UGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKTtpZihiYS5saXN0LmIhPW51bGwpcmV0dXJuIGdldEJvb2xBcnJheVBhcmFtKHRoaXMubm9kZS5yYXdBdHRycyxhYSx4YSk7aWYoYmEubGlzdC50eXBlIT1udWxsKXJldHVybiBnZXREdHlwZUFycmF5UGFyYW0odGhpcy5ub2RlLnJhd0F0dHJzLGFhLHhhKX1yZXR1cm4geGF9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciB0Zk9wcz1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxPUF9TQ09QRV9TVUZGSVg6T1BfU0NPUEVfU1VGRklYJDEsYWJzOmFicyQ0LGFjb3M6YWNvcyQzLGFjb3NoOmFjb3NoJDMsYWRkOmFkZCQzLGFkZE46YWRkTiQzLGFsbDphbGwkMyxhbnk6YW55JDMsYXJnTWF4OmFyZ01heCQzLGFyZ01pbjphcmdNaW4kMyxhc2luOmFzaW4kMyxhc2luaDphc2luaCQzLGF0YW46YXRhbiQzLGF0YW4yOmF0YW4yJDMsYXRhbmg6YXRhbmgkMyxhdmdQb29sOmF2Z1Bvb2wkMyxhdmdQb29sM2QsYmFzaWNMU1RNQ2VsbCxiYXRjaE5vcm06YmF0Y2hOb3JtJDMsYmF0Y2hOb3JtMmQsYmF0Y2hOb3JtM2QsYmF0Y2hOb3JtNGQsYmF0Y2hUb1NwYWNlTkQ6YmF0Y2hUb1NwYWNlTkQkMyxiaW5jb3VudDpiaW5jb3VudCQzLGJpdHdpc2VBbmQ6Yml0d2lzZUFuZCQzLGJvb2xlYW5NYXNrQXN5bmMsYnJvYWRjYXN0QXJnczpicm9hZGNhc3RBcmdzJDMsYnJvYWRjYXN0VG86YnJvYWRjYXN0VG8kMSxidWZmZXI6YnVmZmVyJDEsY2FzdDpjYXN0JDUsY2VpbDpjZWlsJDMsY2xpcEJ5VmFsdWU6Y2xpcEJ5VmFsdWUkMyxjbG9uZTpjbG9uZSQxLGNvbXBsZXg6Y29tcGxleCQ0LGNvbmNhdDpjb25jYXQkMyxjb25jYXQxZCxjb25jYXQyZCxjb25jYXQzZCxjb25jYXQ0ZCxjb252MWQsY29udjJkOmNvbnYyZCQzLGNvbnYyZFRyYW5zcG9zZSxjb252M2QsY29udjNkVHJhbnNwb3NlLGNvczpjb3MkMyxjb3NoOmNvc2gkMyxjb3NpbmVXaW5kb3csY3VtcHJvZDpjdW1wcm9kJDMsY3Vtc3VtOmN1bXN1bSQzLGRlbnNlQmluY291bnQ6ZGVuc2VCaW5jb3VudCQzLGRlcHRoVG9TcGFjZTpkZXB0aFRvU3BhY2UkMyxkZXB0aHdpc2VDb252MmQ6ZGVwdGh3aXNlQ29udjJkJDIsZGlhZzpkaWFnJDMsZGlsYXRpb24yZCxkaXY6ZGl2JDIsZGl2Tm9OYW4sZG90OmRvdCQxLGRyb3BvdXQ6ZHJvcG91dCQxLGVpbnN1bTplaW5zdW0kMyxlbHU6ZWx1JDUsZW5jbG9zaW5nUG93ZXJPZlR3byxlbnN1cmVTaGFwZSxlcXVhbDplcXVhbCQzLGVyZjplcmYkMyxldWNsaWRlYW5Ob3JtLGV4cDpleHAkMyxleHBhbmREaW1zOmV4cGFuZERpbXMkNCxleHBtMTpleHBtMSQzLGV5ZSxmZnQ6ZmZ0JDMsZmlsbDpmaWxsJDQsZmxvb3I6Zmxvb3IkMyxmbG9vckRpdjpmbG9vckRpdiQ0LGZ1c2VkOmZ1c2VkX29wcyxnYXRoZXI6Z2F0aGVyJDEsZ2F0aGVyTkQsZ3JlYXRlcjpncmVhdGVyJDMsZ3JlYXRlckVxdWFsOmdyZWF0ZXJFcXVhbCQzLGlmZnQ6aWZmdCQzLGltYWc6aW1hZyQzLGltYWdlOmltYWdlJDEsaW5Ub3BLQXN5bmMsaXJmZnQsaXNGaW5pdGU6aXNGaW5pdGUkNCxpc0luZjppc0luZiQzLGlzTmFOOmlzTmFOJDQsbGVha3lSZWx1OmxlYWt5UmVsdSQ0LGxlc3M6bGVzcyQzLGxlc3NFcXVhbDpsZXNzRXF1YWwkMyxsaW5hbGcsbGluc3BhY2UsbG9jYWxSZXNwb25zZU5vcm1hbGl6YXRpb24sbG9nOmxvZyQ0LGxvZzFwOmxvZzFwJDMsbG9nU2lnbW9pZCxsb2dTb2Z0bWF4LGxvZ1N1bUV4cCxsb2dpY2FsQW5kOmxvZ2ljYWxBbmQkMyxsb2dpY2FsTm90OmxvZ2ljYWxOb3QkMyxsb2dpY2FsT3I6bG9naWNhbE9yJDMsbG9naWNhbFhvcixsb3NzZXMsbG93ZXJCb3VuZDpsb3dlckJvdW5kJDEsbWF0TXVsOm1hdE11bCQxLG1heDptYXgkNCxtYXhQb29sOm1heFBvb2wkMyxtYXhQb29sM2Q6bWF4UG9vbDNkJDIsbWF4UG9vbFdpdGhBcmdtYXgsbWF4aW11bTptYXhpbXVtJDQsbWVhbjptZWFuJDEsbWVzaGdyaWQsbWluOm1pbiQ0LG1pbmltdW06bWluaW11bSQzLG1pcnJvclBhZDptaXJyb3JQYWQkMSxtb2Q6bW9kJDMsbW9tZW50cyxtb3ZpbmdBdmVyYWdlLG11bDptdWwkMSxtdWx0aVJOTkNlbGwsbXVsdGlub21pYWw6bXVsdGlub21pYWwkMyxuZWc6bmVnJDMsbm9ybSxub3RFcXVhbDpub3RFcXVhbCQzLG9uZUhvdDpvbmVIb3QkMyxvbmVzOm9uZXMkMSxvbmVzTGlrZTpvbmVzTGlrZSQzLG9wOm9wJDEsb3V0ZXJQcm9kdWN0LHBhZCxwYWQxZCxwYWQyZCxwYWQzZCxwYWQ0ZCxwb29sOnBvb2wkMSxwb3c6cG93JDQscHJlbHU6cHJlbHUkNCxwcmludDpwcmludCQxLHByb2Q6cHJvZCQzLHJhZ2dlZEdhdGhlcjpyYWdnZWRHYXRoZXIkMyxyYWdnZWRSYW5nZTpyYWdnZWRSYW5nZSQzLHJhZ2dlZFRlbnNvclRvVGVuc29yOnJhZ2dlZFRlbnNvclRvVGVuc29yJDMscmFuZCxyYW5kb21HYW1tYSxyYW5kb21Ob3JtYWw6cmFuZG9tTm9ybWFsJDEscmFuZG9tU3RhbmRhcmROb3JtYWwscmFuZG9tVW5pZm9ybSxyYW5kb21Vbmlmb3JtSW50LHJhbmdlOnJhbmdlJDQscmVhbDpyZWFsJDMscmVjaXByb2NhbDpyZWNpcHJvY2FsJDMscmVsdTpyZWx1JDQscmVsdTY6cmVsdTYkNCxyZXNoYXBlOnJlc2hhcGUkNCxyZXZlcnNlOnJldmVyc2UkMyxyZXZlcnNlMWQscmV2ZXJzZTJkLHJldmVyc2UzZCxyZXZlcnNlNGQscmZmdCxyb3VuZDpyb3VuZCQ0LHJzcXJ0OnJzcXJ0JDMsc2NhbGFyOnNjYWxhciQxLHNjYXR0ZXJORCxzZWFyY2hTb3J0ZWQ6c2VhcmNoU29ydGVkJDMsc2VsdTpzZWx1JDMsc2VwYXJhYmxlQ29udjJkLHNldGRpZmYxZEFzeW5jLHNpZ21vaWQ6c2lnbW9pZCQ0LHNpZ246c2lnbiQzLHNpZ25hbCxzaW46c2luJDMsc2luaDpzaW5oJDMsc2xpY2U6c2xpY2UkMyxzbGljZTFkLHNsaWNlMmQsc2xpY2UzZCxzbGljZTRkLHNvZnRtYXg6c29mdG1heCQzLHNvZnRwbHVzOnNvZnRwbHVzJDMsc3BhY2VUb0JhdGNoTkQ6c3BhY2VUb0JhdGNoTkQkMyxzcGFyc2U6c3BhcnNlJDEsc3BhcnNlVG9EZW5zZTpzcGFyc2VUb0RlbnNlJDMsc3BlY3RyYWw6c3BlY3RyYWwkMSxzcGxpdDpzcGxpdCQzLHNxcnQ6c3FydCQ0LHNxdWFyZTpzcXVhcmUkNCxzcXVhcmVkRGlmZmVyZW5jZTpzcXVhcmVkRGlmZmVyZW5jZSQzLHNxdWVlemUsc3RhY2ssc3RlcDpzdGVwJDQsc3RyaWRlZFNsaWNlOnN0cmlkZWRTbGljZSQzLHN0cmluZzpzdHJpbmckMSxzdWI6c3ViJDQsc3VtOnN1bSQ1LHRhbjp0YW4kMyx0YW5oOnRhbmgkMyx0ZW5zb3IsdGVuc29yMWQsdGVuc29yMmQsdGVuc29yM2QsdGVuc29yNGQsdGVuc29yNWQsdGVuc29yNmQsdGVuc29yU2NhdHRlclVwZGF0ZTp0ZW5zb3JTY2F0dGVyVXBkYXRlJDMsdGlsZTp0aWxlJDQsdG9wayx0cmFuc3Bvc2U6dHJhbnNwb3NlJDMsdHJ1bmNhdGVkTm9ybWFsLHVuaXF1ZTp1bmlxdWUkNCx1bnNvcnRlZFNlZ21lbnRTdW06dW5zb3J0ZWRTZWdtZW50U3VtJDMsdW5zdGFjayx1cHBlckJvdW5kOnVwcGVyQm91bmQkMSx2YXJpYWJsZSx3aGVyZSx3aGVyZUFzeW5jLHplcm9zOnplcm9zJDIsemVyb3NMaWtlOnplcm9zTGlrZSQ0fSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXhlY3V0ZU9wJGs9KGhhLGFhLHhhLGJhPXRmT3BzKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJCaWFzQWRkIjpjYXNlIkFkZFYyIjpjYXNlIkFkZCI6cmV0dXJuW2JhLmFkZChnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJBZGROIjpyZXR1cm5bYmEuYWRkTihnZXRQYXJhbVZhbHVlKCJ0ZW5zb3JzIixoYSxhYSx4YSkpXTtjYXNlIkZsb29yTW9kIjpjYXNlIk1vZCI6cmV0dXJuW2JhLm1vZChnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJNdWwiOnJldHVybltiYS5tdWwoZ2V0UGFyYW1WYWx1ZSgiYSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImIiLGhhLGFhLHhhKSldO2Nhc2UiUmVhbERpdiI6Y2FzZSJEaXYiOnJldHVybltiYS5kaXYoZ2V0UGFyYW1WYWx1ZSgiYSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImIiLGhhLGFhLHhhKSldO2Nhc2UiRGl2Tm9OYW4iOnJldHVybltiYS5kaXZOb05hbihnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJGbG9vckRpdiI6cmV0dXJuW2JhLmZsb29yRGl2KGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSkpXTtjYXNlIlN1YiI6cmV0dXJuW2JhLnN1YihnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJNaW5pbXVtIjpyZXR1cm5bYmEubWluaW11bShnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJNYXhpbXVtIjpyZXR1cm5bYmEubWF4aW11bShnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJQb3ciOnJldHVybltiYS5wb3coZ2V0UGFyYW1WYWx1ZSgiYSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImIiLGhhLGFhLHhhKSldO2Nhc2UiU3F1YXJlZERpZmZlcmVuY2UiOnJldHVybltiYS5zcXVhcmVkRGlmZmVyZW5jZShnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCRqPShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiQWJzIjpjYXNlIkNvbXBsZXhBYnMiOnJldHVybltiYS5hYnMoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJBY29zIjpyZXR1cm5bYmEuYWNvcyhnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIkFjb3NoIjpyZXR1cm5bYmEuYWNvc2goZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJBc2luIjpyZXR1cm5bYmEuYXNpbihnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIkFzaW5oIjpyZXR1cm5bYmEuYXNpbmgoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJBdGFuIjpyZXR1cm5bYmEuYXRhbihnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIkF0YW4yIjpyZXR1cm5bYmEuYXRhbjIoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInkiLGhhLGFhLHhhKSldO2Nhc2UiQXRhbmgiOnJldHVybltiYS5hdGFuaChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIkNlaWwiOnJldHVybltiYS5jZWlsKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiQ29tcGxleCI6cmV0dXJuW2JhLmNvbXBsZXgoZ2V0UGFyYW1WYWx1ZSgicmVhbCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImltYWciLGhhLGFhLHhhKSldO2Nhc2UiQ29zIjpyZXR1cm5bYmEuY29zKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiQ29zaCI6cmV0dXJuW2JhLmNvc2goZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJFbHUiOnJldHVybltiYS5lbHUoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJFcmYiOnJldHVybltiYS5lcmYoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJFeHAiOnJldHVybltiYS5leHAoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJFeHBtMSI6cmV0dXJuW2JhLmV4cG0xKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiRmxvb3IiOnJldHVybltiYS5mbG9vcihnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIkxvZyI6cmV0dXJuW2JhLmxvZyhnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIkxvZzFwIjpyZXR1cm5bYmEubG9nMXAoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJJbWFnIjpyZXR1cm5bYmEuaW1hZyhnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIk5lZyI6cmV0dXJuW2JhLm5lZyhnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlJlY2lwcm9jYWwiOnJldHVybltiYS5yZWNpcHJvY2FsKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiUmVhbCI6cmV0dXJuW2JhLnJlYWwoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJSZWx1IjpyZXR1cm5bYmEucmVsdShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlJvdW5kIjpyZXR1cm5bYmEucm91bmQoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJTZWx1IjpyZXR1cm5bYmEuc2VsdShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlNpZ21vaWQiOnJldHVybltiYS5zaWdtb2lkKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiU2luIjpyZXR1cm5bYmEuc2luKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiU2lnbiI6cmV0dXJuW2JhLnNpZ24oZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJTaW5oIjpyZXR1cm5bYmEuc2luaChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlNvZnRwbHVzIjpyZXR1cm5bYmEuc29mdHBsdXMoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJTcXJ0IjpyZXR1cm5bYmEuc3FydChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlNxdWFyZSI6cmV0dXJuW2JhLnNxdWFyZShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlRhbmgiOnJldHVybltiYS50YW5oKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiVGFuIjpyZXR1cm5bYmEudGFuKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiQ2xpcEJ5VmFsdWUiOnJldHVybltiYS5jbGlwQnlWYWx1ZShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiY2xpcFZhbHVlTWluIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiY2xpcFZhbHVlTWF4IixoYSxhYSx4YSkpXTtjYXNlIlJlbHU2IjpyZXR1cm5bYmEucmVsdTYoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJSc3FydCI6cmV0dXJuW2JhLnJzcXJ0KGdldFRlbnNvcihoYS5pbnB1dE5hbWVzWzBdLGFhLHhhKSldO2Nhc2UiTGVha3lSZWx1IjpyZXR1cm5bYmEubGVha3lSZWx1KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJhbHBoYSIsaGEsYWEseGEpKV07Y2FzZSJQcmVsdSI6cmV0dXJuW2JhLnByZWx1KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJhbHBoYSIsaGEsYWEseGEpKV07Y2FzZSJJc05hbiI6cmV0dXJuW2JhLmlzTmFOKGdldFRlbnNvcihoYS5pbnB1dE5hbWVzWzBdLGFhLHhhKSldO2Nhc2UiSXNJbmYiOnJldHVybltiYS5pc0luZihnZXRUZW5zb3IoaGEuaW5wdXROYW1lc1swXSxhYSx4YSkpXTtjYXNlIklzRmluaXRlIjpyZXR1cm5bYmEuaXNGaW5pdGUoZ2V0VGVuc29yKGhhLmlucHV0TmFtZXNbMF0sYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFzc2VydFNoYXBlc01hdGNoQWxsb3dVbmRlZmluZWRTaXplKGhhLGFhLHhhPSIiKXtpZighKHR5cGVvZiBoYT09Im51bWJlciJ8fHR5cGVvZiBhYT09Im51bWJlciIpKXthc3NlcnQkMihoYS5sZW5ndGg9PT1hYS5sZW5ndGgsKCk9PnhhK2AgU2hhcGVzICR7aGF9IGFuZCAke2FhfSBtdXN0IG1hdGNoYCk7Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDtiYSsrKXtjb25zdCBTYT1oYVtiYV0sVGE9YWFbYmFdO2Fzc2VydCQyKFNhPDB8fFRhPDB8fFNhPT09VGEsKCk9PnhhK2AgU2hhcGVzICR7aGF9IGFuZCAke2FhfSBtdXN0IG1hdGNoYCl9fX1mdW5jdGlvbiBmdWxsRGVmaW5lZFNoYXBlKGhhKXtyZXR1cm4hKHR5cGVvZiBoYT09Im51bWJlciJ8fGhhLnNvbWUoYWE9PmFhPDApKX1mdW5jdGlvbiBpbmZlckVsZW1lbnRTaGFwZShoYSxhYSx4YSl7bGV0IGJhPW1lcmdlRWxlbWVudFNoYXBlKGhhLHhhKTtjb25zdCBTYT0hZnVsbERlZmluZWRTaGFwZShiYSk7aWYoU2EmJmFhLmxlbmd0aD09PTApdGhyb3cgbmV3IEVycm9yKGBUcmllZCB0byBjYWxjdWxhdGUgZWxlbWVudHMgb2YgYW4gZW1wdHkgbGlzdCB3aXRoIG5vbi1mdWxseS1kZWZpbmVkIGVsZW1lbnRTaGFwZTogJHtiYX1gKTtpZihTYSYmYWEuZm9yRWFjaChUYT0+e2JhPW1lcmdlRWxlbWVudFNoYXBlKFRhLnNoYXBlLGJhKX0pLCFmdWxsRGVmaW5lZFNoYXBlKGJhKSl0aHJvdyBuZXcgRXJyb3IoYE5vbi1mdWxseS1kZWZpbmVkIGVsZW1lbnRTaGFwZTogJHtiYX1gKTtyZXR1cm4gYmF9ZnVuY3Rpb24gbWVyZ2VFbGVtZW50U2hhcGUoaGEsYWEpe2lmKHR5cGVvZiBoYT09Im51bWJlciIpcmV0dXJuIGFhO2lmKHR5cGVvZiBhYT09Im51bWJlciIpcmV0dXJuIGhhO2lmKGhhLmxlbmd0aCE9PWFhLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYEluY29tcGF0aWJsZSByYW5rcyBkdXJpbmcgbWVyZ2U6ICR7aGF9IHZzLiAke2FhfWApO2NvbnN0IHhhPVtdO2ZvcihsZXQgYmE9MDtiYTxoYS5sZW5ndGg7KytiYSl7Y29uc3QgU2E9aGFbYmFdLFRhPWFhW2JhXTtpZihTYT49MCYmVGE+PTAmJlNhIT09VGEpdGhyb3cgbmV3IEVycm9yKGBJbmNvbXBhdGlibGUgc2hhcGUgZHVyaW5nIG1lcmdlOiAke2hhfSB2cy4gJHthYX1gKTt4YVtiYV09U2E+PTA/U2E6VGF9cmV0dXJuIHhhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFRlbnNvckFycmF5e2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhLEVhKXt0aGlzLm5hbWU9YWEsdGhpcy5kdHlwZT14YSx0aGlzLm1heFNpemU9YmEsdGhpcy5lbGVtZW50U2hhcGU9U2EsdGhpcy5pZGVudGljYWxFbGVtZW50U2hhcGVzPVRhLHRoaXMuZHluYW1pY1NpemU9d2EsdGhpcy5jbGVhckFmdGVyUmVhZD1FYSx0aGlzLnRlbnNvcnM9W10sdGhpcy5jbG9zZWRfPSExLHRoaXMuaWRUZW5zb3I9c2NhbGFyJDEoMCksa2VlcCQxKHRoaXMuaWRUZW5zb3IpfWdldCBpZCgpe3JldHVybiB0aGlzLmlkVGVuc29yLmlkfWdldCBjbG9zZWQoKXtyZXR1cm4gdGhpcy5jbG9zZWRffWNsZWFyQW5kQ2xvc2UoYWEpe3RoaXMudGVuc29ycy5mb3JFYWNoKHhhPT57KGFhPT1udWxsfHwhYWEuaGFzKHhhLnRlbnNvci5pZCkpJiZ4YS50ZW5zb3IuZGlzcG9zZSgpfSksdGhpcy50ZW5zb3JzPVtdLHRoaXMuY2xvc2VkXz0hMCx0aGlzLmlkVGVuc29yLmRpc3Bvc2UoKX1zaXplKCl7cmV0dXJuIHRoaXMudGVuc29ycy5sZW5ndGh9cmVhZChhYSl7aWYodGhpcy5jbG9zZWRfKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgJHt0aGlzLm5hbWV9IGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkLmApO2lmKGFhPDB8fGFhPj10aGlzLnNpemUoKSl0aHJvdyBuZXcgRXJyb3IoYFRyaWVkIHRvIHJlYWQgZnJvbSBpbmRleCAke2FhfSwgYnV0IGFycmF5IHNpemUgaXM6ICR7dGhpcy5zaXplKCl9YCk7Y29uc3QgeGE9dGhpcy50ZW5zb3JzW2FhXTtpZih4YS5jbGVhcmVkKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgJHt0aGlzLm5hbWV9OiBDb3VsZCBub3QgcmVhZCBpbmRleCAke2FhfSB0d2ljZSBiZWNhdXNlIGl0IHdhcyBjbGVhcmVkIGFmdGVyIGEgcHJldmlvdXMgcmVhZCAocGVyaGFwcyB0cnkgc2V0dGluZyBjbGVhcl9hZnRlcl9yZWFkID0gZmFsc2U/KS5gKTtyZXR1cm4gdGhpcy5jbGVhckFmdGVyUmVhZCYmKHhhLmNsZWFyZWQ9ITApLHhhLnJlYWQ9ITAseGEudGVuc29yfXJlYWRNYW55KGFhKXtyZXR1cm4gYWEubWFwKHhhPT50aGlzLnJlYWQoeGEpKX13cml0ZShhYSx4YSl7aWYodGhpcy5jbG9zZWRfKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgJHt0aGlzLm5hbWV9IGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkLmApO2lmKGFhPDB8fCF0aGlzLmR5bmFtaWNTaXplJiZhYT49dGhpcy5tYXhTaXplKXRocm93IG5ldyBFcnJvcihgVHJpZWQgdG8gd3JpdGUgdG8gaW5kZXggJHthYX0sIGJ1dCBhcnJheSBpcyBub3QgcmVzaXplYWJsZSBhbmQgc2l6ZSBpczogJHt0aGlzLm1heFNpemV9YCk7Y29uc3QgYmE9dGhpcy50ZW5zb3JzW2FhXXx8e307aWYoeGEuZHR5cGUhPT10aGlzLmR0eXBlKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgJHt0aGlzLm5hbWV9OiBDb3VsZCBub3Qgd3JpdGUgdG8gVGVuc29yQXJyYXkgaW5kZXggJHthYX0sCiAgICAgICAgICBiZWNhdXNlIHRoZSB2YWx1ZSBkdHlwZSBpcyAke3hhLmR0eXBlfSwgYnV0IFRlbnNvckFycmF5IGR0eXBlIGlzICR7dGhpcy5kdHlwZX0uYCk7aWYodGhpcy5zaXplKCk9PT0wJiYodGhpcy5lbGVtZW50U2hhcGU9PW51bGx8fHRoaXMuZWxlbWVudFNoYXBlLmxlbmd0aD09PTApJiYodGhpcy5lbGVtZW50U2hhcGU9eGEuc2hhcGUpLGFzc2VydFNoYXBlc01hdGNoQWxsb3dVbmRlZmluZWRTaXplKHRoaXMuZWxlbWVudFNoYXBlLHhhLnNoYXBlLGBUZW5zb3JBcnJheSAke3RoaXMubmFtZX06IENvdWxkIG5vdCB3cml0ZSB0byBUZW5zb3JBcnJheSBpbmRleCAke2FhfS5gKSxiYS5yZWFkKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgJHt0aGlzLm5hbWV9OiBDb3VsZCBub3Qgd3JpdGUgdG8gVGVuc29yQXJyYXkgaW5kZXggJHthYX0sIGJlY2F1c2UgaXQgaGFzIGFscmVhZHkgYmVlbiByZWFkLmApO2lmKGJhLndyaXR0ZW4pdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JBcnJheSAke3RoaXMubmFtZX06IENvdWxkIG5vdCB3cml0ZSB0byBUZW5zb3JBcnJheSBpbmRleCAke2FhfSwgYmVjYXVzZSBpdCBoYXMgYWxyZWFkeSBiZWVuIHdyaXR0ZW4uYCk7YmEudGVuc29yPXhhLGtlZXAkMSh4YSksYmEud3JpdHRlbj0hMCx0aGlzLnRlbnNvcnNbYWFdPWJhfXdyaXRlTWFueShhYSx4YSl7aWYoYWEubGVuZ3RoIT09eGEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgJHt0aGlzLm5hbWV9OiBjb3VsZCBub3Qgd3JpdGUgbXVsdGlwbGUgdGVuc29ycyxiZWNhdXNlIHRoZSBpbmRleCBzaXplOiAke2FhLmxlbmd0aH0gaXMgbm90IHRoZSBzYW1lIGFzIHRlbnNvcnMgc2l6ZTogJHt4YS5sZW5ndGh9LmApO2FhLmZvckVhY2goKGJhLFNhKT0+dGhpcy53cml0ZShiYSx4YVtTYV0pKX1nYXRoZXIoYWEseGEpe2lmKHhhJiZ4YSE9PXRoaXMuZHR5cGUpdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JBcnJheSBkdHlwZSBpcyAke3RoaXMuZHR5cGV9IGJ1dCBnYXRoZXIgcmVxdWVzdGVkIGR0eXBlICR7eGF9YCk7aWYoYWEpYWE9YWEuc2xpY2UoMCx0aGlzLnNpemUoKSk7ZWxzZXthYT1bXTtmb3IobGV0IFNhPTA7U2E8dGhpcy5zaXplKCk7U2ErKylhYS5wdXNoKFNhKX1pZihhYS5sZW5ndGg9PT0wKXJldHVybiB0ZW5zb3IoW10sWzBdLmNvbmNhdCh0aGlzLmVsZW1lbnRTaGFwZSkpO2NvbnN0IGJhPXRoaXMucmVhZE1hbnkoYWEpO3JldHVybiBhc3NlcnRTaGFwZXNNYXRjaEFsbG93VW5kZWZpbmVkU2l6ZSh0aGlzLmVsZW1lbnRTaGFwZSxiYVswXS5zaGFwZSwiVGVuc29yQXJyYXkgc2hhcGUgbWlzbWF0Y2g6ICIpLHN0YWNrKGJhLDApfWNvbmNhdChhYSl7aWYoYWEmJmFhIT09dGhpcy5kdHlwZSl0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckFycmF5IGR0eXBlIGlzICR7dGhpcy5kdHlwZX0gYnV0IGNvbmNhdCByZXF1ZXN0ZWQgZHR5cGUgJHthYX1gKTtpZih0aGlzLnNpemUoKT09PTApcmV0dXJuIHRlbnNvcihbXSxbMF0uY29uY2F0KHRoaXMuZWxlbWVudFNoYXBlKSk7Y29uc3QgeGE9W107Zm9yKGxldCBTYT0wO1NhPHRoaXMuc2l6ZSgpO1NhKyspeGEucHVzaChTYSk7Y29uc3QgYmE9dGhpcy5yZWFkTWFueSh4YSk7cmV0dXJuIGFzc2VydFNoYXBlc01hdGNoQWxsb3dVbmRlZmluZWRTaXplKHRoaXMuZWxlbWVudFNoYXBlLGJhWzBdLnNoYXBlLGBUZW5zb3JBcnJheSBzaGFwZSBtaXNtYXRjaDogdGVuc29yIGFycmF5IHNoYXBlICgke3RoaXMuZWxlbWVudFNoYXBlfSkgdnMgZmlyc3QgdGVuc29yIHNoYXBlICgke2JhWzBdLnNoYXBlfSlgKSxjb25jYXQkMyhiYSwwKX1zY2F0dGVyKGFhLHhhKXtpZih4YS5kdHlwZSE9PXRoaXMuZHR5cGUpdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JBcnJheSBkdHlwZSBpcyAke3RoaXMuZHR5cGV9IGJ1dCB0ZW5zb3IgaGFzIGR0eXBlICR7eGEuZHR5cGV9YCk7aWYoYWEubGVuZ3RoIT09eGEuc2hhcGVbMF0pdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBsZW4oaW5kaWNlcykgPT0gdGVuc29yLnNoYXBlWzBdLCBidXQgc2F3OiAke2FhLmxlbmd0aH0gdnMuICR7eGEuc2hhcGVbMF19YCk7Y29uc3QgYmE9TWF0aC5tYXgoLi4uYWEpO2lmKCF0aGlzLmR5bmFtaWNTaXplJiZiYT49dGhpcy5tYXhTaXplKXRocm93IG5ldyBFcnJvcihgTWF4IGluZGV4IG11c3QgYmUgPCBhcnJheSBzaXplICgke2JhfSAgdnMuICR7dGhpcy5tYXhTaXplfSlgKTt0aGlzLndyaXRlTWFueShhYSx1bnN0YWNrKHhhLDApKX1zcGxpdChhYSx4YSl7aWYoeGEuZHR5cGUhPT10aGlzLmR0eXBlKXRocm93IG5ldyBFcnJvcihgVGVuc29yQXJyYXkgZHR5cGUgaXMgJHt0aGlzLmR0eXBlfSBidXQgdGVuc29yIGhhcyBkdHlwZSAke3hhLmR0eXBlfWApO2xldCBiYT0wO2NvbnN0IFNhPWFhLm1hcChrYT0+KGJhKz1rYSxiYSkpO2lmKGJhIT09eGEuc2hhcGVbMF0pdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBzdW0gb2YgbGVuZ3RocyB0byBiZSBlcXVhbCB0bwogICAgICAgICAgdGVuc29yLnNoYXBlWzBdLCBidXQgc3VtIG9mIGxlbmd0aHMgaXMKICAgICAgICAke2JhfSwgYW5kIHRlbnNvcidzIHNoYXBlIGlzOiAke3hhLnNoYXBlfWApO2lmKCF0aGlzLmR5bmFtaWNTaXplJiZhYS5sZW5ndGghPT10aGlzLm1heFNpemUpdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JBcnJheSdzIHNpemUgaXMgbm90IGVxdWFsIHRvIHRoZSBzaXplIG9mIGxlbmd0aHMgKCR7dGhpcy5tYXhTaXplfSB2cy4gJHthYS5sZW5ndGh9KSwgYW5kIHRoZSBUZW5zb3JBcnJheSBpcyBub3QgbWFya2VkIGFzIGR5bmFtaWNhbGx5IHJlc2l6ZWFibGVgKTtjb25zdCBUYT1iYT09PTA/MDp4YS5zaXplL2JhLHdhPVtdO3RpZHkkMSgoKT0+e3hhPXJlc2hhcGUkNCh4YSxbMSxiYSxUYV0pO2ZvcihsZXQga2E9MDtrYTxhYS5sZW5ndGg7KytrYSl7Y29uc3QgRmE9WzAsa2E9PT0wPzA6U2Fba2EtMV0sMF0sTGE9WzEsYWFba2FdLFRhXTt3YVtrYV09cmVzaGFwZSQ0KHNsaWNlJDMoeGEsRmEsTGEpLHRoaXMuZWxlbWVudFNoYXBlKX1yZXR1cm4gd2F9KTtjb25zdCBFYT1bXTtmb3IobGV0IGthPTA7a2E8YWEubGVuZ3RoO2thKyspRWFba2FdPWthO3RoaXMud3JpdGVNYW55KEVhLHdhKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgVGVuc29yTGlzdHtnZXQgaWQoKXtyZXR1cm4gdGhpcy5pZFRlbnNvci5pZH1jb25zdHJ1Y3RvcihhYSx4YSxiYSxTYT0tMSl7dGhpcy50ZW5zb3JzPWFhLHRoaXMuZWxlbWVudFNoYXBlPXhhLHRoaXMuZWxlbWVudER0eXBlPWJhLGFhIT1udWxsJiZhYS5mb3JFYWNoKFRhPT57aWYoYmEhPT1UYS5kdHlwZSl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSB0eXBlczsgb3AgZWxlbWVudHMgJHtiYX0sIGJ1dCBsaXN0IGVsZW1lbnRzICR7VGEuZHR5cGV9YCk7YXNzZXJ0U2hhcGVzTWF0Y2hBbGxvd1VuZGVmaW5lZFNpemUoeGEsVGEuc2hhcGUsIlRlbnNvckxpc3Qgc2hhcGUgbWlzbWF0Y2g6ICIpLGtlZXAkMShUYSl9KSx0aGlzLmlkVGVuc29yPXNjYWxhciQxKDApLHRoaXMubWF4TnVtRWxlbWVudHM9U2Esa2VlcCQxKHRoaXMuaWRUZW5zb3IpfWNvcHkoKXtyZXR1cm4gbmV3IFRlbnNvckxpc3QoWy4uLnRoaXMudGVuc29yc10sdGhpcy5lbGVtZW50U2hhcGUsdGhpcy5lbGVtZW50RHR5cGUpfWNsZWFyQW5kQ2xvc2UoYWEpe3RoaXMudGVuc29ycy5mb3JFYWNoKHhhPT57KGFhPT1udWxsfHwhYWEuaGFzKHhhLmlkKSkmJnhhLmRpc3Bvc2UoKX0pLHRoaXMudGVuc29ycy5sZW5ndGg9MCx0aGlzLmlkVGVuc29yLmRpc3Bvc2UoKX1zaXplKCl7cmV0dXJuIHRoaXMudGVuc29ycy5sZW5ndGh9c3RhY2soYWEseGEsYmE9LTEpe2lmKHhhIT09dGhpcy5lbGVtZW50RHR5cGUpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRhdGEgdHlwZXM7IG9wIGVsZW1lbnRzICR7eGF9LCBidXQgbGlzdCBlbGVtZW50cyAke3RoaXMuZWxlbWVudER0eXBlfWApO2lmKGJhIT09LTEmJnRoaXMudGVuc29ycy5sZW5ndGghPT1iYSl0aHJvdyBuZXcgRXJyb3IoYE9wZXJhdGlvbiBleHBlY3RlZCBhIGxpc3Qgd2l0aCAke2JhfSBlbGVtZW50cyBidXQgZ290IGEgbGlzdCB3aXRoICR7dGhpcy50ZW5zb3JzLmxlbmd0aH0gZWxlbWVudHMuYCk7YXNzZXJ0U2hhcGVzTWF0Y2hBbGxvd1VuZGVmaW5lZFNpemUoYWEsdGhpcy5lbGVtZW50U2hhcGUsIlRlbnNvckxpc3Qgc2hhcGUgbWlzbWF0Y2g6ICIpO2NvbnN0IFNhPWluZmVyRWxlbWVudFNoYXBlKHRoaXMuZWxlbWVudFNoYXBlLHRoaXMudGVuc29ycyxhYSk7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IFRhPXRoaXMudGVuc29ycy5tYXAod2E9PnJlc2hhcGUkNCh3YSxTYSkpO3JldHVybiBzdGFjayhUYSwwKX0pfXBvcEJhY2soYWEseGEpe2lmKHhhIT09dGhpcy5lbGVtZW50RHR5cGUpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRhdGEgdHlwZXM7IG9wIGVsZW1lbnRzICR7eGF9LCBidXQgbGlzdCBlbGVtZW50cyAke3RoaXMuZWxlbWVudER0eXBlfWApO2lmKHRoaXMuc2l6ZSgpPT09MCl0aHJvdyBuZXcgRXJyb3IoIlRyeWluZyB0byBwb3AgZnJvbSBhbiBlbXB0eSBsaXN0LiIpO2NvbnN0IGJhPWluZmVyRWxlbWVudFNoYXBlKHRoaXMuZWxlbWVudFNoYXBlLHRoaXMudGVuc29ycyxhYSksU2E9dGhpcy50ZW5zb3JzLnBvcCgpO3JldHVybiBTYS5rZXB0PSExLGFzc2VydFNoYXBlc01hdGNoQWxsb3dVbmRlZmluZWRTaXplKFNhLnNoYXBlLGFhLCJUZW5zb3JMaXN0IHNoYXBlIG1pc21hdGNoOiAiKSxyZXNoYXBlJDQoU2EsYmEpfXB1c2hCYWNrKGFhKXtpZihhYS5kdHlwZSE9PXRoaXMuZWxlbWVudER0eXBlKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhIHR5cGVzOyBvcCBlbGVtZW50cyAke2FhLmR0eXBlfSwgYnV0IGxpc3QgZWxlbWVudHMgJHt0aGlzLmVsZW1lbnREdHlwZX1gKTtpZihhc3NlcnRTaGFwZXNNYXRjaEFsbG93VW5kZWZpbmVkU2l6ZShhYS5zaGFwZSx0aGlzLmVsZW1lbnRTaGFwZSwiVGVuc29yTGlzdCBzaGFwZSBtaXNtYXRjaDogIiksdGhpcy5tYXhOdW1FbGVtZW50cz09PXRoaXMuc2l6ZSgpKXRocm93IG5ldyBFcnJvcigiVHJ5aW5nIHRvIHB1c2ggZWxlbWVudCBpbnRvIGEgZnVsbCBsaXN0LiIpO2tlZXAkMShhYSksdGhpcy50ZW5zb3JzLnB1c2goYWEpfXJlc2l6ZShhYSl7aWYoYWE8MCl0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckxpc3RSZXNpemUgZXhwZWN0cyBzaXplIHRvIGJlIG5vbi1uZWdhdGl2ZS4gR290OiAke2FhfWApO2lmKHRoaXMubWF4TnVtRWxlbWVudHMhPT0tMSYmYWE+dGhpcy5tYXhOdW1FbGVtZW50cyl0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckxpc3RSZXNpemUgaW5wdXQgc2l6ZSAke2FhfSBpcyBncmVhdGVyIG1heE51bUVsZW1lbnQgJHt0aGlzLm1heE51bUVsZW1lbnRzfS5gKTtjb25zdCB4YT1uZXcgVGVuc29yTGlzdChbXSx0aGlzLmVsZW1lbnRTaGFwZSx0aGlzLmVsZW1lbnREdHlwZSx0aGlzLm1heE51bUVsZW1lbnRzKTt4YS50ZW5zb3JzLmxlbmd0aD1hYTtmb3IobGV0IGJhPTA7YmE8TWF0aC5taW4odGhpcy50ZW5zb3JzLmxlbmd0aCxhYSk7KytiYSl4YS50ZW5zb3JzW2JhXT10aGlzLnRlbnNvcnNbYmFdO3JldHVybiB4YX1nZXRJdGVtKGFhLHhhLGJhKXtpZihiYSE9PXRoaXMuZWxlbWVudER0eXBlKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhIHR5cGVzOyBvcCBlbGVtZW50cyAke2JhfSwgYnV0IGxpc3QgZWxlbWVudHMgJHt0aGlzLmVsZW1lbnREdHlwZX1gKTtpZihhYTwwfHxhYT50aGlzLnRlbnNvcnMubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgVHJ5aW5nIHRvIGFjY2VzcyBlbGVtZW50ICR7YWF9IGluIGEgbGlzdCB3aXRoICR7dGhpcy50ZW5zb3JzLmxlbmd0aH0gZWxlbWVudHMuYCk7aWYodGhpcy50ZW5zb3JzW2FhXT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYGVsZW1lbnQgYXQgaW5kZXggJHthYX0gaXMgbnVsbC5gKTthc3NlcnRTaGFwZXNNYXRjaEFsbG93VW5kZWZpbmVkU2l6ZSh0aGlzLnRlbnNvcnNbYWFdLnNoYXBlLHhhLCJUZW5zb3JMaXN0IHNoYXBlIG1pc21hdGNoOiAiKTtjb25zdCBTYT1pbmZlckVsZW1lbnRTaGFwZSh0aGlzLmVsZW1lbnRTaGFwZSx0aGlzLnRlbnNvcnMseGEpO3JldHVybiByZXNoYXBlJDQodGhpcy50ZW5zb3JzW2FhXSxTYSl9c2V0SXRlbShhYSx4YSl7aWYoeGEuZHR5cGUhPT10aGlzLmVsZW1lbnREdHlwZSl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSB0eXBlczsgb3AgZWxlbWVudHMgJHt4YS5kdHlwZX0sIGJ1dCBsaXN0IGVsZW1lbnRzICR7dGhpcy5lbGVtZW50RHR5cGV9YCk7aWYoYWE8MHx8dGhpcy5tYXhOdW1FbGVtZW50cyE9PS0xJiZhYT49dGhpcy5tYXhOdW1FbGVtZW50cyl0aHJvdyBuZXcgRXJyb3IoYFRyeWluZyB0byBzZXQgZWxlbWVudCAke2FhfSBpbiBhIGxpc3Qgd2l0aCBtYXggJHt0aGlzLm1heE51bUVsZW1lbnRzfSBlbGVtZW50cy5gKTthc3NlcnRTaGFwZXNNYXRjaEFsbG93VW5kZWZpbmVkU2l6ZSh0aGlzLmVsZW1lbnRTaGFwZSx4YS5zaGFwZSwiVGVuc29yTGlzdCBzaGFwZSBtaXNtYXRjaDogIiksa2VlcCQxKHhhKSx0aGlzLnRlbnNvcnNbYWFdIT1udWxsJiYodGhpcy50ZW5zb3JzW2FhXS5rZXB0PSExKSx0aGlzLnRlbnNvcnNbYWFdPXhhfWdhdGhlcihhYSx4YSxiYSl7aWYoeGEhPT10aGlzLmVsZW1lbnREdHlwZSl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSB0eXBlczsgb3AgZWxlbWVudHMgJHt4YX0sIGJ1dCBsaXN0IGVsZW1lbnRzICR7dGhpcy5lbGVtZW50RHR5cGV9YCk7YXNzZXJ0U2hhcGVzTWF0Y2hBbGxvd1VuZGVmaW5lZFNpemUodGhpcy5lbGVtZW50U2hhcGUsYmEsIlRlbnNvckxpc3Qgc2hhcGUgbWlzbWF0Y2g6ICIpLGFhPWFhLnNsaWNlKDAsdGhpcy5zaXplKCkpO2NvbnN0IFNhPWluZmVyRWxlbWVudFNoYXBlKHRoaXMuZWxlbWVudFNoYXBlLHRoaXMudGVuc29ycyxiYSk7cmV0dXJuIGFhLmxlbmd0aD09PTA/dGVuc29yKFtdLFswXS5jb25jYXQoU2EpKTp0aWR5JDEoKCk9Pntjb25zdCBUYT1hYS5tYXAod2E9PnJlc2hhcGUkNCh0aGlzLnRlbnNvcnNbd2FdLFNhKSk7cmV0dXJuIHN0YWNrKFRhLDApfSl9Y29uY2F0KGFhLHhhKXtpZihhYSYmYWEhPT10aGlzLmVsZW1lbnREdHlwZSl0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckxpc3QgZHR5cGUgaXMgJHt0aGlzLmVsZW1lbnREdHlwZX0gYnV0IGNvbmNhdCByZXF1ZXN0ZWQgZHR5cGUgJHthYX1gKTthc3NlcnRTaGFwZXNNYXRjaEFsbG93VW5kZWZpbmVkU2l6ZSh0aGlzLmVsZW1lbnRTaGFwZSx4YSwiVGVuc29yTGlzdCBzaGFwZSBtaXNtYXRjaDogIik7Y29uc3QgYmE9aW5mZXJFbGVtZW50U2hhcGUodGhpcy5lbGVtZW50U2hhcGUsdGhpcy50ZW5zb3JzLHhhKTtyZXR1cm4gdGhpcy5zaXplKCk9PT0wP3RlbnNvcihbXSxbMF0uY29uY2F0KGJhKSk6dGlkeSQxKCgpPT57Y29uc3QgU2E9dGhpcy50ZW5zb3JzLm1hcChUYT0+cmVzaGFwZSQ0KFRhLGJhKSk7cmV0dXJuIGNvbmNhdCQzKFNhLDApfSl9fWZ1bmN0aW9uIGZyb21UZW5zb3IoaGEsYWEseGEpe2NvbnN0IGJhPWhhLmR0eXBlO2lmKGhhLnNoYXBlLmxlbmd0aDwxKXRocm93IG5ldyBFcnJvcihgVGVuc29yIG11c3QgYmUgYXQgbGVhc3QgYSB2ZWN0b3IsIGJ1dCBzYXcgc2hhcGU6ICR7aGEuc2hhcGV9YCk7aWYoaGEuZHR5cGUhPT14YSl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSB0eXBlczsgb3AgZWxlbWVudHMgJHtoYS5kdHlwZX0sIGJ1dCBsaXN0IGVsZW1lbnRzICR7eGF9YCk7Y29uc3QgU2E9aGEuc2hhcGUuc2xpY2UoMSk7YXNzZXJ0U2hhcGVzTWF0Y2hBbGxvd1VuZGVmaW5lZFNpemUoU2EsYWEsIlRlbnNvckxpc3Qgc2hhcGUgbWlzbWF0Y2g6ICIpO2NvbnN0IFRhPXVuc3RhY2soaGEpO3JldHVybiBuZXcgVGVuc29yTGlzdChUYSxhYSxiYSl9ZnVuY3Rpb24gcmVzZXJ2ZShoYSxhYSx4YSxiYSl7cmV0dXJuIG5ldyBUZW5zb3JMaXN0KFtdLGhhLGFhLGJhKX1mdW5jdGlvbiBzY2F0dGVyKGhhLGFhLHhhLGJhKXtpZihhYS5sZW5ndGghPT1oYS5zaGFwZVswXSl0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGxlbihpbmRpY2VzKSA9PSB0ZW5zb3Iuc2hhcGVbMF0sIGJ1dCBzYXc6ICR7YWEubGVuZ3RofSB2cy4gJHtoYS5zaGFwZVswXX1gKTtjb25zdCBTYT1NYXRoLm1heCguLi5hYSk7aWYoYmEhPW51bGwmJmJhIT09LTEmJlNhPj1iYSl0aHJvdyBuZXcgRXJyb3IoYE1heCBpbmRleCBtdXN0IGJlIDwgYXJyYXkgc2l6ZSAoJHtTYX0gIHZzLiAke2JhfSlgKTtjb25zdCBUYT1uZXcgVGVuc29yTGlzdChbXSx4YSxoYS5kdHlwZSxiYSksd2E9dW5zdGFjayhoYSwwKTtyZXR1cm4gYWEuZm9yRWFjaCgoRWEsa2EpPT57VGEuc2V0SXRlbShFYSx3YVtrYV0pfSksVGF9ZnVuY3Rpb24gc3BsaXQkMihoYSxhYSx4YSl7bGV0IGJhPTA7Y29uc3QgU2E9YWEubWFwKEZhPT4oYmErPUZhLGJhKSk7aWYoYmEhPT1oYS5zaGFwZVswXSl0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHN1bSBvZiBsZW5ndGhzIHRvIGJlIGVxdWFsIHRvCiAgICAgICAgICB0ZW5zb3Iuc2hhcGVbMF0sIGJ1dCBzdW0gb2YgbGVuZ3RocyBpcwogICAgICAgICR7YmF9LCBhbmQgdGVuc29yJ3Mgc2hhcGUgaXM6ICR7aGEuc2hhcGV9YCk7Y29uc3QgVGE9aGEuc2hhcGUuc2xpY2UoMSksd2E9bWVyZ2VFbGVtZW50U2hhcGUoVGEseGEpLEVhPWJhPT09MD8wOmhhLnNpemUvYmEsa2E9dGlkeSQxKCgpPT57Y29uc3QgRmE9W107aGE9cmVzaGFwZSQ0KGhhLFsxLGJhLEVhXSk7Zm9yKGxldCBMYT0wO0xhPGFhLmxlbmd0aDsrK0xhKXtjb25zdCB0bD1bMCxMYT09PTA/MDpTYVtMYS0xXSwwXSxubD1bMSxhYVtMYV0sRWFdO0ZhW0xhXT1yZXNoYXBlJDQoc2xpY2UkMyhoYSx0bCxubCksd2EpfXJldHVybiBoYS5kaXNwb3NlKCksRmF9KSxBYT1uZXcgVGVuc29yTGlzdChbXSx4YSxoYS5kdHlwZSxhYS5sZW5ndGgpO2ZvcihsZXQgRmE9MDtGYTxrYS5sZW5ndGg7RmErKylBYS5zZXRJdGVtKEZhLGthW0ZhXSk7cmV0dXJuIEFhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCRpPWFzeW5jKGhhLGFhLHhhKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJJZiI6Y2FzZSJTdGF0ZWxlc3NJZiI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRoZW5CcmFuY2giLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJlbHNlQnJhbmNoIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgiY29uZCIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImFyZ3MiLGhhLGFhLHhhKTtyZXR1cm4oYXdhaXQgVGEuZGF0YSgpKVswXT94YS5mdW5jdGlvbk1hcFtiYV0uZXhlY3V0ZUZ1bmN0aW9uQXN5bmMod2EseGEudGVuc29yQXJyYXlNYXAseGEudGVuc29yTGlzdE1hcCk6eGEuZnVuY3Rpb25NYXBbU2FdLmV4ZWN1dGVGdW5jdGlvbkFzeW5jKHdhLHhhLnRlbnNvckFycmF5TWFwLHhhLnRlbnNvckxpc3RNYXApfWNhc2UiV2hpbGUiOmNhc2UiU3RhdGVsZXNzV2hpbGUiOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJib2R5IixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgiY29uZCIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoImFyZ3MiLGhhLGFhLHhhKSx3YT1hd2FpdCB4YS5mdW5jdGlvbk1hcFtTYV0uZXhlY3V0ZUZ1bmN0aW9uQXN5bmMoVGEseGEudGVuc29yQXJyYXlNYXAseGEudGVuc29yTGlzdE1hcCksRWE9VGEubWFwKEZhPT5GYS5pZCk7bGV0IGthPWF3YWl0IHdhWzBdLmRhdGEoKTt3YS5mb3JFYWNoKEZhPT57IUZhLmtlcHQmJkVhLmluZGV4T2YoRmEuaWQpPT09LTEmJkZhLmRpc3Bvc2UoKX0pO2xldCBBYT1UYTtmb3IoO2thWzBdOyl7Y29uc3QgRmE9QWE7QWE9YXdhaXQgeGEuZnVuY3Rpb25NYXBbYmFdLmV4ZWN1dGVGdW5jdGlvbkFzeW5jKEFhLHhhLnRlbnNvckFycmF5TWFwLHhhLnRlbnNvckxpc3RNYXApO2NvbnN0IExhPUFhLm1hcCh0bD0+dGwuaWQpO0ZhLmZvckVhY2godGw9PnshdGwua2VwdCYmRWEuaW5kZXhPZih0bC5pZCk9PT0tMSYmTGEuaW5kZXhPZih0bC5pZCk9PT0tMSYmdGwuZGlzcG9zZSgpfSk7Y29uc3QgZWw9YXdhaXQgeGEuZnVuY3Rpb25NYXBbU2FdLmV4ZWN1dGVGdW5jdGlvbkFzeW5jKEFhLHhhLnRlbnNvckFycmF5TWFwLHhhLnRlbnNvckxpc3RNYXApO2thPWF3YWl0IGVsWzBdLmRhdGEoKSxlbC5mb3JFYWNoKHRsPT57IXRsLmtlcHQmJkVhLmluZGV4T2YodGwuaWQpPT09LTEmJkxhLmluZGV4T2YodGwuaWQpPT09LTEmJnRsLmRpc3Bvc2UoKX0pfXJldHVybiBBYX1jYXNlIkxvb3BDb25kIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgicHJlZCIsaGEsYWEseGEpO3JldHVybltjbG9uZVRlbnNvcihiYSldfWNhc2UiU3dpdGNoIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgicHJlZCIsaGEsYWEseGEpO2xldCBTYT1nZXRQYXJhbVZhbHVlKCJkYXRhIixoYSxhYSx4YSk7cmV0dXJuIFNhLmtlcHR8fChTYT1jbG9uZVRlbnNvcihTYSkpLChhd2FpdCBiYS5kYXRhKCkpWzBdP1t2b2lkIDAsU2FdOltTYSx2b2lkIDBdfWNhc2UiTWVyZ2UiOntjb25zdCBiYT1oYS5pbnB1dE5hbWVzLmZpbmQoU2E9PmdldFRlbnNvcihTYSxhYSx4YSkhPT12b2lkIDApO2lmKGJhKXtjb25zdCBTYT1nZXRUZW5zb3IoYmEsYWEseGEpO3JldHVybltjbG9uZVRlbnNvcihTYSldfXJldHVybn1jYXNlIkVudGVyIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgiZnJhbWVOYW1lIixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgidGVuc29yIixoYSxhYSx4YSk7cmV0dXJuIHhhLmVudGVyRnJhbWUoYmEpLFtjbG9uZVRlbnNvcihTYSldfWNhc2UiRXhpdCI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRlbnNvciIsaGEsYWEseGEpO3JldHVybiB4YS5leGl0RnJhbWUoKSxbY2xvbmVUZW5zb3IoYmEpXX1jYXNlIk5leHRJdGVyYXRpb24iOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKTtyZXR1cm4geGEubmV4dEl0ZXJhdGlvbigpLFtjbG9uZVRlbnNvcihiYSldfWNhc2UiVGVuc29yQXJyYXlWMyI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInNpemUiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoImVsZW1lbnRTaGFwZSIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImR5bmFtaWNTaXplIixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgiY2xlYXJBZnRlclJlYWQiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJpZGVudGljYWxFbGVtZW50U2hhcGVzIixoYSxhYSx4YSksQWE9Z2V0UGFyYW1WYWx1ZSgibmFtZSIsaGEsYWEseGEpLEZhPW5ldyBUZW5zb3JBcnJheShBYSxTYSxiYSxUYSxrYSx3YSxFYSk7cmV0dXJuIHhhLmFkZFRlbnNvckFycmF5KEZhKSxbRmEuaWRUZW5zb3Isc2NhbGFyJDEoMSldfWNhc2UiVGVuc29yQXJyYXlXcml0ZVYzIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yQXJyYXlJZCIsaGEsYWEseGEpLFNhPWdldFBhcmFtVmFsdWUoImluZGV4IixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yIixoYSxhYSx4YSksd2E9eGEuZ2V0VGVuc29yQXJyYXkoYmEuaWQpO3JldHVybiB3YS53cml0ZShTYSxUYSksW3dhLmlkVGVuc29yXX1jYXNlIlRlbnNvckFycmF5UmVhZFYzIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yQXJyYXlJZCIsaGEsYWEseGEpLFNhPWdldFBhcmFtVmFsdWUoImluZGV4IixoYSxhYSx4YSk7cmV0dXJuW3hhLmdldFRlbnNvckFycmF5KGJhLmlkKS5yZWFkKFNhKV19Y2FzZSJUZW5zb3JBcnJheUdhdGhlclYzIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yQXJyYXlJZCIsaGEsYWEseGEpLFNhPWdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpO3JldHVyblt4YS5nZXRUZW5zb3JBcnJheShiYS5pZCkuZ2F0aGVyKFNhLFRhKV19Y2FzZSJUZW5zb3JBcnJheVNjYXR0ZXJWMyI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRlbnNvckFycmF5SWQiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJpbmRpY2VzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yIixoYSxhYSx4YSksd2E9eGEuZ2V0VGVuc29yQXJyYXkoYmEuaWQpO3JldHVybiB3YS5zY2F0dGVyKFNhLFRhKSxbd2EuaWRUZW5zb3JdfWNhc2UiVGVuc29yQXJyYXlDb25jYXRWMyI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRlbnNvckFycmF5SWQiLGhhLGFhLHhhKSxTYT14YS5nZXRUZW5zb3JBcnJheShiYS5pZCksVGE9Z2V0UGFyYW1WYWx1ZSgiZHR5cGUiLGhhLGFhLHhhKTtyZXR1cm5bU2EuY29uY2F0KFRhKV19Y2FzZSJUZW5zb3JBcnJheVNwbGl0VjMiOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3JBcnJheUlkIixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgidGVuc29yIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgibGVuZ3RocyIsaGEsYWEseGEpLHdhPXhhLmdldFRlbnNvckFycmF5KGJhLmlkKTtyZXR1cm4gd2Euc3BsaXQoVGEsU2EpLFt3YS5pZFRlbnNvcl19Y2FzZSJUZW5zb3JBcnJheVNpemVWMyI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRlbnNvckFycmF5SWQiLGhhLGFhLHhhKSxTYT14YS5nZXRUZW5zb3JBcnJheShiYS5pZCk7cmV0dXJuW3NjYWxhciQxKFNhLnNpemUoKSwiaW50MzIiKV19Y2FzZSJUZW5zb3JBcnJheUNsb3NlVjMiOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3JBcnJheUlkIixoYSxhYSx4YSksU2E9eGEuZ2V0VGVuc29yQXJyYXkoYmEuaWQpO3JldHVybiBTYS5jbGVhckFuZENsb3NlKCksW1NhLmlkVGVuc29yXX1jYXNlIlRlbnNvckxpc3RTZXRJdGVtIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yTGlzdElkIixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgiaW5kZXgiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKSx3YT14YS5nZXRUZW5zb3JMaXN0KGJhLmlkKTtyZXR1cm4gd2Euc2V0SXRlbShTYSxUYSksW3dhLmlkVGVuc29yXX1jYXNlIlRlbnNvckxpc3RHZXRJdGVtIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yTGlzdElkIixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgiaW5kZXgiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50RFR5cGUiLGhhLGFhLHhhKTtyZXR1cm5beGEuZ2V0VGVuc29yTGlzdChiYS5pZCkuZ2V0SXRlbShTYSxUYSx3YSldfWNhc2UiVGVuc29yTGlzdFNjYXR0ZXJWMiI6Y2FzZSJUZW5zb3JMaXN0U2NhdHRlciI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJudW1FbGVtZW50cyIsaGEsYWEseGEpLEVhPXNjYXR0ZXIoU2EsYmEsVGEsd2EpO3JldHVybiB4YS5hZGRUZW5zb3JMaXN0KEVhKSxbRWEuaWRUZW5zb3JdfWNhc2UiVGVuc29yTGlzdFJlc2VydmUiOmNhc2UiRW1wdHlUZW5zb3JMaXN0Ijp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgiZWxlbWVudFNoYXBlIixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgiZWxlbWVudERUeXBlIixoYSxhYSx4YSk7bGV0IFRhO2hhLm9wPT09IlRlbnNvckxpc3RSZXNlcnZlIj9UYT0ibnVtRWxlbWVudHMiOlRhPSJtYXhOdW1FbGVtZW50cyI7Y29uc3Qgd2E9Z2V0UGFyYW1WYWx1ZShUYSxoYSxhYSx4YSksRWE9aGEub3A9PT0iVGVuc29yTGlzdFJlc2VydmUiPy0xOndhLGthPXJlc2VydmUoYmEsU2Esd2EsRWEpO3JldHVybiB4YS5hZGRUZW5zb3JMaXN0KGthKSxba2EuaWRUZW5zb3JdfWNhc2UiVGVuc29yTGlzdEdhdGhlciI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRlbnNvckxpc3RJZCIsaGEsYWEseGEpLFNhPWdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50RFR5cGUiLGhhLGFhLHhhKTtyZXR1cm5beGEuZ2V0VGVuc29yTGlzdChiYS5pZCkuZ2F0aGVyKFNhLHdhLFRhKV19Y2FzZSJUZW5zb3JMaXN0U3RhY2siOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3JMaXN0SWQiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50RFR5cGUiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJudW1FbGVtZW50cyIsaGEsYWEseGEpO3JldHVyblt4YS5nZXRUZW5zb3JMaXN0KGJhLmlkKS5zdGFjayhTYSxUYSx3YSldfWNhc2UiVGVuc29yTGlzdEZyb21UZW5zb3IiOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50RFR5cGUiLGhhLGFhLHhhKSx3YT1mcm9tVGVuc29yKGJhLFNhLFRhKTtyZXR1cm4geGEuYWRkVGVuc29yTGlzdCh3YSksW3dhLmlkVGVuc29yXX1jYXNlIlRlbnNvckxpc3RDb25jYXQiOmNhc2UiVGVuc29yTGlzdENvbmNhdFYyIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yTGlzdElkIixoYSxhYSx4YSksU2E9eGEuZ2V0VGVuc29yTGlzdChiYS5pZCksVGE9Z2V0UGFyYW1WYWx1ZSgiZHR5cGUiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKTtyZXR1cm5bU2EuY29uY2F0KFRhLHdhKV19Y2FzZSJUZW5zb3JMaXN0UHVzaEJhY2siOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3JMaXN0SWQiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKSxUYT14YS5nZXRUZW5zb3JMaXN0KGJhLmlkKTtyZXR1cm4gVGEucHVzaEJhY2soU2EpLFtUYS5pZFRlbnNvcl19Y2FzZSJUZW5zb3JMaXN0UG9wQmFjayI6e2NvbnN0IGJhPWdldFBhcmFtVmFsdWUoInRlbnNvckxpc3RJZCIsaGEsYWEseGEpLFNhPWdldFBhcmFtVmFsdWUoImVsZW1lbnRTaGFwZSIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoImVsZW1lbnREVHlwZSIsaGEsYWEseGEpO3JldHVyblt4YS5nZXRUZW5zb3JMaXN0KGJhLmlkKS5wb3BCYWNrKFNhLFRhKV19Y2FzZSJUZW5zb3JMaXN0U3BsaXQiOntjb25zdCBiYT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJlbGVtZW50U2hhcGUiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJsZW5ndGhzIixoYSxhYSx4YSksd2E9c3BsaXQkMihiYSxUYSxTYSk7cmV0dXJuIHhhLmFkZFRlbnNvckxpc3Qod2EpLFt3YS5pZFRlbnNvcl19Y2FzZSJUZW5zb3JMaXN0TGVuZ3RoIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yTGlzdElkIixoYSxhYSx4YSksU2E9eGEuZ2V0VGVuc29yTGlzdChiYS5pZCk7cmV0dXJuW3NjYWxhciQxKFNhLnNpemUoKSwiaW50MzIiKV19Y2FzZSJUZW5zb3JMaXN0UmVzaXplIjp7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgidGVuc29yTGlzdElkIixoYSxhYSx4YSksU2E9Z2V0UGFyYW1WYWx1ZSgic2l6ZSIsaGEsYWEseGEpLHdhPXhhLmdldFRlbnNvckxpc3QoYmEuaWQpLnJlc2l6ZShTYSk7cmV0dXJuIHhhLmFkZFRlbnNvckxpc3Qod2EpLFt3YS5pZFRlbnNvcl19ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZ1c2VkQ29udkFuZERlcHRoV2lzZVBhcmFtcyhoYSxhYSx4YSl7Y29uc3RbYmEsU2FdPWdldFBhcmFtVmFsdWUoImZ1c2VkT3BzIixoYSxhYSx4YSksVGE9YmE9PT0iYmlhc2FkZCIsd2E9IVRhLEVhPVNhPT09InByZWx1IixrYT1iYT09PSJmdXNlZGJhdGNobm9ybSIsQWE9Z2V0UGFyYW1WYWx1ZSgibnVtQXJncyIsaGEsYWEseGEpO2lmKFRhKXtpZihFYSYmQWEhPT0yKXRocm93IG5ldyBFcnJvcigiRnVzZWRDb252MmQgYW5kIERlcHRod2lzZUNvbnYyZCB3aXRoIEJpYXNBZGQgYW5kIFByZWx1IG11c3QgaGF2ZSB0d28gZXh0cmEgYXJndW1lbnRzOiBiaWFzIGFuZCBhbHBoYS4iKTtpZighRWEmJlRhJiZBYSE9PTEpdGhyb3cgbmV3IEVycm9yKCJGdXNlZENvbnYyZCBhbmQgRGVwdGh3aXNlQ29udjJkIHdpdGggQmlhc0FkZCBtdXN0IGhhdmUgb25lIGV4dHJhIGFyZ3VtZW50OiBiaWFzLiIpfWlmKGthKXRocm93IG5ldyBFcnJvcigiRnVzZWRDb252MmQgYW5kIERlcHRod2lzZUNvbnYyZCB3aXRoIEZ1c2VkQmF0Y2hOb3JtIGlzIG5vdCBzdXBwb3J0ZWQiKTtjb25zdCBGYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGVzIixoYSxhYSx4YSksTGE9Z2V0UGFkZGluZyhoYSxhYSx4YSksZWw9Z2V0UGFyYW1WYWx1ZSgiZGF0YUZvcm1hdCIsaGEsYWEseGEpLnRvVXBwZXJDYXNlKCksdGw9Z2V0UGFyYW1WYWx1ZSgiZGlsYXRpb25zIixoYSxhYSx4YSk7bGV0W25sLHNsXT1nZXRQYXJhbVZhbHVlKCJhcmdzIixoYSxhYSx4YSk7d2EmJihzbD1ubCxubD12b2lkIDApO2NvbnN0IHJsPWdldFBhcmFtVmFsdWUoImxlYWt5cmVsdUFscGhhIixoYSxhYSx4YSk7cmV0dXJue3N0cmlkZTpGYSxwYWQ6TGEsZGF0YUZvcm1hdDplbCxkaWxhdGlvbnM6dGwsYmlhc0FyZzpubCxwcmVsdUFyZzpzbCxhY3RpdmF0aW9uRnVuYzpTYSxsZWFreXJlbHVBbHBoYTpybH19Y29uc3QgZXhlY3V0ZU9wJGg9KGhhLGFhLHhhLGJhPXRmT3BzKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJDb252MUQiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGUiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJwYWQiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJkYXRhRm9ybWF0IixoYSxhYSx4YSkudG9VcHBlckNhc2UoKSxFYT1nZXRQYXJhbVZhbHVlKCJkaWxhdGlvbiIsaGEsYWEseGEpO3JldHVybltiYS5jb252MWQoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImZpbHRlciIsaGEsYWEseGEpLFNhLFRhLHdhLEVhKV19Y2FzZSJDb252MkQiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGVzIixoYSxhYSx4YSksVGE9Z2V0UGFkZGluZyhoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgiZGF0YUZvcm1hdCIsaGEsYWEseGEpLnRvVXBwZXJDYXNlKCksRWE9Z2V0UGFyYW1WYWx1ZSgiZGlsYXRpb25zIixoYSxhYSx4YSk7cmV0dXJuW2JhLmNvbnYyZChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiZmlsdGVyIixoYSxhYSx4YSksW1NhWzFdLFNhWzJdXSxUYSx3YSxbRWFbMV0sRWFbMl1dKV19Y2FzZSJfRnVzZWRDb252MkQiOntjb25zdHtzdHJpZGU6U2EscGFkOlRhLGRhdGFGb3JtYXQ6d2EsZGlsYXRpb25zOkVhLGJpYXNBcmc6a2EscHJlbHVBcmc6QWEsYWN0aXZhdGlvbkZ1bmM6RmEsbGVha3lyZWx1QWxwaGE6TGF9PWZ1c2VkQ29udkFuZERlcHRoV2lzZVBhcmFtcyhoYSxhYSx4YSk7cmV0dXJuW2JhLmZ1c2VkLmNvbnYyZCh7eDpnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksZmlsdGVyOmdldFBhcmFtVmFsdWUoImZpbHRlciIsaGEsYWEseGEpLHN0cmlkZXM6W1NhWzFdLFNhWzJdXSxwYWQ6VGEsZGF0YUZvcm1hdDp3YSxkaWxhdGlvbnM6W0VhWzFdLEVhWzJdXSxiaWFzOmthLGFjdGl2YXRpb246RmEscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpBYSxsZWFreXJlbHVBbHBoYTpMYX0pXX1jYXNlIkZ1c2VkRGVwdGh3aXNlQ29udjJkTmF0aXZlIjp7Y29uc3R7c3RyaWRlOlNhLHBhZDpUYSxkYXRhRm9ybWF0OndhLGRpbGF0aW9uczpFYSxiaWFzQXJnOmthLHByZWx1QXJnOkFhLGFjdGl2YXRpb25GdW5jOkZhLGxlYWt5cmVsdUFscGhhOkxhfT1mdXNlZENvbnZBbmREZXB0aFdpc2VQYXJhbXMoaGEsYWEseGEpO3JldHVybltiYS5mdXNlZC5kZXB0aHdpc2VDb252MmQoe3g6Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGZpbHRlcjpnZXRQYXJhbVZhbHVlKCJmaWx0ZXIiLGhhLGFhLHhhKSxzdHJpZGVzOltTYVsxXSxTYVsyXV0scGFkOlRhLGRhdGFGb3JtYXQ6d2EsZGlsYXRpb25zOltFYVsxXSxFYVsyXV0sYmlhczprYSxhY3RpdmF0aW9uOkZhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6QWEsbGVha3lyZWx1QWxwaGE6TGF9KV19Y2FzZSJDb252MkRCYWNrcHJvcElucHV0IjpjYXNlIkNvbnYyZFRyYW5zcG9zZSI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoIm91dHB1dFNoYXBlIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgic3RyaWRlcyIsaGEsYWEseGEpLHdhPWdldFBhZGRpbmcoaGEsYWEseGEpO3JldHVybltiYS5jb252MmRUcmFuc3Bvc2UoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImZpbHRlciIsaGEsYWEseGEpLFNhLFtUYVsxXSxUYVsyXV0sd2EpXX1jYXNlIkRlcHRod2lzZUNvbnYyZE5hdGl2ZSI6Y2FzZSJEZXB0aHdpc2VDb252MmQiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGVzIixoYSxhYSx4YSksVGE9Z2V0UGFkZGluZyhoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgiZGlsYXRpb25zIixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgiZGF0YUZvcm1hdCIsaGEsYWEseGEpLnRvVXBwZXJDYXNlKCk7cmV0dXJuW2JhLmRlcHRod2lzZUNvbnYyZChnZXRQYXJhbVZhbHVlKCJpbnB1dCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImZpbHRlciIsaGEsYWEseGEpLFtTYVsxXSxTYVsyXV0sVGEsRWEsW3dhWzFdLHdhWzJdXSldfWNhc2UiQ29udjNEIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgic3RyaWRlcyIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoInBhZCIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImRhdGFGb3JtYXQiLGhhLGFhLHhhKS50b1VwcGVyQ2FzZSgpLEVhPWdldFBhcmFtVmFsdWUoImRpbGF0aW9ucyIsaGEsYWEseGEpO3JldHVybltiYS5jb252M2QoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImZpbHRlciIsaGEsYWEseGEpLFtTYVsxXSxTYVsyXSxTYVszXV0sVGEsd2EsW0VhWzFdLEVhWzJdLEVhWzNdXSldfWNhc2UiQXZnUG9vbCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoInN0cmlkZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJwYWQiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJrZXJuZWxTaXplIixoYSxhYSx4YSk7cmV0dXJuW2JhLmF2Z1Bvb2woZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLFt3YVsxXSx3YVsyXV0sW1NhWzFdLFNhWzJdXSxUYSldfWNhc2UiTWF4UG9vbCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoInN0cmlkZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJwYWQiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJrZXJuZWxTaXplIixoYSxhYSx4YSk7cmV0dXJuW2JhLm1heFBvb2woZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLFt3YVsxXSx3YVsyXV0sW1NhWzFdLFNhWzJdXSxUYSldfWNhc2UiTWF4UG9vbFdpdGhBcmdtYXgiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGVzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgicGFkIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgia2VybmVsU2l6ZSIsaGEsYWEseGEpLEVhPWdldFBhcmFtVmFsdWUoImluY2x1ZGVCYXRjaEluSW5kZXgiLGhhLGFhLHhhKSx7cmVzdWx0OmthLGluZGV4ZXM6QWF9PWJhLm1heFBvb2xXaXRoQXJnbWF4KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxbd2FbMV0sd2FbMl1dLFtTYVsxXSxTYVsyXV0sVGEsRWEpO3JldHVybltrYSxBYV19Y2FzZSJBdmdQb29sM0QiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGVzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgicGFkIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgia2VybmVsU2l6ZSIsaGEsYWEseGEpO3JldHVybltiYS5hdmdQb29sM2QoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLFt3YVsxXSx3YVsyXSx3YVszXV0sW1NhWzFdLFNhWzJdLFNhWzNdXSxUYSldfWNhc2UiTWF4UG9vbDNEIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgic3RyaWRlcyIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoInBhZCIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImtlcm5lbFNpemUiLGhhLGFhLHhhKTtyZXR1cm5bYmEubWF4UG9vbDNkKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxbd2FbMV0sd2FbMl0sd2FbM11dLFtTYVsxXSxTYVsyXSxTYVszXV0sVGEpXX1jYXNlIkRpbGF0aW9uMkQiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdHJpZGVzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgicGFkIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgiZGlsYXRpb25zIixoYSxhYSx4YSksRWE9U2FbMV0sa2E9U2FbMl0sQWE9d2FbMV0sRmE9d2FbMl07cmV0dXJuW2JhLmRpbGF0aW9uMmQoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImZpbHRlciIsaGEsYWEseGEpLFtFYSxrYV0sVGEsW0FhLEZhXSwiTkhXQyIpXX1kZWZhdWx0OnRocm93IFR5cGVFcnJvcihgTm9kZSB0eXBlICR7aGEub3B9IGlzIG5vdCBpbXBsZW1lbnRlZGApfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXhlY3V0ZU9wJGc9KGhhLGFhLHhhLGJhPXRmT3BzKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJGaWxsIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgic2hhcGUiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoInZhbHVlIixoYSxhYSx4YSk7cmV0dXJuW2JhLmZpbGwoU2Esd2EsVGEpXX1jYXNlIkxpblNwYWNlIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgic3RhcnQiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJzdG9wIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgibnVtIixoYSxhYSx4YSk7cmV0dXJuW2JhLmxpbnNwYWNlKFNhLFRhLHdhKV19Y2FzZSJNdWx0aW5vbWlhbCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoImxvZ2l0cyIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoIm51bVNhbXBsZXMiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJzZWVkIixoYSxhYSx4YSk7cmV0dXJuW2JhLm11bHRpbm9taWFsKFNhLFRhLHdhKV19Y2FzZSJPbmVIb3QiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJpbmRpY2VzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgiZGVwdGgiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJvblZhbHVlIixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgib2ZmVmFsdWUiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpO3JldHVybltiYS5vbmVIb3QoU2EsVGEsd2EsRWEsa2EpXX1jYXNlIk9uZXMiOnJldHVybltiYS5vbmVzKGdldFBhcmFtVmFsdWUoInNoYXBlIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiZHR5cGUiLGhhLGFhLHhhKSldO2Nhc2UiT25lc0xpa2UiOnJldHVybltiYS5vbmVzTGlrZShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIlJhbmRvbVN0YW5kYXJkTm9ybWFsIjpyZXR1cm5bYmEucmFuZG9tU3RhbmRhcmROb3JtYWwoZ2V0UGFyYW1WYWx1ZSgic2hhcGUiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNlZWQiLGhhLGFhLHhhKSldO2Nhc2UiUmFuZG9tVW5pZm9ybSI6cmV0dXJuW2JhLnJhbmRvbVVuaWZvcm0oZ2V0UGFyYW1WYWx1ZSgic2hhcGUiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJtaW52YWwiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJtYXh2YWwiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpKV07Y2FzZSJSYW5kb21Vbmlmb3JtSW50IjpyZXR1cm5bYmEucmFuZG9tVW5pZm9ybUludChnZXRQYXJhbVZhbHVlKCJzaGFwZSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoIm1pbnZhbCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoIm1heHZhbCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNlZWQiLGhhLGFhLHhhKSldO2Nhc2UiUmFuZ2UiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzdGFydCIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoInN0b3AiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJzdGVwIixoYSxhYSx4YSk7cmV0dXJuW2JhLnJhbmdlKFNhLFRhLHdhLGdldFBhcmFtVmFsdWUoImR0eXBlIixoYSxhYSx4YSkpXX1jYXNlIlRydW5jYXRlZE5vcm1hbCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoInNoYXBlIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgibWVhbiIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoInN0ZERldiIsaGEsYWEseGEpLEVhPWdldFBhcmFtVmFsdWUoInNlZWQiLGhhLGFhLHhhKTtyZXR1cm5bYmEudHJ1bmNhdGVkTm9ybWFsKFNhLFRhLHdhLGdldFBhcmFtVmFsdWUoImR0eXBlIixoYSxhYSx4YSksRWEpXX1jYXNlIlplcm9zIjpyZXR1cm5bYmEuemVyb3MoZ2V0UGFyYW1WYWx1ZSgic2hhcGUiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJkdHlwZSIsaGEsYWEseGEpKV07Y2FzZSJaZXJvc0xpa2UiOnJldHVybltiYS56ZXJvc0xpa2UoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5tc1BhcmFtcyhoYSxhYSx4YSl7Y29uc3QgYmE9Z2V0UGFyYW1WYWx1ZSgiYm94ZXMiLGhhLGFhLHhhKSxTYT1nZXRQYXJhbVZhbHVlKCJzY29yZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJtYXhPdXRwdXRTaXplIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgiaW91VGhyZXNob2xkIixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgic2NvcmVUaHJlc2hvbGQiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJzb2Z0Tm1zU2lnbWEiLGhhLGFhLHhhKTtyZXR1cm57Ym94ZXM6YmEsc2NvcmVzOlNhLG1heE91dHB1dFNpemU6VGEsaW91VGhyZXNob2xkOndhLHNjb3JlVGhyZXNob2xkOkVhLHNvZnRObXNTaWdtYTprYX19Y29uc3QgZXhlY3V0ZU9wJGY9YXN5bmMoaGEsYWEseGEsYmEsU2E9dGZPcHMpPT57c3dpdGNoKGhhLm9wKXtjYXNlIk5vbk1heFN1cHByZXNzaW9uVjUiOntjb25zdHtib3hlczpUYSxzY29yZXM6d2EsbWF4T3V0cHV0U2l6ZTpFYSxpb3VUaHJlc2hvbGQ6a2Esc2NvcmVUaHJlc2hvbGQ6QWEsc29mdE5tc1NpZ21hOkZhfT1ubXNQYXJhbXMoaGEsYWEseGEpLExhPWF3YWl0IFNhLmltYWdlLm5vbk1heFN1cHByZXNzaW9uV2l0aFNjb3JlQXN5bmMoVGEsd2EsRWEsa2EsQWEsRmEpO3JldHVybltMYS5zZWxlY3RlZEluZGljZXMsTGEuc2VsZWN0ZWRTY29yZXNdfWNhc2UiTm9uTWF4U3VwcHJlc3Npb25WNCI6e2NvbnN0e2JveGVzOlRhLHNjb3Jlczp3YSxtYXhPdXRwdXRTaXplOkVhLGlvdVRocmVzaG9sZDprYSxzY29yZVRocmVzaG9sZDpBYX09bm1zUGFyYW1zKGhhLGFhLHhhKSxGYT1nZXRQYXJhbVZhbHVlKCJwYWRUb01heE91dHB1dFNpemUiLGhhLGFhLHhhKSxMYT1hd2FpdCBTYS5pbWFnZS5ub25NYXhTdXBwcmVzc2lvblBhZGRlZEFzeW5jKFRhLHdhLEVhLGthLEFhLEZhKTtyZXR1cm5bTGEuc2VsZWN0ZWRJbmRpY2VzLExhLnZhbGlkT3V0cHV0c119Y2FzZSJOb25NYXhTdXBwcmVzc2lvblYzIjpjYXNlIk5vbk1heFN1cHByZXNzaW9uVjIiOntjb25zdHtib3hlczpUYSxzY29yZXM6d2EsbWF4T3V0cHV0U2l6ZTpFYSxpb3VUaHJlc2hvbGQ6a2Esc2NvcmVUaHJlc2hvbGQ6QWF9PW5tc1BhcmFtcyhoYSxhYSx4YSk7cmV0dXJuW2F3YWl0IFNhLmltYWdlLm5vbk1heFN1cHByZXNzaW9uQXN5bmMoVGEsd2EsRWEsa2EsQWEpXX1jYXNlIldoZXJlIjp7Y29uc3QgVGE9U2EuY2FzdChnZXRQYXJhbVZhbHVlKCJjb25kaXRpb24iLGhhLGFhLHhhKSwiYm9vbCIpLHdhPVthd2FpdCBTYS53aGVyZUFzeW5jKFRhKV07cmV0dXJuIFRhLmRpc3Bvc2UoKSx3YX1jYXNlIkxpc3REaWZmIjpyZXR1cm4gU2Euc2V0ZGlmZjFkQXN5bmMoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInkiLGhhLGFhLHhhKSk7ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCRlPShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiTG93ZXJCb3VuZCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoInNvcnRlZFNlcXVlbmNlIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgidmFsdWVzIixoYSxhYSx4YSk7cmV0dXJuW2JhLmxvd2VyQm91bmQoU2EsVGEpXX1jYXNlIlRvcEtWMiI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJrIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgic29ydGVkIixoYSxhYSx4YSksRWE9YmEudG9wayhTYSxUYSx3YSk7cmV0dXJuW0VhLnZhbHVlcyxFYS5pbmRpY2VzXX1jYXNlIlVwcGVyQm91bmQiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJzb3J0ZWRTZXF1ZW5jZSIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoInZhbHVlcyIsaGEsYWEseGEpO3JldHVybltiYS51cHBlckJvdW5kKFNhLFRhKV19Y2FzZSJVbmlxdWUiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksVGE9YmEudW5pcXVlKFNhKTtyZXR1cm5bVGEudmFsdWVzLFRhLmluZGljZXNdfWNhc2UiVW5pcXVlVjIiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpLHdhPWJhLnVuaXF1ZShTYSxUYSk7cmV0dXJuW3dhLnZhbHVlcyx3YS5pbmRpY2VzXX1kZWZhdWx0OnRocm93IFR5cGVFcnJvcihgTm9kZSB0eXBlICR7aGEub3B9IGlzIG5vdCBpbXBsZW1lbnRlZGApfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXhlY3V0ZU9wJGQ9KGhhLGFhLHhhLGJhPXRmT3BzKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJDb25zdCI6cmV0dXJuIGFhW2hhLm5hbWVdO2Nhc2UiUGxhY2Vob2xkZXJXaXRoRGVmYXVsdCI6Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiZGVmYXVsdCIsaGEsYWEseGEpO3JldHVybltnZXRUZW5zb3IoaGEubmFtZSxhYSx4YSl8fFNhXTtjYXNlIlBsYWNlaG9sZGVyIjpyZXR1cm5bZ2V0VGVuc29yKGhhLm5hbWUsYWEseGEpXTtjYXNlIklkZW50aXR5IjpjYXNlIlN0b3BHcmFkaWVudCI6Y2FzZSJGYWtlUXVhbnRXaXRoTWluTWF4VmFycyI6e2NvbnN0IEZhPWdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKTtyZXR1cm5bY2xvbmVUZW5zb3IoRmEpXX1jYXNlIklkZW50aXR5TiI6cmV0dXJuIGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKS5tYXAoRmE9PmNsb25lVGVuc29yKEZhKSk7Y2FzZSJTbmFwc2hvdCI6Y29uc3QgVGE9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpO3JldHVybltjbG9uZVRlbnNvcihUYSldO2Nhc2UiU2hhcGUiOnJldHVybltiYS50ZW5zb3IxZChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkuc2hhcGUsImludDMyIildO2Nhc2UiU2hhcGVOIjpyZXR1cm4gZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLm1hcChGYT0+YmEudGVuc29yMWQoRmEuc2hhcGUpKTtjYXNlIlNpemUiOnJldHVybltiYS5zY2FsYXIoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLnNpemUsImludDMyIildO2Nhc2UiUmFuayI6cmV0dXJuW2JhLnNjYWxhcihnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkucmFuaywiaW50MzIiKV07Y2FzZSJOb09wIjpyZXR1cm5bYmEuc2NhbGFyKDEpXTtjYXNlIlByaW50Ijpjb25zdCB3YT1nZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgiZGF0YSIsaGEsYWEseGEpLGthPWdldFBhcmFtVmFsdWUoIm1lc3NhZ2UiLGhhLGFhLHhhKSxBYT1nZXRQYXJhbVZhbHVlKCJzdW1tYXJpemUiLGhhLGFhLHhhKTtjb25zb2xlLndhcm4oIlRoZSBncmFwaCBoYXMgYSB0Zi5wcmludCgpIG9wZXJhdGlvbix1c3VhbGx5IHVzZWQgZm9yIGRlYnVnZ2luZywgd2hpY2ggc2xvd3MgZG93biBwZXJmb3JtYW5jZS4iKSxjb25zb2xlLmxvZyhrYSk7Zm9yKGxldCBGYT0wO0ZhPEVhLmxlbmd0aDtGYSsrKWNvbnNvbGUubG9nKEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKEVhW0ZhXS5kYXRhU3luYygpKS5zbGljZSgwLEFhKSk7cmV0dXJuW3dhXTtkZWZhdWx0OnRocm93IFR5cGVFcnJvcihgTm9kZSB0eXBlICR7aGEub3B9IGlzIG5vdCBpbXBsZW1lbnRlZGApfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgSGFzaFRhYmxle2dldCBpZCgpe3JldHVybiB0aGlzLmhhbmRsZS5pZH1jb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy5rZXlEVHlwZT1hYSx0aGlzLnZhbHVlRFR5cGU9eGEsdGhpcy5oYW5kbGU9c2NhbGFyJDEoMCksdGhpcy50ZW5zb3JNYXA9bmV3IE1hcCxrZWVwJDEodGhpcy5oYW5kbGUpfWNsZWFyQW5kQ2xvc2UoKXt0aGlzLnRlbnNvck1hcC5mb3JFYWNoKGFhPT5hYS5kaXNwb3NlKCkpLHRoaXMudGVuc29yTWFwLmNsZWFyKCksdGhpcy5oYW5kbGUuZGlzcG9zZSgpfXNpemUoKXtyZXR1cm4gdGhpcy50ZW5zb3JNYXAuc2l6ZX10ZW5zb3JTaXplKCl7cmV0dXJuIHNjYWxhciQxKHRoaXMuc2l6ZSgpLCJpbnQzMiIpfWFzeW5jIGltcG9ydChhYSx4YSl7dGhpcy5jaGVja0tleUFuZFZhbHVlVGVuc29yKGFhLHhhKTtjb25zdCBiYT1hd2FpdCBhYS5kYXRhKCk7cmV0dXJuIHRoaXMudGVuc29yTWFwLmZvckVhY2goU2E9PlNhLmRpc3Bvc2UoKSksdGhpcy50ZW5zb3JNYXAuY2xlYXIoKSx0aWR5JDEoKCk9Pntjb25zdCBTYT11bnN0YWNrKHhhKSxUYT1iYS5sZW5ndGgsd2E9U2EubGVuZ3RoO2Fzc2VydCQyKFRhPT09d2EsKCk9PmBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGRvZXNuJ3QgbWF0Y2gsIGtleXMgaGFzICR7VGF9IGVsZW1lbnRzLCB0aGUgdmFsdWVzIGhhcyAke3dhfSBlbGVtZW50cy5gKTtmb3IobGV0IEVhPTA7RWE8VGE7RWErKyl7Y29uc3Qga2E9YmFbRWFdLEFhPVNhW0VhXTtrZWVwJDEoQWEpLHRoaXMudGVuc29yTWFwLnNldChrYSxBYSl9cmV0dXJuIHRoaXMuaGFuZGxlfSl9YXN5bmMgZmluZChhYSx4YSl7dGhpcy5jaGVja0tleUFuZFZhbHVlVGVuc29yKGFhLHhhKTtjb25zdCBiYT1hd2FpdCBhYS5kYXRhKCk7cmV0dXJuIHRpZHkkMSgoKT0+e2NvbnN0IFNhPVtdO2ZvcihsZXQgVGE9MDtUYTxiYS5sZW5ndGg7VGErKyl7Y29uc3Qgd2E9YmFbVGFdLEVhPXRoaXMuZmluZFdpdGhEZWZhdWx0KHdhLHhhKTtTYS5wdXNoKEVhKX1yZXR1cm4gc3RhY2soU2EpfSl9ZmluZFdpdGhEZWZhdWx0KGFhLHhhKXtjb25zdCBiYT10aGlzLnRlbnNvck1hcC5nZXQoYWEpO3JldHVybiBiYT8/eGF9Y2hlY2tLZXlBbmRWYWx1ZVRlbnNvcihhYSx4YSl7aWYoYWEuZHR5cGUhPT10aGlzLmtleURUeXBlKXRocm93IG5ldyBFcnJvcihgRXhwZWN0IGtleSBkdHlwZSAke3RoaXMua2V5RFR5cGV9LCBidXQgZ290ICR7YWEuZHR5cGV9YCk7aWYoeGEuZHR5cGUhPT10aGlzLnZhbHVlRFR5cGUpdGhyb3cgbmV3IEVycm9yKGBFeHBlY3QgdmFsdWUgZHR5cGUgJHt0aGlzLnZhbHVlRFR5cGV9LCBidXQgZ290ICR7eGEuZHR5cGV9YCl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCRjPWFzeW5jKGhhLGFhLHhhLGJhKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJIYXNoVGFibGUiOmNhc2UiSGFzaFRhYmxlVjIiOntjb25zdCBTYT1iYS5nZXRIYXNoVGFibGVIYW5kbGVCeU5hbWUoaGEubmFtZSk7aWYoU2EhPW51bGwpcmV0dXJuW1NhXTt7Y29uc3QgVGE9Z2V0UGFyYW1WYWx1ZSgia2V5RFR5cGUiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJ2YWx1ZURUeXBlIixoYSxhYSx4YSksRWE9bmV3IEhhc2hUYWJsZShUYSx3YSk7cmV0dXJuIGJhLmFkZEhhc2hUYWJsZShoYS5uYW1lLEVhKSxbRWEuaGFuZGxlXX19Y2FzZSJJbml0aWFsaXplVGFibGUiOmNhc2UiSW5pdGlhbGl6ZVRhYmxlVjIiOmNhc2UiTG9va3VwVGFibGVJbXBvcnQiOmNhc2UiTG9va3VwVGFibGVJbXBvcnRWMiI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoInRhYmxlSGFuZGxlIixoYSxhYSx4YSxiYSksVGE9Z2V0UGFyYW1WYWx1ZSgia2V5cyIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoInZhbHVlcyIsaGEsYWEseGEpO3JldHVyblthd2FpdCBiYS5nZXRIYXNoVGFibGVCeUlkKFNhLmlkKS5pbXBvcnQoVGEsd2EpXX1jYXNlIkxvb2t1cFRhYmxlRmluZCI6Y2FzZSJMb29rdXBUYWJsZUZpbmRWMiI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoInRhYmxlSGFuZGxlIixoYSxhYSx4YSxiYSksVGE9Z2V0UGFyYW1WYWx1ZSgia2V5cyIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImRlZmF1bHRWYWx1ZSIsaGEsYWEseGEpO3JldHVyblthd2FpdCBiYS5nZXRIYXNoVGFibGVCeUlkKFNhLmlkKS5maW5kKFRhLHdhKV19Y2FzZSJMb29rdXBUYWJsZVNpemUiOmNhc2UiTG9va3VwVGFibGVTaXplVjIiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJ0YWJsZUhhbmRsZSIsaGEsYWEseGEsYmEpO3JldHVybltiYS5nZXRIYXNoVGFibGVCeUlkKFNhLmlkKS50ZW5zb3JTaXplKCldfWRlZmF1bHQ6dGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtoYS5vcH0gaXMgbm90IGltcGxlbWVudGVkYCl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleGVjdXRlT3AkYj0oaGEsYWEseGEsYmE9dGZPcHMpPT57c3dpdGNoKGhhLm9wKXtjYXNlIlJlc2l6ZUJpbGluZWFyIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiaW1hZ2VzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgic2l6ZSIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImFsaWduQ29ybmVycyIsaGEsYWEseGEpLEVhPWdldFBhcmFtVmFsdWUoImhhbGZQaXhlbENlbnRlcnMiLGhhLGFhLHhhKTtyZXR1cm5bYmEuaW1hZ2UucmVzaXplQmlsaW5lYXIoU2EsW1RhWzBdLFRhWzFdXSx3YSxFYSldfWNhc2UiUmVzaXplTmVhcmVzdE5laWdoYm9yIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiaW1hZ2VzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgic2l6ZSIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoImFsaWduQ29ybmVycyIsaGEsYWEseGEpLEVhPWdldFBhcmFtVmFsdWUoImhhbGZQaXhlbENlbnRlcnMiLGhhLGFhLHhhKTtyZXR1cm5bYmEuaW1hZ2UucmVzaXplTmVhcmVzdE5laWdoYm9yKFNhLFtUYVswXSxUYVsxXV0sd2EsRWEpXX1jYXNlIkNyb3BBbmRSZXNpemUiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJpbWFnZSIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoImJveGVzIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgiYm94SW5kIixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgiY3JvcFNpemUiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJtZXRob2QiLGhhLGFhLHhhKSxBYT1nZXRQYXJhbVZhbHVlKCJleHRyYXBvbGF0aW9uVmFsdWUiLGhhLGFhLHhhKTtyZXR1cm5bYmEuaW1hZ2UuY3JvcEFuZFJlc2l6ZShTYSxUYSx3YSxFYSxrYSxBYSldfWNhc2UiSW1hZ2VQcm9qZWN0aXZlVHJhbnNmb3JtVjMiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJpbWFnZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJ0cmFuc2Zvcm1zIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgib3V0cHV0U2hhcGUiLGhhLGFhLHhhKSxFYT1nZXRQYXJhbVZhbHVlKCJmaWxsVmFsdWUiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJpbnRlcnBvbGF0aW9uIixoYSxhYSx4YSksQWE9Z2V0UGFyYW1WYWx1ZSgiZmlsbE1vZGUiLGhhLGFhLHhhKTtyZXR1cm5bYmEuaW1hZ2UudHJhbnNmb3JtKFNhLFRhLGthLnRvTG93ZXJDYXNlKCksQWEudG9Mb3dlckNhc2UoKSxFYSx3YSldfWRlZmF1bHQ6dGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtoYS5vcH0gaXMgbm90IGltcGxlbWVudGVkYCl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleGVjdXRlT3AkYT0oaGEsYWEseGEsYmE9dGZPcHMpPT57c3dpdGNoKGhhLm9wKXtjYXNlIkVxdWFsIjpyZXR1cm5bYmEuZXF1YWwoZ2V0UGFyYW1WYWx1ZSgiYSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImIiLGhhLGFhLHhhKSldO2Nhc2UiTm90RXF1YWwiOnJldHVybltiYS5ub3RFcXVhbChnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJHcmVhdGVyIjpyZXR1cm5bYmEuZ3JlYXRlcihnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpKV07Y2FzZSJHcmVhdGVyRXF1YWwiOnJldHVybltiYS5ncmVhdGVyRXF1YWwoZ2V0UGFyYW1WYWx1ZSgiYSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImIiLGhhLGFhLHhhKSldO2Nhc2UiTGVzcyI6cmV0dXJuW2JhLmxlc3MoZ2V0UGFyYW1WYWx1ZSgiYSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImIiLGhhLGFhLHhhKSldO2Nhc2UiTGVzc0VxdWFsIjpyZXR1cm5bYmEubGVzc0VxdWFsKGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSkpXTtjYXNlIkxvZ2ljYWxBbmQiOnJldHVybltiYS5sb2dpY2FsQW5kKGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSkpXTtjYXNlIkxvZ2ljYWxOb3QiOnJldHVybltiYS5sb2dpY2FsTm90KGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSldO2Nhc2UiTG9naWNhbE9yIjpyZXR1cm5bYmEubG9naWNhbE9yKGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSkpXTtjYXNlIlNlbGVjdCI6Y2FzZSJTZWxlY3RWMiI6cmV0dXJuW2JhLndoZXJlKGdldFBhcmFtVmFsdWUoImNvbmRpdGlvbiIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSkpXTtjYXNlIkJpdHdpc2VBbmQiOnJldHVybltiYS5iaXR3aXNlQW5kKGdldFBhcmFtVmFsdWUoImEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSkpXTtkZWZhdWx0OnRocm93IFR5cGVFcnJvcihgTm9kZSB0eXBlICR7aGEub3B9IGlzIG5vdCBpbXBsZW1lbnRlZGApfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXhlY3V0ZU9wJDk9KGhhLGFhLHhhLGJhPXRmT3BzKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJCYXRjaE1hdE11bCI6Y2FzZSJCYXRjaE1hdE11bFYyIjpjYXNlIk1hdE11bCI6cmV0dXJuW2JhLm1hdE11bChnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYiIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInRyYW5zcG9zZUEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJ0cmFuc3Bvc2VCIixoYSxhYSx4YSkpXTtjYXNlIkVpbnN1bSI6cmV0dXJuW2JhLmVpbnN1bShnZXRQYXJhbVZhbHVlKCJlcXVhdGlvbiIsaGEsYWEseGEpLC4uLmdldFBhcmFtVmFsdWUoInRlbnNvcnMiLGhhLGFhLHhhKSldO2Nhc2UiVHJhbnNwb3NlIjpyZXR1cm5bYmEudHJhbnNwb3NlKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJwZXJtIixoYSxhYSx4YSkpXTtjYXNlIl9GdXNlZE1hdE11bCI6Y29uc3RbU2EsVGFdPWdldFBhcmFtVmFsdWUoImZ1c2VkT3BzIixoYSxhYSx4YSksd2E9U2E9PT0iYmlhc2FkZCIsRWE9VGE9PT0icHJlbHUiLGthPWdldFBhcmFtVmFsdWUoIm51bUFyZ3MiLGhhLGFhLHhhKSxBYT1nZXRQYXJhbVZhbHVlKCJsZWFreXJlbHVBbHBoYSIsaGEsYWEseGEpO2lmKHdhKXtpZihFYSYma2EhPT0yKXRocm93IG5ldyBFcnJvcigiRnVzZWQgTWF0TXVsIHdpdGggQmlhc0FkZCBhbmQgUHJlbHUgbXVzdCBoYXZlIHR3byBleHRyYSBhcmd1bWVudHM6IGJpYXMgYW5kIGFscGhhLiIpO2lmKCFFYSYma2EhPT0xKXRocm93IG5ldyBFcnJvcigiRnVzZWQgTWF0TXVsIHdpdGggQmlhc0FkZCBtdXN0IGhhdmUgb25lIGV4dHJhIGFyZ3VtZW50OiBiaWFzLiIpfWNvbnN0W0ZhLExhXT1nZXRQYXJhbVZhbHVlKCJhcmdzIixoYSxhYSx4YSk7cmV0dXJuW2JhLmZ1c2VkLm1hdE11bCh7YTpnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksYjpnZXRQYXJhbVZhbHVlKCJiIixoYSxhYSx4YSksdHJhbnNwb3NlQTpnZXRQYXJhbVZhbHVlKCJ0cmFuc3Bvc2VBIixoYSxhYSx4YSksdHJhbnNwb3NlQjpnZXRQYXJhbVZhbHVlKCJ0cmFuc3Bvc2VCIixoYSxhYSx4YSksYmlhczpGYSxhY3RpdmF0aW9uOlRhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6TGEsbGVha3lyZWx1QWxwaGE6QWF9KV07Y2FzZSJNYXRyaXhCYW5kUGFydCI6cmV0dXJuW2JhLmxpbmFsZy5iYW5kUGFydChnZXRQYXJhbVZhbHVlKCJhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgibnVtTG93ZXIiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJudW1VcHBlciIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCQ4PShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiRXVjbGlkZWFuTm9ybSI6cmV0dXJuW2JhLmV1Y2xpZGVhbk5vcm0oZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImF4aXMiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJrZWVwRGltcyIsaGEsYWEseGEpKV07Y2FzZSJGdXNlZEJhdGNoTm9ybSI6Y2FzZSJGdXNlZEJhdGNoTm9ybVYyIjpyZXR1cm5bYmEuYmF0Y2hOb3JtKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJtZWFuIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgidmFyaWFuY2UiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJvZmZzZXQiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJzY2FsZSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImVwc2lsb24iLGhhLGFhLHhhKSldO2Nhc2UiRnVzZWRCYXRjaE5vcm1WMyI6cmV0dXJuW2JhLmJhdGNoTm9ybShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgibWVhbiIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInZhcmlhbmNlIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgib2Zmc2V0IixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgic2NhbGUiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJlcHNpbG9uIixoYSxhYSx4YSkpXTtjYXNlIkxSTiI6cmV0dXJuW2JhLmxvY2FsUmVzcG9uc2VOb3JtYWxpemF0aW9uKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJyYWRpdXMiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiaWFzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiYWxwaGEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJiZXRhIixoYSxhYSx4YSkpXTtjYXNlIlNvZnRtYXgiOnJldHVybltiYS5zb2Z0bWF4KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiTG9nU29mdG1heCI6cmV0dXJuW2JhLmxvZ1NvZnRtYXgoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCQ3PShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiUmFnZ2VkR2F0aGVyIjp7Y29uc3R7b3V0cHV0TmVzdGVkU3BsaXRzOlNhLG91dHB1dERlbnNlVmFsdWVzOlRhfT1iYS5yYWdnZWRHYXRoZXIoZ2V0UGFyYW1WYWx1ZSgicGFyYW1zTmVzdGVkU3BsaXRzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgicGFyYW1zRGVuc2VWYWx1ZXMiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJpbmRpY2VzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgib3V0cHV0UmFnZ2VkUmFuayIsaGEsYWEseGEpKTtyZXR1cm4gU2EuY29uY2F0KFRhKX1jYXNlIlJhZ2dlZFJhbmdlIjp7Y29uc3R7cnROZXN0ZWRTcGxpdHM6U2EscnREZW5zZVZhbHVlczpUYX09YmEucmFnZ2VkUmFuZ2UoZ2V0UGFyYW1WYWx1ZSgic3RhcnRzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgibGltaXRzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgic3BsaXRzIixoYSxhYSx4YSkpO3JldHVybltTYSxUYV19Y2FzZSJSYWdnZWRUZW5zb3JUb1RlbnNvciI6cmV0dXJuW2JhLnJhZ2dlZFRlbnNvclRvVGVuc29yKGdldFBhcmFtVmFsdWUoInNoYXBlIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgidmFsdWVzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiZGVmYXVsdFZhbHVlIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgicm93UGFydGl0aW9uVGVuc29ycyIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInJvd1BhcnRpdGlvblR5cGVzIixoYSxhYSx4YSkpXTtkZWZhdWx0OnRocm93IFR5cGVFcnJvcihgTm9kZSB0eXBlICR7aGEub3B9IGlzIG5vdCBpbXBsZW1lbnRlZGApfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXhlY3V0ZU9wJDY9KGhhLGFhLHhhLGJhPXRmT3BzKT0+e3N3aXRjaChoYS5vcCl7Y2FzZSJNYXgiOntjb25zdCBFYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSksa2E9Z2V0UGFyYW1WYWx1ZSgia2VlcERpbXMiLGhhLGFhLHhhKTtyZXR1cm5bYmEubWF4KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxFYSxrYSldfWNhc2UiTWVhbiI6e2NvbnN0IEVhPWdldFBhcmFtVmFsdWUoImF4aXMiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJrZWVwRGltcyIsaGEsYWEseGEpO3JldHVybltiYS5tZWFuKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxFYSxrYSldfWNhc2UiTWluIjp7Y29uc3QgRWE9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpLGthPWdldFBhcmFtVmFsdWUoImtlZXBEaW1zIixoYSxhYSx4YSk7cmV0dXJuW2JhLm1pbihnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksRWEsa2EpXX1jYXNlIlN1bSI6e2NvbnN0IEVhPWdldFBhcmFtVmFsdWUoImF4aXMiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJrZWVwRGltcyIsaGEsYWEseGEpO3JldHVybltiYS5zdW0oZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLEVhLGthKV19Y2FzZSJBbGwiOntjb25zdCBFYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSksa2E9Z2V0UGFyYW1WYWx1ZSgia2VlcERpbXMiLGhhLGFhLHhhKTtyZXR1cm5bYmEuYWxsKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxFYSxrYSldfWNhc2UiQW55Ijp7Y29uc3QgRWE9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpLGthPWdldFBhcmFtVmFsdWUoImtlZXBEaW1zIixoYSxhYSx4YSk7cmV0dXJuW2JhLmFueShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksRWEsa2EpXX1jYXNlIkFyZ01heCI6e2NvbnN0IEVhPWdldFBhcmFtVmFsdWUoImF4aXMiLGhhLGFhLHhhKTtyZXR1cm5bYmEuYXJnTWF4KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxFYSldfWNhc2UiQXJnTWluIjp7Y29uc3QgRWE9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpO3JldHVybltiYS5hcmdNaW4oZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLEVhKV19Y2FzZSJQcm9kIjp7Y29uc3QgRWE9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpLGthPWdldFBhcmFtVmFsdWUoImtlZXBEaW1zIixoYSxhYSx4YSk7cmV0dXJuW2JhLnByb2QoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLEVhLGthKV19Y2FzZSJDdW1wcm9kIjp7Y29uc3QgRWE9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpLGthPWdldFBhcmFtVmFsdWUoImV4Y2x1c2l2ZSIsaGEsYWEseGEpLEFhPWdldFBhcmFtVmFsdWUoInJldmVyc2UiLGhhLGFhLHhhKTtyZXR1cm5bYmEuY3VtcHJvZChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksRWEsa2EsQWEpXX1jYXNlIkN1bXN1bSI6e2NvbnN0IEVhPWdldFBhcmFtVmFsdWUoImF4aXMiLGhhLGFhLHhhKSxrYT1nZXRQYXJhbVZhbHVlKCJleGNsdXNpdmUiLGhhLGFhLHhhKSxBYT1nZXRQYXJhbVZhbHVlKCJyZXZlcnNlIixoYSxhYSx4YSk7cmV0dXJuW2JhLmN1bXN1bShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksRWEsa2EsQWEpXX1jYXNlIkJpbmNvdW50Ijpjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgid2VpZ2h0cyIsaGEsYWEseGEpLHdhPWdldFBhcmFtVmFsdWUoInNpemUiLGhhLGFhLHhhKTtyZXR1cm5bYmEuYmluY291bnQoU2EsVGEsd2EpXTtjYXNlIkRlbnNlQmluY291bnQiOntjb25zdCBFYT1nZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksa2E9Z2V0UGFyYW1WYWx1ZSgid2VpZ2h0cyIsaGEsYWEseGEpLEFhPWdldFBhcmFtVmFsdWUoInNpemUiLGhhLGFhLHhhKSxGYT1nZXRQYXJhbVZhbHVlKCJiaW5hcnlPdXRwdXQiLGhhLGFhLHhhKTtyZXR1cm5bYmEuZGVuc2VCaW5jb3VudChFYSxrYSxBYSxGYSldfWRlZmF1bHQ6dGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtoYS5vcH0gaXMgbm90IGltcGxlbWVudGVkYCl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleGVjdXRlT3AkNT0oaGEsYWEseGEsYmE9dGZPcHMpPT57c3dpdGNoKGhhLm9wKXtjYXNlIkNvbmNhdFYyIjpjYXNlIkNvbmNhdCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoIm4iLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSk7bGV0IHdhPWdldFBhcmFtVmFsdWUoInRlbnNvcnMiLGhhLGFhLHhhKTtyZXR1cm4gd2E9d2Euc2xpY2UoMCxTYSksW2JhLmNvbmNhdCh3YSxUYSldfWNhc2UiR2F0aGVyIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKTtyZXR1cm5bYmEuZ2F0aGVyKFNhLGJhLmNhc3QoVGEsImludDMyIiksMCldfWNhc2UiR2F0aGVyVjIiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgiYmF0Y2hEaW1zIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLEVhPWdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKTtyZXR1cm5bYmEuZ2F0aGVyKHdhLGJhLmNhc3QoRWEsImludDMyIiksU2EsVGEpXX1jYXNlIlJldmVyc2UiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJkaW1zIixoYSxhYSx4YSksVGE9W107Zm9yKGxldCBFYT0wO0VhPFNhLmxlbmd0aDtFYSsrKVNhW0VhXSYmVGEucHVzaChFYSk7Y29uc3Qgd2E9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpO3JldHVybltiYS5yZXZlcnNlKHdhLFRhKV19Y2FzZSJSZXZlcnNlVjIiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpO3JldHVybltiYS5yZXZlcnNlKFRhLFNhKV19Y2FzZSJTbGljZSI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoImJlZ2luIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgic2l6ZSIsaGEsYWEseGEpO3JldHVybltiYS5zbGljZShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksU2EsVGEpXX1jYXNlIlN0cmlkZWRTbGljZSI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoImJlZ2luIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgiZW5kIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgic3RyaWRlcyIsaGEsYWEseGEpLEVhPWdldFBhcmFtVmFsdWUoImJlZ2luTWFzayIsaGEsYWEseGEpLGthPWdldFBhcmFtVmFsdWUoImVuZE1hc2siLGhhLGFhLHhhKSxBYT1nZXRQYXJhbVZhbHVlKCJlbGxpcHNpc01hc2siLGhhLGFhLHhhKSxGYT1nZXRQYXJhbVZhbHVlKCJuZXdBeGlzTWFzayIsaGEsYWEseGEpLExhPWdldFBhcmFtVmFsdWUoInNocmlua0F4aXNNYXNrIixoYSxhYSx4YSksZWw9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpO3JldHVybltiYS5zdHJpZGVkU2xpY2UoZWwsU2EsVGEsd2EsRWEsa2EsQWEsRmEsTGEpXX1jYXNlIlBhY2siOnJldHVybiB0aWR5JDEoKCk9Pntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgidGVuc29ycyIsaGEsYWEseGEpLHdhPVRhWzBdLnNoYXBlLEVhPWJhLnNxdWVlemUoVGFbMF0pLnNoYXBlLGthPVRhLm1hcChBYT0+e2NvbnN0IEZhPWFycmF5c0VxdWFsJDEoQWEuc2hhcGUsd2EpO2lmKCFGYSYmIWFycmF5c0VxdWFsJDEoYmEuc3F1ZWV6ZShBYSkuc2hhcGUsRWEpKXRocm93IG5ldyBFcnJvcigidGhlIGlucHV0IHRlbnNvcnMgc2hhcGUgZG9lcyBub3QgbWF0Y2giKTtyZXR1cm4gRmE/QWE6YmEucmVzaGFwZShBYSx3YSl9KTtyZXR1cm5bYmEuc3RhY2soa2EsU2EpXX0pO2Nhc2UiVW5wYWNrIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoInRlbnNvciIsaGEsYWEseGEpO3JldHVybiBiYS51bnN0YWNrKFRhLFNhKX1jYXNlIlRpbGUiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJyZXBzIixoYSxhYSx4YSk7cmV0dXJuW2JhLnRpbGUoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLFNhKV19Y2FzZSJTcGxpdCI6Y2FzZSJTcGxpdFYiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgibnVtT3JTaXplU3BsaXRzIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpO3JldHVybiBiYS5zcGxpdCh3YSxUYSxTYSl9Y2FzZSJTY2F0dGVyTmQiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJpbmRpY2VzIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgidmFsdWVzIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgic2hhcGUiLGhhLGFhLHhhKTtyZXR1cm5bYmEuc2NhdHRlck5EKFNhLFRhLHdhKV19Y2FzZSJHYXRoZXJOZCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJpbmRpY2VzIixoYSxhYSx4YSk7cmV0dXJuW2JhLmdhdGhlck5EKFNhLFRhKV19Y2FzZSJTcGFyc2VUb0RlbnNlIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgic3BhcnNlSW5kaWNlcyIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoIm91dHB1dFNoYXBlIixoYSxhYSx4YSksd2E9Z2V0UGFyYW1WYWx1ZSgic3BhcnNlVmFsdWVzIixoYSxhYSx4YSksRWE9Z2V0UGFyYW1WYWx1ZSgiZGVmYXVsdFZhbHVlIixoYSxhYSx4YSk7cmV0dXJuW2JhLnNwYXJzZVRvRGVuc2UoU2Esd2EsVGEsd2EuZHR5cGU9PT1FYS5kdHlwZT9FYTpiYS5jYXN0KEVhLHdhLmR0eXBlKSldfWNhc2UiVGVuc29yU2NhdHRlclVwZGF0ZSI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJ2YWx1ZXMiLGhhLGFhLHhhKSx3YT1nZXRQYXJhbVZhbHVlKCJ0ZW5zb3IiLGhhLGFhLHhhKTtyZXR1cm5bYmEudGVuc29yU2NhdHRlclVwZGF0ZSh3YSxTYSxUYSldfWRlZmF1bHQ6dGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtoYS5vcH0gaXMgbm90IGltcGxlbWVudGVkYCl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleGVjdXRlT3AkND0oaGEsYWEseGEsYmE9dGZPcHMpPT57c3dpdGNoKGhhLm9wKXtjYXNlIlNwYXJzZUZpbGxFbXB0eVJvd3MiOntjb25zdHtvdXRwdXRJbmRpY2VzOlNhLG91dHB1dFZhbHVlczpUYSxlbXB0eVJvd0luZGljYXRvcjp3YSxyZXZlcnNlSW5kZXhNYXA6RWF9PWJhLnNwYXJzZS5zcGFyc2VGaWxsRW1wdHlSb3dzKGdldFBhcmFtVmFsdWUoImluZGljZXMiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJ2YWx1ZXMiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJkZW5zZVNoYXBlIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiZGVmYXVsdFZhbHVlIixoYSxhYSx4YSkpO3JldHVybltTYSxUYSx3YSxFYV19Y2FzZSJTcGFyc2VSZXNoYXBlIjp7Y29uc3R7b3V0cHV0SW5kaWNlczpTYSxvdXRwdXRTaGFwZTpUYX09YmEuc3BhcnNlLnNwYXJzZVJlc2hhcGUoZ2V0UGFyYW1WYWx1ZSgiaW5wdXRJbmRpY2VzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiaW5wdXRTaGFwZSIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoIm5ld1NoYXBlIixoYSxhYSx4YSkpO3JldHVybltTYSxUYV19Y2FzZSJTcGFyc2VTZWdtZW50TWVhbiI6cmV0dXJuW2JhLnNwYXJzZS5zcGFyc2VTZWdtZW50TWVhbihnZXRQYXJhbVZhbHVlKCJkYXRhIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiaW5kaWNlcyIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNlZ21lbnRJZHMiLGhhLGFhLHhhKSldO2Nhc2UiU3BhcnNlU2VnbWVudFN1bSI6cmV0dXJuW2JhLnNwYXJzZS5zcGFyc2VTZWdtZW50U3VtKGdldFBhcmFtVmFsdWUoImRhdGEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJpbmRpY2VzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgic2VnbWVudElkcyIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCQzPShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiRkZUIjpyZXR1cm5bYmEuZmZ0KGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSldO2Nhc2UiSUZGVCI6cmV0dXJuW2JhLmlmZnQoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07Y2FzZSJSRkZUIjpyZXR1cm5bYmEucmZmdChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSkpXTtjYXNlIklSRkZUIjpyZXR1cm5bYmEuaXJmZnQoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCQyPShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiU3RhdGljUmVnZXhSZXBsYWNlIjpyZXR1cm5bYmEuc3RyaW5nLnN0YXRpY1JlZ2V4UmVwbGFjZShnZXRQYXJhbVZhbHVlKCJpbnB1dCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInBhdHRlcm4iLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJyZXdyaXRlIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgicmVwbGFjZUdsb2JhbCIsaGEsYWEseGEpKV07Y2FzZSJTdHJpbmdOR3JhbXMiOntjb25zdHtuR3JhbXM6U2EsbkdyYW1zU3BsaXRzOlRhfT1iYS5zdHJpbmcuc3RyaW5nTkdyYW1zKGdldFBhcmFtVmFsdWUoImRhdGEiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJkYXRhU3BsaXRzIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgic2VwYXJhdG9yIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgibkdyYW1XaWR0aHMiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJsZWZ0UGFkIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgicmlnaHRQYWQiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJwYWRXaWR0aCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInByZXNlcnZlU2hvcnRTZXF1ZW5jZXMiLGhhLGFhLHhhKSk7cmV0dXJuW1NhLFRhXX1jYXNlIlN0cmluZ1NwbGl0Ijp7Y29uc3R7aW5kaWNlczpTYSx2YWx1ZXM6VGEsc2hhcGU6d2F9PWJhLnN0cmluZy5zdHJpbmdTcGxpdChnZXRQYXJhbVZhbHVlKCJpbnB1dCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImRlbGltaXRlciIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNraXBFbXB0eSIsaGEsYWEseGEpKTtyZXR1cm5bU2EsVGEsd2FdfWNhc2UiU3RyaW5nVG9IYXNoQnVja2V0RmFzdCI6cmV0dXJuW2JhLnN0cmluZy5zdHJpbmdUb0hhc2hCdWNrZXRGYXN0KGdldFBhcmFtVmFsdWUoImlucHV0IixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgibnVtQnVja2V0cyIsaGEsYWEseGEpKV07ZGVmYXVsdDp0aHJvdyBUeXBlRXJyb3IoYE5vZGUgdHlwZSAke2hhLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4ZWN1dGVPcCQxPShoYSxhYSx4YSxiYT10Zk9wcyk9Pntzd2l0Y2goaGEub3Ape2Nhc2UiQ2FzdCI6cmV0dXJuW2JhLmNhc3QoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoImR0eXBlIixoYSxhYSx4YSkpXTtjYXNlIkV4cGFuZERpbXMiOntjb25zdCBTYT1nZXRQYXJhbVZhbHVlKCJheGlzIixoYSxhYSx4YSk7cmV0dXJuW2JhLmV4cGFuZERpbXMoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLFNhKV19Y2FzZSJTcXVlZXplIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiYXhpcyIsaGEsYWEseGEpO3JldHVybltiYS5zcXVlZXplKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxTYSldfWNhc2UiUmVzaGFwZSI6cmV0dXJuW2JhLnJlc2hhcGUoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNoYXBlIixoYSxhYSx4YSkpXTtjYXNlIkVuc3VyZVNoYXBlIjpyZXR1cm5bYmEuZW5zdXJlU2hhcGUoZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNoYXBlIixoYSxhYSx4YSkpXTtjYXNlIk1pcnJvclBhZCI6cmV0dXJuW2JhLm1pcnJvclBhZChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgicGFkZGluZyIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoIm1vZGUiLGhhLGFhLHhhKSldO2Nhc2UiUGFkVjIiOmNhc2UiUGFkIjpyZXR1cm5bYmEucGFkKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxnZXRQYXJhbVZhbHVlKCJwYWRkaW5nIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiY29uc3RhbnRWYWx1ZSIsaGEsYWEseGEpKV07Y2FzZSJTcGFjZVRvQmF0Y2hORCI6e2NvbnN0IFNhPWdldFBhcmFtVmFsdWUoImJsb2NrU2hhcGUiLGhhLGFhLHhhKSxUYT1nZXRQYXJhbVZhbHVlKCJwYWRkaW5ncyIsaGEsYWEseGEpO3JldHVybltiYS5zcGFjZVRvQmF0Y2hORChnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksU2EsVGEpXX1jYXNlIkJhdGNoVG9TcGFjZU5EIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiYmxvY2tTaGFwZSIsaGEsYWEseGEpLFRhPWdldFBhcmFtVmFsdWUoImNyb3BzIixoYSxhYSx4YSk7cmV0dXJuW2JhLmJhdGNoVG9TcGFjZU5EKGdldFBhcmFtVmFsdWUoIngiLGhhLGFhLHhhKSxTYSxUYSldfWNhc2UiRGVwdGhUb1NwYWNlIjp7Y29uc3QgU2E9Z2V0UGFyYW1WYWx1ZSgiYmxvY2tTaXplIixoYSxhYSx4YSksVGE9Z2V0UGFyYW1WYWx1ZSgiZGF0YUZvcm1hdCIsaGEsYWEseGEpLnRvVXBwZXJDYXNlKCk7cmV0dXJuW2JhLmRlcHRoVG9TcGFjZShnZXRQYXJhbVZhbHVlKCJ4IixoYSxhYSx4YSksU2EsVGEpXX1jYXNlIkJyb2FkY2FzdFRvIjpyZXR1cm5bYmEuYnJvYWRjYXN0VG8oZ2V0UGFyYW1WYWx1ZSgieCIsaGEsYWEseGEpLGdldFBhcmFtVmFsdWUoInNoYXBlIixoYSxhYSx4YSkpXTtjYXNlIkJyb2FkY2FzdEFyZ3MiOnJldHVybltiYS5icm9hZGNhc3RBcmdzKGdldFBhcmFtVmFsdWUoInMwIixoYSxhYSx4YSksZ2V0UGFyYW1WYWx1ZSgiczEiLGhhLGFhLHhhKSldO2RlZmF1bHQ6dGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtoYS5vcH0gaXMgbm90IGltcGxlbWVudGVkYCl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBleGVjdXRlT3AoaGEsYWEseGEsYmEsU2E9dGlkeSQxKXtjb25zdCBUYT0oKHdhLEVhLGthKT0+e3N3aXRjaCh3YS5jYXRlZ29yeSl7Y2FzZSJhcml0aG1ldGljIjpyZXR1cm4gU2EoKCk9PmV4ZWN1dGVPcCRrKHdhLEVhLGthKSk7Y2FzZSJiYXNpY19tYXRoIjpyZXR1cm4gU2EoKCk9PmV4ZWN1dGVPcCRqKHdhLEVhLGthKSk7Y2FzZSJjb250cm9sIjpyZXR1cm4gZXhlY3V0ZU9wJGkod2EsRWEsa2EpO2Nhc2UiY29udm9sdXRpb24iOnJldHVybiBTYSgoKT0+ZXhlY3V0ZU9wJGgod2EsRWEsa2EpKTtjYXNlImNyZWF0aW9uIjpyZXR1cm4gU2EoKCk9PmV4ZWN1dGVPcCRnKHdhLEVhLGthKSk7Y2FzZSJkeW5hbWljIjpyZXR1cm4gZXhlY3V0ZU9wJGYod2EsRWEsa2EpO2Nhc2UiZXZhbHVhdGlvbiI6cmV0dXJuIFNhKCgpPT5leGVjdXRlT3AkZSh3YSxFYSxrYSkpO2Nhc2UiaW1hZ2UiOnJldHVybiBTYSgoKT0+ZXhlY3V0ZU9wJGIod2EsRWEsa2EpKTtjYXNlImdyYXBoIjpyZXR1cm4gU2EoKCk9PmV4ZWN1dGVPcCRkKHdhLEVhLGthKSk7Y2FzZSJsb2dpY2FsIjpyZXR1cm4gU2EoKCk9PmV4ZWN1dGVPcCRhKHdhLEVhLGthKSk7Y2FzZSJtYXRyaWNlcyI6cmV0dXJuIFNhKCgpPT5leGVjdXRlT3AkOSh3YSxFYSxrYSkpO2Nhc2Uibm9ybWFsaXphdGlvbiI6cmV0dXJuIFNhKCgpPT5leGVjdXRlT3AkOCh3YSxFYSxrYSkpO2Nhc2UicmFnZ2VkIjpyZXR1cm4gU2EoKCk9PmV4ZWN1dGVPcCQ3KHdhLEVhLGthKSk7Y2FzZSJyZWR1Y3Rpb24iOnJldHVybiBTYSgoKT0+ZXhlY3V0ZU9wJDYod2EsRWEsa2EpKTtjYXNlInNsaWNlX2pvaW4iOnJldHVybiBTYSgoKT0+ZXhlY3V0ZU9wJDUod2EsRWEsa2EpKTtjYXNlInNwYXJzZSI6cmV0dXJuIFNhKCgpPT5leGVjdXRlT3AkNCh3YSxFYSxrYSkpO2Nhc2Uic3BlY3RyYWwiOnJldHVybiBTYSgoKT0+ZXhlY3V0ZU9wJDMod2EsRWEsa2EpKTtjYXNlInN0cmluZyI6cmV0dXJuIFNhKCgpPT5leGVjdXRlT3AkMih3YSxFYSxrYSkpO2Nhc2UidHJhbnNmb3JtYXRpb24iOnJldHVybiBTYSgoKT0+ZXhlY3V0ZU9wJDEod2EsRWEsa2EpKTtjYXNlImhhc2hfdGFibGUiOnJldHVybiBleGVjdXRlT3AkYyh3YSxFYSxrYSxiYSk7Y2FzZSJjdXN0b20iOmNvbnN0IEFhPWdldFJlZ2lzdGVyZWRPcCh3YS5vcCk7aWYoQWEmJkFhLmN1c3RvbUV4ZWN1dG9yKXJldHVybiBBYS5jdXN0b21FeGVjdXRvcihuZXcgTm9kZVZhbHVlSW1wbCh3YSxFYSxrYSkpO3Rocm93IFR5cGVFcnJvcihgQ3VzdG9tIG9wICR7d2Eub3B9IGlzIG5vdCByZWdpc3RlcmVkLmApO2RlZmF1bHQ6dGhyb3cgVHlwZUVycm9yKGBVbmtub3duIG9wICcke3dhLm9wfScuIEZpbGUgYW4gaXNzdWUgYXQgaHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvdGZqcy9pc3N1ZXMgc28gd2UgY2FuIGFkZCBpdCwgb3IgcmVnaXN0ZXIgYSBjdXN0b20gZXhlY3V0aW9uIHdpdGggdGYucmVnaXN0ZXJPcCgpYCl9fSkoaGEsYWEseGEpO3JldHVybiBpc1Byb21pc2UkMShUYSk/VGEudGhlbih3YT0+W10uY29uY2F0KHdhKSk6W10uY29uY2F0KFRhKX1jbGFzcyBFeGVjdXRpb25Db250ZXh0e2NvbnN0cnVjdG9yKGFhPXt9LHhhPXt9LGJhPXt9LFNhPXt9LFRhKXt0aGlzLndlaWdodE1hcD1hYSx0aGlzLnRlbnNvckFycmF5TWFwPXhhLHRoaXMudGVuc29yTGlzdE1hcD1iYSx0aGlzLmZ1bmN0aW9uTWFwPVNhLHRoaXMucGFyc2VOb2RlTmFtZUNhY2hlPVRhLHRoaXMucm9vdENvbnRleHQ9e2lkOjAsZnJhbWVOYW1lOiIiLGl0ZXJhdGlvbklkOjB9LHRoaXMuY29udGV4dHM9W3RoaXMucm9vdENvbnRleHRdLHRoaXMubGFzdElkPTAsdGhpcy5nZW5lcmF0ZUN1cnJlbnRDb250ZXh0SWRzKCl9bmV3RnJhbWUoYWEseGEpe3JldHVybntpZDphYSxmcmFtZU5hbWU6eGEsaXRlcmF0aW9uSWQ6MH19c2V0IGN1cnJlbnRDb250ZXh0KGFhKXt0aGlzLmNvbnRleHRzIT09YWEmJih0aGlzLmNvbnRleHRzPWFhLHRoaXMuZ2VuZXJhdGVDdXJyZW50Q29udGV4dElkcygpKX1nZXQgY3VycmVudENvbnRleHQoKXtyZXR1cm4gdGhpcy5jb250ZXh0c31nZXQgY3VycmVudENvbnRleHRJZCgpe3JldHVybiB0aGlzLl9jdXJyZW50Q29udGV4dElkc1swXX1nZXQgY3VycmVudENvbnRleHRJZHMoKXtyZXR1cm4gdGhpcy5fY3VycmVudENvbnRleHRJZHN9Z2VuZXJhdGVDdXJyZW50Q29udGV4dElkcygpe2NvbnN0IGFhPVtdO2ZvcihsZXQgeGE9MDt4YTx0aGlzLmNvbnRleHRzLmxlbmd0aC0xO3hhKyspe2NvbnN0IGJhPXRoaXMuY29udGV4dHMuc2xpY2UoMCx0aGlzLmNvbnRleHRzLmxlbmd0aC14YSk7YWEucHVzaCh0aGlzLmNvbnRleHRJZGZvckNvbnRleHRzKGJhKSl9YWEucHVzaCgiIiksdGhpcy5fY3VycmVudENvbnRleHRJZHM9YWF9Y29udGV4dElkZm9yQ29udGV4dHMoYWEpe3JldHVybiBhYT9hYS5tYXAoeGE9PnhhLmlkPT09MCYmeGEuaXRlcmF0aW9uSWQ9PT0wPyIiOmAke3hhLmZyYW1lTmFtZX0tJHt4YS5pdGVyYXRpb25JZH1gKS5qb2luKCIvIik6IiJ9ZW50ZXJGcmFtZShhYSl7dGhpcy5jb250ZXh0cyYmKHRoaXMubGFzdElkKyssdGhpcy5jb250ZXh0cz10aGlzLmNvbnRleHRzLnNsaWNlKCksdGhpcy5jb250ZXh0cy5wdXNoKHRoaXMubmV3RnJhbWUodGhpcy5sYXN0SWQsYWEpKSx0aGlzLl9jdXJyZW50Q29udGV4dElkcy51bnNoaWZ0KHRoaXMuY29udGV4dElkZm9yQ29udGV4dHModGhpcy5jb250ZXh0cykpKX1leGl0RnJhbWUoKXtpZih0aGlzLmNvbnRleHRzJiZ0aGlzLmNvbnRleHRzLmxlbmd0aD4xKXRoaXMuY29udGV4dHM9dGhpcy5jb250ZXh0cy5zbGljZSgpLHRoaXMuY29udGV4dHMuc3BsaWNlKC0xKSx0aGlzLmN1cnJlbnRDb250ZXh0SWRzLnNoaWZ0KCk7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBleGl0IGZyYW1lLCB0aGUgY29udGV4dCBpcyBlbXB0eSIpfW5leHRJdGVyYXRpb24oKXtpZih0aGlzLmNvbnRleHRzJiZ0aGlzLmNvbnRleHRzLmxlbmd0aD4wKXt0aGlzLmNvbnRleHRzPXRoaXMuY29udGV4dHMuc2xpY2UoKSx0aGlzLmxhc3RJZCsrO2NvbnN0IGFhPU9iamVjdC5hc3NpZ24oe30sdGhpcy5jb250ZXh0c1t0aGlzLmNvbnRleHRzLmxlbmd0aC0xXSk7YWEuaXRlcmF0aW9uSWQrPTEsYWEuaWQ9dGhpcy5sYXN0SWQsdGhpcy5jb250ZXh0cy5zcGxpY2UoLTEsMSxhYSksdGhpcy5fY3VycmVudENvbnRleHRJZHMuc3BsaWNlKDAsMSx0aGlzLmNvbnRleHRJZGZvckNvbnRleHRzKHRoaXMuY29udGV4dHMpKX1lbHNlIHRocm93IG5ldyBFcnJvcigiQ2Fubm90IGluY3JlYXNlIGZyYW1lIGl0ZXJhdGlvbiwgdGhlIGNvbnRleHQgaXMgZW1wdHkiKX1nZXRXZWlnaHQoYWEpe3JldHVybiB0aGlzLndlaWdodE1hcFthYV19YWRkVGVuc29yQXJyYXkoYWEpe3RoaXMudGVuc29yQXJyYXlNYXBbYWEuaWRdPWFhfWdldFRlbnNvckFycmF5KGFhKXtyZXR1cm4gdGhpcy50ZW5zb3JBcnJheU1hcFthYV19YWRkVGVuc29yTGlzdChhYSl7dGhpcy50ZW5zb3JMaXN0TWFwW2FhLmlkXT1hYX1nZXRUZW5zb3JMaXN0KGFhKXtyZXR1cm4gdGhpcy50ZW5zb3JMaXN0TWFwW2FhXX1kaXNwb3NlKGFhKXtmb3IoY29uc3QgeGEgaW4gdGhpcy50ZW5zb3JBcnJheU1hcCl0aGlzLnRlbnNvckFycmF5TWFwW3hhXS5jbGVhckFuZENsb3NlKGFhKTtmb3IoY29uc3QgeGEgaW4gdGhpcy50ZW5zb3JMaXN0TWFwKXRoaXMudGVuc29yTGlzdE1hcFt4YV0uY2xlYXJBbmRDbG9zZShhYSl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdldEV4ZWN1dGlvblN1YmdyYXBoKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1uZXcgU2V0LFRhPVtdO2xldCB3YT1udWxsLEVhPW51bGw7Y29uc3Qga2E9bmV3IFNldCxBYT1uZXcgU2V0KE9iamVjdC5rZXlzKGhhKS5tYXAoZWw9PnBhcnNlTm9kZU5hbWUoZWwpWzBdKSk7YmE9YmF8fFtdO2NvbnN0IEZhPW5ldyBTZXQoYmEubWFwKGVsPT5wYXJzZU5vZGVOYW1lKGVsLm5hbWUpWzBdKSksTGE9Wy4uLmFhXTtmb3IoO0xhLmxlbmd0aD4wOyl7Y29uc3QgZWw9TGEucG9wKCk7aWYoKGlzQ29udHJvbEZsb3coZWwpfHxpc0R5bmFtaWNTaGFwZShlbCl8fGlzSGFzaFRhYmxlKGVsKSkmJndhPT1udWxsJiYod2E9ZWwsRWE9d2EuY2hpbGRyZW4ubWFwKHRsPT50bC5uYW1lKS5maWx0ZXIodGw9PlNhLmhhcyh0bCkpKSxTYS5hZGQoZWwubmFtZSkseGFbZWwubmFtZV09PW51bGwmJiFBYS5oYXMoZWwubmFtZSkmJiFGYS5oYXMoZWwubmFtZSkpe2lmKGVsLmlucHV0cy5sZW5ndGg9PT0wKXtUYS5wdXNoKGVsLm5hbWUpO2NvbnRpbnVlfWVsLmlucHV0cy5mb3JFYWNoKHRsPT57a2EuaGFzKHRsLm5hbWUpfHwoa2EuYWRkKHRsLm5hbWUpLExhLnB1c2godGwpKX0pfX1yZXR1cm57aW5wdXRzOmhhLG91dHB1dHM6YWEsdXNlZE5vZGVzOlNhLG1pc3NpbmdJbnB1dHM6VGEsZHluYW1pY05vZGU6d2Esc3luY0lucHV0czpFYX19ZnVuY3Rpb24gZ2V0Tm9kZXNJblRvcG9sb2dpY2FsT3JkZXIoaGEsYWEpe2NvbnN0e3VzZWROb2Rlczp4YSxpbnB1dHM6YmF9PWFhLFNhPU9iamVjdC5rZXlzKGJhKS5tYXAocmw9PnBhcnNlTm9kZU5hbWUocmwpWzBdKS5tYXAocmw9PmhhLm5vZGVzW3JsXSksVGE9aGEuaW5pdE5vZGVzfHxbXSx3YT1ybD0+eGEuaGFzKHR5cGVvZiBybD09InN0cmluZyI/cmw6cmwubmFtZSk7ZnVuY3Rpb24gRWEocmwpe3JldHVyblsuLi5uZXcgTWFwKHJsLm1hcChvbD0+W29sLm5hbWUsb2xdKSkudmFsdWVzKCldfWNvbnN0IGthPUVhKFsuLi5TYSwuLi5oYS53ZWlnaHRzLC4uLlRhXSkuZmlsdGVyKHdhKSxBYT1FYShbLi4ua2EsLi4uT2JqZWN0LnZhbHVlcyhoYS5ub2RlcyldKS5maWx0ZXIod2EpLEZhPW5ldyBNYXAoQWEubWFwKHJsPT5bcmwubmFtZSxybF0pKSxMYT17fTtmb3IoY29uc3Qgcmwgb2YgQWEpe0xhW3JsLm5hbWVdPUxhW3JsLm5hbWVdfHwwO2Zvcihjb25zdCBvbCBvZiBybC5jaGlsZHJlbil3YShvbCl8fChMYVtvbC5uYW1lXT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpLExhW29sLm5hbWVdPShMYVtvbC5uYW1lXXx8MCkrMX1jb25zdCBlbD1PYmplY3QuZW50cmllcyhMYSkuZmlsdGVyKChbLHJsXSk9PnJsPT09MCkubWFwKChbcmxdKT0+cmwpLHRsPVsuLi5lbF07Zm9yKDtlbC5sZW5ndGg+MDspe2NvbnN0IHJsPWVsLnBvcCgpLG9sPUZhLmdldChybCk7Zm9yKGNvbnN0IGFsIG9mIG9sLmNoaWxkcmVuLmZpbHRlcih3YSkpLS1MYVthbC5uYW1lXT09PTAmJih0bC5wdXNoKGFsLm5hbWUpLGVsLnB1c2goYWwubmFtZSkpfWNvbnN0IG5sPXRsLm1hcChybD0+RmEuZ2V0KHJsKSksc2w9ZmlsdGVyUHJlZGVmaW5lZFJlYWNoYWJsZU5vZGVzKG5sLGthKTtyZXR1cm4gdmFsaWRhdGVOb2Rlc0V4ZWN1dGlvbk9yZGVyKHNsLGthKSxzbH1mdW5jdGlvbiBmaWx0ZXJQcmVkZWZpbmVkUmVhY2hhYmxlTm9kZXMoaGEsYWEpe2NvbnN0IHhhPW5ldyBNYXAoaGEubWFwKHdhPT5bd2EubmFtZSx3YV0pKSxiYT1hYS5tYXAod2E9PndhLm5hbWUpLFNhPW5ldyBTZXQoYmEpO2Zvcig7YmEubGVuZ3RoPjA7KXtjb25zdCB3YT1iYS5wb3AoKSxFYT14YS5nZXQod2EpO2Zvcihjb25zdCBrYSBvZiBFYS5jaGlsZHJlbikheGEuaGFzKGthLm5hbWUpfHxTYS5oYXMoa2EubmFtZSl8fChTYS5hZGQoa2EubmFtZSksYmEucHVzaChrYS5uYW1lKSl9cmV0dXJuIGhhLmZpbHRlcih3YT0+U2EuaGFzKHdhLm5hbWUpKX1jbGFzcyBOb2Rlc0V4ZWN1dGlvbk9yZGVyRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYE5vZGVzRXhlY3V0aW9uT3JkZXJFcnJvcjogJHthYX1gKX19ZnVuY3Rpb24gdmFsaWRhdGVOb2Rlc0V4ZWN1dGlvbk9yZGVyKGhhLGFhKXtjb25zdCB4YT1uZXcgTWFwKGhhLm1hcCgoRWEsa2EpPT5bRWEubmFtZSxrYV0pKSxiYT1uZXcgU2V0KGFhLm1hcChFYT0+RWEubmFtZSkpLFNhPUVhPT5iYS5oYXModHlwZW9mIEVhPT0ic3RyaW5nIj9FYTpFYS5uYW1lKSxUYT1uZXcgU2V0KGhhLm1hcChFYT0+RWEubmFtZSkpLHdhPUVhPT5UYS5oYXModHlwZW9mIEVhPT0ic3RyaW5nIj9FYTpFYS5uYW1lKTtmb3IoY29uc3QgRWEgb2YgaGEpe2Zvcihjb25zdCBrYSBvZiBFYS5jaGlsZHJlbi5maWx0ZXIod2EpKXtpZigheGEuaGFzKGthLm5hbWUpKXRocm93IG5ldyBOb2Rlc0V4ZWN1dGlvbk9yZGVyRXJyb3IoYENoaWxkICR7a2EubmFtZX0gb2Ygbm9kZSAke0VhLm5hbWV9IGlzIHVucmVhY2hhYmxlLmApO2lmKHhhLmdldChFYS5uYW1lKT54YS5nZXQoa2EubmFtZSkpdGhyb3cgbmV3IE5vZGVzRXhlY3V0aW9uT3JkZXJFcnJvcihgTm9kZSAke0VhLm5hbWV9IGlzIHNjaGVkdWxlZCB0byBydW4gYWZ0ZXIgaXRzIGNoaWxkICR7a2EubmFtZX0uYCl9aWYoIVNhKEVhKSlmb3IoY29uc3Qga2Egb2YgRWEuaW5wdXRzKXtpZigheGEuaGFzKGthLm5hbWUpKXRocm93IG5ldyBOb2Rlc0V4ZWN1dGlvbk9yZGVyRXJyb3IoYElucHV0ICR7a2EubmFtZX0gb2Ygbm9kZSAke0VhLm5hbWV9IGlzIHVucmVhY2hhYmxlLmApO2lmKHhhLmdldChrYS5uYW1lKT54YS5nZXQoRWEubmFtZSkpdGhyb3cgbmV3IE5vZGVzRXhlY3V0aW9uT3JkZXJFcnJvcihgTm9kZSAke0VhLm5hbWV9IGlzIHNjaGVkdWxlZCB0byBydW4gYmVmb3JlIGl0cyBpbnB1dCAke2thLm5hbWV9LmApfX19ZnVuY3Rpb24gZ2V0Tm9kZUxpdmVVbnRpbE1hcChoYSl7Y29uc3QgYWE9bmV3IE1hcChoYS5tYXAoKEVhLGthKT0+W0VhLm5hbWUsa2FdKSkseGE9TnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsYmE9aGEubWFwKChFYSxrYSk9PmlzQ29udHJvbEZsb3coRWEpP3hhOmthKSxTYT1FYT0+e2NvbnN0IGthPWJhW2FhLmdldChFYS5uYW1lKV07cmV0dXJuIGthPz8tMX0sVGE9aGEubWFwKChFYSxrYSk9PkVhLmNoaWxkcmVuLm1hcChTYSkucmVkdWNlKChBYSxGYSk9Pk1hdGgubWF4KEFhLEZhKSxiYVtrYV0pKSx3YT1uZXcgTWFwO2ZvcihsZXQgRWE9MDtFYTxoYS5sZW5ndGg7KytFYSl7Y29uc3Qga2E9VGFbRWFdO2lmKGthPT09eGEpY29udGludWU7Y29uc3QgQWE9aGFbRWFdLEZhPWhhW2thXTt3YS5oYXMoRmEubmFtZSl8fHdhLnNldChGYS5uYW1lLFtdKSx3YS5nZXQoRmEubmFtZSkucHVzaChBYSl9cmV0dXJuIHdhfWNvbnN0IENPTlRST0xfRkxPV19PUFM9bmV3IFNldChbIlN3aXRjaCIsIk1lcmdlIiwiRW50ZXIiLCJFeGl0IiwiTmV4dEl0ZXJhdGlvbiIsIlN0YXRlbGVzc0lmIiwiU3RhdGVsZXNzV2hpbGUiLCJpZiIsIldoaWxlIl0pLERZTkFNSUNfU0hBUEVfT1BTPW5ldyBTZXQoWyJOb25NYXhTdXBwcmVzc2lvblYyIiwiTm9uTWF4U3VwcHJlc3Npb25WMyIsIk5vbk1heFN1cHByZXNzaW9uVjUiLCJXaGVyZSJdKSxIQVNIX1RBQkxFX09QUz1uZXcgU2V0KFsiSGFzaFRhYmxlIiwiSGFzaFRhYmxlVjIiLCJMb29rdXBUYWJsZUltcG9ydCIsIkxvb2t1cFRhYmxlSW1wb3J0VjIiLCJMb29rdXBUYWJsZUZpbmQiLCJMb29rdXBUYWJsZUZpbmRWMiIsIkxvb2t1cFRhYmxlU2l6ZSIsIkxvb2t1cFRhYmxlU2l6ZVYyIl0pO2Z1bmN0aW9uIGlzQ29udHJvbEZsb3coaGEpe3JldHVybiBDT05UUk9MX0ZMT1dfT1BTLmhhcyhoYS5vcCl9ZnVuY3Rpb24gaXNEeW5hbWljU2hhcGUoaGEpe3JldHVybiBEWU5BTUlDX1NIQVBFX09QUy5oYXMoaGEub3ApfWZ1bmN0aW9uIGlzSGFzaFRhYmxlKGhhKXtyZXR1cm4gSEFTSF9UQUJMRV9PUFMuaGFzKGhhLm9wKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBHcmFwaEV4ZWN1dG9ye2dldCB3ZWlnaHRJZHMoKXtyZXR1cm4gdGhpcy5wYXJlbnQ/dGhpcy5wYXJlbnQud2VpZ2h0SWRzOnRoaXMuX3dlaWdodElkc31nZXQgZnVuY3Rpb25FeGVjdXRvck1hcCgpe3JldHVybiB0aGlzLnBhcmVudD90aGlzLnBhcmVudC5mdW5jdGlvbkV4ZWN1dG9yTWFwOnRoaXMuX2Z1bmN0aW9uRXhlY3V0b3JNYXB9Z2V0IHdlaWdodE1hcCgpe3JldHVybiB0aGlzLnBhcmVudD90aGlzLnBhcmVudC53ZWlnaHRNYXA6dGhpcy5fd2VpZ2h0TWFwfXNldCB3ZWlnaHRNYXAoYWEpe2NvbnN0IHhhPU9iamVjdC5rZXlzKGFhKS5tYXAoYmE9PmFhW2JhXS5tYXAoU2E9PlNhLmlkKSk7dGhpcy5fd2VpZ2h0SWRzPVtdLmNvbmNhdCguLi54YSksdGhpcy5fd2VpZ2h0TWFwPWFhfXNldCByZXNvdXJjZU1hbmFnZXIoYWEpe3RoaXMuX3Jlc291cmNlTWFuYWdlcj1hYX1nZXQgaW5wdXRzKCl7cmV0dXJuIHRoaXMuX2lucHV0cy5tYXAoYWE9Pih7bmFtZTphYS5uYW1lLHNoYXBlOmFhLmF0dHJQYXJhbXMuc2hhcGU/YWEuYXR0clBhcmFtcy5zaGFwZS52YWx1ZTp2b2lkIDAsZHR5cGU6YWEuYXR0clBhcmFtcy5kdHlwZT9hYS5hdHRyUGFyYW1zLmR0eXBlLnZhbHVlOnZvaWQgMH0pKX1nZXQgb3V0cHV0cygpe3JldHVybiB0aGlzLl9vdXRwdXRzLm1hcChhYT0+KHtuYW1lOmFhLm5hbWUsc2hhcGU6YWEuYXR0clBhcmFtcy5zaGFwZT9hYS5hdHRyUGFyYW1zLnNoYXBlLnZhbHVlOnZvaWQgMCxkdHlwZTphYS5hdHRyUGFyYW1zLmR0eXBlP2FhLmF0dHJQYXJhbXMuZHR5cGUudmFsdWU6dm9pZCAwfSkpfWdldCBpbnB1dE5vZGVzKCl7cmV0dXJuIHRoaXMuX2lucHV0cy5tYXAoYWE9PmFhLnNpZ25hdHVyZUtleXx8YWEubmFtZSl9Z2V0IG91dHB1dE5vZGVzKCl7cmV0dXJuIHRoaXMuX291dHB1dHMubWFwKGFhPT57Y29uc3QgeGE9YWEuc2lnbmF0dXJlS2V5fHxhYS5uYW1lO3JldHVybiBhYS5kZWZhdWx0T3V0cHV0P2Ake3hhfToke2FhLmRlZmF1bHRPdXRwdXR9YDp4YX0pfWdldCBmdW5jdGlvbnMoKXtyZXR1cm4gT2JqZWN0LmtleXModGhpcy5fZnVuY3Rpb25zKS5yZWR1Y2UoKGFhLHhhKT0+KGFhW3hhXT10aGlzLl9mdW5jdGlvbnNbeGFdLnNpZ25hdHVyZSxhYSkse30pfWNvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLmdyYXBoPWFhLHRoaXMucGFyZW50PXhhLHRoaXMuY29tcGlsZWRNYXA9bmV3IE1hcCx0aGlzLnBhcnNlTm9kZU5hbWVDYWNoZT1uZXcgTWFwLHRoaXMuX3dlaWdodE1hcD17fSx0aGlzLlNFUEFSQVRPUj0iLCIsdGhpcy5fZnVuY3Rpb25zPXt9LHRoaXMuX2Z1bmN0aW9uRXhlY3V0b3JNYXA9e30sdGhpcy5rZWVwSW50ZXJtZWRpYXRlVGVuc29ycz0hMSx0aGlzLl9vdXRwdXRzPWFhLm91dHB1dHMsdGhpcy5faW5wdXRzPWFhLmlucHV0cyx0aGlzLl9pbml0Tm9kZXM9YWEuaW5pdE5vZGVzLHRoaXMuX3NpZ25hdHVyZT1hYS5zaWduYXR1cmUsdGhpcy5fZnVuY3Rpb25zPWFhLmZ1bmN0aW9ucyxhYS5mdW5jdGlvbnMhPW51bGwmJk9iamVjdC5rZXlzKGFhLmZ1bmN0aW9ucykuZm9yRWFjaChiYT0+e3RoaXMuX2Z1bmN0aW9uRXhlY3V0b3JNYXBbYmFdPW5ldyBHcmFwaEV4ZWN1dG9yKGFhLmZ1bmN0aW9uc1tiYV0sdGhpcyl9KX1nZXRDb21waWxhdGlvbktleShhYSx4YSl7Y29uc3QgYmE9YWEubWFwKFRhPT5UYS5uYW1lKS5zb3J0KCksU2E9eGEubWFwKFRhPT5UYS5uYW1lKS5zb3J0KCk7cmV0dXJuIGJhLmpvaW4odGhpcy5TRVBBUkFUT1IpKyItLSIrU2Euam9pbih0aGlzLlNFUEFSQVRPUil9Y29tcGlsZShhYSx4YSl7Y29uc3QgYmE9Z2V0RXhlY3V0aW9uU3ViZ3JhcGgoYWEseGEsdGhpcy53ZWlnaHRNYXAsdGhpcy5faW5pdE5vZGVzKSx7bWlzc2luZ0lucHV0czpTYSxkeW5hbWljTm9kZTpUYSxzeW5jSW5wdXRzOndhfT1iYTtpZihUYSE9bnVsbCl0aHJvdyBuZXcgRXJyb3IoYFRoaXMgZXhlY3V0aW9uIGNvbnRhaW5zIHRoZSBub2RlICcke1RhLm5hbWV9Jywgd2hpY2ggaGFzIHRoZSBkeW5hbWljIG9wICcke1RhLm9wfScuIFBsZWFzZSB1c2UgbW9kZWwuZXhlY3V0ZUFzeW5jKCkgaW5zdGVhZC4gQWx0ZXJuYXRpdmVseSwgdG8gYXZvaWQgdGhlIGR5bmFtaWMgb3BzLCBzcGVjaWZ5IHRoZSBpbnB1dHMgWyR7d2F9XWApO2lmKFNhLmxlbmd0aD4wKXtjb25zdCBBYT14YS5tYXAoTGE9PkxhLm5hbWUpLEZhPU9iamVjdC5rZXlzKGFhKTt0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb21wdXRlIHRoZSBvdXRwdXRzIFske0FhfV0gZnJvbSB0aGUgcHJvdmlkZWQgaW5wdXRzIFske0ZhfV0uIE1pc3NpbmcgdGhlIGZvbGxvd2luZyBpbnB1dHM6IFske1NhfV1gKX1jb25zdCBFYT1nZXROb2Rlc0luVG9wb2xvZ2ljYWxPcmRlcih0aGlzLmdyYXBoLGJhKSxrYT1nZXROb2RlTGl2ZVVudGlsTWFwKEVhKTtyZXR1cm57b3JkZXJlZE5vZGVzOkVhLG5vZGVMaXZlVW50aWxNYXA6a2F9fWNsb25lQW5kS2VlcFRlbnNvcihhYSl7aWYoYWE9PW51bGwpcmV0dXJuIG51bGw7Y29uc3QgeGE9YWEuY2xvbmUoKTtyZXR1cm4ga2VlcCQxKHhhKSx4YX1jbG9uZVRlbnNvckxpc3QoYWEpe3JldHVybiBhYT9hYS5tYXAoYmE9PnRoaXMuY2xvbmVBbmRLZWVwVGVuc29yKGJhKSk6bnVsbH1jbG9uZVRlbnNvck1hcChhYSl7cmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhhYSkubWFwKChbeGEsYmFdKT0+W3hhLHRoaXMuY2xvbmVUZW5zb3JMaXN0KGJhKV0pKX1leGVjdXRlKGFhLHhhKXt0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JzKCksYWE9dGhpcy5tYXBJbnB1dHMoYWEpO2NvbnN0IGJhPU9iamVjdC5rZXlzKGFhKS5zb3J0KCk7dGhpcy5jaGVja0lucHV0cyhhYSksdGhpcy5jaGVja0lucHV0U2hhcGVBbmRUeXBlKGFhKSx4YT10aGlzLm1hcE91dHB1dHMoeGEpLHRoaXMuY2hlY2tPdXRwdXRzKHhhKTtjb25zdCBTYT1iYS5tYXAoZWw9PnRoaXMuZ3JhcGgubm9kZXNbcGFyc2VOb2RlTmFtZShlbClbMF1dKSxUYT14YS5tYXAoZWw9PnBhcnNlTm9kZU5hbWUoZWwpWzBdKSx3YT1uZXcgU2V0KFRhKTtsZXQgRWE9VGEubWFwKGVsPT50aGlzLmdyYXBoLm5vZGVzW2VsXSk7RWEubGVuZ3RoPT09MCYmKEVhPXRoaXMuX291dHB1dHMpO2NvbnN0IGthPXRoaXMuZ2V0Q29tcGlsYXRpb25LZXkoU2EsRWEpO2xldCBBYT10aGlzLmNvbXBpbGVkTWFwLmdldChrYSk7QWE9PW51bGwmJihBYT10aGlzLmNvbXBpbGUoYWEsRWEpLHRoaXMuY29tcGlsZWRNYXAuc2V0KGthLEFhKSk7dHJ5e3RoaXMua2VlcEludGVybWVkaWF0ZVRlbnNvcnM9ZW52JDEoKS5nZXRCb29sKCJLRUVQX0lOVEVSTUVESUFURV9URU5TT1JTIil9Y2F0Y2goZWwpe3RoaXMua2VlcEludGVybWVkaWF0ZVRlbnNvcnM9ITEsY29uc29sZS53YXJuKGVsLm1lc3NhZ2UpfWNvbnN0IEZhPXt9LExhPXt9O3JldHVybiB0aWR5JDEoKCk9Pntjb25zdCBlbD1uZXcgRXhlY3V0aW9uQ29udGV4dCh0aGlzLndlaWdodE1hcCxGYSxMYSx0aGlzLmZ1bmN0aW9uRXhlY3V0b3JNYXAsdGhpcy5wYXJzZU5vZGVOYW1lQ2FjaGUpLHRsPU9iamVjdC5hc3NpZ24oe30sdGhpcy53ZWlnaHRNYXApO3RoaXMua2VlcEludGVybWVkaWF0ZVRlbnNvcnMmJih0aGlzLmNsb25lZFRlbnNvcnNNYXA9dGhpcy5jbG9uZVRlbnNvck1hcCh0aGlzLndlaWdodE1hcCkpLE9iamVjdC5rZXlzKGFhKS5mb3JFYWNoKG9sPT57Y29uc3RbYWwsbGxdPXBhcnNlTm9kZU5hbWUob2wsZWwpLGlsPVtdO2lsW2xsXT1hYVtvbF0sdGxbYWxdPWlsLHRoaXMua2VlcEludGVybWVkaWF0ZVRlbnNvcnMmJih0aGlzLmNsb25lZFRlbnNvcnNNYXBbYWxdPXRoaXMuY2xvbmVUZW5zb3JMaXN0KGlsKSl9KTtjb25zdCBubD10aGlzLmdldEZyb3plblRlbnNvcklkcyh0bCkse29yZGVyZWROb2RlczpzbCxub2RlTGl2ZVVudGlsTWFwOnJsfT1BYTtmb3IoY29uc3Qgb2wgb2Ygc2wpe2lmKHRsW29sLm5hbWVdKWNvbnRpbnVlO2NvbnN0IGFsPWV4ZWN1dGVPcChvbCx0bCxlbCx0aGlzLl9yZXNvdXJjZU1hbmFnZXIpO2lmKGlzUHJvbWlzZSQxKGFsKSl0aHJvdyBuZXcgRXJyb3IoYFRoZSBleGVjdXRpb24gb2YgdGhlIG9wICcke29sLm9wfScgcmV0dXJuZWQgYSBwcm9taXNlLiBQbGVhc2UgdXNlIG1vZGVsLmV4ZWN1dGVBc3luYygpIGluc3RlYWQuYCk7dGxbb2wubmFtZV09YWwsdGhpcy5rZWVwSW50ZXJtZWRpYXRlVGVuc29ycyYmKHRoaXMuY2xvbmVkVGVuc29yc01hcFtvbC5uYW1lXT10aGlzLmNsb25lVGVuc29yTGlzdChhbCkpLHRoaXMuY2hlY2tUZW5zb3JGb3JEaXNwb3NhbFdpdGhOb2RlTGl2ZVVudGlsSW5mbyhvbCx0bCxlbCxubCx3YSxybC5nZXQob2wubmFtZSkpfXJldHVybiB0aGlzLnBhcmVudD09bnVsbCYmZWwuZGlzcG9zZShubCkseGEubWFwKG9sPT5nZXRUZW5zb3Iob2wsdGwsZWwpKX0pfWdldEZyb3plblRlbnNvcklkcyhhYSl7Y29uc3QgeGE9W10uY29uY2F0LmFwcGx5KFtdLE9iamVjdC5rZXlzKGFhKS5tYXAoYmE9PmFhW2JhXSkubWFwKGJhPT5iYS5tYXAoU2E9PlNhLmlkKSkpO3JldHVybiBuZXcgU2V0KHhhKX1jaGVja1RlbnNvckZvckRpc3Bvc2FsKGFhLHhhLGJhLFNhLFRhLHdhLEVhKXtpZighKGlzQ29udHJvbEZsb3coeGEpfHx3YS5oYXMoYWEpKSl7Zm9yKGNvbnN0IGthIG9mIGJhW2FhXSlrYSE9bnVsbCYmKEVhW2thLmlkXT0oRWFba2EuaWRdfHwwKSt4YS5jaGlsZHJlbi5sZW5ndGgpO2Zvcihjb25zdCBrYSBvZiB4YS5pbnB1dHMpe2lmKGlzQ29udHJvbEZsb3coa2EpKWNvbnRpbnVlO2NvbnN0IEFhPWdldFRlbnNvcnNGb3JDdXJyZW50Q29udGV4dChrYS5uYW1lLGJhLFNhKTtpZihBYSE9bnVsbClmb3IoY29uc3QgRmEgb2YgQWEpe2lmKCFGYXx8RmEua2VwdHx8VGEuaGFzKEZhLmlkKSljb250aW51ZTtjb25zdCBMYT1FYVtGYS5pZF07TGE9PT0xPyhGYS5kaXNwb3NlKCksZGVsZXRlIEVhW0ZhLmlkXSk6TGEhPW51bGwmJkVhW0ZhLmlkXS0tfX19fWNoZWNrVGVuc29yRm9yRGlzcG9zYWxXaXRoTm9kZUxpdmVVbnRpbEluZm8oYWEseGEsYmEsU2EsVGEsd2Epe2Z1bmN0aW9uIEVhKGthKXtyZXR1cm4gaXNDb250cm9sRmxvdyhrYSl8fFRhLmhhcyhrYS5uYW1lKX1pZighKGlzQ29udHJvbEZsb3coYWEpfHx3YT09bnVsbCkpZm9yKGNvbnN0IGthIG9mIHdhKXtpZihFYShrYSkpY29udGludWU7Y29uc3QgQWE9Z2V0VGVuc29yc0ZvckN1cnJlbnRDb250ZXh0KGthLm5hbWUseGEsYmEpO2Zvcihjb25zdCBGYSBvZiBBYSkhRmF8fEZhLmtlcHR8fFNhLmhhcyhGYS5pZCl8fEZhLmRpc3Bvc2UoKX19YXN5bmMgZXhlY3V0ZUFzeW5jKGFhLHhhKXtyZXR1cm4gdGhpcy5fZXhlY3V0ZUFzeW5jKGFhLHhhKX1kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ycygpe3RoaXMuY2xvbmVkVGVuc29yc01hcCYmKE9iamVjdC52YWx1ZXModGhpcy5jbG9uZWRUZW5zb3JzTWFwKS5mb3JFYWNoKGFhPT57Zm9yKGNvbnN0IHhhIG9mIGFhKXhhJiYheGEuaXNEaXNwb3NlZCYmeGEuZGlzcG9zZSgpfSksdGhpcy5jbG9uZWRUZW5zb3JzTWFwPW51bGwpfWdldEludGVybWVkaWF0ZVRlbnNvcnMoKXtyZXR1cm4gdGhpcy5jbG9uZWRUZW5zb3JzTWFwfWFzeW5jIF9leGVjdXRlQXN5bmMoYWEseGEsYmE9ITEsU2E9e30sVGE9e30pe3RoaXMuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvcnMoKSxiYXx8KGFhPXRoaXMubWFwSW5wdXRzKGFhKSx0aGlzLmNoZWNrSW5wdXRzKGFhKSx0aGlzLmNoZWNrSW5wdXRTaGFwZUFuZFR5cGUoYWEpLHhhPXRoaXMubWFwT3V0cHV0cyh4YSksdGhpcy5jaGVja091dHB1dHMoeGEpKTt0cnl7dGhpcy5rZWVwSW50ZXJtZWRpYXRlVGVuc29ycz1lbnYkMSgpLmdldEJvb2woIktFRVBfSU5URVJNRURJQVRFX1RFTlNPUlMiKX1jYXRjaChlbCl7dGhpcy5rZWVwSW50ZXJtZWRpYXRlVGVuc29ycz0hMSxjb25zb2xlLndhcm4oZWwubWVzc2FnZSl9Y29uc3Qgd2E9bmV3IEV4ZWN1dGlvbkNvbnRleHQodGhpcy53ZWlnaHRNYXAsU2EsVGEsdGhpcy5mdW5jdGlvbkV4ZWN1dG9yTWFwLHRoaXMucGFyc2VOb2RlTmFtZUNhY2hlKTt0aGlzLmtlZXBJbnRlcm1lZGlhdGVUZW5zb3JzJiYodGhpcy5jbG9uZWRUZW5zb3JzTWFwPXRoaXMuY2xvbmVUZW5zb3JNYXAodGhpcy53ZWlnaHRNYXApKTtjb25zdCBFYT1hd2FpdCB0aGlzLmV4ZWN1dGVXaXRoQ29udHJvbEZsb3coYWEsd2EseGEsYmEpLGthPXhhLm1hcChlbD0+Z2V0VGVuc29yKGVsLEVhLHdhKSksQWE9a2EubWFwKGVsPT5lbC5pZCksRmE9T2JqZWN0LmtleXMoYWEpLm1hcChlbD0+YWFbZWxdLmlkKSxMYT1uZXcgU2V0KFsuLi5BYSwuLi5GYSwuLi50aGlzLndlaWdodElkc10pO3JldHVybiBPYmplY3QudmFsdWVzKEVhKS5mb3JFYWNoKGVsPT57ZWwuZm9yRWFjaCh0bD0+e3RsJiYhdGwuaXNEaXNwb3NlZCYmIUxhLmhhcyh0bC5pZCkmJnRsLmRpc3Bvc2UoKX0pfSksdGhpcy5wYXJlbnQ9PW51bGwmJndhLmRpc3Bvc2UoTGEpLGthfWFzeW5jIGV4ZWN1dGVGdW5jdGlvbkFzeW5jKGFhLHhhLGJhKXtjb25zdCBTYT1hYS5yZWR1Y2UoKFRhLHdhLEVhKT0+KFRhW3RoaXMuaW5wdXRzW0VhXS5uYW1lXT13YSxUYSkse30pO3JldHVybiB0aGlzLl9leGVjdXRlQXN5bmMoU2EsdGhpcy5vdXRwdXROb2RlcywhMCx4YSxiYSl9YXN5bmMgZXhlY3V0ZVdpdGhDb250cm9sRmxvdyhhYSx4YSxiYSxTYSl7Y29uc3QgVGE9T2JqZWN0LmtleXMoYWEpLHdhPVRhLm1hcChpbD0+dGhpcy5ncmFwaC5ub2Rlc1twYXJzZU5vZGVOYW1lKGlsKVswXV0pLEVhPWJhLm1hcChpbD0+cGFyc2VOb2RlTmFtZShpbClbMF0pLGthPW5ldyBTZXQoRWEpO2xldCBBYT1FYS5tYXAoaWw9PnRoaXMuZ3JhcGgubm9kZXNbaWxdKTtBYS5sZW5ndGg9PT0wJiYoQWE9dGhpcy5fb3V0cHV0cyk7Y29uc3R7dXNlZE5vZGVzOkZhLG1pc3NpbmdJbnB1dHM6TGEsZHluYW1pY05vZGU6ZWwsc3luY0lucHV0czp0bH09Z2V0RXhlY3V0aW9uU3ViZ3JhcGgoYWEsQWEsdGhpcy53ZWlnaHRNYXAsdGhpcy5faW5pdE5vZGVzKSxubD1bLi4ud2EsLi4udGhpcy5ncmFwaC53ZWlnaHRzLC4uLnRoaXMuX2luaXROb2Rlc3x8W11dLm1hcChpbD0+KHtub2RlOmlsLGNvbnRleHRzOnhhLmN1cnJlbnRDb250ZXh0fSkpLHNsPU9iamVjdC5hc3NpZ24oe30sdGhpcy53ZWlnaHRNYXApO09iamVjdC5rZXlzKGFhKS5mb3JFYWNoKGlsPT57Y29uc3RbY2wsdWxdPXBhcnNlTm9kZU5hbWUoaWwpLGRsPVtdO2RsW3VsXT1hYVtpbF0sc2xbY2xdPWRsfSk7Y29uc3Qgcmw9e30sb2w9dGhpcy5nZXRGcm96ZW5UZW5zb3JJZHMoc2wpLGFsPXt9O2Zvcig7bmwubGVuZ3RoPjA7KXtjb25zdCBpbD10aGlzLnByb2Nlc3NTdGFjayh3YSxubCx4YSxzbCxhbCxvbCxrYSxybCxGYSk7YXdhaXQgUHJvbWlzZS5hbGwoaWwpfWVsPT1udWxsJiYhU2EmJmNvbnNvbGUud2FybigiVGhpcyBtb2RlbCBleGVjdXRpb24gZGlkIG5vdCBjb250YWluIGFueSBub2RlcyB3aXRoIGNvbnRyb2wgZmxvdyBvciBkeW5hbWljIG91dHB1dCBzaGFwZXMuIFlvdSBjYW4gdXNlIG1vZGVsLmV4ZWN1dGUoKSBpbnN0ZWFkLiIpO2NvbnN0IGxsPUFhLmZpbHRlcihpbD0+IWlzQ29udHJvbEZsb3coaWwpJiYhZ2V0VGVuc29yKGlsLm5hbWUsc2wseGEpKS5tYXAoaWw9PmlsLm5hbWUpO2lmKGxsLmxlbmd0aD4wKXtsZXQgaWw9IiI7dGhyb3cgZWwhPW51bGwmJihpbD1gQWx0ZXJuYXRpdmVseSwgdG8gYXZvaWQgdGhlIGR5bmFtaWMgb3BzLCB1c2UgbW9kZWwuZXhlY3V0ZSgpIGFuZCBzcGVjaWZ5IHRoZSBpbnB1dHMgWyR7dGx9XWApLG5ldyBFcnJvcihgQ2Fubm90IGNvbXB1dGUgdGhlIG91dHB1dHMgWyR7bGx9XSBmcm9tIHRoZSBwcm92aWRlZCBpbnB1dHMgWyR7VGF9XS4gQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSBmb2xsb3dpbmcgaW5wdXRzOiBbJHtMYX1dLiAke2lsfWApfXJldHVybiBzbH1wcm9jZXNzU3RhY2soYWEseGEsYmEsU2EsVGEsd2EsRWEsa2EsQWEpe2NvbnN0IEZhPVtdO2Zvcig7eGEubGVuZ3RoPjA7KXtjb25zdCBMYT14YS5wb3AoKTtiYS5jdXJyZW50Q29udGV4dD1MYS5jb250ZXh0cztsZXQgZWw9IiI7aWYoTGEubm9kZS5vcD09PSJFbnRlciImJmdldFBhcmFtVmFsdWUoImlzQ29uc3RhbnQiLExhLm5vZGUsU2EsYmEpJiYoW2VsXT1nZXROb2RlTmFtZUFuZEluZGV4KExhLm5vZGUubmFtZSxiYSkpLFNhW0xhLm5vZGUubmFtZV09PW51bGwpe2NvbnN0IHRsPWV4ZWN1dGVPcChMYS5ub2RlLFNhLGJhLHRoaXMuX3Jlc291cmNlTWFuYWdlcik7ZWx8fChbZWxdPWdldE5vZGVOYW1lQW5kSW5kZXgoTGEubm9kZS5uYW1lLGJhKSk7Y29uc3Qgbmw9YmEuY3VycmVudENvbnRleHQ7aXNQcm9taXNlJDEodGwpP0ZhLnB1c2godGwudGhlbihzbD0+KFNhW2VsXT1zbCx0aGlzLmtlZXBJbnRlcm1lZGlhdGVUZW5zb3JzJiYodGhpcy5jbG9uZWRUZW5zb3JzTWFwW2VsXT10aGlzLmNsb25lVGVuc29yTGlzdChzbCkpLGJhLmN1cnJlbnRDb250ZXh0PW5sLHRoaXMuY2hlY2tUZW5zb3JGb3JEaXNwb3NhbChlbCxMYS5ub2RlLFNhLGJhLHdhLEVhLGthKSx0aGlzLnByb2Nlc3NDaGlsZE5vZGVzKExhLm5vZGUseGEsYmEsU2EsVGEsQWEpLHNsKSkpOihTYVtlbF09dGwsdGhpcy5rZWVwSW50ZXJtZWRpYXRlVGVuc29ycyYmKHRoaXMuY2xvbmVkVGVuc29yc01hcFtlbF09dGhpcy5jbG9uZVRlbnNvckxpc3QodGwpKSx0aGlzLmNoZWNrVGVuc29yRm9yRGlzcG9zYWwoZWwsTGEubm9kZSxTYSxiYSx3YSxFYSxrYSksdGhpcy5wcm9jZXNzQ2hpbGROb2RlcyhMYS5ub2RlLHhhLGJhLFNhLFRhLEFhKSl9ZWxzZSB0aGlzLnByb2Nlc3NDaGlsZE5vZGVzKExhLm5vZGUseGEsYmEsU2EsVGEsQWEpfXJldHVybiBGYX1wcm9jZXNzQ2hpbGROb2RlcyhhYSx4YSxiYSxTYSxUYSx3YSl7YWEuY2hpbGRyZW4uZm9yRWFjaChFYT0+e2NvbnN0W2thXT1nZXROb2RlTmFtZUFuZEluZGV4KEVhLm5hbWUsYmEpO1RhW2thXXx8IXdhLmhhcyhFYS5uYW1lKXx8KEVhLm9wPT09Ik1lcmdlIj9FYS5pbnB1dE5hbWVzLnNvbWUoQWE9PiEhZ2V0VGVuc29yKEFhLFNhLGJhKSkmJihUYVtrYV09ITAseGEucHVzaCh7Y29udGV4dHM6YmEuY3VycmVudENvbnRleHQsbm9kZTpFYX0pKTpFYS5pbnB1dE5hbWVzLmV2ZXJ5KEFhPT4hIWdldFRlbnNvcihBYSxTYSxiYSkpJiYoVGFba2FdPSEwLHhhLnB1c2goe2NvbnRleHRzOmJhLmN1cnJlbnRDb250ZXh0LG5vZGU6RWF9KSkpfSl9ZGlzcG9zZSgpe09iamVjdC5rZXlzKHRoaXMud2VpZ2h0TWFwKS5mb3JFYWNoKGFhPT50aGlzLndlaWdodE1hcFthYV0uZm9yRWFjaCh4YT0+eGEuZGlzcG9zZSgpKSl9Y2hlY2tJbnB1dFNoYXBlQW5kVHlwZShhYSl7T2JqZWN0LmtleXMoYWEpLmZvckVhY2goeGE9Pntjb25zdCBiYT1hYVt4YV0sW1NhXT1wYXJzZU5vZGVOYW1lKHhhKSxUYT10aGlzLmdyYXBoLm5vZGVzW1NhXTtpZihUYS5hdHRyUGFyYW1zLnNoYXBlJiZUYS5hdHRyUGFyYW1zLnNoYXBlLnZhbHVlKXtjb25zdCB3YT1UYS5hdHRyUGFyYW1zLnNoYXBlLnZhbHVlLEVhPXdhLmxlbmd0aD09PWJhLnNoYXBlLmxlbmd0aCYmYmEuc2hhcGUuZXZlcnkoKGthLEFhKT0+d2FbQWFdPT09LTF8fHdhW0FhXT09PWthKTthc3NlcnQkMihFYSwoKT0+YFRoZSBzaGFwZSBvZiBkaWN0Wycke1RhLm5hbWV9J10gcHJvdmlkZWQgaW4gbW9kZWwuZXhlY3V0ZShkaWN0KSBtdXN0IGJlIFske3dhfV0sIGJ1dCB3YXMgWyR7YmEuc2hhcGV9XWApfVRhLmF0dHJQYXJhbXMuZHR5cGUmJlRhLmF0dHJQYXJhbXMuZHR5cGUudmFsdWUmJmFzc2VydCQyKGJhLmR0eXBlPT09VGEuYXR0clBhcmFtcy5kdHlwZS52YWx1ZSwoKT0+YFRoZSBkdHlwZSBvZiBkaWN0Wycke1RhLm5hbWV9J10gcHJvdmlkZWQgaW4gbW9kZWwuZXhlY3V0ZShkaWN0KSBtdXN0IGJlICR7VGEuYXR0clBhcmFtcy5kdHlwZS52YWx1ZX0sIGJ1dCB3YXMgJHtiYS5kdHlwZX1gKX0pfW1hcElucHV0cyhhYSl7dmFyIHhhLGJhO2NvbnN0IFNhPXt9O2Zvcihjb25zdCBUYSBpbiBhYSl7Y29uc3Qgd2E9KGJhPSh4YT10aGlzLl9zaWduYXR1cmUpPT09bnVsbHx8eGE9PT12b2lkIDA/dm9pZCAwOnhhLmlucHV0cyk9PT1udWxsfHxiYT09PXZvaWQgMD92b2lkIDA6YmFbVGFdO3dhIT1udWxsP1NhW3dhLm5hbWVdPWFhW1RhXTpTYVtUYV09YWFbVGFdfXJldHVybiBTYX1jaGVja0lucHV0cyhhYSl7Y29uc3QgeGE9T2JqZWN0LmtleXMoYWEpLmZpbHRlcihiYT0+e2NvbnN0W1NhXT1wYXJzZU5vZGVOYW1lKGJhKTtyZXR1cm4gdGhpcy5ncmFwaC5ub2Rlc1tTYV09PW51bGx9KTtpZih4YS5sZW5ndGg+MCl0aHJvdyBuZXcgRXJyb3IoYFRoZSBkaWN0IHByb3ZpZGVkIGluIG1vZGVsLmV4ZWN1dGUoZGljdCkgaGFzIGtleXM6IFske3hhfV0gdGhhdCBhcmUgbm90IHBhcnQgb2YgZ3JhcGhgKX1tYXBPdXRwdXRzKGFhKXtyZXR1cm4gYWEubWFwKHhhPT57dmFyIGJhLFNhO2NvbnN0IFRhPShTYT0oYmE9dGhpcy5fc2lnbmF0dXJlKT09PW51bGx8fGJhPT09dm9pZCAwP3ZvaWQgMDpiYS5vdXRwdXRzKT09PW51bGx8fFNhPT09dm9pZCAwP3ZvaWQgMDpTYVt4YV07cmV0dXJuIFRhIT1udWxsP1RhLm5hbWU6eGF9LHt9KX1jaGVja091dHB1dHMoYWEpe2FhLmZvckVhY2goeGE9Pntjb25zdFtiYV09cGFyc2VOb2RlTmFtZSh4YSk7aWYoIXRoaXMuZ3JhcGgubm9kZXNbYmFdKXRocm93IG5ldyBFcnJvcihgVGhlIG91dHB1dCAnJHt4YX0nIGlzIG5vdCBmb3VuZCBpbiB0aGUgZ3JhcGhgKX0pfX1jbGFzcyBSZXNvdXJjZU1hbmFnZXJ7Y29uc3RydWN0b3IoYWE9e30seGE9e30pe3RoaXMuaGFzaFRhYmxlTmFtZVRvSGFuZGxlPWFhLHRoaXMuaGFzaFRhYmxlTWFwPXhhfWFkZEhhc2hUYWJsZShhYSx4YSl7dGhpcy5oYXNoVGFibGVOYW1lVG9IYW5kbGVbYWFdPXhhLmhhbmRsZSx0aGlzLmhhc2hUYWJsZU1hcFt4YS5pZF09eGF9Z2V0SGFzaFRhYmxlSGFuZGxlQnlOYW1lKGFhKXtyZXR1cm4gdGhpcy5oYXNoVGFibGVOYW1lVG9IYW5kbGVbYWFdfWdldEhhc2hUYWJsZUJ5SWQoYWEpe3JldHVybiB0aGlzLmhhc2hUYWJsZU1hcFthYV19ZGlzcG9zZSgpe2Zvcihjb25zdCBhYSBpbiB0aGlzLmhhc2hUYWJsZU1hcCl0aGlzLmhhc2hUYWJsZU1hcFthYV0uY2xlYXJBbmRDbG9zZSgpLGRlbGV0ZSB0aGlzLmhhc2hUYWJsZU1hcFthYV07Zm9yKGNvbnN0IGFhIGluIHRoaXMuaGFzaFRhYmxlTmFtZVRvSGFuZGxlKXRoaXMuaGFzaFRhYmxlTmFtZVRvSGFuZGxlW2FhXS5kaXNwb3NlKCksZGVsZXRlIHRoaXMuaGFzaFRhYmxlTmFtZVRvSGFuZGxlW2FhXX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgVEZIVUJfU0VBUkNIX1BBUkFNPSI/dGZqcy1mb3JtYXQ9ZmlsZSIsREVGQVVMVF9NT0RFTF9OQU1FPSJtb2RlbC5qc29uIjtjbGFzcyBHcmFwaE1vZGVse2dldCBtb2RlbFZlcnNpb24oKXtyZXR1cm4gdGhpcy52ZXJzaW9ufWdldCBpbnB1dE5vZGVzKCl7cmV0dXJuIHRoaXMuZXhlY3V0b3IuaW5wdXROb2Rlc31nZXQgb3V0cHV0Tm9kZXMoKXtyZXR1cm4gdGhpcy5leGVjdXRvci5vdXRwdXROb2Rlc31nZXQgaW5wdXRzKCl7cmV0dXJuIHRoaXMuZXhlY3V0b3IuaW5wdXRzfWdldCBvdXRwdXRzKCl7cmV0dXJuIHRoaXMuZXhlY3V0b3Iub3V0cHV0c31nZXQgd2VpZ2h0cygpe3JldHVybiB0aGlzLmV4ZWN1dG9yLndlaWdodE1hcH1nZXQgbWV0YWRhdGEoKXtyZXR1cm4gdGhpcy5hcnRpZmFjdHMudXNlckRlZmluZWRNZXRhZGF0YX1nZXQgbW9kZWxTaWduYXR1cmUoKXtyZXR1cm4gdGhpcy5zaWduYXR1cmV9Z2V0IG1vZGVsU3RydWN0dXJlZE91dHB1dEtleXMoKXtyZXR1cm4gdGhpcy5zdHJ1Y3R1cmVkT3V0cHV0S2V5c31jb25zdHJ1Y3RvcihhYSx4YT17fSxiYT1pbyQxKXt0aGlzLm1vZGVsVXJsPWFhLHRoaXMubG9hZE9wdGlvbnM9eGEsdGhpcy52ZXJzaW9uPSJuL2EiLHRoaXMuaW89YmEseGE9PW51bGwmJih0aGlzLmxvYWRPcHRpb25zPXt9KSx0aGlzLnJlc291cmNlTWFuYWdlcj1uZXcgUmVzb3VyY2VNYW5hZ2VyfWZpbmRJT0hhbmRsZXIoKXtjb25zdCBhYT10aGlzLm1vZGVsVXJsO2lmKGFhLmxvYWQhPW51bGwpdGhpcy5oYW5kbGVyPWFhO2Vsc2UgaWYodGhpcy5sb2FkT3B0aW9ucy5yZXF1ZXN0SW5pdCE9bnVsbCl0aGlzLmhhbmRsZXI9dGhpcy5pby5icm93c2VySFRUUFJlcXVlc3QoYWEsdGhpcy5sb2FkT3B0aW9ucyk7ZWxzZXtjb25zdCB4YT10aGlzLmlvLmdldExvYWRIYW5kbGVycyhhYSx0aGlzLmxvYWRPcHRpb25zKTtpZih4YS5sZW5ndGg9PT0wKXhhLnB1c2godGhpcy5pby5icm93c2VySFRUUFJlcXVlc3QoYWEsdGhpcy5sb2FkT3B0aW9ucykpO2Vsc2UgaWYoeGEubGVuZ3RoPjEpdGhyb3cgbmV3IEVycm9yKGBGb3VuZCBtb3JlIHRoYW4gb25lICgke3hhLmxlbmd0aH0pIGxvYWQgaGFuZGxlcnMgZm9yIFVSTCAnJHtbYWFdfSdgKTt0aGlzLmhhbmRsZXI9eGFbMF19fWxvYWQoKXtpZih0aGlzLmZpbmRJT0hhbmRsZXIoKSx0aGlzLmhhbmRsZXIubG9hZD09bnVsbCl0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBwcm9jZWVkIHdpdGggbW9kZWwgbG9hZGluZyBiZWNhdXNlIHRoZSBJT0hhbmRsZXIgcHJvdmlkZWQgZG9lcyBub3QgaGF2ZSB0aGUgYGxvYWRgIG1ldGhvZCBpbXBsZW1lbnRlZC4iKTtjb25zdCBhYT10aGlzLmhhbmRsZXIubG9hZCgpO3JldHVybiBpc1Byb21pc2UkMShhYSk/YWEudGhlbih4YT0+eGEuZ2V0V2VpZ2h0U3RyZWFtPT1udWxsP3RoaXMubG9hZFN5bmMoeGEpOnRoaXMubG9hZFN0cmVhbWluZyh4YSkpOnRoaXMubG9hZFN5bmMoYWEpfWxvYWRTeW5jKGFhKXtjb25zdCB4YT10aGlzLmlvLmRlY29kZVdlaWdodHMoYWEud2VpZ2h0RGF0YSxhYS53ZWlnaHRTcGVjcyk7cmV0dXJuIHRoaXMubG9hZFdpdGhXZWlnaHRNYXAoYWEseGEpfWFzeW5jIGxvYWRTdHJlYW1pbmcoYWEpe2lmKGFhLmdldFdlaWdodFN0cmVhbT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoIk1vZGVsIGFydGlmYWN0cyBtaXNzaW5nIHN0cmVhbVdlaWdodHMgZnVuY3Rpb24iKTtjb25zdCB4YT1hd2FpdCBkZWNvZGVXZWlnaHRzU3RyZWFtKGFhLmdldFdlaWdodFN0cmVhbSgpLGFhLndlaWdodFNwZWNzKTtyZXR1cm4gdGhpcy5sb2FkV2l0aFdlaWdodE1hcChhYSx4YSl9bG9hZFdpdGhXZWlnaHRNYXAoYWEseGEpe3RoaXMuYXJ0aWZhY3RzPWFhO2NvbnN0IGJhPXRoaXMuYXJ0aWZhY3RzLm1vZGVsVG9wb2xvZ3k7bGV0IFNhPXRoaXMuYXJ0aWZhY3RzLnNpZ25hdHVyZTtpZih0aGlzLmFydGlmYWN0cy51c2VyRGVmaW5lZE1ldGFkYXRhIT1udWxsKXtjb25zdCBUYT10aGlzLmFydGlmYWN0cy51c2VyRGVmaW5lZE1ldGFkYXRhO1RhLnNpZ25hdHVyZSE9bnVsbCYmKFNhPVRhLnNpZ25hdHVyZSksVGEuc3RydWN0dXJlZE91dHB1dEtleXMhPW51bGwmJih0aGlzLnN0cnVjdHVyZWRPdXRwdXRLZXlzPVRhLnN0cnVjdHVyZWRPdXRwdXRLZXlzKX1pZih0aGlzLnNpZ25hdHVyZT1TYSx0aGlzLnZlcnNpb249YCR7YmEudmVyc2lvbnMucHJvZHVjZXJ9LiR7YmEudmVyc2lvbnMubWluQ29uc3VtZXJ9YCx0aGlzLmV4ZWN1dG9yPW5ldyBHcmFwaEV4ZWN1dG9yKE9wZXJhdGlvbk1hcHBlci5JbnN0YW5jZS50cmFuc2Zvcm1HcmFwaChiYSx0aGlzLnNpZ25hdHVyZSkpLHRoaXMuZXhlY3V0b3Iud2VpZ2h0TWFwPXRoaXMuY29udmVydFRlbnNvck1hcFRvVGVuc29yc01hcCh4YSksdGhpcy5leGVjdXRvci5yZXNvdXJjZU1hbmFnZXI9dGhpcy5yZXNvdXJjZU1hbmFnZXIsYWEubW9kZWxJbml0aWFsaXplciE9bnVsbCYmYWEubW9kZWxJbml0aWFsaXplci5ub2RlIT1udWxsKXtjb25zdCBUYT1PcGVyYXRpb25NYXBwZXIuSW5zdGFuY2UudHJhbnNmb3JtR3JhcGgoYWEubW9kZWxJbml0aWFsaXplcik7dGhpcy5pbml0aWFsaXplcj1uZXcgR3JhcGhFeGVjdXRvcihUYSksdGhpcy5pbml0aWFsaXplci53ZWlnaHRNYXA9dGhpcy5leGVjdXRvci53ZWlnaHRNYXAsdGhpcy5pbml0aWFsaXplci5yZXNvdXJjZU1hbmFnZXI9dGhpcy5yZXNvdXJjZU1hbmFnZXIsdGhpcy5pbml0aWFsaXplclNpZ25hdHVyZT1hYS5pbml0aWFsaXplclNpZ25hdHVyZX1yZXR1cm4hMH1hc3luYyBzYXZlKGFhLHhhKXtpZih0eXBlb2YgYWE9PSJzdHJpbmciKXtjb25zdCBiYT10aGlzLmlvLmdldFNhdmVIYW5kbGVycyhhYSk7aWYoYmEubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIGFueSBzYXZlIGhhbmRsZXJzIGZvciBVUkwgJyR7YWF9J2ApO2lmKGJhLmxlbmd0aD4xKXRocm93IG5ldyBFcnJvcihgRm91bmQgbW9yZSB0aGFuIG9uZSAoJHtiYS5sZW5ndGh9KSBzYXZlIGhhbmRsZXJzIGZvciBVUkwgJyR7YWF9J2ApO2FhPWJhWzBdfWlmKGFhLnNhdmU9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJHcmFwaE1vZGVsLnNhdmUoKSBjYW5ub3QgcHJvY2VlZCBiZWNhdXNlIHRoZSBJT0hhbmRsZXIgcHJvdmlkZWQgZG9lcyBub3QgaGF2ZSB0aGUgYHNhdmVgIGF0dHJpYnV0ZSBkZWZpbmVkLiIpO3JldHVybiBhYS5zYXZlKHRoaXMuYXJ0aWZhY3RzKX1hZGRTdHJ1Y3R1cmVkT3V0cHV0TmFtZXMoYWEpe2lmKHRoaXMuc3RydWN0dXJlZE91dHB1dEtleXMpe2NvbnN0IHhhPWFhIGluc3RhbmNlb2YgVGVuc29yJDE/W2FhXTphYSxiYT17fTtyZXR1cm4geGEuZm9yRWFjaCgoU2EsVGEpPT5iYVt0aGlzLnN0cnVjdHVyZWRPdXRwdXRLZXlzW1RhXV09U2EpLGJhfXJldHVybiBhYX1wcmVkaWN0KGFhLHhhKXtjb25zdCBiYT10aGlzLmV4ZWN1dGUoYWEsdGhpcy5vdXRwdXROb2Rlcyk7cmV0dXJuIHRoaXMuYWRkU3RydWN0dXJlZE91dHB1dE5hbWVzKGJhKX1hc3luYyBwcmVkaWN0QXN5bmMoYWEseGEpe2NvbnN0IGJhPWF3YWl0IHRoaXMuZXhlY3V0ZUFzeW5jKGFhLHRoaXMub3V0cHV0Tm9kZXMpO3JldHVybiB0aGlzLmFkZFN0cnVjdHVyZWRPdXRwdXROYW1lcyhiYSl9bm9ybWFsaXplSW5wdXRzKGFhKXt2YXIgeGE7aWYoIShhYSBpbnN0YW5jZW9mIFRlbnNvciQxKSYmIUFycmF5LmlzQXJyYXkoYWEpKXtjb25zdCBUYT0oeGE9dGhpcy5zaWduYXR1cmUpPT09bnVsbHx8eGE9PT12b2lkIDA/dm9pZCAwOnhhLmlucHV0cztpZihUYSE9bnVsbClmb3IoY29uc3Qgd2EgaW4gVGEpe2NvbnN0IEVhPVRhW3dhXTtFYS5yZXNvdXJjZUlkIT1udWxsJiYoYWFbd2FdPXRoaXMucmVzb3VyY2VJZFRvQ2FwdHVyZWRJbnB1dFtFYS5yZXNvdXJjZUlkXSl9cmV0dXJuIGFhfWFhPUFycmF5LmlzQXJyYXkoYWEpP2FhOlthYV07Y29uc3QgYmE9T2JqZWN0LmtleXModGhpcy5yZXNvdXJjZUlkVG9DYXB0dXJlZElucHV0KS5sZW5ndGg7aWYoYWEubGVuZ3RoK2JhIT09dGhpcy5pbnB1dE5vZGVzLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYElucHV0IHRlbnNvciBjb3VudCBtaXNtYXRjaCwgdGhlIGdyYXBoIG1vZGVsIGhhcyAke3RoaXMuaW5wdXROb2Rlcy5sZW5ndGgtYmF9IG5vbi1yZXNvdXJjZSBwbGFjZWhvbGRlcnMsIHdoaWxlIHRoZXJlIGFyZSAke2FhLmxlbmd0aH0gaW5wdXQgdGVuc29ycyBwcm92aWRlZC5gKTtsZXQgU2E9MDtyZXR1cm4gdGhpcy5pbnB1dE5vZGVzLnJlZHVjZSgoVGEsd2EpPT57dmFyIEVhLGthLEFhO2NvbnN0IEZhPShBYT0oa2E9KEVhPXRoaXMuc2lnbmF0dXJlKT09PW51bGx8fEVhPT09dm9pZCAwP3ZvaWQgMDpFYS5pbnB1dHMpPT09bnVsbHx8a2E9PT12b2lkIDA/dm9pZCAwOmthW3dhXSk9PT1udWxsfHxBYT09PXZvaWQgMD92b2lkIDA6QWEucmVzb3VyY2VJZDtyZXR1cm4gRmEhPW51bGw/VGFbd2FdPXRoaXMucmVzb3VyY2VJZFRvQ2FwdHVyZWRJbnB1dFtGYV06VGFbd2FdPWFhW1NhKytdLFRhfSx7fSl9bm9ybWFsaXplT3V0cHV0cyhhYSl7cmV0dXJuIGFhPWFhfHx0aGlzLm91dHB1dE5vZGVzLEFycmF5LmlzQXJyYXkoYWEpP2FhOlthYV19ZXhlY3V0ZUluaXRpYWxpemVyR3JhcGgoKXtyZXR1cm4gdGhpcy5pbml0aWFsaXplcj09bnVsbD9bXTp0aGlzLmluaXRpYWxpemVyU2lnbmF0dXJlPT1udWxsP3RoaXMuaW5pdGlhbGl6ZXIuZXhlY3V0ZSh7fSxbXSk6dGhpcy5pbml0aWFsaXplci5leGVjdXRlKHt9LE9iamVjdC5rZXlzKHRoaXMuaW5pdGlhbGl6ZXJTaWduYXR1cmUub3V0cHV0cykpfWFzeW5jIGV4ZWN1dGVJbml0aWFsaXplckdyYXBoQXN5bmMoKXtyZXR1cm4gdGhpcy5pbml0aWFsaXplcj09bnVsbD9bXTp0aGlzLmluaXRpYWxpemVyU2lnbmF0dXJlPT1udWxsP3RoaXMuaW5pdGlhbGl6ZXIuZXhlY3V0ZUFzeW5jKHt9LFtdKTp0aGlzLmluaXRpYWxpemVyLmV4ZWN1dGVBc3luYyh7fSxPYmplY3Qua2V5cyh0aGlzLmluaXRpYWxpemVyU2lnbmF0dXJlLm91dHB1dHMpKX1zZXRSZXNvdXJjZUlkVG9DYXB0dXJlZElucHV0KGFhKXtpZih0aGlzLnJlc291cmNlSWRUb0NhcHR1cmVkSW5wdXQ9e30sdGhpcy5pbml0aWFsaXplclNpZ25hdHVyZSl7Y29uc3QgeGE9dGhpcy5pbml0aWFsaXplclNpZ25hdHVyZS5vdXRwdXRzLGJhPU9iamVjdC5rZXlzKHhhKTtmb3IobGV0IFNhPTA7U2E8YmEubGVuZ3RoO1NhKyspe2NvbnN0IFRhPWJhW1NhXSx3YT14YVtUYV07dGhpcy5yZXNvdXJjZUlkVG9DYXB0dXJlZElucHV0W3dhLnJlc291cmNlSWRdPWFhW1NhXX19fWV4ZWN1dGUoYWEseGEpe3RoaXMucmVzb3VyY2VJZFRvQ2FwdHVyZWRJbnB1dD09bnVsbCYmdGhpcy5zZXRSZXNvdXJjZUlkVG9DYXB0dXJlZElucHV0KHRoaXMuZXhlY3V0ZUluaXRpYWxpemVyR3JhcGgoKSksYWE9dGhpcy5ub3JtYWxpemVJbnB1dHMoYWEpLHhhPXRoaXMubm9ybWFsaXplT3V0cHV0cyh4YSk7Y29uc3QgYmE9dGhpcy5leGVjdXRvci5leGVjdXRlKGFhLHhhKTtyZXR1cm4gYmEubGVuZ3RoPjE/YmE6YmFbMF19YXN5bmMgZXhlY3V0ZUFzeW5jKGFhLHhhKXt0aGlzLnJlc291cmNlSWRUb0NhcHR1cmVkSW5wdXQ9PW51bGwmJnRoaXMuc2V0UmVzb3VyY2VJZFRvQ2FwdHVyZWRJbnB1dChhd2FpdCB0aGlzLmV4ZWN1dGVJbml0aWFsaXplckdyYXBoQXN5bmMoKSksYWE9dGhpcy5ub3JtYWxpemVJbnB1dHMoYWEpLHhhPXRoaXMubm9ybWFsaXplT3V0cHV0cyh4YSk7Y29uc3QgYmE9YXdhaXQgdGhpcy5leGVjdXRvci5leGVjdXRlQXN5bmMoYWEseGEpO3JldHVybiBiYS5sZW5ndGg+MT9iYTpiYVswXX1nZXRJbnRlcm1lZGlhdGVUZW5zb3JzKCl7cmV0dXJuIHRoaXMuZXhlY3V0b3IuZ2V0SW50ZXJtZWRpYXRlVGVuc29ycygpfWRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JzKCl7dGhpcy5leGVjdXRvci5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ycygpfWNvbnZlcnRUZW5zb3JNYXBUb1RlbnNvcnNNYXAoYWEpe3JldHVybiBPYmplY3Qua2V5cyhhYSkucmVkdWNlKCh4YSxiYSk9Pih4YVtiYV09W2FhW2JhXV0seGEpLHt9KX1kaXNwb3NlKCl7dGhpcy5leGVjdXRvci5kaXNwb3NlKCksdGhpcy5pbml0aWFsaXplciYmKHRoaXMuaW5pdGlhbGl6ZXIuZGlzcG9zZSgpLHRoaXMucmVzb3VyY2VJZFRvQ2FwdHVyZWRJbnB1dCYmZGlzcG9zZSQxKHRoaXMucmVzb3VyY2VJZFRvQ2FwdHVyZWRJbnB1dCkpLHRoaXMucmVzb3VyY2VNYW5hZ2VyLmRpc3Bvc2UoKX19YXN5bmMgZnVuY3Rpb24gbG9hZEdyYXBoTW9kZWwoaGEsYWE9e30seGE9aW8kMSl7aWYoaGE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJtb2RlbFVybCBpbiBsb2FkR3JhcGhNb2RlbCgpIGNhbm5vdCBiZSBudWxsLiBQbGVhc2UgcHJvdmlkZSBhIHVybCBvciBhbiBJT0hhbmRsZXIgdGhhdCBsb2FkcyB0aGUgbW9kZWwiKTthYT09bnVsbCYmKGFhPXt9KSxhYS5mcm9tVEZIdWImJnR5cGVvZiBoYT09InN0cmluZyImJihoYT1nZXRURkh1YlVybChoYSkpO2NvbnN0IGJhPW5ldyBHcmFwaE1vZGVsKGhhLGFhLHhhKTtyZXR1cm4gYXdhaXQgYmEubG9hZCgpLGJhfWZ1bmN0aW9uIGdldFRGSHViVXJsKGhhKXtyZXR1cm4gaGEuZW5kc1dpdGgoIi8iKXx8KGhhPWhhKyIvIiksYCR7aGF9JHtERUZBVUxUX01PREVMX05BTUV9JHtURkhVQl9TRUFSQ0hfUEFSQU19YH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi92YXIgWmlwTWlzbWF0Y2hNb2RlOyhmdW5jdGlvbihoYSl7aGFbaGEuRkFJTD0wXT0iRkFJTCIsaGFbaGEuU0hPUlRFU1Q9MV09IlNIT1JURVNUIixoYVtoYS5MT05HRVNUPTJdPSJMT05HRVNUIn0pKFppcE1pc21hdGNoTW9kZXx8KFppcE1pc21hdGNoTW9kZT17fSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFzc2VydE5vdENvbXBsZXgkMihoYSxhYSl7QXJyYXkuaXNBcnJheShoYSl8fChoYT1baGFdKSxoYS5mb3JFYWNoKHhhPT57eGEhPW51bGwmJmFzc2VydCQyKHhhLmR0eXBlIT09ImNvbXBsZXg2NCIsKCk9PmAke2FhfSBkb2VzIG5vdCBzdXBwb3J0IGNvbXBsZXg2NCB0ZW5zb3JzIGluIHRoZSBDUFUgYmFja2VuZC5gKX0pfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHdoZXJlSW1wbCQzPXdoZXJlSW1wbCQ0O2NsYXNzIE1hdGhCYWNrZW5kQ1BVIGV4dGVuZHMgS2VybmVsQmFja2VuZCQxe25leHREYXRhSWQoKXtyZXR1cm4gTWF0aEJhY2tlbmRDUFUubmV4dERhdGFJZCsrfWNvbnN0cnVjdG9yKCl7c3VwZXIoKSx0aGlzLmJsb2NrU2l6ZT00OCx0aGlzLmZpcnN0VXNlPSEwLHRoaXMuZGF0YT1uZXcgRGF0YVN0b3JhZ2UkMSh0aGlzLGVuZ2luZSQxKCkpfXdyaXRlKGFhLHhhLGJhKXt0aGlzLmZpcnN0VXNlJiYodGhpcy5maXJzdFVzZT0hMSxlbnYkMSgpLmdldCgiSVNfTk9ERSIpJiZ3YXJuJDEoYAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09CkhpLCBsb29rcyBsaWtlIHlvdSBhcmUgcnVubmluZyBUZW5zb3JGbG93LmpzIGluIE5vZGUuanMuIFRvIHNwZWVkIHRoaW5ncyB1cCBkcmFtYXRpY2FsbHksIGluc3RhbGwgb3VyIG5vZGUgYmFja2VuZCwgdmlzaXQgaHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvdGZqcy1ub2RlIGZvciBtb3JlIGRldGFpbHMuIAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09YCkpO2NvbnN0IFNhPXtpZDp0aGlzLm5leHREYXRhSWQoKX07cmV0dXJuIHRoaXMuZGF0YS5zZXQoU2Ese3ZhbHVlczphYSxkdHlwZTpiYSxyZWZDb3VudDoxfSksU2F9bWFrZVRlbnNvckluZm8oYWEseGEsYmEpe2xldCBTYTtpZih4YT09PSJzdHJpbmciJiZiYSE9bnVsbCYmYmEubGVuZ3RoPjAmJmlzU3RyaW5nJDEoYmFbMF0pKXtjb25zdCBUYT1iYS5tYXAod2E9PmVuY29kZVN0cmluZyQxKHdhKSk7U2E9dGhpcy53cml0ZShUYSxhYSx4YSl9ZWxzZSBTYT10aGlzLndyaXRlKGJhLGFhLHhhKTtyZXR1cm57ZGF0YUlkOlNhLHNoYXBlOmFhLGR0eXBlOnhhfX1yZWZDb3VudChhYSl7cmV0dXJuIHRoaXMuZGF0YS5oYXMoYWEpP3RoaXMuZGF0YS5nZXQoYWEpLnJlZkNvdW50OjB9aW5jUmVmKGFhKXtjb25zdCB4YT10aGlzLmRhdGEuZ2V0KGFhKTt4YS5yZWZDb3VudCsrfWRlY1JlZihhYSl7aWYodGhpcy5kYXRhLmhhcyhhYSkpe2NvbnN0IHhhPXRoaXMuZGF0YS5nZXQoYWEpO3hhLnJlZkNvdW50LS19fW1vdmUoYWEseGEsYmEsU2EsVGEpe3RoaXMuZGF0YS5zZXQoYWEse3ZhbHVlczp4YSxkdHlwZTpTYSxyZWZDb3VudDpUYX0pfW51bURhdGFJZHMoKXtyZXR1cm4gdGhpcy5kYXRhLm51bURhdGFJZHMoKX1hc3luYyByZWFkKGFhKXtyZXR1cm4gdGhpcy5yZWFkU3luYyhhYSl9cmVhZFN5bmMoYWEpe2NvbnN0e2R0eXBlOnhhLGNvbXBsZXhUZW5zb3JJbmZvczpiYX09dGhpcy5kYXRhLmdldChhYSk7aWYoeGE9PT0iY29tcGxleDY0Iil7Y29uc3QgU2E9dGhpcy5yZWFkU3luYyhiYS5yZWFsLmRhdGFJZCksVGE9dGhpcy5yZWFkU3luYyhiYS5pbWFnLmRhdGFJZCk7cmV0dXJuIG1lcmdlUmVhbEFuZEltYWdBcnJheXMkMShTYSxUYSl9cmV0dXJuIGNvbnZlcnRCYWNrZW5kVmFsdWVzQW5kQXJyYXlCdWZmZXIodGhpcy5kYXRhLmdldChhYSkudmFsdWVzLHhhKX1idWZmZXJTeW5jKGFhKXtjb25zdCB4YT10aGlzLnJlYWRTeW5jKGFhLmRhdGFJZCk7aWYoYWEuZHR5cGU9PT0ic3RyaW5nIil0cnl7Y29uc3QgYmE9eGEubWFwKFNhPT5kZWNvZGVTdHJpbmckMShTYSkpO3JldHVybiBidWZmZXIkMShhYS5zaGFwZSxhYS5kdHlwZSxiYSl9Y2F0Y2h7dGhyb3cgbmV3IEVycm9yKCJGYWlsZWQgdG8gZGVjb2RlIGVuY29kZWQgc3RyaW5nIGJ5dGVzIGludG8gdXRmLTgiKX1yZXR1cm4gYnVmZmVyJDEoYWEuc2hhcGUsYWEuZHR5cGUseGEpfW1ha2VPdXRwdXQoYWEseGEsYmEpe3JldHVybiBlbmdpbmUkMSgpLm1ha2VUZW5zb3JGcm9tVGVuc29ySW5mbyh0aGlzLm1ha2VUZW5zb3JJbmZvKHhhLGJhLGFhKSx0aGlzKX1kaXNwb3NlRGF0YShhYSx4YT0hMSl7aWYodGhpcy5kYXRhLmhhcyhhYSkpe2lmKHRoaXMuZGF0YS5nZXQoYWEpLnJlZkNvdW50LS0sIXhhJiZ0aGlzLmRhdGEuZ2V0KGFhKS5yZWZDb3VudD4wKXJldHVybiExO2NvbnN0e2NvbXBsZXhUZW5zb3JJbmZvczpiYX09dGhpcy5kYXRhLmdldChhYSk7YmEhPW51bGwmJih0aGlzLmRpc3Bvc2VEYXRhKGJhLnJlYWwuZGF0YUlkLCEwKSx0aGlzLmRpc3Bvc2VEYXRhKGJhLmltYWcuZGF0YUlkLCEwKSksdGhpcy5kYXRhLmRlbGV0ZShhYSl9cmV0dXJuITB9ZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWEpe3RoaXMuZGlzcG9zZURhdGEoYWEuZGF0YUlkKX1hc3luYyB0aW1lKGFhKXtjb25zdCB4YT1ub3ckMSgpO3JldHVybiBhYSgpLHtrZXJuZWxNczpub3ckMSgpLXhhfX1tZW1vcnkoKXtyZXR1cm57dW5yZWxpYWJsZTohMCxyZWFzb25zOlsiVGhlIHJlcG9ydGVkIG1lbW9yeSBpcyBhbiB1cHBlciBib3VuZC4gRHVlIHRvIGF1dG9tYXRpYyBnYXJiYWdlIGNvbGxlY3Rpb24sIHRoZSB0cnVlIGFsbG9jYXRlZCBtZW1vcnkgbWF5IGJlIGxlc3MuIl19fXdoZXJlKGFhKXthc3NlcnROb3RDb21wbGV4JDIoW2FhXSwid2hlcmUiKTtjb25zdCB4YT10aGlzLnJlYWRTeW5jKGFhLmRhdGFJZCk7cmV0dXJuIHdoZXJlSW1wbCQzKGFhLnNoYXBlLHhhKX1kaXNwb3NlKCl7fWZsb2F0UHJlY2lzaW9uKCl7cmV0dXJuIDMyfWVwc2lsb24oKXtyZXR1cm4gc3VwZXIuZXBzaWxvbigpfX1NYXRoQmFja2VuZENQVS5uZXh0RGF0YUlkPTA7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzaW1wbGVBYnNJbXBsJDEoaGEpe2NvbnN0IGFhPW5ldyBGbG9hdDMyQXJyYXkoaGEubGVuZ3RoKTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoOysreGEpYWFbeGFdPU1hdGguYWJzKGhhW3hhXSk7cmV0dXJuIGFhfWNvbnN0IGFicyQzPWhhPT57Y29uc3R7eDphYX09aGEuaW5wdXRzLHhhPWhhLmJhY2tlbmQ7YXNzZXJ0Tm90Q29tcGxleCQyKGFhLCJhYnMiKTtsZXQgYmE9bmV3IEZsb2F0MzJBcnJheShzaXplRnJvbVNoYXBlJDEoYWEuc2hhcGUpKTtjb25zdCBTYT14YS5kYXRhLmdldChhYS5kYXRhSWQpLnZhbHVlcztyZXR1cm4gYmE9c2ltcGxlQWJzSW1wbCQxKFNhKSx4YS5tYWtlT3V0cHV0KGJhLGFhLnNoYXBlLGFhLmR0eXBlKX0sYWJzQ29uZmlnJDI9e2tlcm5lbE5hbWU6QWJzJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphYnMkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKGhhKXtyZXR1cm4oYWEseGEsYmEsU2EsVGEpPT57Y29uc3Qgd2E9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShhYSx4YSksRWE9d2EubGVuZ3RoLGthPWNvbXB1dGVTdHJpZGVzJDEod2EpLEFhPXNpemVGcm9tU2hhcGUkMSh3YSksRmE9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKFRhLEFhKSxMYT1hYS5sZW5ndGgsZWw9eGEubGVuZ3RoLHRsPWNvbXB1dGVTdHJpZGVzJDEoYWEpLG5sPWNvbXB1dGVTdHJpZGVzJDEoeGEpLHNsPWdldEJyb2FkY2FzdERpbXMkMyhhYSx3YSkscmw9Z2V0QnJvYWRjYXN0RGltcyQzKHhhLHdhKTtpZihzbC5sZW5ndGgrcmwubGVuZ3RoPT09MClmb3IobGV0IG9sPTA7b2w8RmEubGVuZ3RoOysrb2wpRmFbb2xdPWhhKGJhW29sJWJhLmxlbmd0aF0sU2Fbb2wlU2EubGVuZ3RoXSk7ZWxzZSBmb3IobGV0IG9sPTA7b2w8RmEubGVuZ3RoOysrb2wpe2NvbnN0IGFsPWluZGV4VG9Mb2MkMShvbCxFYSxrYSksbGw9YWwuc2xpY2UoLUxhKTtzbC5mb3JFYWNoKGRsPT5sbFtkbF09MCk7Y29uc3QgaWw9bG9jVG9JbmRleCQxKGxsLExhLHRsKSxjbD1hbC5zbGljZSgtZWwpO3JsLmZvckVhY2goZGw9PmNsW2RsXT0wKTtjb25zdCB1bD1sb2NUb0luZGV4JDEoY2wsZWwsbmwpO0ZhW29sXT1oYShiYVtpbF0sU2FbdWxdKX1yZXR1cm5bRmEsd2FdfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb21wbGV4JDMoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7cmVhbDpiYSxpbWFnOlNhfT1hYSxUYT14YS5kYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcyx3YT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxFYT14YS5tYWtlVGVuc29ySW5mbyhiYS5zaGFwZSwiY29tcGxleDY0Iiksa2E9eGEuZGF0YS5nZXQoRWEuZGF0YUlkKTtyZXR1cm4ga2EuY29tcGxleFRlbnNvckluZm9zPXtyZWFsOnhhLm1ha2VUZW5zb3JJbmZvKGJhLnNoYXBlLCJmbG9hdDMyIixUYSksaW1hZzp4YS5tYWtlVGVuc29ySW5mbyhTYS5zaGFwZSwiZmxvYXQzMiIsd2EpfSxFYX1jb25zdCBjb21wbGV4Q29uZmlnJDI9e2tlcm5lbE5hbWU6Q29tcGxleCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Y29tcGxleCQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB6ZXJvcyQxKGhhLGFhLHhhPSJmbG9hdDMyIil7aWYoeGE9PT0iY29tcGxleDY0Iil7Y29uc3QgU2E9emVyb3MkMShoYSxhYSwiZmxvYXQzMiIpLFRhPXplcm9zJDEoaGEsYWEsImZsb2F0MzIiKTtyZXR1cm4gY29tcGxleCQzKHtpbnB1dHM6e3JlYWw6U2EsaW1hZzpUYX0sYmFja2VuZDpoYX0pfWNvbnN0IGJhPW1ha2VaZXJvc1R5cGVkQXJyYXkkMShzaXplRnJvbVNoYXBlJDEoYWEpLHhhKTtyZXR1cm4gaGEubWFrZVRlbnNvckluZm8oYWEseGEsYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGlkZW50aXR5JDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWE7cmV0dXJuIHhhLmluY1JlZihiYS5kYXRhSWQpLHtkYXRhSWQ6YmEuZGF0YUlkLHNoYXBlOmJhLnNoYXBlLGR0eXBlOmJhLmR0eXBlfX1jb25zdCBpZGVudGl0eUNvbmZpZyQyPXtrZXJuZWxOYW1lOklkZW50aXR5JDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzppZGVudGl0eSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZWFsJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7aW5wdXQ6YmF9PWFhLFNhPXhhLmRhdGEuZ2V0KGJhLmRhdGFJZCkuY29tcGxleFRlbnNvckluZm9zLnJlYWwsVGE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXM7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFNhLnNoYXBlLFNhLmR0eXBlLFRhKX1jb25zdCByZWFsQ29uZmlnJDI9e2tlcm5lbE5hbWU6UmVhbCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cmVhbCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjYXN0SW1wbCQxKGhhLGFhLHhhLGJhKXtpZihiYT09PSJpbnQzMiIpe2NvbnN0IFNhPUludDMyQXJyYXkuZnJvbShoYSk7cmV0dXJuW2FhLCJpbnQzMiIsU2FdfWlmKGJhPT09ImJvb2wiKXtjb25zdCBTYT10b1R5cGVkQXJyYXkkMShbMF0seGEpLFtUYSx3YV09Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChFYSxrYSk9PkVhIT09a2E/MTowKShhYSxbXSxoYSxTYSwiYm9vbCIpO3JldHVyblt3YSwiYm9vbCIsVGFdfXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gQ2FzdDogZmFpbGVkIHRvIGNhc3QgJHt4YX0gdG8gJHtiYX1gKX1mdW5jdGlvbiBjYXN0JDMoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2R0eXBlOlRhfT1iYTtpZihUYT09PSJjb21wbGV4NjQiKXtpZihTYS5kdHlwZT09PSJjb21wbGV4NjQiKXJldHVybiBpZGVudGl0eSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtjb25zdCBGYT16ZXJvcyQxKHhhLFNhLnNoYXBlLFNhLmR0eXBlKSxMYT1jYXN0JDMoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7ZHR5cGU6ImZsb2F0MzIifX0pLGVsPWNvbXBsZXgkMyh7aW5wdXRzOntyZWFsOkxhLGltYWc6RmF9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKExhKSxlbH1pZihTYS5kdHlwZT09PSJjb21wbGV4NjQiKXtjb25zdCBGYT1yZWFsJDIoe2lucHV0czp7aW5wdXQ6U2F9LGJhY2tlbmQ6eGF9KSxMYT1jYXN0JDMoe2lucHV0czp7eDpGYX0sYmFja2VuZDp4YSxhdHRyczp7ZHR5cGU6VGF9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKSxMYX1pZighaGFzRW5jb2RpbmdMb3NzJDEoU2EuZHR5cGUsVGEpKXtjb25zdCBGYT1pZGVudGl0eSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtyZXR1cm57ZGF0YUlkOkZhLmRhdGFJZCxzaGFwZTpGYS5zaGFwZSxkdHlwZTpUYX19Y29uc3Qgd2E9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsW0VhLGthLEFhXT1jYXN0SW1wbCQxKHdhLFNhLnNoYXBlLFNhLmR0eXBlLFRhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRWEsa2EsQWEpfWNvbnN0IGNhc3RDb25maWckMj17a2VybmVsTmFtZTpDYXN0JDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpjYXN0JDN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJpbmFyeUtlcm5lbEZ1bmMkMihoYSxhYSx4YSxiYSl7cmV0dXJuIHhhPT1udWxsPyh7aW5wdXRzOlNhLGJhY2tlbmQ6VGF9KT0+e2NvbnN0e2E6d2EsYjpFYX09U2Esa2E9VGE7YXNzZXJ0Tm90Q29tcGxleCQyKFt3YSxFYV0saGEpO2NvbnN0IEFhPWthLmRhdGEuZ2V0KHdhLmRhdGFJZCkudmFsdWVzLEZhPWthLmRhdGEuZ2V0KEVhLmRhdGFJZCkudmFsdWVzLExhPXdhLmR0eXBlPT09InN0cmluZyI/ZnJvbVVpbnQ4VG9TdHJpbmdBcnJheSQxKEFhKTpBYSxlbD13YS5kdHlwZT09PSJzdHJpbmciP2Zyb21VaW50OFRvU3RyaW5nQXJyYXkkMShGYSk6RmEsdGw9YmF8fHdhLmR0eXBlLFtubCxzbF09YWEod2Euc2hhcGUsRWEuc2hhcGUsTGEsZWwsdGwpO3JldHVybiBrYS5tYWtlVGVuc29ySW5mbyhzbCx0bCxubCl9Oih7aW5wdXRzOlNhLGJhY2tlbmQ6VGF9KT0+e2NvbnN0e2E6d2EsYjpFYX09U2Esa2E9VGE7aWYod2EuZHR5cGU9PT0iY29tcGxleDY0Inx8RWEuZHR5cGU9PT0iY29tcGxleDY0Iil7Y29uc3QgQWE9Y2FzdCQzKHtpbnB1dHM6e3g6d2F9LGJhY2tlbmQ6a2EsYXR0cnM6e2R0eXBlOiJjb21wbGV4NjQifX0pLEZhPWthLmRhdGEuZ2V0KEFhLmRhdGFJZCksTGE9RmEuY29tcGxleFRlbnNvckluZm9zLnJlYWwsZWw9RmEuY29tcGxleFRlbnNvckluZm9zLmltYWcsdGw9a2EuZGF0YS5nZXQoTGEuZGF0YUlkKS52YWx1ZXMsbmw9a2EuZGF0YS5nZXQoZWwuZGF0YUlkKS52YWx1ZXMsc2w9Y2FzdCQzKHtpbnB1dHM6e3g6RWF9LGJhY2tlbmQ6a2EsYXR0cnM6e2R0eXBlOiJjb21wbGV4NjQifX0pLHJsPWthLmRhdGEuZ2V0KHNsLmRhdGFJZCksb2w9cmwuY29tcGxleFRlbnNvckluZm9zLnJlYWwsYWw9cmwuY29tcGxleFRlbnNvckluZm9zLmltYWcsbGw9a2EuZGF0YS5nZXQob2wuZGF0YUlkKS52YWx1ZXMsaWw9a2EuZGF0YS5nZXQoYWwuZGF0YUlkKS52YWx1ZXMsW2NsLHVsLGRsXT14YSh3YS5zaGFwZSxFYS5zaGFwZSx0bCxubCxsbCxpbCksaGw9a2EubWFrZVRlbnNvckluZm8oZGwsImZsb2F0MzIiLGNsKSxwbD1rYS5tYWtlVGVuc29ySW5mbyhkbCwiZmxvYXQzMiIsdWwpLGZsPWNvbXBsZXgkMyh7aW5wdXRzOntyZWFsOmhsLGltYWc6cGx9LGJhY2tlbmQ6a2F9KTtyZXR1cm4ga2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oQWEpLGthLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSxrYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhobCksa2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocGwpLGZsfWVsc2V7Y29uc3QgQWE9a2EuZGF0YS5nZXQod2EuZGF0YUlkKS52YWx1ZXMsRmE9a2EuZGF0YS5nZXQoRWEuZGF0YUlkKS52YWx1ZXMsTGE9YmF8fHdhLmR0eXBlLFtlbCx0bF09YWEod2Euc2hhcGUsRWEuc2hhcGUsQWEsRmEsTGEpO3JldHVybiBrYS5tYWtlVGVuc29ySW5mbyh0bCxMYSxlbCl9fX1mdW5jdGlvbiBjcmVhdGVDb21wbGV4QmluYXJ5S2VybmVsSW1wbChoYSl7cmV0dXJuKGFhLHhhLGJhLFNhLFRhLHdhKT0+e2NvbnN0IEVhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoYWEseGEpLGthPXNpemVGcm9tU2hhcGUkMShFYSksQWE9RWEubGVuZ3RoLEZhPWNvbXB1dGVTdHJpZGVzJDEoRWEpLExhPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMSgiZmxvYXQzMiIsa2EpLGVsPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMSgiZmxvYXQzMiIsa2EpLHRsPWdldEJyb2FkY2FzdERpbXMkMyhhYSxFYSksbmw9Z2V0QnJvYWRjYXN0RGltcyQzKHhhLEVhKSxzbD1tZXJnZVJlYWxBbmRJbWFnQXJyYXlzJDEoYmEsU2EpLHJsPW1lcmdlUmVhbEFuZEltYWdBcnJheXMkMShUYSx3YSksb2w9YWEubGVuZ3RoLGFsPWNvbXB1dGVTdHJpZGVzJDEoYWEpLGxsPXhhLmxlbmd0aCxpbD1jb21wdXRlU3RyaWRlcyQxKHhhKTtpZih0bC5sZW5ndGgrbmwubGVuZ3RoPT09MClmb3IobGV0IGNsPTA7Y2w8TGEubGVuZ3RoO2NsKyspe2NvbnN0IHVsPWNsJXNsLmxlbmd0aCxkbD1jbCVybC5sZW5ndGgsaGw9aGEoc2xbdWwqMl0sc2xbdWwqMisxXSxybFtkbCoyXSxybFtkbCoyKzFdKTtMYVtjbF09aGwucmVhbCxlbFtjbF09aGwuaW1hZ31lbHNlIGZvcihsZXQgY2w9MDtjbDxMYS5sZW5ndGg7Y2wrKyl7Y29uc3QgdWw9aW5kZXhUb0xvYyQxKGNsLEFhLEZhKSxkbD11bC5zbGljZSgtb2wpO3RsLmZvckVhY2goZ2w9PmRsW2dsXT0wKTtjb25zdCBobD1sb2NUb0luZGV4JDEoZGwsb2wsYWwpLHBsPXVsLnNsaWNlKC1sbCk7bmwuZm9yRWFjaChnbD0+cGxbZ2xdPTApO2NvbnN0IGZsPWxvY1RvSW5kZXgkMShwbCxsbCxpbCksbWw9aGEoc2xbaGwqMl0sc2xbaGwqMisxXSxybFtmbCoyXSxybFtmbCoyKzFdKTtMYVtjbF09bWwucmVhbCxlbFtjbF09bWwuaW1hZ31yZXR1cm5bTGEsZWwsRWFdfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhZGRJbXBsJDE9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9PmhhK2FhKSxhZGRDb21wbGV4SW1wbD1jcmVhdGVDb21wbGV4QmluYXJ5S2VybmVsSW1wbCgoaGEsYWEseGEsYmEpPT4oe3JlYWw6aGEreGEsaW1hZzphYStiYX0pKSxhZGQkMj1iaW5hcnlLZXJuZWxGdW5jJDIoQWRkJDIsYWRkSW1wbCQxLGFkZENvbXBsZXhJbXBsKSxhZGRDb25maWckMj17a2VybmVsTmFtZTpBZGQkMixiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmFkZCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiaW5jb3VudEltcGwkMShoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9c2l6ZUZyb21TaGFwZSQxKGJhKSx3YT1tYWtlWmVyb3NUeXBlZEFycmF5JDEoU2EseGEpO2ZvcihsZXQgRWE9MDtFYTxoYS5sZW5ndGg7RWErKyl7Y29uc3Qga2E9aGFbRWFdO2lmKGthPDApdGhyb3cgbmV3IEVycm9yKCJJbnB1dCB4IG11c3QgYmUgbm9uLW5lZ2F0aXZlISIpO2thPj1TYXx8KFRhPjA/d2Fba2FdKz1hYVtFYV06d2Fba2FdKz0xKX1yZXR1cm4gd2F9ZnVuY3Rpb24gYmluY291bnRSZWR1Y2VJbXBsJDEoaGEsYWEseGEsYmE9ITEpe2NvbnN0IFNhPWhhLnNoYXBlWzBdLFRhPWhhLnNoYXBlWzFdLHdhPWJ1ZmZlciQxKFtTYSx4YV0sYWEuZHR5cGUpO2ZvcihsZXQgRWE9MDtFYTxTYTtFYSsrKWZvcihsZXQga2E9MDtrYTxUYTtrYSsrKXtjb25zdCBBYT1oYS5nZXQoRWEsa2EpO2lmKEFhPDApdGhyb3cgbmV3IEVycm9yKCJJbnB1dCB4IG11c3QgYmUgbm9uLW5lZ2F0aXZlISIpO0FhPj14YXx8KGJhP3dhLnNldCgxLEVhLEFhKTphYS5zaXplPjA/d2Euc2V0KHdhLmdldChFYSxBYSkrYWEuZ2V0KEVhLGthKSxFYSxBYSk6d2Euc2V0KHdhLmdldChFYSxBYSkrMSxFYSxBYSkpfXJldHVybiB3YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBiaXR3aXNlQW5kSW1wbCQxPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYSZhYSksYml0d2lzZUFuZCQyPWJpbmFyeUtlcm5lbEZ1bmMkMihCaXR3aXNlQW5kJDEsYml0d2lzZUFuZEltcGwkMSksYml0d2lzZUFuZENvbmZpZyQyPXtrZXJuZWxOYW1lOkJpdHdpc2VBbmQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmJpdHdpc2VBbmQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY3JlYXRlU2ltcGxlVW5hcnlJbXBsJDEoaGEpe3JldHVybihhYSx4YSxiYSk9Pntjb25zdCBTYT1nZXRBcnJheUZyb21EVHlwZSQxKHhhLGFhLmxlbmd0aCk7Zm9yKGxldCBUYT0wO1RhPGFhLmxlbmd0aDsrK1RhKVNhW1RhXT1oYShhYVtUYV0sYmEpO3JldHVybiBTYX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5hcnlLZXJuZWxGdW5jJDIoaGEsYWEseGEpe2NvbnN0IGJhPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbCQxKGFhKTtyZXR1cm4gdW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoaGEsYmEseGEpfWZ1bmN0aW9uIHVuYXJ5S2VybmVsRnVuY0Zyb21JbXBsKGhhLGFhLHhhKXtyZXR1cm4oe2lucHV0czpiYSxhdHRyczpTYSxiYWNrZW5kOlRhfSk9Pntjb25zdHt4OndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIod2EsaGEpO2NvbnN0IEVhPVRhLGthPUVhLmRhdGEuZ2V0KHdhLmRhdGFJZCkudmFsdWVzO2xldCBBYTtpZih3YS5kdHlwZT09PSJzdHJpbmciKXtpZighQXJyYXkuaXNBcnJheShrYSkpdGhyb3cgbmV3IEVycm9yKCJTdHJpbmcgdGVuc29yJ3MgdmFsdWUgd2FzIG5vdCBhbiBpbnN0YW5jZSBvZiBBcnJheSIpO0FhPWZyb21VaW50OFRvU3RyaW5nQXJyYXkkMShrYSl9ZWxzZSBBYT1rYTtjb25zdCBGYT14YXx8d2EuZHR5cGUsTGE9YWEoQWEsRmEsU2EpO3JldHVybiBFYS5tYWtlVGVuc29ySW5mbyh3YS5zaGFwZSxGYSxMYSl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgY2VpbEltcGwkMT1jcmVhdGVTaW1wbGVVbmFyeUltcGwkMShoYT0+TWF0aC5jZWlsKGhhKSksY2VpbCQyPXVuYXJ5S2VybmVsRnVuY0Zyb21JbXBsKENlaWwkMSxjZWlsSW1wbCQxKSxjZWlsQ29uZmlnJDI9e2tlcm5lbE5hbWU6Q2VpbCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Y2VpbCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb25jYXRJbXBsJDMoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWdldEFycmF5RnJvbURUeXBlJDEoeGEsc2l6ZUZyb21TaGFwZSQxKGFhKSk7aWYoYmEmJnhhIT09InN0cmluZyIpe2xldCBUYT0wO2hhLmZvckVhY2god2E9Pntjb25zdCBFYT1zaXplRnJvbVNoYXBlJDEod2Euc2hhcGUpO1NhLnNldCh3YS52YWxzLFRhKSxUYSs9RWF9KX1lbHNle2xldCBUYT0wO2hhLmZvckVhY2god2E9Pntjb25zdCBFYT14YT09PSJzdHJpbmciP2Zyb21VaW50OFRvU3RyaW5nQXJyYXkkMSh3YS52YWxzKTp3YS52YWxzO2xldCBrYT0wO2ZvcihsZXQgQWE9MDtBYTx3YS5zaGFwZVswXTsrK0FhKXtjb25zdCBGYT1BYSphYVsxXStUYTtmb3IobGV0IExhPTA7TGE8d2Euc2hhcGVbMV07KytMYSlTYVtGYStMYV09RWFba2ErK119VGErPXdhLnNoYXBlWzFdfSl9cmV0dXJuIFNhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGVxdWFsSW1wbCQxPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYT09PWFhPzE6MCksZXF1YWwkMj1iaW5hcnlLZXJuZWxGdW5jJDIoRXF1YWwkMSxlcXVhbEltcGwkMSxudWxsLCJib29sIiksZXF1YWxDb25maWckMj17a2VybmVsTmFtZTpFcXVhbCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZXF1YWwkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleHBJbXBsJDE9Y3JlYXRlU2ltcGxlVW5hcnlJbXBsJDEoaGE9Pk1hdGguZXhwKGhhKSksZXhwJDI9dW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoRXhwJDEsZXhwSW1wbCQxLCJmbG9hdDMyIiksZXhwQ29uZmlnJDI9e2tlcm5lbE5hbWU6RXhwJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpleHAkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBleHBtMUltcGwkMT1jcmVhdGVTaW1wbGVVbmFyeUltcGwkMShoYT0+TWF0aC5leHBtMShoYSkpLGV4cG0xJDI9dW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoRXhwbTEkMSxleHBtMUltcGwkMSksZXhwbTFDb25maWckMj17a2VybmVsTmFtZTpFeHBtMSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZXhwbTEkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBmbG9vckltcGwkMT1jcmVhdGVTaW1wbGVVbmFyeUltcGwkMShoYT0+TWF0aC5mbG9vcihoYSkpLGZsb29yJDI9dW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoRmxvb3IkMSxmbG9vckltcGwkMSksZmxvb3JDb25maWckMj17a2VybmVsTmFtZTpGbG9vciQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Zmxvb3IkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZmxvb3JEaXZJbXBsJDE9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9Pk1hdGguZmxvb3IoaGEvYWEpKSxmbG9vckRpdiQzPWJpbmFyeUtlcm5lbEZ1bmMkMihGbG9vckRpdiQxLGZsb29yRGl2SW1wbCQxLG51bGwsImludDMyIiksZmxvb3JEaXZDb25maWckMj17a2VybmVsTmFtZTpGbG9vckRpdiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Zmxvb3JEaXYkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2F0aGVyTmRJbXBsJDEoaGEsYWEseGEsYmEsU2EsVGEsd2EsRWEsa2Epe2NvbnN0IEFhPWJ1ZmZlciQxKFtiYSxUYV0seGEpO2ZvcihsZXQgRmE9MDtGYTxiYTtGYSsrKXtjb25zdCBMYT1bXTtsZXQgZWw9MDtmb3IobGV0IHRsPTA7dGw8U2E7dGwrKyl7Y29uc3Qgbmw9aGFbRmEqU2ErdGxdO2VsKz1ubCp3YVt0bF0sTGEucHVzaChubCl9aWYoZWw8MHx8ZWw+PWthL1RhKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbmRpY2VzOiAke0xhfSBkb2VzIG5vdCBpbmRleCBpbnRvICR7RWF9YCk7Zm9yKGxldCB0bD0wO3RsPFRhO3RsKyspQWEudmFsdWVzW0ZhKlRhK3RsXT1hYS5nZXQoLi4uYWEuaW5kZXhUb0xvYyhlbCpUYSt0bCkpfXJldHVybiBBYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnYXRoZXJWMkltcGwkMShoYSxhYSx4YSl7Y29uc3QgYmE9YnVmZmVyJDEoeGEsaGEuZHR5cGUpO2ZvcihsZXQgU2E9MDtTYTxiYS5zaXplOysrU2Epe2NvbnN0IHdhPWJhLmluZGV4VG9Mb2MoU2EpLnNsaWNlKCksRWE9d2FbMF0sa2E9d2FbMl0sQWE9YWEubG9jVG9JbmRleChbRWEsa2FdKTt3YVsyXT1hYS52YWx1ZXNbQWFdO2NvbnN0IEZhPWhhLmxvY1RvSW5kZXgod2EpOzA8PUZhJiZGYTxoYS52YWx1ZXMubGVuZ3RoJiYoYmEudmFsdWVzW1NhXT1oYS52YWx1ZXNbRmFdKX1yZXR1cm4gYmF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZ3JlYXRlckltcGwkMT1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsJDEoKGhhLGFhKT0+aGE+YWE/MTowKSxncmVhdGVyJDI9YmluYXJ5S2VybmVsRnVuYyQyKEdyZWF0ZXIkMSxncmVhdGVySW1wbCQxLG51bGwsImJvb2wiKSxncmVhdGVyQ29uZmlnJDI9e2tlcm5lbE5hbWU6R3JlYXRlciQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Z3JlYXRlciQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBncmVhdGVyRXF1YWxJbXBsJDE9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9PmhhPj1hYT8xOjApLGdyZWF0ZXJFcXVhbCQyPWJpbmFyeUtlcm5lbEZ1bmMkMihHcmVhdGVyRXF1YWwkMSxncmVhdGVyRXF1YWxJbXBsJDEsbnVsbCwiYm9vbCIpLGdyZWF0ZXJFcXVhbENvbmZpZyQyPXtrZXJuZWxOYW1lOkdyZWF0ZXJFcXVhbCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Z3JlYXRlckVxdWFsJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGxlc3NJbXBsJDE9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9PmhhPGFhPzE6MCksbGVzcyQyPWJpbmFyeUtlcm5lbEZ1bmMkMihMZXNzJDEsbGVzc0ltcGwkMSxudWxsLCJib29sIiksbGVzc0NvbmZpZyQyPXtrZXJuZWxOYW1lOkxlc3MkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxlc3MkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbGVzc0VxdWFsSW1wbCQxPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYTw9YWE/MTowKSxsZXNzRXF1YWwkMj1iaW5hcnlLZXJuZWxGdW5jJDIoTGVzc0VxdWFsJDEsbGVzc0VxdWFsSW1wbCQxLG51bGwsImJvb2wiKSxsZXNzRXF1YWxDb25maWckMj17a2VybmVsTmFtZTpMZXNzRXF1YWwkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxlc3NFcXVhbCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsaW5TcGFjZUltcGwkMShoYSxhYSx4YSl7Y29uc3QgYmE9KGFhLWhhKS8oeGEtMSksU2E9bWFrZVplcm9zVHlwZWRBcnJheSQxKHhhLCJmbG9hdDMyIik7U2FbMF09aGE7Zm9yKGxldCBUYT0xO1RhPFNhLmxlbmd0aDtUYSsrKVNhW1RhXT1TYVtUYS0xXStiYTtyZXR1cm4gU2F9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsb2dJbXBsJDE9Y3JlYXRlU2ltcGxlVW5hcnlJbXBsJDEoaGE9Pk1hdGgubG9nKGhhKSksbG9nJDM9dW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoTG9nJDEsbG9nSW1wbCQxKSxsb2dDb25maWckMj17a2VybmVsTmFtZTpMb2ckMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxvZyQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhJbXBsJDMoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMShiYSxzaXplRnJvbVNoYXBlJDEoeGEpKTtmb3IobGV0IFRhPTA7VGE8U2EubGVuZ3RoOysrVGEpe2NvbnN0IHdhPVRhKmFhO2xldCBFYT1oYVt3YV07Zm9yKGxldCBrYT0wO2thPGFhOysra2Epe2NvbnN0IEFhPWhhW3dhK2thXTsoTnVtYmVyLmlzTmFOKEFhKXx8QWE+RWEpJiYoRWE9QWEpfVNhW1RhXT1FYX1yZXR1cm4gU2F9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWF4aW11bUltcGwkMT1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsJDEoKGhhLGFhKT0+TWF0aC5tYXgoaGEsYWEpKSxtYXhpbXVtJDM9YmluYXJ5S2VybmVsRnVuYyQyKE1heGltdW0kMixtYXhpbXVtSW1wbCQxKSxtYXhpbXVtQ29uZmlnJDI9e2tlcm5lbE5hbWU6TWF4aW11bSQyLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bWF4aW11bSQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBtaW5pbXVtSW1wbCQxPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5NYXRoLm1pbihoYSxhYSkpLG1pbmltdW0kMj1iaW5hcnlLZXJuZWxGdW5jJDIoTWluaW11bSQyLG1pbmltdW1JbXBsJDEpLG1pbmltdW1Db25maWckMj17a2VybmVsTmFtZTpNaW5pbXVtJDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptaW5pbXVtJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG11bHRpcGx5SW1wbCQxPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYSphYSksbXVsdGlwbHlDb21wbGV4SW1wbD1jcmVhdGVDb21wbGV4QmluYXJ5S2VybmVsSW1wbCgoaGEsYWEseGEsYmEpPT4oe3JlYWw6aGEqeGEtYWEqYmEsaW1hZzpoYSpiYSthYSp4YX0pKSxtdWx0aXBseSQyPWJpbmFyeUtlcm5lbEZ1bmMkMihNdWx0aXBseSQyLG11bHRpcGx5SW1wbCQxLG11bHRpcGx5Q29tcGxleEltcGwpLG11bHRpcGx5Q29uZmlnJDI9e2tlcm5lbE5hbWU6TXVsdGlwbHkkMixiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOm11bHRpcGx5JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5lZ0ltcGwkMShoYSxhYSx4YSl7Y29uc3QgYmE9Y3JlYXRlU2NhbGFyVmFsdWUkMSgtMSx4YSk7cmV0dXJuIG11bHRpcGx5SW1wbCQxKFtdLGFhLGJhLGhhLHhhKX1mdW5jdGlvbiBuZWckMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYTthc3NlcnROb3RDb21wbGV4JDIoYmEsIm5lZyIpO2NvbnN0IFNhPXhhLmRhdGEuZ2V0KGJhLmRhdGFJZCkudmFsdWVzLFtUYSx3YV09bmVnSW1wbCQxKFNhLGJhLnNoYXBlLGJhLmR0eXBlKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8od2EsYmEuZHR5cGUsVGEpfWNvbnN0IG5lZ0NvbmZpZyQyPXtrZXJuZWxOYW1lOk5lZyQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bmVnJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG5vdEVxdWFsSW1wbCQxPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYSE9PWFhPzE6MCksbm90RXF1YWwkMj1iaW5hcnlLZXJuZWxGdW5jJDIoTm90RXF1YWwkMSxub3RFcXVhbEltcGwkMSxudWxsLCJib29sIiksbm90RXF1YWxDb25maWckMj17a2VybmVsTmFtZTpOb3RFcXVhbCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bm90RXF1YWwkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdHJhbnNwb3NlSW1wbCQzKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1hYS5sZW5ndGgsd2E9c2l6ZUZyb21TaGFwZSQxKGFhKSxFYT1jb21wdXRlU3RyaWRlcyQxKGFhKSxrYT1jb21wdXRlU3RyaWRlcyQxKFNhKSxBYT1nZXRUeXBlZEFycmF5RnJvbURUeXBlJDEoeGEsc2l6ZUZyb21TaGFwZSQxKFNhKSk7Zm9yKGxldCBGYT0wO0ZhPHdhOysrRmEpe2NvbnN0IExhPWluZGV4VG9Mb2MkMShGYSxUYSxFYSksZWw9bmV3IEFycmF5KExhLmxlbmd0aCk7Zm9yKGxldCBubD0wO25sPGVsLmxlbmd0aDtubCsrKWVsW25sXT1MYVtiYVtubF1dO2NvbnN0IHRsPWxvY1RvSW5kZXgkMShlbCxUYSxrYSk7QWFbdGxdPWhhW0ZhXX1yZXR1cm4gQWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdHJhbnNwb3NlJDIoaGEpe2NvbnN0e2lucHV0czphYSxhdHRyczp4YSxiYWNrZW5kOmJhfT1oYSx7eDpTYX09YWEse3Blcm06VGF9PXhhO2Fzc2VydE5vdENvbXBsZXgkMihTYSwidHJhbnNwb3NlIik7Y29uc3Qgd2E9U2Euc2hhcGUubGVuZ3RoLEVhPW5ldyBBcnJheSh3YSk7Zm9yKGxldCBMYT0wO0xhPEVhLmxlbmd0aDtMYSsrKUVhW0xhXT1TYS5zaGFwZVtUYVtMYV1dO2NvbnN0IGthPWJhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLEFhPXRyYW5zcG9zZUltcGwkMyhrYSxTYS5zaGFwZSxTYS5kdHlwZSxUYSxFYSk7cmV0dXJue2RhdGFJZDpiYS53cml0ZShBYSxFYSxTYS5kdHlwZSksc2hhcGU6RWEsZHR5cGU6U2EuZHR5cGV9fWNvbnN0IHRyYW5zcG9zZUNvbmZpZyQyPXtrZXJuZWxOYW1lOlRyYW5zcG9zZSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6dHJhbnNwb3NlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHByb2RJbXBsJDEoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoaGEsYmEpLHdhPXVwY2FzdFR5cGUkMShhYSwiaW50MzIiKSxFYT1tYWtlWmVyb3NUeXBlZEFycmF5JDEoc2l6ZUZyb21TaGFwZSQxKFNhKSx3YSksa2E9c2l6ZUZyb21TaGFwZSQxKFRhKTtmb3IobGV0IEFhPTA7QWE8RWEubGVuZ3RoOysrQWEpe2NvbnN0IEZhPUFhKmthO2xldCBMYT0xO2ZvcihsZXQgZWw9MDtlbDxrYTsrK2VsKUxhKj14YVtGYStlbF07RWFbQWFdPUxhfXJldHVybntvdXRWYWxzOkVhLG91dFNoYXBlOlNhLG91dER0eXBlOndhfX1mdW5jdGlvbiBwcm9kJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGEsa2VlcERpbXM6d2F9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihTYSwicHJvZCIpO2NvbnN0IEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKSxBYT1nZXRBeGVzUGVybXV0YXRpb24kMShrYSxFYSk7bGV0IEZhPWthLExhPVNhO2NvbnN0IGVsPVtdO0FhIT1udWxsJiYoTGE9dHJhbnNwb3NlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpBYX19KSxlbC5wdXNoKExhKSxGYT1nZXRJbm5lck1vc3RBeGVzJDEoRmEubGVuZ3RoLEVhKSk7Y29uc3QgdGw9eGEuZGF0YS5nZXQoTGEuZGF0YUlkKS52YWx1ZXMse291dFZhbHM6bmwsb3V0U2hhcGU6c2wsb3V0RHR5cGU6cmx9PXByb2RJbXBsJDEoTGEuc2hhcGUsTGEuZHR5cGUsdGwsRmEpO2xldCBvbD1zbDtyZXR1cm4gd2EmJihvbD1leHBhbmRTaGFwZVRvS2VlcERpbSQxKHNsLGthKSksZWwuZm9yRWFjaChhbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpKSx4YS5tYWtlVGVuc29ySW5mbyhvbCxybCxubCl9Y29uc3QgcHJvZENvbmZpZyQyPXtrZXJuZWxOYW1lOlByb2QkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnByb2QkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdmFsaWRhdGVJbmRpY2VzJDEoaGEsYWEseGEpe2hhLmZvckVhY2goKGJhLFNhKT0+e2lmKGJhPDB8fGJhPj14YSl7Y29uc3QgVGE9aW5kZXhUb0xvYyQxKFNhLGFhLmxlbmd0aCxjb21wdXRlU3RyaWRlcyQxKGFhKSkuam9pbigiLCIpO3Rocm93IG5ldyBFcnJvcihgaW5kaWNlc1ske1RhfV0gPSAke2JhfSBpcyBub3QgaW4gWzAsICR7eGF9KWApfX0pfWZ1bmN0aW9uIHZhbGlkYXRlU3BsaXRzJDEoaGEsYWEpe2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7Kyt4YSl7Y29uc3QgYmE9aGFbeGFdLFNhPXhhPT09aGEubGVuZ3RoLTE/YWE6aGFbeGErMV0ubGVuZ3RoO2lmKGJhLmxlbmd0aD09PTApdGhyb3cgbmV3IEVycm9yKCJSYWdnZWQgc3BsaXRzIG1heSBub3QgYmUgZW1wdHkiKTtpZihiYVswXTwwKXRocm93IG5ldyBFcnJvcigiUmFnZ2VkIHNwbGl0cyBtdXN0IGJlIG5vbi1uZWdhdGl2ZSIpO2lmKGJhW2JhLmxlbmd0aC0xXT5TYSl0aHJvdyBuZXcgRXJyb3IoIlJhZ2dlZCBzcGxpdHMgbXVzdCBub3QgcG9pbnQgcGFzdCB2YWx1ZXMiKTtmb3IobGV0IFRhPTE7VGE8YmEubGVuZ3RoOysrVGEpaWYoYmFbVGEtMV0+YmFbVGFdKXRocm93IG5ldyBFcnJvcigiUmFnZ2VkIHNwbGl0cyBtdXN0IGJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIiKX19ZnVuY3Rpb24gbWFrZVNwbGl0cyQxKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1bXTtsZXQgVGE9MDtjb25zdCB3YT1hYS5sZW5ndGgtMSt4YS5sZW5ndGgsRWE9bmV3IEFycmF5KHdhKS5maWxsKG51bGwpLm1hcCgoKT0+WzBdKTt2YWxpZGF0ZVNwbGl0cyQxKHhhLGJhKTtsZXQga2E9MTtmb3IobGV0IEFhPTA7QWE8YWEubGVuZ3RoLTE7KytBYSl7a2EqPWFhW0FhXTtjb25zdCBGYT1hYVtBYSsxXTtmb3IobGV0IExhPTE7TGE8a2ErMTsrK0xhKUVhW0FhXS5wdXNoKExhKkZhKX1mb3IobGV0IEFhPTA7QWE8aGEubGVuZ3RoOysrQWEpe2xldCBGYT1oYVtBYV0sTGE9aGFbQWFdKzE7Zm9yKGxldCBlbD0wO2VsPHhhLmxlbmd0aDsrK2VsKXtjb25zdCB0bD14YVtlbF0sbmw9ZWwrYWEubGVuZ3RoLTE7aWYobmw+PTApe2NvbnN0IHNsPUVhW25sXSxybD1zbFtzbC5sZW5ndGgtMV0tdGxbRmFdO2ZvcihsZXQgb2w9RmE7b2w8TGE7KytvbClFYVtubF0ucHVzaCh0bFtvbCsxXStybCl9RmE9dGxbRmFdLExhPXRsW0xhXX1MYSE9PUZhJiYoU2EucHVzaChbRmEsTGFdKSxUYSs9TGEtRmEpfXJldHVybntvdXRTcGxpdHM6RWEsdmFsdWVTbGljZXM6U2EsbnVtVmFsdWVzOlRhfX1mdW5jdGlvbiBnZXRTcGxpdHMkMShoYSl7Y29uc3QgYWE9W107Zm9yKGxldCB4YT0wO3hhPGhhLmxlbmd0aDsrK3hhKXtjb25zdCBiYT1oYVt4YV0ubGVuZ3RoLFNhPWdldEFycmF5RnJvbURUeXBlJDEoImludDMyIixiYSk7YWEucHVzaChTYSksaGFbeGFdLmZvckVhY2goKFRhLHdhKT0+U2Fbd2FdPVRhKX1yZXR1cm4gYWF9ZnVuY3Rpb24gY29tcHV0ZUZsYXRPdXRlckRpbXMkMShoYSxhYSl7Y29uc3QgeGE9aGEuc2xpY2UoMCxhYSk7Zm9yKDt4YS5sZW5ndGg8YWE7KXhhLnB1c2goMSk7Zm9yKGxldCBiYT1hYTtiYTxoYS5sZW5ndGg7YmErKyl4YVthYS0xXSo9aGFbYmFdO3JldHVybiB4YX1mdW5jdGlvbiB3cml0ZVZhbHVlU2xpY2VzJDEoaGEsYWEseGEsYmEsU2EsVGEpe2NvbnN0IHdhPWNvbXB1dGVGbGF0T3V0ZXJEaW1zJDEoYWEsMilbMV0sRWE9Y29tcHV0ZUZsYXRPdXRlckRpbXMkMShUYSwyKVsxXTtsZXQga2E9MDtmb3IoY29uc3QgQWEgb2YgeGEpZm9yKGxldCBGYT1BYVswXTtGYTxBYVsxXTsrK0ZhKXtmb3IobGV0IExhPTA7TGE8YmE7KytMYSlTYVtrYSpFYStMYV09aGFbRmEqd2ErTGFdOysra2F9fWZ1bmN0aW9uIGdldFZhbHVlcyQxKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1hYS5zbGljZSgpO1RhWzBdPVNhO2NvbnN0IHdhPWdldEFycmF5RnJvbURUeXBlJDEoeGEsc2l6ZUZyb21TaGFwZSQxKFRhKSksRWE9aGEubGVuZ3RoLGthPUVhPT09MD8wOkVhL2FhWzBdO3JldHVybiB3cml0ZVZhbHVlU2xpY2VzJDEoaGEsYWEsYmEsa2Esd2EsVGEpLFt3YSxUYV19ZnVuY3Rpb24gcmFnZ2VkR2F0aGVySW1wbCQxKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhKXtpZihoYS5sZW5ndGg9PT0wKXRocm93IG5ldyBFcnJvcigicGFyYW1zTmVzdGVkU3BsaXRzIG11c3QgYmUgbm9uIGVtcHR5Iik7aWYoYWFbMF0ubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoIlNwbGl0IHRlbnNvcnMgbXVzdCBub3QgYmUgc2NhbGFycyIpO2NvbnN0IGthPWFhWzBdWzBdLTE7aWYodmFsaWRhdGVJbmRpY2VzJDEoVGEsd2Esa2EpLGJhLmxlbmd0aD09PTApdGhyb3cgbmV3IEVycm9yKCJwYXJhbXMucmFuayBtdXN0IGJlIG5vbnplcm8iKTtjb25zdCBBYT1iYVswXSx7b3V0U3BsaXRzOkZhLHZhbHVlU2xpY2VzOkxhLG51bVZhbHVlczplbH09bWFrZVNwbGl0cyQxKFRhLHdhLGhhLEFhKSx0bD1nZXRTcGxpdHMkMShGYSksbmw9Z2V0VmFsdWVzJDEoeGEsYmEsU2EsTGEsZWwpO3JldHVyblt0bCxubFswXSxubFsxXV19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSU5UMzJfTUFYJDE9MjE0NzQ4MzY0NztmdW5jdGlvbiByYWdnZWRSYW5nZUltcGwkMShoYSxhYSx4YSxiYSxTYSxUYSx3YSl7aWYoYWEubGVuZ3RoPjEpdGhyb3cgbmV3IEVycm9yKCJzdGFydHMgbXVzdCBiZSBhIHNjYWxhciBvciB2ZWN0b3IiKTtpZihTYS5sZW5ndGg+MSl0aHJvdyBuZXcgRXJyb3IoImxpbWl0cyBtdXN0IGJlIGEgc2NhbGFyIG9yIHZlY3RvciIpO2lmKHdhLmxlbmd0aD4xKXRocm93IG5ldyBFcnJvcigiZGVsdGFzIG11c3QgYmUgYSBzY2FsYXIgb3IgdmVjdG9yIik7Y29uc3QgRWE9YWEubGVuZ3RoPT09MCxrYT1TYS5sZW5ndGg9PT0wLEFhPXdhLmxlbmd0aD09PTAsRmE9W107RWF8fEZhLnB1c2goYWFbMF0pLGthfHxGYS5wdXNoKFNhWzBdKSxBYXx8RmEucHVzaCh3YVswXSk7Zm9yKGxldCBybD0xO3JsPEZhLmxlbmd0aDsrK3JsKWlmKEZhW3JsXSE9PUZhW3JsLTFdKXRocm93IG5ldyBFcnJvcigic3RhcnRzLCBsaW1pdHMsIGFuZCBkZWx0YXMgbXVzdCBoYXZlIHRoZSBzYW1lIHNoYXBlIik7Y29uc3QgTGE9RmEubGVuZ3RoPT09MD8xOkZhWzBdLGVsPWdldEFycmF5RnJvbURUeXBlJDEoImludDMyIixMYSsxKTtlbFswXT0wO2ZvcihsZXQgcmw9MDtybDxMYTsrK3JsKXtjb25zdCBvbD1FYT9oYVswXTpoYVtybF0sYWw9a2E/YmFbMF06YmFbcmxdLGxsPUFhP1RhWzBdOlRhW3JsXTtpZihsbD09PTApdGhyb3cgbmV3IEVycm9yKCJSZXF1aXJlcyBkZWx0YSAhPSAwIik7bGV0IGlsO2lmKGxsPjAmJmFsPG9sfHxsbDwwJiZhbD5vbClpbD0wO2Vsc2UgaWYoaWw9TWF0aC5jZWlsKE1hdGguYWJzKChhbC1vbCkvbGwpKSxpbD5JTlQzMl9NQVgkMSl0aHJvdyBuZXcgRXJyb3IoYFJlcXVpcmVzICgobGltaXQgLSBzdGFydCkgLyBkZWx0YSkgPD0gJHtJTlQzMl9NQVgkMX1gKTtlbFtybCsxXT1lbFtybF0raWx9Y29uc3QgdGw9ZWxbTGFdLG5sPWdldEFycmF5RnJvbURUeXBlJDEoeGEsdGwpO2xldCBzbD0wO2ZvcihsZXQgcmw9MDtybDxMYTsrK3JsKXtjb25zdCBvbD1lbFtybCsxXS1lbFtybF07bGV0IGFsPUVhP2hhWzBdOmhhW3JsXTtjb25zdCBsbD1BYT9UYVswXTpUYVtybF07Zm9yKGxldCBpbD0wO2lsPG9sOysraWwpbmxbc2wrK109YWwsYWwrPWxsfXJldHVybltlbCxubF19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovdmFyIFJvd1BhcnRpdGlvblR5cGUkMj1Sb3dQYXJ0aXRpb25UeXBlJDM7bGV0IFJhZ2dlZFRlbnNvclRvVGVuc29yT3AkMT1jbGFzcyBsY3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSxGYSl7dGhpcy5zaGFwZT1hYSx0aGlzLnNoYXBlU2hhcGU9eGEsdGhpcy52YWx1ZXM9YmEsdGhpcy52YWx1ZXNTaGFwZT1TYSx0aGlzLnZhbHVlc0RUeXBlPVRhLHRoaXMuZGVmYXVsdFZhbHVlPXdhLHRoaXMuZGVmYXVsdFZhbHVlU2hhcGU9RWEsdGhpcy5yb3dQYXJ0aXRpb25WYWx1ZXM9a2EsdGhpcy5yb3dQYXJ0aXRpb25WYWx1ZXNTaGFwZXM9QWEsdGhpcy5yb3dQYXJ0aXRpb25UeXBlcz1nZXRSb3dQYXJ0aXRpb25UeXBlc0hlbHBlciQxKEZhKSx0aGlzLnJhZ2dlZFJhbms9Z2V0UmFnZ2VkUmFuayQxKHRoaXMucm93UGFydGl0aW9uVHlwZXMpfWdldFJvd1BhcnRpdGlvblR5cGVCeURpbWVuc2lvbihhYSl7cmV0dXJuIHRoaXMucm93UGFydGl0aW9uVHlwZXNbMF09PT1Sb3dQYXJ0aXRpb25UeXBlJDIuRklSU1RfRElNX1NJWkU/dGhpcy5yb3dQYXJ0aXRpb25UeXBlc1thYSsxXTp0aGlzLnJvd1BhcnRpdGlvblR5cGVzW2FhXX1nZXRSb3dQYXJ0aXRpb25UZW5zb3IoYWEpe3JldHVybiB0aGlzLnJvd1BhcnRpdGlvblR5cGVzWzBdPT09Um93UGFydGl0aW9uVHlwZSQyLkZJUlNUX0RJTV9TSVpFP3RoaXMucm93UGFydGl0aW9uVmFsdWVzW2FhKzFdOnRoaXMucm93UGFydGl0aW9uVmFsdWVzW2FhXX1nZXRNYXhXaWR0aChhYSl7Y29uc3QgeGE9dGhpcy5nZXRSb3dQYXJ0aXRpb25UZW5zb3IoYWEtMSk7c3dpdGNoKHRoaXMuZ2V0Um93UGFydGl0aW9uVHlwZUJ5RGltZW5zaW9uKGFhLTEpKXtjYXNlIFJvd1BhcnRpdGlvblR5cGUkMi5WQUxVRV9ST1dJRFM6cmV0dXJuIGxjLmdldE1heFdpZHRoVmFsdWVSb3dJRCh4YSk7Y2FzZSBSb3dQYXJ0aXRpb25UeXBlJDIuUk9XX1NQTElUUzpyZXR1cm4gbGMuZ2V0TWF4V2lkdGhSb3dTcGxpdCh4YSk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBoYW5kbGUgcGFydGl0aW9uIHR5cGUgJHtSb3dQYXJ0aXRpb25UeXBlJDJbdGhpcy5nZXRSb3dQYXJ0aXRpb25UeXBlQnlEaW1lbnNpb24oYWEtMSldfWApfX1zdGF0aWMgZ2V0TWF4V2lkdGhSb3dTcGxpdChhYSl7Y29uc3QgeGE9YWEubGVuZ3RoO2lmKHhhPT09MHx8eGE9PT0xKXJldHVybiAwO2xldCBiYT0wO2ZvcihsZXQgU2E9MDtTYTx4YS0xOysrU2Epe2NvbnN0IFRhPWFhW1NhKzFdLWFhW1NhXTtUYT5iYSYmKGJhPVRhKX1yZXR1cm4gYmF9c3RhdGljIGdldE1heFdpZHRoVmFsdWVSb3dJRChhYSl7Y29uc3QgeGE9YWEubGVuZ3RoO2lmKHhhPT09MClyZXR1cm4gMDtsZXQgYmE9MCxTYT1hYVswXSxUYT0wO2ZvcihsZXQgd2E9MTt3YTx4YTsrK3dhKXtjb25zdCBFYT1hYVt3YV07RWEhPT1TYSYmKFNhPUVhLFRhPU1hdGgubWF4KHdhLWJhLFRhKSxiYT13YSl9cmV0dXJuIE1hdGgubWF4KHhhLWJhLFRhKX10ZW5zb3JTaGFwZUZyb21UZW5zb3IoYWEseGEsYmE9ITApe2lmKHhhLmxlbmd0aD09PTApe2lmKGFhWzBdPT09LTEpcmV0dXJuW107dGhyb3cgbmV3IEVycm9yKCJUaGUgb25seSB2YWxpZCBzY2FsYXIgc2hhcGUgdGVuc29yIGlzIHRoZSBmdWxseSB1bmtub3duIHNoYXBlIHNwZWNpZmllZCBhcyAtMS4iKX1yZXR1cm4gbWFrZVNoYXBlJDEoYWEsYmEpfWNhbGN1bGF0ZU91dHB1dFNpemUoYWEpe2NvbnN0IHhhPXRoaXMudmFsdWVzU2hhcGUsYmE9dGhpcy5kZWZhdWx0VmFsdWVTaGFwZTt2YWxpZGF0ZURlZmF1bHRWYWx1ZVNoYXBlJDEoYmEseGEpO2NvbnN0IFNhPXRoaXMudGVuc29yU2hhcGVGcm9tVGVuc29yKHRoaXMuc2hhcGUsdGhpcy5zaGFwZVNoYXBlKSx3YT1jb21iaW5lUmFnZ2VkVGVuc29yVG9UZW5zb3JTaGFwZXMkMSh0aGlzLnJhZ2dlZFJhbmssU2EseGEpO3dhWzBdPDAmJih3YVswXT1hYSk7Zm9yKGxldCBFYT0xO0VhPD10aGlzLnJhZ2dlZFJhbms7KytFYSl3YVtFYV08MCYmKHdhW0VhXT10aGlzLmdldE1heFdpZHRoKEVhKSk7cmV0dXJuIHdhfWNhbGN1bGF0ZUZpcnN0UGFyZW50T3V0cHV0SW5kZXgoYWEseGEsYmEpe2NvbnN0IFNhPU1hdGgubWluKGFhLGJhKSxUYT1bXTtsZXQgd2E9MDtmb3IobGV0IEVhPTA7RWE8U2E7KytFYSx3YSs9eGEpVGEucHVzaCh3YSk7Zm9yKGxldCBFYT1TYTtFYTxhYTsrK0VhKVRhLnB1c2goLTEpO3JldHVybiBhc3NlcnQkMihUYS5sZW5ndGg9PT1hYSwoKT0+IkZpbmFsIGxlbmd0aCBvZiByZXN1bHQgbXVzdCBiZSBlcXVhbCB0byBmaXJzdERpbWVuc2lvbi4iKSxUYX1jYWxjdWxhdGVPdXRwdXRJbmRleFJvd1NwbGl0KGFhLHhhLGJhLFNhKXtjb25zdCBUYT1hYS5sZW5ndGgsd2E9W107Zm9yKGxldCBFYT0wO0VhPFRhLTE7KytFYSl7Y29uc3Qga2E9YWFbRWErMV0tYWFbRWFdO2xldCBBYT1NYXRoLm1pbihTYSxrYSksRmE9eGFbRWFdO0ZhPT09LTEmJihBYT0wKTtmb3IobGV0IExhPTA7TGE8QWE7KytMYSl3YS5wdXNoKEZhKSxGYSs9YmE7Zm9yKGxldCBMYT0wO0xhPGthLUFhOysrTGEpd2EucHVzaCgtMSl9aWYoVGE+MCYmd2EubGVuZ3RoIT09YWFbVGEtMV0pdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIHJvdyBzcGxpdCBzaXplLiIpO3JldHVybiB3YX1jYWxjdWxhdGVPdXRwdXRJbmRleFZhbHVlUm93SUQoYWEseGEsYmEsU2Epe2NvbnN0IFRhPWFhLmxlbmd0aCx3YT1bXTtpZihUYT09PTApcmV0dXJuW107bGV0IEVhPTAsa2E9YWFbMF07aWYoa2E+PXhhLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYEdvdCBjdXJyZW50VmFsdWVSb3dJZD0ke2thfSwgd2hpY2ggaXMgbm90IGxlc3MgdGhhbiAke3hhLmxlbmd0aH1gKTtsZXQgQWE9eGFba2FdO3dhLnB1c2goQWEpO2ZvcihsZXQgRmE9MTtGYTxUYTsrK0ZhKXtjb25zdCBMYT1hYVtGYV07aWYoTGE9PT1rYSlBYT49MCYmKCsrRWEsRWE8U2E/QWErPWJhOkFhPS0xKTtlbHNle2lmKEVhPTAsa2E9TGEsTGE+PXhhLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYEdvdCBuZXh0VmFsdWVSb3dJZD0ke0xhfSB3aGljaCBpcyBub3QgbGVzcyB0aGFuICR7eGEubGVuZ3RofWApO0FhPXhhW0xhXX13YS5wdXNoKEFhKX1pZih3YS5sZW5ndGghPT1hYS5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIHJvdyBpZHMuIik7cmV0dXJuIHdhfWNhbGN1bGF0ZU91dHB1dEluZGV4KGFhLHhhLGJhLFNhKXtjb25zdCBUYT10aGlzLmdldFJvd1BhcnRpdGlvblRlbnNvcihhYSksd2E9dGhpcy5nZXRSb3dQYXJ0aXRpb25UeXBlQnlEaW1lbnNpb24oYWEpO3N3aXRjaCh3YSl7Y2FzZSBSb3dQYXJ0aXRpb25UeXBlJDIuVkFMVUVfUk9XSURTOnJldHVybiB0aGlzLmNhbGN1bGF0ZU91dHB1dEluZGV4VmFsdWVSb3dJRChUYSx4YSxiYSxTYSk7Y2FzZSBSb3dQYXJ0aXRpb25UeXBlJDIuUk9XX1NQTElUUzppZihUYS5sZW5ndGgtMT54YS5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKGBSb3cgcGFydGl0aW9uIHNpemUgaXMgZ3JlYXRlciB0aGFuIG91dHB1dCBzaXplOiAke1RhLmxlbmd0aC0xfSA+ICR7eGEubGVuZ3RofWApO3JldHVybiB0aGlzLmNhbGN1bGF0ZU91dHB1dEluZGV4Um93U3BsaXQoVGEseGEsYmEsU2EpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBwYXJ0aXRpb24gdHlwZTogJHtSb3dQYXJ0aXRpb25UeXBlJDJbd2FdfWApfX1nZXRGaXJzdERpbWVuc2lvblNpemUoKXtjb25zdCBhYT10aGlzLnJvd1BhcnRpdGlvblZhbHVlc1swXTtpZih0aGlzLnJvd1BhcnRpdGlvblR5cGVzLmxlbmd0aD09PTApdGhyb3cgbmV3IEVycm9yKCJObyByb3dfcGFydGl0aW9uX3R5cGVzIGdpdmVuLiIpO2NvbnN0IHhhPXRoaXMucm93UGFydGl0aW9uVHlwZXNbMF07c3dpdGNoKHhhKXtjYXNlIFJvd1BhcnRpdGlvblR5cGUkMi5GSVJTVF9ESU1fU0laRTpyZXR1cm4gYWFbMF07Y2FzZSBSb3dQYXJ0aXRpb25UeXBlJDIuVkFMVUVfUk9XSURTOnRocm93IG5ldyBFcnJvcigiQ2Fubm90IGhhbmRsZSBWQUxVRV9ST1dJRFMgaW4gZmlyc3QgZGltZW5zaW9uLiIpO2Nhc2UgUm93UGFydGl0aW9uVHlwZSQyLlJPV19TUExJVFM6cmV0dXJuIHRoaXMucm93UGFydGl0aW9uVmFsdWVzU2hhcGVzWzBdWzBdLTE7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBoYW5kbGUgdHlwZSAke1Jvd1BhcnRpdGlvblR5cGUkMlt4YV19YCl9fWNvbXB1dGUoKXtpZih0aGlzLnJvd1BhcnRpdGlvblZhbHVlc1swXS5sZW5ndGg8PTApdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGZpcnN0IHBhcnRpdGlvbiBpbnB1dC4gVGVuc29yIHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBlbGVtZW50LiIpO2NvbnN0IHhhPXRoaXMuZ2V0Rmlyc3REaW1lbnNpb25TaXplKCksYmE9dGhpcy5jYWxjdWxhdGVPdXRwdXRTaXplKHhhKSxTYT1uZXcgQXJyYXkodGhpcy5yYWdnZWRSYW5rKzEpO1NhW1NhLmxlbmd0aC0xXT0xO2ZvcihsZXQga2E9U2EubGVuZ3RoLTI7a2E+PTA7LS1rYSlTYVtrYV09U2Fba2ErMV0qYmFba2ErMV07Y29uc3QgVGE9bWFrZVNoYXBlJDEoYmEsITEpLHdhPWdldEFycmF5RnJvbURUeXBlJDEodGhpcy52YWx1ZXNEVHlwZSxzaXplRnJvbVNoYXBlJDEoVGEpKTtpZihTYVswXSpiYVswXT4wKXtsZXQga2E9dGhpcy5jYWxjdWxhdGVGaXJzdFBhcmVudE91dHB1dEluZGV4KHhhLFNhWzBdLGJhWzBdKTtmb3IobGV0IEFhPTE7QWE8PXRoaXMucmFnZ2VkUmFuazsrK0FhKWthPXRoaXMuY2FsY3VsYXRlT3V0cHV0SW5kZXgoQWEtMSxrYSxTYVtBYV0sYmFbQWFdKTt0aGlzLnNldE91dHB1dCh0aGlzLnJhZ2dlZFJhbmssa2Esd2EsVGEpfXJldHVybltUYSx3YV19c2V0T3V0cHV0KGFhLHhhLGJhLFNhKXtpZihiYS5sZW5ndGg9PT0wKXJldHVybjtjb25zdCBUYT10aGlzLnZhbHVlcyx3YT1iYTtsZXQgRWE9U2Euc2xpY2UoKTtFYT1FYS5zbGljZShhYSsxKTtjb25zdCBrYT1zaXplRnJvbVNoYXBlJDEoRWEpLEFhPXhhLmxlbmd0aDtsZXQgRmE9dGhpcy5kZWZhdWx0VmFsdWU7aWYoRmEubGVuZ3RoIT09a2EmJkZhLmxlbmd0aCE9PTEpe2NvbnN0IG5sPXRoaXMuZGVmYXVsdFZhbHVlU2hhcGU7dGlkeSQxKCgpPT57Y29uc3Qgc2w9cmVzaGFwZSQ0KEZhLG5sKTtGYT1icm9hZGNhc3RUbyQxKHNsLEVhKS5kYXRhU3luYygpfSl9bGV0IExhPTAsZWw9MCx0bD0wO2ZvcihsZXQgbmw9MDtubDw9QWE7KytubCl7bGV0IHNsPW5sPEFhP3hhW25sXTotMTtpZihzbD09PXRsKXsrK3RsO2NvbnRpbnVlfWlmKGVsPHRsKXtjb25zdCBybD1UYS5zdWJhcnJheShMYSprYSksb2w9d2Euc3ViYXJyYXkoZWwqa2EpLGFsPSh0bC1lbCkqa2E7Y29weUFycmF5JDEob2wscmwsYWwpfWlmKG5sPj1BYSl7Y29uc3Qgcmw9YmEubGVuZ3RoO3NsPU1hdGguZmxvb3Iocmwva2EpfWlmKHNsPnRsKWlmKHRoaXMuZGVmYXVsdFZhbHVlLmxlbmd0aD09PTEpd2Euc3ViYXJyYXkodGwqa2Esc2wqa2EpLmZpbGwodGhpcy5kZWZhdWx0VmFsdWVbMF0pLHRsPXNsO2Vsc2UgZm9yKDtzbD50bDspe2NvbnN0IHJsPXdhLnNsaWNlKHRsKmthKTtjb3B5QXJyYXkkMShybCxGYSxrYSksKyt0bH1zbDwwPyhMYT1ubCsxLGVsPXRsKTooTGE9bmwsZWw9dGwsdGw9ZWwrMSl9fX07ZnVuY3Rpb24gY29weUFycmF5JDEoaGEsYWEseGEpe2ZvcihsZXQgYmE9MDtiYTx4YTtiYSsrKWhhW2JhXT1hYVtiYV19ZnVuY3Rpb24gbWFrZVNoYXBlJDEoaGEsYWEpe2NvbnN0IHhhPVtdO2ZvcihsZXQgYmEgb2YgaGEpe2lmKGJhPDApe2lmKCFhYSl0aHJvdyBuZXcgRXJyb3IoYERpbWVuc2lvbiAke2JhfSBtdXN0IGJlID49IDBgKTtpZihiYTwtMSl0aHJvdyBuZXcgRXJyb3IoYERpbWVuc2lvbiAke2JhfSBtdXN0IGJlID49IC0xYCk7YmE9LTF9eGEucHVzaChiYSl9cmV0dXJuIHhhfWZ1bmN0aW9uIHJhZ2dlZFRlbnNvclRvVGVuc29ySW1wbCQxKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthLEFhKXtyZXR1cm4gbmV3IFJhZ2dlZFRlbnNvclRvVGVuc29yT3AkMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSkuY29tcHV0ZSgpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhbmdlSW1wbCQxKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1oYT09PWFhLFRhPWhhPGFhJiZ4YTwwLHdhPWFhPGhhJiZ4YT4xO2lmKFNhfHxUYXx8d2EpcmV0dXJuIG1ha2VaZXJvc1R5cGVkQXJyYXkkMSgwLGJhKTtjb25zdCBFYT1NYXRoLmFicyhNYXRoLmNlaWwoKGFhLWhhKS94YSkpLGthPW1ha2VaZXJvc1R5cGVkQXJyYXkkMShFYSxiYSk7YWE8aGEmJnhhPT09MSYmKHhhPS0xKSxrYVswXT1oYTtmb3IobGV0IEFhPTE7QWE8a2EubGVuZ3RoO0FhKyspa2FbQWFdPWthW0FhLTFdK3hhO3JldHVybiBrYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJzcXJ0SW1wbCQxPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbCQxKGhhPT4xL01hdGguc3FydChoYSkpLHJzcXJ0JDI9dW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoUnNxcnQkMSxyc3FydEltcGwkMSkscnNxcnRDb25maWckMj17a2VybmVsTmFtZTpSc3FydCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cnNxcnQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2NhdHRlckltcGwkMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSl7Y29uc3QgRmE9W2JhL1NhLFNhXSxMYT1oYS52YWx1ZXMsZWw9YWEudmFsdWVzO2lmKGJhPT09MClyZXR1cm4gYnVmZmVyJDEoeGEsYWEuZHR5cGUpO2NvbnN0IHRsPWthIGluc3RhbmNlb2YgVGVuc29yQnVmZmVyJDE/a2E6YnVmZmVyJDEoRmEsYWEuZHR5cGUpO3R5cGVvZiBrYT09InN0cmluZyJ8fHR5cGVvZiBrYT09Im51bWJlciI/dGwudmFsdWVzLmZpbGwoa2EpOnR5cGVvZiBrYT09ImJvb2xlYW4iJiZ0bC52YWx1ZXMuZmlsbCgra2EpO2ZvcihsZXQgbmw9MDtubDxUYTtubCsrKXtjb25zdCBzbD1bXTtsZXQgcmw9MDtmb3IobGV0IG9sPTA7b2w8d2E7b2wrKyl7Y29uc3QgYWw9TGFbbmwqd2Erb2xdO3NsLnB1c2goYWwpLHJsKz1hbCpFYVtvbF19aWYocmw8MHx8cmw+PWJhL1NhKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbmRpY2VzOiAke3NsfSBkb2VzIG5vdCBpbmRleCBpbnRvICR7eGF9YCk7Zm9yKGxldCBvbD0wO29sPFNhO29sKyspQWE/dGwudmFsdWVzW3JsKlNhK29sXSs9ZWxbbmwqU2Erb2xdOnRsLnZhbHVlc1tybCpTYStvbF09YWEucmFuaz09PTA/ZWxbMF06ZWxbbmwqU2Erb2xdfXJldHVybiB0bH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNpZ21vaWRJbXBsJDE9Y3JlYXRlU2ltcGxlVW5hcnlJbXBsJDEoaGE9PjEvKDErTWF0aC5leHAoLWhhKSkpLHNpZ21vaWQkMz11bmFyeUtlcm5lbEZ1bmMkMihTaWdtb2lkJDIsaGE9PjEvKDErTWF0aC5leHAoLWhhKSkpLHNpZ21vaWRDb25maWckMj17a2VybmVsTmFtZTpTaWdtb2lkJDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzaWdtb2lkJDN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNsaWNlSW1wbCQxKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1pc1NsaWNlQ29udGlub3VzJDEoYmEsYWEseGEpLHdhPXNpemVGcm9tU2hhcGUkMSh4YSksRWE9Y29tcHV0ZVN0cmlkZXMkMShiYSk7aWYoVGEpe2NvbnN0IExhPWNvbXB1dGVGbGF0T2Zmc2V0JDEoYWEsRWEpO3JldHVybiBTYT09PSJzdHJpbmciP2hhLnNsaWNlKExhLExhK3dhKTpoYS5zdWJhcnJheShMYSxMYSt3YSl9Y29uc3Qga2E9U2E9PT0ic3RyaW5nIj9mcm9tVWludDhUb1N0cmluZ0FycmF5JDEoaGEpOmhhLEFhPWJ1ZmZlciQxKGJhLFNhLGthKSxGYT1idWZmZXIkMSh4YSxTYSk7Zm9yKGxldCBMYT0wO0xhPEZhLnNpemU7KytMYSl7Y29uc3QgZWw9RmEuaW5kZXhUb0xvYyhMYSksdGw9ZWwubWFwKChubCxzbCk9Pm5sK2FhW3NsXSk7RmEuc2V0KEFhLmdldCguLi50bCksLi4uZWwpfXJldHVybiBTYT09PSJzdHJpbmciP2Zyb21TdHJpbmdBcnJheVRvVWludDgkMShGYS52YWx1ZXMpOkZhLnZhbHVlc31mdW5jdGlvbiBzbGljZSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtiZWdpbjpUYSxzaXplOndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsInNsaWNlIik7Y29uc3RbRWEsa2FdPXBhcnNlU2xpY2VQYXJhbXMkMShTYSxUYSx3YSk7YXNzZXJ0UGFyYW1zVmFsaWQkMShTYSxFYSxrYSk7Y29uc3QgQWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsRmE9c2xpY2VJbXBsJDEoQWEsRWEsa2EsU2Euc2hhcGUsU2EuZHR5cGUpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSxTYS5kdHlwZSxGYSl9Y29uc3Qgc2xpY2VDb25maWckMj17a2VybmVsTmFtZTpTbGljZSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6c2xpY2UkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlRmlsbEVtcHR5Um93c0ltcGwkMShoYSxhYSx4YSxiYSxTYSxUYSx3YSl7Y29uc3QgRWE9YWFbMF0sa2E9VGFbMF0sQWE9bmV3IEFycmF5KGthKSxGYT1uZXcgQXJyYXkoRWEpLExhPWFhWzFdO2lmKGthPT09MCl7aWYoRWEhPT0wKXRocm93IG5ldyBFcnJvcihnZXRTcGFyc2VGaWxsRW1wdHlSb3dzSW5kaWNlc0RlbnNlU2hhcGVNaXNtYXRjaCQxKEVhKSk7Y29uc3Qgcmw9Z2V0QXJyYXlGcm9tRFR5cGUkMSh4YSwwKSxvbD1nZXRBcnJheUZyb21EVHlwZSQxKFNhLDApO3JldHVybltybCxbMCxMYV0sb2wsQWEsRmFdfWxldCBlbD0hMCx0bD0wO2NvbnN0IG5sPW5ldyBBcnJheShrYSkuZmlsbCgwKTtmb3IobGV0IHJsPTA7cmw8RWE7KytybCl7Y29uc3Qgb2w9aGFbcmwqTGFdO2lmKG9sPDApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZUZpbGxFbXB0eVJvd3NOZWdhdGl2ZUluZGV4RXJyb3JNZXNzYWdlJDEocmwsb2wpKTtpZihvbD49a2EpdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZUZpbGxFbXB0eVJvd3NPdXRPZlJhbmdlSW5kZXhFcnJvck1lc3NhZ2UkMShybCxvbCxrYSkpOysrbmxbb2xdLGVsPWVsJiZvbD49dGwsdGw9b2x9bGV0IHNsPSEwO2ZvcihsZXQgcmw9MDtybDxrYTsrK3JsKXtjb25zdCBvbD1ubFtybF09PT0wO0FhW3JsXT1vbCxzbD1zbCYmIW9sLG5sW3JsXT1NYXRoLm1heChubFtybF0sMSkscmw+MCYmKG5sW3JsXSs9bmxbcmwtMV0pfWlmKHNsJiZlbCl7Y29uc3Qgcmw9aGEsb2w9YmE7Zm9yKGxldCBhbD0wO2FsPEVhOysrYWwpRmFbYWxdPWFsO3JldHVybltybCxbRWEsTGFdLG9sLEFhLEZhXX1lbHNle2NvbnN0IHJsPW5sW2thLTFdLG9sPWdldEFycmF5RnJvbURUeXBlJDEoeGEscmwqTGEpLGFsPWdldEFycmF5RnJvbURUeXBlJDEoU2EscmwpLGxsPW5ldyBBcnJheShrYSkuZmlsbCgwKTtmb3IobGV0IGlsPTA7aWw8RWE7KytpbCl7Y29uc3QgY2w9aGFbaWwqTGFdLHVsPWxsW2NsXSxkbD0oY2w9PT0wPzA6bmxbY2wtMV0pK3VsO2xsW2NsXSsrO2ZvcihsZXQgaGw9MDtobDxMYTsrK2hsKW9sW2RsKkxhK2hsXT1oYVtpbCpMYStobF07YWxbZGxdPWJhW2lsXSxGYVtpbF09ZGx9Zm9yKGxldCBpbD0wO2lsPGthOysraWwpaWYobGxbaWxdPT09MCl7Y29uc3QgdWw9aWw9PT0wPzA6bmxbaWwtMV07b2xbdWwqTGErMF09aWw7Zm9yKGxldCBkbD0xO2RsPExhOysrZGwpb2xbdWwqTGErZGxdPTA7YWxbdWxdPXdhfXJldHVybltvbCxbcmwsTGFdLGFsLEFhLEZhXX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlUmVzaGFwZUltcGwkMShoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9c2l6ZUZyb21TaGFwZSQxKGJhKSx3YT1hYVswXSxFYT1TYS5sZW5ndGgsa2E9W107bGV0IEFhPTEsRmE9LTE7Zm9yKGxldCBybD0wO3JsPEVhOysrcmwpe2NvbnN0IG9sPVNhW3JsXTtpZihvbD09PS0xKXtpZihGYSE9PS0xKXRocm93IG5ldyBFcnJvcihnZXRTcGFyc2VSZXNoYXBlTXVsdGlwbGVOZWdhdGl2ZU9uZU91dHB1dERpbUVycm9yTWVzc2FnZSQxKEZhLHJsKSk7RmE9cmwsa2EucHVzaCgxKX1lbHNle2lmKG9sPDApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVJlc2hhcGVOZWdhdGl2ZU91dHB1dERpbUVycm9yTWVzc2FnZSQxKHJsLG9sKSk7QWEqPW9sLGthLnB1c2gob2wpfX1pZihGYSE9PS0xKXtpZihBYTw9MCl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlUmVzaGFwZUVtcHR5VGVuc29yWmVyb091dHB1dERpbUVycm9yTWVzc2FnZSQxKCkpO2NvbnN0IHJsPU1hdGgudHJ1bmMoVGEvQWEpO2lmKEFhKnJsIT09VGEpdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVJlc2hhcGVJbnB1dE91dHB1dE11bHRpcGxlRXJyb3JNZXNzYWdlJDEoYmEsa2EpKTtrYVtGYV09cmx9aWYoc2l6ZUZyb21TaGFwZSQxKGthKSE9PVRhKXRocm93IG5ldyBFcnJvcihnZXRTcGFyc2VSZXNoYXBlSW5wdXRPdXRwdXRNaXNtYXRjaEVycm9yTWVzc2FnZSQxKGJhLGthKSk7Y29uc3QgZWw9YmEubGVuZ3RoLHRsPVtdO2lmKGVsPjApe3RsW2VsLTFdPTE7Zm9yKGxldCBybD1lbC0yO3JsPj0wOy0tcmwpdGxbcmxdPXRsW3JsKzFdKmJhW3JsKzFdfWNvbnN0IG5sPVtdO2lmKEVhPjApe25sW0VhLTFdPTE7Zm9yKGxldCBybD1FYS0yO3JsPj0wOy0tcmwpbmxbcmxdPW5sW3JsKzFdKmthW3JsKzFdfWNvbnN0IHNsPWdldEFycmF5RnJvbURUeXBlJDEoeGEsd2EqRWEpO2ZvcihsZXQgcmw9MDtybDx3YTsrK3JsKXtsZXQgb2w9MDtmb3IobGV0IGFsPTA7YWw8ZWw7KythbClvbCs9aGFbcmwqZWwrYWxdKnRsW2FsXTtmb3IobGV0IGFsPTA7YWw8RWE7KythbClzbFtybCpFYSthbF09TWF0aC50cnVuYyhvbC9ubFthbF0pLG9sJT1ubFthbF19cmV0dXJuW3NsLFt3YSxFYV0sa2FdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25JbXBsJDEoaGEsYWEseGEsYmEsU2EsVGE9ITEsd2E9MCl7Y29uc3QgRWE9YmEubGVuZ3RoLGthPVthYVswXSxoYS5sZW5ndGgvYWFbMF1dLEFhPWthWzFdLExhPUVhPjA/U2FbRWEtMV0rMTowO2lmKExhPDApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25OZWdhdGl2ZVNlZ21lbnRJZHNFcnJvck1lc3NhZ2UkMSgpKTtjb25zdCBlbD1hYS5zbGljZSgpO2VsWzBdPUxhO2NvbnN0IHRsPWVsLnJlZHVjZSgobGwsaWwpPT5sbCppbCwxKSxubD1nZXRBcnJheUZyb21EVHlwZSQxKHhhLHRsKTtpZihFYT09PTApcmV0dXJuIExhPjAmJm5sLmZpbGwod2EpLFtubCxlbF07aWYoTGE8PTApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25OZWdhdGl2ZVNlZ21lbnRJZHNFcnJvck1lc3NhZ2UkMSgpKTtsZXQgc2w9MCxybD0xLG9sPTAsYWw9U2Fbc2xdO2Zvcig7Oyl7bGV0IGxsPTA7aWYocmw8RWEpe2lmKGxsPVNhW3JsXSxhbD09PWxsKXsrK3JsO2NvbnRpbnVlfWlmKGFsPj1sbCl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbk5vbkluY3JlYXNpbmdTZWdtZW50SWRzRXJyb3JNZXNzYWdlJDEoKSl9aWYoYWw8MHx8YWw+PUxhKXRocm93IG5ldyBFcnJvcihnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uU2VnbWVudElkT3V0T2ZSYW5nZUVycm9yTWVzc2FnZSQxKGFsLExhKSk7YWw+b2wmJm5sLmZpbGwod2Esb2wqQWEsYWwqQWEpO2ZvcihsZXQgaWw9c2w7aWw8cmw7KytpbCl7Y29uc3QgY2w9YmFbaWxdO2lmKGNsPDB8fGNsPj1rYVswXSl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbkluZGljZXNPdXRPZlJhbmdlRXJyb3JNZXNzYWdlJDEoaWwsYmFbaWxdLGthWzBdKSk7Zm9yKGxldCB1bD0wO3VsPEFhO3VsKyspbmxbYWwqQWErdWxdKz1oYVtjbCpBYSt1bF19aWYoVGEpZm9yKGxldCBpbD0wO2lsPEFhO2lsKyspbmxbYWwqQWEraWxdLz1ybC1zbDtpZihzbD1ybCwrK3JsLG9sPWFsKzEsYWw9bGwscmw+RWEpYnJlYWt9cmV0dXJuIG9sPExhJiZubC5maWxsKHdhLG9sKkFhLExhKkFhKSxbbmwsZWxdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3FydEltcGwkMT1jcmVhdGVTaW1wbGVVbmFyeUltcGwkMShoYT0+TWF0aC5zcXJ0KGhhKSksc3FydCQzPXVuYXJ5S2VybmVsRnVuYyQyKFNxcnQkMSxoYT0+TWF0aC5zcXJ0KGhhKSksc3FydENvbmZpZyQyPXtrZXJuZWxOYW1lOlNxcnQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNxcnQkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3F1YXJlZERpZmZlcmVuY2VJbXBsJDE9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9Pntjb25zdCB4YT1oYS1hYTtyZXR1cm4geGEqeGF9KSxzcXVhcmVkRGlmZmVyZW5jZSQyPWJpbmFyeUtlcm5lbEZ1bmMkMihTcXVhcmVkRGlmZmVyZW5jZSQxLHNxdWFyZWREaWZmZXJlbmNlSW1wbCQxKSxzcXVhcmVkRGlmZmVyZW5jZUNvbmZpZyQyPXtrZXJuZWxOYW1lOlNxdWFyZWREaWZmZXJlbmNlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzcXVhcmVkRGlmZmVyZW5jZSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzdGF0aWNSZWdleFJlcGxhY2VJbXBsJDE9Y3JlYXRlU2ltcGxlVW5hcnlJbXBsJDEoKGhhLGFhKT0+e2NvbnN0e3BhdHRlcm46eGEscmVwbGFjZUdsb2JhbDpiYSxyZXdyaXRlOlNhfT1hYTtyZXR1cm4gaGEucmVwbGFjZShuZXcgUmVnRXhwKHhhLGJhPyJnIjoiIiksU2EpfSksc3RhdGljUmVnZXhSZXBsYWNlJDI9dW5hcnlLZXJuZWxGdW5jRnJvbUltcGwoU3RhdGljUmVnZXhSZXBsYWNlJDEsc3RhdGljUmVnZXhSZXBsYWNlSW1wbCQxKSxzdGF0aWNSZWdleFJlcGxhY2VDb25maWckMj17a2VybmVsTmFtZTpTdGF0aWNSZWdleFJlcGxhY2UkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnN0YXRpY1JlZ2V4UmVwbGFjZSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdHJpZGVkU2xpY2VJbXBsJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWJ1ZmZlciQxKGhhLGFhLmR0eXBlKTtmb3IobGV0IFRhPTA7VGE8U2Euc2l6ZTtUYSsrKXtjb25zdCB3YT1TYS5pbmRleFRvTG9jKFRhKSxFYT1uZXcgQXJyYXkod2EubGVuZ3RoKTtmb3IobGV0IGthPTA7a2E8RWEubGVuZ3RoO2thKyspRWFba2FdPXdhW2thXSp4YVtrYV0rYmFba2FdO1NhLnNldChhYS5nZXQoLi4uRWEpLC4uLndhKX1yZXR1cm4gU2F9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFN0cmluZ05HcmFtc09wJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEsd2Epe3RoaXMuc2VwYXJhdG9yPWVuY29kZVN0cmluZyQxKGFhKSx0aGlzLm5HcmFtV2lkdGhzPXhhLHRoaXMubGVmdFBhZD1lbmNvZGVTdHJpbmckMShiYSksdGhpcy5yaWdodFBhZD1lbmNvZGVTdHJpbmckMShTYSksdGhpcy5wYWRXaWR0aD1UYSx0aGlzLnByZXNlcnZlU2hvcnQ9d2F9Z2V0UGFkV2lkdGgoYWEpe3JldHVybiBNYXRoLm1pbih0aGlzLnBhZFdpZHRoPDA/YWEtMTp0aGlzLnBhZFdpZHRoLGFhLTEpfWdldE51bU5HcmFtcyhhYSx4YSl7Y29uc3QgYmE9dGhpcy5nZXRQYWRXaWR0aCh4YSk7cmV0dXJuIE1hdGgubWF4KDAsYWErMipiYS14YSsxKX1jcmVhdGVOR3JhbXMoYWEseGEsYmEsU2EsVGEsd2Epe2ZvcihsZXQgRWE9MDtFYTxUYTsrK0VhKXtjb25zdCBrYT10aGlzLmdldFBhZFdpZHRoKHdhKSxBYT1NYXRoLm1heCgwLGthLUVhKSxGYT1NYXRoLm1heCgwLGthLShUYS0oRWErMSkpKSxMYT13YS0oQWErRmEpLGVsPXhhKyhBYT4wPzA6RWEta2EpO2xldCB0bD0wO3RsKz1BYSp0aGlzLmxlZnRQYWQubGVuZ3RoO2ZvcihsZXQgYWw9MDthbDxMYTsrK2FsKXRsKz1hYVtlbCthbF0ubGVuZ3RoO3RsKz1GYSp0aGlzLnJpZ2h0UGFkLmxlbmd0aDtjb25zdCBubD1BYStGYStMYS0xO3RsKz1ubCp0aGlzLnNlcGFyYXRvci5sZW5ndGgsYmFbU2ErRWFdPW5ldyBVaW50OEFycmF5KHRsKTtjb25zdCBzbD1iYVtTYStFYV07bGV0IHJsPTA7Y29uc3Qgb2w9YWw9PmFsLmZvckVhY2gobGw9PnNsW3JsKytdPWxsKTtmb3IobGV0IGFsPTA7YWw8QWE7KythbClvbCh0aGlzLmxlZnRQYWQpLG9sKHRoaXMuc2VwYXJhdG9yKTtmb3IobGV0IGFsPTA7YWw8TGEtMTsrK2FsKW9sKGFhW2VsK2FsXSksb2wodGhpcy5zZXBhcmF0b3IpO2lmKExhPjApe29sKGFhW2VsK0xhLTFdKTtmb3IobGV0IGFsPTA7YWw8RmE7KythbClvbCh0aGlzLnNlcGFyYXRvciksb2wodGhpcy5yaWdodFBhZCl9ZWxzZXtmb3IobGV0IGFsPTA7YWw8RmEtMTsrK2FsKW9sKHRoaXMucmlnaHRQYWQpLG9sKHRoaXMuc2VwYXJhdG9yKTtvbCh0aGlzLnJpZ2h0UGFkKX19fWNvbXB1dGUoYWEseGEpe2NvbnN0IGJhPWFhLmxlbmd0aCxTYT14YS5sZW5ndGg7aWYoU2E+MCl7bGV0IGthPXhhWzBdO2lmKGthIT09MCl0aHJvdyBuZXcgRXJyb3IoYEZpcnN0IHNwbGl0IHZhbHVlIG11c3QgYmUgMCwgZ290ICR7a2F9YCk7Zm9yKGxldCBBYT0xO0FhPFNhOysrQWEpe2xldCBGYT14YVtBYV0+PWthO2lmKEZhPUZhJiZ4YVtBYV08PWJhLCFGYSl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc3BsaXQgdmFsdWUgJHt4YVtBYV19LCBtdXN0IGJlIGluIFske2thfSwgJHtiYX1dYCk7a2E9eGFbQWFdfWlmKGthIT09YmEpdGhyb3cgbmV3IEVycm9yKGBMYXN0IHNwbGl0IHZhbHVlIG11c3QgYmUgZGF0YSBzaXplLiBFeHBlY3RlZCAke2JhfSwgZ290ICR7a2F9YCl9Y29uc3QgVGE9U2EtMSx3YT1nZXRBcnJheUZyb21EVHlwZSQxKCJpbnQzMiIsU2EpO2lmKGJhPT09MHx8U2E9PT0wKXtjb25zdCBrYT1uZXcgQXJyYXkoYmEpO2ZvcihsZXQgQWE9MDtBYTw9VGE7KytBYSl3YVtBYV09MDtyZXR1cm5ba2Esd2FdfXdhWzBdPTA7Zm9yKGxldCBrYT0xO2thPD1UYTsrK2thKXtjb25zdCBBYT14YVtrYV0teGFba2EtMV07bGV0IEZhPTA7dGhpcy5uR3JhbVdpZHRocy5mb3JFYWNoKExhPT57RmErPXRoaXMuZ2V0TnVtTkdyYW1zKEFhLExhKX0pLHRoaXMucHJlc2VydmVTaG9ydCYmQWE+MCYmRmE9PT0wJiYoRmE9MSksd2Fba2FdPXdhW2thLTFdK0ZhfWNvbnN0IEVhPW5ldyBBcnJheSh3YVtUYV0pO2ZvcihsZXQga2E9MDtrYTxUYTsrK2thKXtjb25zdCBBYT14YVtrYV07bGV0IEZhPXdhW2thXTtpZih0aGlzLm5HcmFtV2lkdGhzLmZvckVhY2goTGE9Pntjb25zdCBlbD14YVtrYSsxXS14YVtrYV0sdGw9dGhpcy5nZXROdW1OR3JhbXMoZWwsTGEpO3RoaXMuY3JlYXRlTkdyYW1zKGFhLEFhLEVhLEZhLHRsLExhKSxGYSs9dGx9KSx0aGlzLnByZXNlcnZlU2hvcnQmJkZhPT09d2Fba2FdKXtjb25zdCBMYT14YVtrYSsxXS14YVtrYV07aWYoTGE9PT0wKWNvbnRpbnVlO2NvbnN0IGVsPUxhKzIqdGhpcy5wYWRXaWR0aDt0aGlzLmNyZWF0ZU5HcmFtcyhhYSxBYSxFYSxGYSwxLGVsKX19cmV0dXJuW0VhLHdhXX19O2Z1bmN0aW9uIHN0cmluZ05HcmFtc0ltcGwkMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSl7cmV0dXJuIG5ldyBTdHJpbmdOR3JhbXNPcCQxKHhhLGJhLFNhLFRhLHdhLEVhKS5jb21wdXRlKGhhLGFhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGxpdCQxKGhhLGFhLHhhLGJhKXtpZighaGEubGVuZ3RoKXJldHVybjtpZihhYS5sZW5ndGg9PT0wKXtmb3IobGV0IFRhPTA7VGE8aGEubGVuZ3RoOysrVGEpYmEucHVzaChoYS5zdWJhcnJheShUYSxUYSsxKSk7cmV0dXJufWlmKGFhLmxlbmd0aD09PTEpe2NvbnN0IFRhPWFhWzBdO2xldCB3YT1oYS5pbmRleE9mKFRhKTtmb3IoO3dhIT09LTE7KXtjb25zdCBFYT1oYS5zdWJhcnJheSgwLHdhKTsoIXhhfHxFYS5sZW5ndGghPT0wKSYmYmEucHVzaChFYSksaGE9aGEuc3ViYXJyYXkod2ErMSksd2E9aGEuaW5kZXhPZihUYSl9KCF4YXx8aGEubGVuZ3RoIT09MCkmJmJhLnB1c2goaGEpO3JldHVybn1sZXQgU2E9MDtmb3IobGV0IFRhPTA7VGE8aGEubGVuZ3RoKzE7VGErKylpZihUYT09PWhhLmxlbmd0aHx8YWEuaW5kZXhPZihoYVtUYV0pIT09LTEpe2NvbnN0IHdhPWhhLnN1YmFycmF5KFNhLFRhKTsoIXhhfHx3YS5sZW5ndGghPT0wKSYmYmEucHVzaCh3YSksU2E9VGErMX19ZnVuY3Rpb24gc3RyaW5nU3BsaXRJbXBsJDEoaGEsYWEseGEpe2NvbnN0IGJhPWhhLmxlbmd0aCxTYT1bXTtsZXQgVGE9MCx3YT0wO2NvbnN0IEVhPW5ldyBBcnJheShiYSk7Zm9yKGxldCBlbD0wO2VsPGJhOysrZWwpe2NvbnN0IHRsPVNhLmxlbmd0aDtzcGxpdCQxKGhhW2VsXSxhYSx4YSxTYSk7Y29uc3Qgbmw9U2EubGVuZ3RoLXRsO0VhW2VsXT1ubCxUYSs9bmwsd2E9TWF0aC5tYXgod2EsbmwpfWNvbnN0IGthPWdldEFycmF5RnJvbURUeXBlJDEoImludDMyIixUYSoyKSxBYT1uZXcgQXJyYXkoVGEpLEZhPVtiYSx3YV07bGV0IExhPTA7Zm9yKGxldCBlbD0wO2VsPGJhOysrZWwpZm9yKGxldCB0bD0wO3RsPEVhW2VsXTsrK3RsKWthW0xhKjJdPWVsLGthW0xhKjIrMV09dGwsQWFbTGFdPVNhW0xhXSwrK0xhO3JldHVybltrYSxBYSxGYV19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nVG9IYXNoQnVja2V0RmFzdEltcGwkMShoYSxhYSl7Y29uc3QgeGE9Z2V0QXJyYXlGcm9tRFR5cGUkMSgiaW50MzIiLGhhLmxlbmd0aCk7Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDsrK2JhKXhhW2JhXT1maW5nZXJQcmludDY0JDEoaGFbYmFdKS5tb2R1bG8oYWEpLmdldExvd0JpdHNVbnNpZ25lZCgpO3JldHVybiB4YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzdWJJbXBsJDE9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9PmhhLWFhKSxzdWJDb21wbGV4SW1wbD1jcmVhdGVDb21wbGV4QmluYXJ5S2VybmVsSW1wbCgoaGEsYWEseGEsYmEpPT4oe3JlYWw6aGEteGEsaW1hZzphYS1iYX0pKSxzdWIkMz1iaW5hcnlLZXJuZWxGdW5jJDIoU3ViJDEsc3ViSW1wbCQxLHN1YkNvbXBsZXhJbXBsKSxzdWJDb25maWckMj17a2VybmVsTmFtZTpTdWIkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnN1YiQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0aWxlSW1wbCQxKGhhLGFhKXtjb25zdCB4YT1uZXcgQXJyYXkoaGEucmFuayk7Zm9yKGxldCBTYT0wO1NhPHhhLmxlbmd0aDtTYSsrKXhhW1NhXT1oYS5zaGFwZVtTYV0qYWFbU2FdO2NvbnN0IGJhPWJ1ZmZlciQxKHhhLGhhLmR0eXBlKTtmb3IobGV0IFNhPTA7U2E8YmEudmFsdWVzLmxlbmd0aDsrK1NhKXtjb25zdCBUYT1iYS5pbmRleFRvTG9jKFNhKSx3YT1uZXcgQXJyYXkoaGEucmFuayk7Zm9yKGxldCBrYT0wO2thPHdhLmxlbmd0aDtrYSsrKXdhW2thXT1UYVtrYV0laGEuc2hhcGVba2FdO2NvbnN0IEVhPWhhLmxvY1RvSW5kZXgod2EpO2JhLnZhbHVlc1tTYV09aGEudmFsdWVzW0VhXX1yZXR1cm4gYmF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgY29tcGFyZVBhaXIkMT0oaGEsYWEpPT57Y29uc3QgeGE9YWEudmFsdWUtaGEudmFsdWU7cmV0dXJuIHhhPT09MD9oYS5pbmRleC1hYS5pbmRleDp4YX07ZnVuY3Rpb24gc2VsZWN0JDQoaGEsYWEseGE9MCxiYT1oYS5sZW5ndGgtMSl7Zm9yKDtiYT54YTspe2lmKGJhLXhhPjYwMCl7Y29uc3QgRWE9YmEteGErMSxrYT1hYS14YSsxLEFhPU1hdGgubG9nKEVhKSxGYT0uNSpNYXRoLmV4cCgyKkFhLzMpLExhPS41Kk1hdGguc3FydChBYSpGYSooRWEtRmEpL0VhKSpNYXRoLnNpZ24oa2EtRWEvMiksZWw9TWF0aC5tYXgoeGEsTWF0aC5mbG9vcihhYS1rYSpGYS9FYStMYSkpLHRsPU1hdGgubWluKGJhLE1hdGguZmxvb3IoYWErKEVhLWthKSpGYS9FYStMYSkpO3NlbGVjdCQ0KGhhLGFhLGVsLHRsKX1jb25zdCBTYT1oYVthYV07bGV0IFRhPXhhLHdhPWJhO2Zvcihzd2FwJDEoaGEseGEsYWEpLGNvbXBhcmVQYWlyJDEoaGFbYmFdLFNhKT4wJiZzd2FwJDEoaGEseGEsYmEpO1RhPHdhOyl7Zm9yKHN3YXAkMShoYSxUYSx3YSksVGErKyx3YS0tO2NvbXBhcmVQYWlyJDEoaGFbVGFdLFNhKTwwOylUYT1UYSsxO2Zvcig7Y29tcGFyZVBhaXIkMShoYVt3YV0sU2EpPjA7KXdhPXdhLTF9Y29tcGFyZVBhaXIkMShoYVt4YV0sU2EpPT09MD9zd2FwJDEoaGEseGEsd2EpOih3YT13YSsxLHN3YXAkMShoYSx3YSxiYSkpLHdhPD1hYSYmKHhhPXdhKzEpLGFhPD13YSYmKGJhPXdhLTEpfX1mdW5jdGlvbiB0b3BLSW1wbCQxKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1hYVthYS5sZW5ndGgtMV0sW3dhLEVhXT1baGEubGVuZ3RoL1RhLFRhXSxrYT1nZXRUeXBlZEFycmF5RnJvbURUeXBlJDEoeGEsd2EqYmEpLEFhPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMSgiaW50MzIiLHdhKmJhKTtmb3IobGV0IExhPTA7TGE8d2E7TGErKyl7Y29uc3QgZWw9TGEqRWEsdGw9aGEuc3ViYXJyYXkoZWwsZWwrRWEpO2xldCBubD1uZXcgQXJyYXkodGwubGVuZ3RoKTt0bC5mb3JFYWNoKChhbCxsbCk9Pm5sW2xsXT17dmFsdWU6YWwsaW5kZXg6bGx9KSxiYTxubC5sZW5ndGgmJihzZWxlY3QkNChubCxiYSksbmw9bmwuc2xpY2UoMCxiYSkpLFNhJiZubC5zb3J0KGNvbXBhcmVQYWlyJDEpO2NvbnN0IHNsPUxhKmJhLHJsPWthLnN1YmFycmF5KHNsLHNsK2JhKSxvbD1BYS5zdWJhcnJheShzbCxzbCtiYSk7Zm9yKGxldCBhbD0wO2FsPGJhO2FsKyspcmxbYWxdPW5sW2FsXS52YWx1ZSxvbFthbF09bmxbYWxdLmluZGV4fWNvbnN0IEZhPWFhLnNsaWNlKCk7cmV0dXJuIEZhW0ZhLmxlbmd0aC0xXT1iYSxbYnVmZmVyJDEoRmEseGEsa2EpLGJ1ZmZlciQxKEZhLCJpbnQzMiIsQWEpXX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB1bmlxdWVJbXBsJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPXBhcnNlQXhpc1BhcmFtJDEoYWEseGEpWzBdLFRhPVsxLHhhWzBdLDFdO2ZvcihsZXQgbmw9MDtubDxTYTtubCsrKVRhWzBdKj14YVtubF07VGFbMV09eGFbU2FdO2ZvcihsZXQgbmw9U2ErMTtubDx4YS5sZW5ndGg7bmwrKylUYVsyXSo9eGFbbmxdO2NvbnN0IHdhPW5ldyBNYXAsRWE9bmV3IEludDMyQXJyYXkoeGFbU2FdKSxrYT1uZXcgVGVuc29yQnVmZmVyJDEoVGEsYmEsaGEpLEFhPVtdLEZhPVRhWzBdPT09MSYmVGFbMl09PT0xO2ZvcihsZXQgbmw9MDtubDx4YVtTYV07bmwrKyl7bGV0IHNsO2lmKEZhKXNsPWhhW25sXS50b1N0cmluZygpO2Vsc2V7Y29uc3Qgb2w9W107Zm9yKGxldCBhbD0wO2FsPFRhWzBdO2FsKyspZm9yKGxldCBsbD0wO2xsPFRhWzJdO2xsKyspb2wucHVzaChrYS5nZXQoYWwsbmwsbGwpKTtzbD1vbC5qb2luKCIsIil9Y29uc3Qgcmw9d2EuZ2V0KHNsKTtpZihybCE9bnVsbClFYVtubF09cmw7ZWxzZXtjb25zdCBvbD13YS5zaXplO3dhLnNldChzbCxvbCksRWFbbmxdPW9sLEFhLnB1c2gobmwpfX1jb25zdCBMYT1UYS5zbGljZSgpO0xhWzFdPXdhLnNpemU7Y29uc3QgZWw9bmV3IFRlbnNvckJ1ZmZlciQxKExhLGJhKTtBYS5mb3JFYWNoKChubCxzbCk9Pntmb3IobGV0IHJsPTA7cmw8VGFbMF07cmwrKylmb3IobGV0IG9sPTA7b2w8VGFbMl07b2wrKyllbC5zZXQoa2EuZ2V0KHJsLG5sLG9sKSxybCxzbCxvbCl9KTtjb25zdCB0bD14YS5zbGljZSgpO3JldHVybiB0bFtTYV09TGFbMV0se291dHB1dFZhbHVlczplbC52YWx1ZXMsb3V0cHV0U2hhcGU6dGwsaW5kaWNlczpFYX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovdmFyIHNoYXJlZCQxPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZEltcGw6YWRkSW1wbCQxLGJpbmNvdW50SW1wbDpiaW5jb3VudEltcGwkMSxiaW5jb3VudFJlZHVjZUltcGw6YmluY291bnRSZWR1Y2VJbXBsJDEsYml0d2lzZUFuZEltcGw6Yml0d2lzZUFuZEltcGwkMSxjYXN0SW1wbDpjYXN0SW1wbCQxLGNlaWxJbXBsOmNlaWxJbXBsJDEsY29uY2F0SW1wbDpjb25jYXRJbXBsJDMsZXF1YWxJbXBsOmVxdWFsSW1wbCQxLGV4cEltcGw6ZXhwSW1wbCQxLGV4cG0xSW1wbDpleHBtMUltcGwkMSxmbG9vckRpdkltcGw6Zmxvb3JEaXZJbXBsJDEsZmxvb3JJbXBsOmZsb29ySW1wbCQxLGdhdGhlck5kSW1wbDpnYXRoZXJOZEltcGwkMSxnYXRoZXJWMkltcGw6Z2F0aGVyVjJJbXBsJDEsZ3JlYXRlckVxdWFsSW1wbDpncmVhdGVyRXF1YWxJbXBsJDEsZ3JlYXRlckltcGw6Z3JlYXRlckltcGwkMSxsZXNzRXF1YWxJbXBsOmxlc3NFcXVhbEltcGwkMSxsZXNzSW1wbDpsZXNzSW1wbCQxLGxpblNwYWNlSW1wbDpsaW5TcGFjZUltcGwkMSxsb2dJbXBsOmxvZ0ltcGwkMSxtYXhJbXBsOm1heEltcGwkMyxtYXhpbXVtSW1wbDptYXhpbXVtSW1wbCQxLG1pbmltdW1JbXBsOm1pbmltdW1JbXBsJDEsbXVsdGlwbHlJbXBsOm11bHRpcGx5SW1wbCQxLG5lZ0ltcGw6bmVnSW1wbCQxLG5vdEVxdWFsSW1wbDpub3RFcXVhbEltcGwkMSxwcm9kSW1wbDpwcm9kSW1wbCQxLHJhZ2dlZEdhdGhlckltcGw6cmFnZ2VkR2F0aGVySW1wbCQxLHJhZ2dlZFJhbmdlSW1wbDpyYWdnZWRSYW5nZUltcGwkMSxyYWdnZWRUZW5zb3JUb1RlbnNvckltcGw6cmFnZ2VkVGVuc29yVG9UZW5zb3JJbXBsJDEscmFuZ2VJbXBsOnJhbmdlSW1wbCQxLHJzcXJ0SW1wbDpyc3FydEltcGwkMSxzY2F0dGVySW1wbDpzY2F0dGVySW1wbCQxLHNpZ21vaWRJbXBsOnNpZ21vaWRJbXBsJDEsc2ltcGxlQWJzSW1wbDpzaW1wbGVBYnNJbXBsJDEsc2xpY2VJbXBsOnNsaWNlSW1wbCQxLHNwYXJzZUZpbGxFbXB0eVJvd3NJbXBsOnNwYXJzZUZpbGxFbXB0eVJvd3NJbXBsJDEsc3BhcnNlUmVzaGFwZUltcGw6c3BhcnNlUmVzaGFwZUltcGwkMSxzcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbDpzcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbCQxLHNxcnRJbXBsOnNxcnRJbXBsJDEsc3F1YXJlZERpZmZlcmVuY2VJbXBsOnNxdWFyZWREaWZmZXJlbmNlSW1wbCQxLHN0YXRpY1JlZ2V4UmVwbGFjZUltcGw6c3RhdGljUmVnZXhSZXBsYWNlSW1wbCQxLHN0cmlkZWRTbGljZUltcGw6c3RyaWRlZFNsaWNlSW1wbCQxLHN0cmluZ05HcmFtc0ltcGw6c3RyaW5nTkdyYW1zSW1wbCQxLHN0cmluZ1NwbGl0SW1wbDpzdHJpbmdTcGxpdEltcGwkMSxzdHJpbmdUb0hhc2hCdWNrZXRGYXN0SW1wbDpzdHJpbmdUb0hhc2hCdWNrZXRGYXN0SW1wbCQxLHN1YkltcGw6c3ViSW1wbCQxLHRpbGVJbXBsOnRpbGVJbXBsJDEsdG9wS0ltcGw6dG9wS0ltcGwkMSx0cmFuc3Bvc2VJbXBsOnRyYW5zcG9zZUltcGwkMyx1bmlxdWVJbXBsOnVuaXF1ZUltcGwkMX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3JlZ2lzdGVyQmFja2VuZCQxKCJjcHUiLCgpPT5uZXcgTWF0aEJhY2tlbmRDUFUsMSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBlbHUkMz11bmFyeUtlcm5lbEZ1bmMkMihFbHUkMixoYT0+aGE+PTA/aGE6TWF0aC5leHAoaGEpLTEpLGVsdUNvbmZpZyQyPXtrZXJuZWxOYW1lOkVsdSQyLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZWx1JDN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxlYWt5UmVsdSQzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHthbHBoYTpUYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFtTYV0sImxlYWt5UmVsdSIpO2NvbnN0IHdhPXNpemVGcm9tU2hhcGUkMShTYS5zaGFwZSksRWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsa2E9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKCJmbG9hdDMyIix3YSk7Zm9yKGxldCBBYT0wO0FhPEVhLmxlbmd0aDtBYSsrKWthW0FhXT1FYVtBYV08MD9UYSpFYVtBYV06RWFbQWFdO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhTYS5zaGFwZSwiZmxvYXQzMiIsa2EpfWNvbnN0IGxlYWt5UmVsdUNvbmZpZyQyPXtrZXJuZWxOYW1lOkxlYWt5UmVsdSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bGVha3lSZWx1JDN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcHJlbHVJbXBsPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYTwwP2FhKmhhOmhhKTtmdW5jdGlvbiBwcmVsdSQzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3g6YmEsYWxwaGE6U2F9PWFhO2Fzc2VydE5vdENvbXBsZXgkMihbYmEsU2FdLCJwcmVsdSIpO2NvbnN0IFRhPXhhLmRhdGEuZ2V0KGJhLmRhdGFJZCkudmFsdWVzLHdhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLFtFYSxrYV09cHJlbHVJbXBsKGJhLnNoYXBlLFNhLnNoYXBlLFRhLHdhLCJmbG9hdDMyIik7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKGthLCJmbG9hdDMyIixFYSl9Y29uc3QgcHJlbHVDb25maWckMj17a2VybmVsTmFtZTpQcmVsdSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cHJlbHUkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCByZWx1JDM9dW5hcnlLZXJuZWxGdW5jJDIoUmVsdSQyLGhhPT5NYXRoLm1heCgwLGhhKSkscmVsdUNvbmZpZyQyPXtrZXJuZWxOYW1lOlJlbHUkMixiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnJlbHUkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCByZWx1NiQzPXVuYXJ5S2VybmVsRnVuYyQyKFJlbHU2JDIsaGE9Pk1hdGgubWluKE1hdGgubWF4KDAsaGEpLDYpKSxyZWx1NkNvbmZpZyQyPXtrZXJuZWxOYW1lOlJlbHU2JDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyZWx1NiQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhcHBseUFjdGl2YXRpb24kMShoYSxhYSx4YSxiYSxTYSl7aWYoeGE9PT0ibGluZWFyIilyZXR1cm4gaWRlbnRpdHkkMih7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmhhfSk7aWYoeGE9PT0icmVsdSIpcmV0dXJuIHJlbHUkMyh7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmhhfSk7aWYoeGE9PT0iZWx1IilyZXR1cm4gZWx1JDMoe2lucHV0czp7eDphYX0sYmFja2VuZDpoYX0pO2lmKHhhPT09InJlbHU2IilyZXR1cm4gcmVsdTYkMyh7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmhhfSk7aWYoeGE9PT0icHJlbHUiKXJldHVybiBwcmVsdSQzKHtpbnB1dHM6e3g6YWEsYWxwaGE6YmF9LGJhY2tlbmQ6aGF9KTtpZih4YT09PSJsZWFreXJlbHUiKXJldHVybiBsZWFreVJlbHUkMyh7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmhhLGF0dHJzOnthbHBoYTpTYX19KTtpZih4YT09PSJzaWdtb2lkIilyZXR1cm4gc2lnbW9pZCQzKHtpbnB1dHM6e3g6YWF9LGJhY2tlbmQ6aGF9KTt0aHJvdyBuZXcgRXJyb3IoYEFjdGl2YXRpb24gJHt4YX0gaGFzIG5vdCBiZWVuIGltcGxlbWVudGVkIGZvciB0aGUgQ1BVIGJhY2tlbmQuYCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaGFwZSQzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtzaGFwZTpUYX09YmEsd2E9c2l6ZUZyb21TaGFwZSQxKFNhLnNoYXBlKSxFYT1pbmZlckZyb21JbXBsaWNpdFNoYXBlJDEoVGEsd2EpLGthPXNpemVGcm9tU2hhcGUkMShFYSk7YXNzZXJ0JDIod2E9PT1rYSwoKT0+YFRoZSBuZXcgc2hhcGUgKCR7RWF9KSBoYXMgJHtrYX0gZWxlbWVudHMgYW5kIHRoZSBvbGQgc2hhcGUgKCR7U2Euc2hhcGV9KSBoYXMgJHt3YX0gZWxlbWVudHMuIFRoZSBuZXcgc2hhcGUgYW5kIG9sZCBzaGFwZSBtdXN0IGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGVsZW1lbnRzLmApLHhhLmluY1JlZihTYS5kYXRhSWQpO2NvbnN0IEFhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCk7aWYoQWEuY29tcGxleFRlbnNvckluZm9zIT1udWxsKXtjb25zdCBGYT1BYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbCxMYT1BYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZztGYS5zaGFwZT1FYSxMYS5zaGFwZT1FYX1yZXR1cm57ZGF0YUlkOlNhLmRhdGFJZCxzaGFwZTpFYSxkdHlwZTpTYS5kdHlwZX19Y29uc3QgcmVzaGFwZUNvbmZpZyQyPXtrZXJuZWxOYW1lOlJlc2hhcGUkMixiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnJlc2hhcGUkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiYXRjaE1hdE11bCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2E6U2EsYjpUYX09YWEse3RyYW5zcG9zZUE6d2EsdHJhbnNwb3NlQjpFYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFtTYSxUYV0sIm1hdE11bCIpO2NvbnN0IGthPVNhLnNoYXBlLmxlbmd0aCxBYT1UYS5zaGFwZS5sZW5ndGgsRmE9d2E/U2Euc2hhcGVba2EtMl06U2Euc2hhcGVba2EtMV0sTGE9RWE/VGEuc2hhcGVbQWEtMV06VGEuc2hhcGVbQWEtMl0sZWw9d2E/U2Euc2hhcGVba2EtMV06U2Euc2hhcGVba2EtMl0sdGw9RWE/VGEuc2hhcGVbQWEtMl06VGEuc2hhcGVbQWEtMV0sbmw9U2Euc2hhcGUuc2xpY2UoMCwtMiksc2w9VGEuc2hhcGUuc2xpY2UoMCwtMikscmw9c2l6ZUZyb21TaGFwZSQxKG5sKSxvbD1zaXplRnJvbVNoYXBlJDEoc2wpLGxsPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoU2Euc2hhcGUuc2xpY2UoMCwtMiksVGEuc2hhcGUuc2xpY2UoMCwtMikpLmNvbmNhdChbZWwsdGxdKTthc3NlcnQkMihGYT09PUxhLCgpPT5gRXJyb3IgaW4gbWF0TXVsOiBpbm5lciBzaGFwZXMgKCR7RmF9KSBhbmQgKCR7TGF9KSBvZiBUZW5zb3JzIHdpdGggc2hhcGVzICR7U2Euc2hhcGV9IGFuZCAke1RhLnNoYXBlfSBhbmQgdHJhbnNwb3NlQT0ke3dhfSBhbmQgdHJhbnNwb3NlQj0ke0VhfSBtdXN0IG1hdGNoLmApO2NvbnN0IGlsPXdhP1tybCxGYSxlbF06W3JsLGVsLEZhXSxjbD1FYT9bb2wsdGwsTGFdOltvbCxMYSx0bF0sdWw9cmVzaGFwZSQzKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmlsfX0pLGRsPXJlc2hhcGUkMyh7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpjbH19KSxobD13YT91bC5zaGFwZVsxXTp1bC5zaGFwZVsyXSxwbD13YT91bC5zaGFwZVsyXTp1bC5zaGFwZVsxXSxmbD1FYT9kbC5zaGFwZVsxXTpkbC5zaGFwZVsyXSxtbD1NYXRoLm1heChybCxvbCksZ2w9eGEuZGF0YS5nZXQodWwuZGF0YUlkKS52YWx1ZXMsJGw9eGEuZGF0YS5nZXQoZGwuZGF0YUlkKS52YWx1ZXMseGw9Y29tcHV0ZVN0cmlkZXMkMSh1bC5zaGFwZSkseWw9Y29tcHV0ZVN0cmlkZXMkMShkbC5zaGFwZSksW2JsLFNsLENsXT13YT9beGxbMF0sMSx4bFsxXV06W3hsWzBdLHhsWzFdLDFdLFtUbCx3bCxJbF09RWE/WzEseWxbMV0seWxbMF1dOlt5bFsxXSwxLHlsWzBdXSxObD1wbCpmbCx2bD1idWZmZXIkMShbbWwscGwsZmxdLHVsLmR0eXBlKSxrbD12bC52YWx1ZXMsRWw9eGEuYmxvY2tTaXplO2ZvcihsZXQgQWw9MDtBbDxtbDtBbCsrKXtjb25zdCBSbD1BbCVybCxQbD1BbCVvbDtmb3IobGV0IERsPTA7RGw8cGw7RGwrPUVsKXtjb25zdCBfbD1NYXRoLm1pbihEbCtFbCxwbCk7Zm9yKGxldCBGbD0wO0ZsPGZsO0ZsKz1FbCl7Y29uc3QgT2w9TWF0aC5taW4oRmwrRWwsZmwpO2ZvcihsZXQgTWw9MDtNbDxobDtNbCs9RWwpe2NvbnN0IFVsPU1hdGgubWluKE1sK0VsLGhsKTtmb3IobGV0IEJsPURsO0JsPF9sO0JsKyspZm9yKGxldCBMbD1GbDtMbDxPbDtMbCsrKXtsZXQgemw9MDtmb3IobGV0IFZsPU1sO1ZsPFVsO1ZsKyspe2NvbnN0IHFsPWdsW1JsKmJsK0JsKlNsK1ZsKkNsXSxHbD0kbFtWbCpUbCtMbCp3bCtQbCpJbF07emwrPXFsKkdsfWtsW0FsKk5sKyhCbCpmbCtMbCldKz16bH19fX19cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHVsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhkbCkseGEubWFrZVRlbnNvckluZm8obGwsdmwuZHR5cGUsdmwudmFsdWVzKX1jb25zdCBiYXRjaE1hdE11bENvbmZpZyQyPXtrZXJuZWxOYW1lOkJhdGNoTWF0TXVsJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpiYXRjaE1hdE11bCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIF9mdXNlZE1hdE11bCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2E6U2EsYjpUYSxiaWFzOndhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWF9PWFhLHt0cmFuc3Bvc2VBOmthLHRyYW5zcG9zZUI6QWEsYWN0aXZhdGlvbjpGYSxsZWFreXJlbHVBbHBoYTpMYX09YmE7bGV0IGVsLHRsLG5sO2NvbnN0IHNsPVtdO2VsPWJhdGNoTWF0TXVsJDIoe2lucHV0czp7YTpTYSxiOlRhfSxhdHRyczp7dHJhbnNwb3NlQTprYSx0cmFuc3Bvc2VCOkFhfSxiYWNrZW5kOnhhfSksd2EmJih0bD1hZGQkMih7aW5wdXRzOnthOmVsLGI6d2F9LGJhY2tlbmQ6eGF9KSxzbC5wdXNoKGVsKSxlbD10bCksRmEmJihubD1hcHBseUFjdGl2YXRpb24kMSh4YSxlbCxGYSxFYSxMYSksc2wucHVzaChlbCksZWw9bmwpO2Zvcihjb25zdCBvbCBvZiBzbCl4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhvbCk7cmV0dXJuIGVsfWNvbnN0IF9mdXNlZE1hdE11bENvbmZpZyQyPXtrZXJuZWxOYW1lOl9GdXNlZE1hdE11bCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6X2Z1c2VkTWF0TXVsJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYWNvcyQyPXVuYXJ5S2VybmVsRnVuYyQyKEFjb3MkMSxoYT0+TWF0aC5hY29zKGhhKSksYWNvc0NvbmZpZyQyPXtrZXJuZWxOYW1lOkFjb3MkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmFjb3MkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhY29zaCQyPXVuYXJ5S2VybmVsRnVuYyQyKEFjb3NoJDEsaGE9Pk1hdGguYWNvc2goaGEpKSxhY29zaENvbmZpZyQyPXtrZXJuZWxOYW1lOkFjb3NoJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphY29zaCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhZGROJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSxiYT1hYTthc3NlcnROb3RDb21wbGV4JDIoYWEsImFkZE4iKTtjb25zdCBTYT1iYS5tYXAoRWE9PnhhLmRhdGEuZ2V0KEVhLmRhdGFJZCkudmFsdWVzKSxUYT1idWZmZXIkMShiYVswXS5zaGFwZSxiYVswXS5kdHlwZSksd2E9VGEudmFsdWVzO2ZvcihsZXQgRWE9MDtFYTxiYS5sZW5ndGg7RWErKyl7Y29uc3Qga2E9U2FbRWFdO2ZvcihsZXQgQWE9MDtBYTx3YS5sZW5ndGg7QWErKyl3YVtBYV0rPWthW0FhXX1yZXR1cm4geGEubWFrZVRlbnNvckluZm8oVGEuc2hhcGUsVGEuZHR5cGUsVGEudmFsdWVzKX1jb25zdCBhZGROQ29uZmlnJDI9e2tlcm5lbE5hbWU6QWRkTiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6YWRkTiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhbGwkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJhbGwiKTtjb25zdCBFYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtsZXQga2E9RWE7Y29uc3QgQWE9Z2V0QXhlc1Blcm11dGF0aW9uJDEoa2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQgRmE9U2E7QWEhPW51bGwmJihGYT10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkFhfX0pLGthPWdldElubmVyTW9zdEF4ZXMkMShrYS5sZW5ndGgsU2Euc2hhcGUubGVuZ3RoKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgiYWxsIixrYSxGYS5zaGFwZS5sZW5ndGgpO2NvbnN0W0xhLGVsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoRmEuc2hhcGUsa2EpLHRsPXNpemVGcm9tU2hhcGUkMShlbCksbmw9bWFrZVplcm9zVHlwZWRBcnJheSQxKHNpemVGcm9tU2hhcGUkMShMYSksRmEuZHR5cGUpLHNsPXhhLmRhdGEuZ2V0KEZhLmRhdGFJZCkudmFsdWVzO2ZvcihsZXQgb2w9MDtvbDxubC5sZW5ndGg7KytvbCl7Y29uc3QgYWw9b2wqdGw7bGV0IGxsPXNsW2FsXTtmb3IobGV0IGlsPTA7aWw8dGw7KytpbCl7Y29uc3QgY2w9c2xbYWwraWxdO2xsPWxsJiZjbH1ubFtvbF09bGx9QWEhPW51bGwmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKTtjb25zdCBybD14YS5tYWtlVGVuc29ySW5mbyhMYSxGYS5kdHlwZSxubCk7aWYod2Epe2NvbnN0IG9sPWV4cGFuZFNoYXBlVG9LZWVwRGltJDEoTGEsRWEpLGFsPXJlc2hhcGUkMyh7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpvbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpLGFsfXJldHVybiBybH1jb25zdCBhbGxDb25maWckMj17a2VybmVsTmFtZTpBbGwkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmFsbCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhbnkkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJhbnkiKTtjb25zdCBFYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtsZXQga2E9RWE7Y29uc3QgQWE9Z2V0QXhlc1Blcm11dGF0aW9uJDEoa2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQgRmE9U2E7QWEhPW51bGwmJihGYT10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkFhfX0pLGthPWdldElubmVyTW9zdEF4ZXMkMShrYS5sZW5ndGgsU2Euc2hhcGUubGVuZ3RoKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgiYW55IixrYSxGYS5zaGFwZS5sZW5ndGgpO2NvbnN0W0xhLGVsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoRmEuc2hhcGUsa2EpLHRsPXNpemVGcm9tU2hhcGUkMShlbCksbmw9bWFrZVplcm9zVHlwZWRBcnJheSQxKHNpemVGcm9tU2hhcGUkMShMYSksRmEuZHR5cGUpLHNsPXhhLmRhdGEuZ2V0KEZhLmRhdGFJZCkudmFsdWVzO2ZvcihsZXQgb2w9MDtvbDxubC5sZW5ndGg7KytvbCl7Y29uc3QgYWw9b2wqdGw7bGV0IGxsPXNsW2FsXTtmb3IobGV0IGlsPTA7aWw8dGw7KytpbCl7Y29uc3QgY2w9c2xbYWwraWxdO2xsPWxsfHxjbH1ubFtvbF09bGx9QWEhPW51bGwmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKTtjb25zdCBybD14YS5tYWtlVGVuc29ySW5mbyhMYSxGYS5kdHlwZSxubCk7aWYod2Epe2NvbnN0IG9sPWV4cGFuZFNoYXBlVG9LZWVwRGltJDEoTGEsRWEpLGFsPXJlc2hhcGUkMyh7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpvbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpLGFsfXJldHVybiBybH1jb25zdCBhbnlDb25maWckMj17a2VybmVsTmFtZTpBbnkkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmFueSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhcmdNYXgkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJhcmdNYXgiKTtsZXQgd2E9cGFyc2VBeGlzUGFyYW0kMShUYSxTYS5zaGFwZSk7Y29uc3QgRWE9Z2V0QXhlc1Blcm11dGF0aW9uJDEod2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQga2E9U2E7Y29uc3QgQWE9W107RWEhPW51bGwmJihrYT10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkVhfX0pLEFhLnB1c2goa2EpLHdhPWdldElubmVyTW9zdEF4ZXMkMSh3YS5sZW5ndGgsa2Euc2hhcGUubGVuZ3RoKSksd2E9W3dhWzBdXSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcyQxKCJhcmdNYXgiLHdhLGthLnNoYXBlLmxlbmd0aCk7Y29uc3RbRmEsTGFdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShrYS5zaGFwZSx3YSksZWw9c2l6ZUZyb21TaGFwZSQxKEZhKSx0bD1tYWtlWmVyb3NUeXBlZEFycmF5JDEoZWwsImludDMyIiksbmw9c2l6ZUZyb21TaGFwZSQxKExhKSxzbD14YS5kYXRhLmdldChrYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IHJsPTA7cmw8dGwubGVuZ3RoOysrcmwpe2NvbnN0IG9sPXJsKm5sO2xldCBhbD1zbFtvbF0sbGw9MDtmb3IobGV0IGlsPTA7aWw8bmw7KytpbCl7Y29uc3QgY2w9c2xbb2wraWxdO2NsPmFsJiYoYWw9Y2wsbGw9aWwpfXRsW3JsXT1sbH1yZXR1cm4gQWEuZm9yRWFjaChybD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpKSx4YS5tYWtlVGVuc29ySW5mbyhGYSwiaW50MzIiLHRsKX1jb25zdCBhcmdNYXhDb25maWckMj17a2VybmVsTmFtZTpBcmdNYXgkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmFyZ01heCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhcmdNaW4kMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJhcmdNaW4iKTtsZXQgd2E9cGFyc2VBeGlzUGFyYW0kMShUYSxTYS5zaGFwZSk7Y29uc3QgRWE9Z2V0QXhlc1Blcm11dGF0aW9uJDEod2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQga2E9U2E7Y29uc3QgQWE9W107RWEhPW51bGwmJihrYT10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkVhfX0pLEFhLnB1c2goa2EpLHdhPWdldElubmVyTW9zdEF4ZXMkMSh3YS5sZW5ndGgsa2Euc2hhcGUubGVuZ3RoKSksd2E9W3dhWzBdXSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcyQxKCJhcmdNaW4iLHdhLGthLnNoYXBlLmxlbmd0aCk7Y29uc3RbRmEsTGFdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShrYS5zaGFwZSx3YSksZWw9c2l6ZUZyb21TaGFwZSQxKEZhKSx0bD1tYWtlWmVyb3NUeXBlZEFycmF5JDEoZWwsImludDMyIiksbmw9c2l6ZUZyb21TaGFwZSQxKExhKSxzbD14YS5kYXRhLmdldChrYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IHJsPTA7cmw8dGwubGVuZ3RoOysrcmwpe2NvbnN0IG9sPXJsKm5sO2xldCBhbD1zbFtvbF0sbGw9MDtmb3IobGV0IGlsPTA7aWw8bmw7KytpbCl7Y29uc3QgY2w9c2xbb2wraWxdO2NsPGFsJiYoYWw9Y2wsbGw9aWwpfXRsW3JsXT1sbH1yZXR1cm4gQWEuZm9yRWFjaChybD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpKSx4YS5tYWtlVGVuc29ySW5mbyhGYSwiaW50MzIiLHRsKX1jb25zdCBhcmdNaW5Db25maWckMj17a2VybmVsTmFtZTpBcmdNaW4kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmFyZ01pbiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGFzaW4kMj11bmFyeUtlcm5lbEZ1bmMkMihBc2luJDEsaGE9Pk1hdGguYXNpbihoYSkpLGFzaW5Db25maWckMj17a2VybmVsTmFtZTpBc2luJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphc2luJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYXNpbmgkMj11bmFyeUtlcm5lbEZ1bmMkMihBc2luaCQxLGhhPT5NYXRoLmFzaW5oKGhhKSksYXNpbmhDb25maWckMj17a2VybmVsTmFtZTpBc2luaCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6YXNpbmgkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBhdGFuJDI9dW5hcnlLZXJuZWxGdW5jJDIoQXRhbiQxLGhhPT5NYXRoLmF0YW4oaGEpKSxhdGFuQ29uZmlnJDI9e2tlcm5lbE5hbWU6QXRhbiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6YXRhbiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGF0YW4ySW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsJDEoKGhhLGFhKT0+TWF0aC5hdGFuMihoYSxhYSkpLGF0YW4yJDI9YmluYXJ5S2VybmVsRnVuYyQyKEF0YW4yJDEsYXRhbjJJbXBsKSxhdGFuMkNvbmZpZyQyPXtrZXJuZWxOYW1lOkF0YW4yJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphdGFuMiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGF0YW5oJDI9dW5hcnlLZXJuZWxGdW5jJDIoQXRhbmgkMSxoYT0+TWF0aC5hdGFuaChoYSkpLGF0YW5oQ29uZmlnJDI9e2tlcm5lbE5hbWU6QXRhbmgkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmF0YW5oJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHBvb2woaGEsYWEseGEsYmEsU2EsVGEpe2NvbnN0IHdhPVNhLnN0cmlkZUhlaWdodCxFYT1TYS5zdHJpZGVXaWR0aCxrYT1TYS5kaWxhdGlvbkhlaWdodCxBYT1TYS5kaWxhdGlvbldpZHRoLEZhPVNhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCxMYT1TYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxlbD1TYS5wYWRJbmZvLnRvcCx0bD1TYS5wYWRJbmZvLmxlZnQsbmw9VGE9PT0ibWF4Ij9OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLHNsPWJ1ZmZlciQxKFNhLm91dFNoYXBlLHhhKSxybD1zbC52YWx1ZXMsb2w9U2Eub3V0U2hhcGVbMV0qU2Eub3V0U2hhcGVbMl0qU2Eub3V0U2hhcGVbM10sYWw9U2Eub3V0U2hhcGVbMl0qU2Eub3V0U2hhcGVbM10sbGw9U2Eub3V0U2hhcGVbM107Zm9yKGxldCBpbD0wO2lsPFNhLmJhdGNoU2l6ZTsrK2lsKXtjb25zdCBjbD1pbCpvbCx1bD1pbCpiYVswXTtmb3IobGV0IGRsPTA7ZGw8U2EuaW5DaGFubmVsczsrK2RsKWZvcihsZXQgaGw9MDtobDxTYS5vdXRIZWlnaHQ7KytobCl7Y29uc3QgcGw9aGwqd2EtZWwsZmw9TWF0aC5tYXgoMCxwbCksbWw9TWF0aC5taW4oU2EuaW5IZWlnaHQsRmErcGwpLGdsPWNsK2hsKmFsO2ZvcihsZXQgJGw9MDskbDxTYS5vdXRXaWR0aDsrKyRsKXtjb25zdCB4bD0kbCpFYS10bCx5bD1NYXRoLm1heCgwLHhsKSxibD1NYXRoLm1pbihTYS5pbldpZHRoLExhK3hsKTtsZXQgU2w9bmwsQ2w9MCxUbD0wO2ZvcihsZXQgSWw9Zmw7SWw8bWw7SWwrPWthKXtjb25zdCBObD11bCtJbCpiYVsxXTtmb3IobGV0IHZsPXlsO3ZsPGJsO3ZsKz1BYSl7Y29uc3Qga2w9TmwrdmwqYmFbMl0sRWw9aGFba2wrZGxdO1RhPT09Im1heCImJkVsPlNsP1NsPUVsOlRhPT09ImF2ZyImJihDbCs9RWwsVGwrKyl9aWYoaXNOYU4oU2wpKWJyZWFrfWNvbnN0IHdsPWdsKyRsKmxsK2RsO3JsW3dsXT1UYT09PSJhdmciP0NsL1RsOlNsfX19cmV0dXJuIHNsfWZ1bmN0aW9uIG1heFBvb2xQb3NpdGlvbnMoaGEsYWEseGEsYmEsU2E9ITEsVGE9ITEpe2NvbnN0IHdhPWJ1ZmZlciQxKGJhLm91dFNoYXBlLCJpbnQzMiIpLEVhPWJhLnN0cmlkZUhlaWdodCxrYT1iYS5zdHJpZGVXaWR0aCxBYT1iYS5kaWxhdGlvbkhlaWdodCxGYT1iYS5kaWxhdGlvbldpZHRoLExhPWJhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCxlbD1iYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCx0bD1iYS5wYWRJbmZvLnRvcCxubD1iYS5wYWRJbmZvLmxlZnQsc2w9YnVmZmVyJDEoYWEseGEsaGEpO2ZvcihsZXQgcmw9MDtybDxiYS5iYXRjaFNpemU7KytybClmb3IobGV0IG9sPTA7b2w8YmEuaW5DaGFubmVsczsrK29sKWZvcihsZXQgYWw9MDthbDxiYS5vdXRIZWlnaHQ7KythbCl7Y29uc3QgbGw9YWwqRWEtdGw7bGV0IGlsPWxsO2Zvcig7aWw8MDspaWwrPUFhO2NvbnN0IGNsPU1hdGgubWluKGJhLmluSGVpZ2h0LExhK2xsKTtmb3IobGV0IHVsPTA7dWw8YmEub3V0V2lkdGg7Kyt1bCl7Y29uc3QgZGw9dWwqa2Etbmw7bGV0IGhsPWRsO2Zvcig7aGw8MDspaGwrPUZhO2NvbnN0IHBsPU1hdGgubWluKGJhLmluV2lkdGgsZWwrZGwpO2xldCBmbD1OdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksbWw9LTE7Zm9yKGxldCBnbD1pbDtnbDxjbDtnbCs9QWEpe2NvbnN0ICRsPWdsLWxsO2ZvcihsZXQgeGw9aGw7eGw8cGw7eGwrPUZhKXtjb25zdCB5bD14bC1kbCxibD1zbC5nZXQocmwsZ2wseGwsb2wpO2JsPmZsJiYoZmw9YmwsU2E/bWw9VGE/KChybCpiYS5pbkhlaWdodCtnbCkqYmEuaW5XaWR0aCt4bCkqYmEuaW5DaGFubmVscytvbDooZ2wqYmEuaW5XaWR0aCt4bCkqYmEuaW5DaGFubmVscytvbDptbD0kbCplbCt5bCl9fXdhLnNldChtbCxybCxhbCx1bCxvbCl9fXJldHVybiB3YX1mdW5jdGlvbiBwb29sM2QoaGEsYWEseGEsYmEsU2EsVGEpe2NvbnN0IHdhPVNhLnN0cmlkZURlcHRoLEVhPVNhLnN0cmlkZUhlaWdodCxrYT1TYS5zdHJpZGVXaWR0aCxBYT1TYS5kaWxhdGlvbkRlcHRoLEZhPVNhLmRpbGF0aW9uSGVpZ2h0LExhPVNhLmRpbGF0aW9uV2lkdGgsZWw9U2EuZWZmZWN0aXZlRmlsdGVyRGVwdGgsdGw9U2EuZWZmZWN0aXZlRmlsdGVySGVpZ2h0LG5sPVNhLmVmZmVjdGl2ZUZpbHRlcldpZHRoLHNsPVNhLnBhZEluZm8uZnJvbnQscmw9U2EucGFkSW5mby50b3Asb2w9U2EucGFkSW5mby5sZWZ0LGFsPVRhPT09Im1heCI/TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZOk51bWJlci5QT1NJVElWRV9JTkZJTklUWSxsbD1idWZmZXIkMShTYS5vdXRTaGFwZSx4YSksaWw9bGwudmFsdWVzLGNsPVNhLm91dFNoYXBlWzFdKlNhLm91dFNoYXBlWzJdKlNhLm91dFNoYXBlWzNdKlNhLm91dFNoYXBlWzRdLHVsPVNhLm91dFNoYXBlWzJdKlNhLm91dFNoYXBlWzNdKlNhLm91dFNoYXBlWzRdLGRsPVNhLm91dFNoYXBlWzNdKlNhLm91dFNoYXBlWzRdLGhsPVNhLm91dFNoYXBlWzRdO2ZvcihsZXQgcGw9MDtwbDxTYS5iYXRjaFNpemU7KytwbCl7Y29uc3QgZmw9cGwqY2wsbWw9cGwqYmFbMF07Zm9yKGxldCBnbD0wO2dsPFNhLmluQ2hhbm5lbHM7KytnbClmb3IobGV0ICRsPTA7JGw8U2Eub3V0RGVwdGg7KyskbCl7Y29uc3QgeGw9JGwqd2Etc2w7bGV0IHlsPXhsO2Zvcig7eWw8MDspeWwrPUFhO2NvbnN0IGJsPU1hdGgubWluKFNhLmluRGVwdGgsZWwreGwpLFNsPWZsKyRsKnVsO2ZvcihsZXQgQ2w9MDtDbDxTYS5vdXRIZWlnaHQ7KytDbCl7Y29uc3QgVGw9Q2wqRWEtcmw7bGV0IHdsPVRsO2Zvcig7d2w8MDspd2wrPUZhO2NvbnN0IElsPU1hdGgubWluKFNhLmluSGVpZ2h0LHRsK1RsKSxObD1TbCtDbCpkbDtmb3IobGV0IHZsPTA7dmw8U2Eub3V0V2lkdGg7Kyt2bCl7Y29uc3Qga2w9dmwqa2Etb2w7bGV0IEVsPWtsO2Zvcig7RWw8MDspRWwrPUxhO2NvbnN0IEFsPU1hdGgubWluKFNhLmluV2lkdGgsbmwra2wpLFJsPU5sK3ZsKmhsO2xldCBQbD1hbCxEbD0wLF9sPTA7Zm9yKGxldCBPbD15bDtPbDxibDtPbCs9QWEpe2NvbnN0IE1sPW1sK09sKmJhWzFdO2ZvcihsZXQgVWw9d2w7VWw8SWw7VWwrPUZhKXtjb25zdCBCbD1NbCtVbCpiYVsyXTtmb3IobGV0IExsPUVsO0xsPEFsO0xsKz1MYSl7Y29uc3Qgemw9QmwrTGwqYmFbM10sVmw9aGFbemwrZ2xdO2lmKFRhPT09Im1heCImJlZsPlBsP1BsPVZsOlRhPT09ImF2ZyImJihEbCs9VmwsX2wrKyksaXNOYU4oUGwpKWJyZWFrfWlmKGlzTmFOKFBsKSlicmVha31pZihpc05hTihQbCkpYnJlYWt9Y29uc3QgRmw9UmwrZ2w7aWxbRmxdPVRhPT09ImF2ZyI/RGwvTWF0aC5tYXgoX2wsMSk6UGx9fX19cmV0dXJuIGxsfWZ1bmN0aW9uIG1heFBvb2wzZFBvc2l0aW9ucyhoYSxhYSl7Y29uc3QgeGE9YnVmZmVyJDEoYWEub3V0U2hhcGUsImludDMyIiksYmE9YWEuc3RyaWRlRGVwdGgsU2E9YWEuc3RyaWRlSGVpZ2h0LFRhPWFhLnN0cmlkZVdpZHRoLHdhPWFhLmRpbGF0aW9uRGVwdGgsRWE9YWEuZGlsYXRpb25IZWlnaHQsa2E9YWEuZGlsYXRpb25XaWR0aCxBYT1hYS5lZmZlY3RpdmVGaWx0ZXJEZXB0aCxGYT1hYS5lZmZlY3RpdmVGaWx0ZXJIZWlnaHQsTGE9YWEuZWZmZWN0aXZlRmlsdGVyV2lkdGgsZWw9YWEucGFkSW5mby5mcm9udCx0bD1hYS5wYWRJbmZvLnRvcCxubD1hYS5wYWRJbmZvLmxlZnQ7Zm9yKGxldCBzbD0wO3NsPGFhLmJhdGNoU2l6ZTsrK3NsKWZvcihsZXQgcmw9MDtybDxhYS5pbkNoYW5uZWxzOysrcmwpZm9yKGxldCBvbD0wO29sPGFhLm91dERlcHRoOysrb2wpe2NvbnN0IGFsPW9sKmJhLWVsO2xldCBsbD1hbDtmb3IoO2xsPDA7KWxsKz13YTtjb25zdCBpbD1NYXRoLm1pbihhYS5pbkRlcHRoLEFhK2FsKTtmb3IobGV0IGNsPTA7Y2w8YWEub3V0SGVpZ2h0OysrY2wpe2NvbnN0IHVsPWNsKlNhLXRsO2xldCBkbD11bDtmb3IoO2RsPDA7KWRsKz1FYTtjb25zdCBobD1NYXRoLm1pbihhYS5pbkhlaWdodCxGYSt1bCk7Zm9yKGxldCBwbD0wO3BsPGFhLm91dFdpZHRoOysrcGwpe2NvbnN0IGZsPXBsKlRhLW5sO2xldCBtbD1mbDtmb3IoO21sPDA7KW1sKz1rYTtjb25zdCBnbD1NYXRoLm1pbihhYS5pbldpZHRoLExhK2ZsKTtsZXQgJGw9TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLHhsPS0xO2ZvcihsZXQgeWw9bGw7eWw8aWw7eWwrPXdhKXtjb25zdCBibD15bC1hbDtmb3IobGV0IFNsPWRsO1NsPGhsO1NsKz1FYSl7Y29uc3QgQ2w9U2wtdWw7Zm9yKGxldCBUbD1tbDtUbDxnbDtUbCs9a2Epe2NvbnN0IHdsPVRsLWZsLElsPWhhLmdldChzbCx5bCxTbCxUbCxybCk7SWw+PSRsJiYoJGw9SWwseGw9YmwqRmEqTGErQ2wqRmErd2wpfX19eGEuc2V0KHhsLHNsLG9sLGNsLHBsLHJsKX19fXJldHVybiB4YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhdmdQb29sJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJhdmdQb29sIik7Y29uc3R7ZmlsdGVyU2l6ZTpUYSxzdHJpZGVzOndhLHBhZDpFYSxkaW1Sb3VuZGluZ01vZGU6a2F9PWJhLEFhPTE7YXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEod2EsQWEpLCgpPT5gRXJyb3IgaW4gYXZnUG9vbDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt3YX0gYW5kIGRpbGF0aW9ucyAnJHtBYX0nYCk7Y29uc3QgRmE9Y29tcHV0ZVBvb2wyREluZm8kMShTYS5zaGFwZSxUYSx3YSxBYSxFYSxrYSk7bGV0IExhO2lmKEZhLmZpbHRlcldpZHRoPT09MSYmRmEuZmlsdGVySGVpZ2h0PT09MSYmYXJyYXlzRXF1YWwkMShGYS5pblNoYXBlLEZhLm91dFNoYXBlKSlMYT1pZGVudGl0eSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtlbHNle2NvbnN0IGVsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLHRsPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLG5sPXBvb2woZWwsU2Euc2hhcGUsU2EuZHR5cGUsdGwsRmEsImF2ZyIpO0xhPXhhLm1ha2VUZW5zb3JJbmZvKEZhLm91dFNoYXBlLFNhLmR0eXBlLG5sLnZhbHVlcyl9cmV0dXJuIExhfWNvbnN0IGF2Z1Bvb2xDb25maWckMj17a2VybmVsTmFtZTpBdmdQb29sJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphdmdQb29sJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2wzRCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtmaWx0ZXJTaXplOlRhLHN0cmlkZXM6d2EscGFkOkVhLGRpbVJvdW5kaW5nTW9kZTprYSxkYXRhRm9ybWF0OkFhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsImF2Z1Bvb2wzZCIpO2NvbnN0IEZhPWNvbXB1dGVQb29sM0RJbmZvJDEoU2Euc2hhcGUsVGEsd2EsMSxFYSxrYSxBYSksTGE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsZWw9cG9vbDNkKExhLFNhLnNoYXBlLFNhLmR0eXBlLGNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLEZhLCJhdmciKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oZWwuc2hhcGUsImZsb2F0MzIiLGVsLnZhbHVlcyl9Y29uc3QgYXZnUG9vbDNEQ29uZmlnJDI9e2tlcm5lbE5hbWU6QXZnUG9vbDNEJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphdmdQb29sM0QkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXZnUG9vbDNER3JhZCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2R5OlNhLGlucHV0OlRhfT1hYSx7ZmlsdGVyU2l6ZTp3YSxzdHJpZGVzOkVhLHBhZDprYSxkaW1Sb3VuZGluZ01vZGU6QWF9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJhdmdQb29sM0RHcmFkIik7Y29uc3QgRmE9Y29tcHV0ZVBvb2wzREluZm8kMShUYS5zaGFwZSx3YSxFYSwxLGthLEFhKSxMYT1GYS5zdHJpZGVEZXB0aCxlbD1GYS5zdHJpZGVIZWlnaHQsdGw9RmEuc3RyaWRlV2lkdGgsbmw9RmEuZmlsdGVyRGVwdGgsc2w9RmEuZmlsdGVySGVpZ2h0LHJsPUZhLmZpbHRlcldpZHRoLG9sPUZhLmRpbGF0aW9uRGVwdGgsYWw9RmEuZGlsYXRpb25IZWlnaHQsbGw9RmEuZGlsYXRpb25XaWR0aCxpbD1GYS5lZmZlY3RpdmVGaWx0ZXJEZXB0aCxjbD1GYS5lZmZlY3RpdmVGaWx0ZXJIZWlnaHQsdWw9RmEuZWZmZWN0aXZlRmlsdGVyV2lkdGgsZGw9aWwtMS1GYS5wYWRJbmZvLmZyb250LGhsPXVsLTEtRmEucGFkSW5mby5sZWZ0LHBsPWNsLTEtRmEucGFkSW5mby50b3AsZmw9YnVmZmVyJDEoVGEuc2hhcGUsImZsb2F0MzIiKSxtbD0xLyhubCpzbCpybCksZ2w9eGEuYnVmZmVyU3luYyhTYSk7Zm9yKGxldCAkbD0wOyRsPEZhLmJhdGNoU2l6ZTsrKyRsKWZvcihsZXQgeGw9MDt4bDxGYS5pbkNoYW5uZWxzOysreGwpZm9yKGxldCB5bD0wO3lsPEZhLmluRGVwdGg7Kyt5bClmb3IobGV0IGJsPTA7Ymw8RmEuaW5IZWlnaHQ7KytibClmb3IobGV0IFNsPTA7U2w8RmEuaW5XaWR0aDsrK1NsKXtjb25zdCBDbD15bC1kbCxUbD1ibC1wbCx3bD1TbC1obDtsZXQgSWw9MDtmb3IobGV0IE5sPTA7Tmw8aWw7TmwrPW9sKXtjb25zdCB2bD0oQ2wrTmwpL0xhO2lmKCEodmw8MHx8dmw+PUZhLm91dERlcHRofHxNYXRoLmZsb29yKHZsKSE9PXZsKSlmb3IobGV0IGtsPTA7a2w8Y2w7a2wrPWFsKXtjb25zdCBFbD0oVGwra2wpL2VsO2lmKCEoRWw8MHx8RWw+PUZhLm91dEhlaWdodHx8TWF0aC5mbG9vcihFbCkhPT1FbCkpZm9yKGxldCBBbD0wO0FsPHVsO0FsKz1sbCl7Y29uc3QgUmw9KHdsK0FsKS90bDtpZihSbDwwfHxSbD49RmEub3V0V2lkdGh8fE1hdGguZmxvb3IoUmwpIT09UmwpY29udGludWU7Y29uc3QgUGw9Z2wuZ2V0KCRsLHZsLEVsLFJsLHhsKTtJbCs9UGx9fX1mbC5zZXQoSWwqbWwsJGwseWwsYmwsU2wseGwpfXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhmbC5zaGFwZSxmbC5kdHlwZSxmbC52YWx1ZXMpfWNvbnN0IGF2Z1Bvb2wzREdyYWRDb25maWckMj17a2VybmVsTmFtZTpBdmdQb29sM0RHcmFkJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzphdmdQb29sM0RHcmFkJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2xHcmFkJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsaW5wdXQ6VGF9PWFhLHdhPVRhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJhdmdQb29sR3JhZCIpO2NvbnN0e2ZpbHRlclNpemU6RWEsc3RyaWRlczprYSxwYWQ6QWF9PWJhLEZhPWNvbXB1dGVQb29sMkRJbmZvJDEod2Euc2hhcGUsRWEsa2EsMSxBYSksTGE9RmEuc3RyaWRlSGVpZ2h0LGVsPUZhLnN0cmlkZVdpZHRoLHRsPUZhLmZpbHRlckhlaWdodCxubD1GYS5maWx0ZXJXaWR0aCxzbD1GYS5kaWxhdGlvbkhlaWdodCxybD1GYS5kaWxhdGlvbldpZHRoLG9sPUZhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCxhbD1GYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxsbD1hbC0xLUZhLnBhZEluZm8ubGVmdCxpbD1vbC0xLUZhLnBhZEluZm8udG9wLGNsPWJ1ZmZlciQxKHdhLnNoYXBlLCJmbG9hdDMyIiksdWw9MS8odGwqbmwpLGRsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGhsPWJ1ZmZlciQxKFNhLnNoYXBlLCJmbG9hdDMyIixkbCk7Zm9yKGxldCBwbD0wO3BsPEZhLmJhdGNoU2l6ZTsrK3BsKWZvcihsZXQgZmw9MDtmbDxGYS5pbkNoYW5uZWxzOysrZmwpZm9yKGxldCBtbD0wO21sPEZhLmluSGVpZ2h0OysrbWwpZm9yKGxldCBnbD0wO2dsPEZhLmluV2lkdGg7KytnbCl7Y29uc3QgJGw9bWwtaWwseGw9Z2wtbGw7bGV0IHlsPTA7Zm9yKGxldCBibD0wO2JsPG9sO2JsKz1zbCl7Y29uc3QgU2w9KCRsK2JsKS9MYTtpZighKFNsPDB8fFNsPj1GYS5vdXRIZWlnaHR8fE1hdGguZmxvb3IoU2wpIT09U2wpKWZvcihsZXQgQ2w9MDtDbDxhbDtDbCs9cmwpe2NvbnN0IFRsPSh4bCtDbCkvZWw7aWYoVGw8MHx8VGw+PUZhLm91dFdpZHRofHxNYXRoLmZsb29yKFRsKSE9PVRsKWNvbnRpbnVlO2NvbnN0IHdsPWhsLmdldChwbCxTbCxUbCxmbCk7eWwrPXdsfX1jbC5zZXQoeWwqdWwscGwsbWwsZ2wsZmwpfXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhjbC5zaGFwZSxjbC5kdHlwZSxjbC52YWx1ZXMpfWNvbnN0IGF2Z1Bvb2xHcmFkQ29uZmlnJDI9e2tlcm5lbE5hbWU6QXZnUG9vbEdyYWQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmF2Z1Bvb2xHcmFkJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJhdGNoTm9ybSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2Esc2NhbGU6VGEsb2Zmc2V0OndhLG1lYW46RWEsdmFyaWFuY2U6a2F9PWFhO2Fzc2VydCQyKEVhLnNoYXBlLmxlbmd0aD09PWthLnNoYXBlLmxlbmd0aCwoKT0+IkJhdGNoIG5vcm1hbGl6YXRpb24gZ3JhZGllbnQgcmVxdWlyZXMgbWVhbiBhbmQgdmFyaWFuY2UgdG8gaGF2ZSBlcXVhbCByYW5rcy4iKSxhc3NlcnQkMih3YT09bnVsbHx8RWEuc2hhcGUubGVuZ3RoPT09d2Euc2hhcGUubGVuZ3RoLCgpPT4iQmF0Y2ggbm9ybWFsaXphdGlvbiBncmFkaWVudCByZXF1aXJlcyBtZWFuIGFuZCBvZmZzZXQgdG8gaGF2ZSBlcXVhbCByYW5rcy4iKSxhc3NlcnQkMihUYT09bnVsbHx8RWEuc2hhcGUubGVuZ3RoPT09VGEuc2hhcGUubGVuZ3RoLCgpPT4iQmF0Y2ggbm9ybWFsaXphdGlvbiBncmFkaWVudCByZXF1aXJlcyBtZWFuIGFuZCBzY2FsZSB0byBoYXZlIGVxdWFsIHJhbmtzLiIpLGFzc2VydE5vdENvbXBsZXgkMihbU2EsRWEsa2EsVGEsd2FdLCJiYXRjaE5vcm0iKTtsZXR7dmFyaWFuY2VFcHNpbG9uOkFhfT1iYTtBYT09bnVsbCYmKEFhPS4wMDEpO2NvbnN0IEZhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLExhPXhhLmRhdGEuZ2V0KEVhLmRhdGFJZCkudmFsdWVzLGVsPXhhLmRhdGEuZ2V0KGthLmRhdGFJZCkudmFsdWVzLHRsPVRhP3hhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzOm5ldyBGbG9hdDMyQXJyYXkoWzFdKSxubD13YT94YS5kYXRhLmdldCh3YS5kYXRhSWQpLnZhbHVlczpuZXcgRmxvYXQzMkFycmF5KFswXSksc2w9bmV3IEZsb2F0MzJBcnJheShGYS5sZW5ndGgpLHJsPW5sLmxlbmd0aCxvbD10bC5sZW5ndGgsYWw9ZWwubGVuZ3RoLGxsPUxhLmxlbmd0aDtsZXQgaWw9MCxjbD0wLHVsPTAsZGw9MDtmb3IobGV0IGhsPTA7aGw8RmEubGVuZ3RoOysraGwpc2xbaGxdPW5sW2lsKytdKyhGYVtobF0tTGFbY2wrK10pKnRsW3VsKytdL01hdGguc3FydChlbFtkbCsrXStBYSksaWw+PXJsJiYoaWw9MCksY2w+PWxsJiYoY2w9MCksdWw+PW9sJiYodWw9MCksZGw+PWFsJiYoZGw9MCk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFNhLnNoYXBlLFNhLmR0eXBlLHNsKX1jb25zdCBiYXRjaE5vcm1Db25maWckMj17a2VybmVsTmFtZTpGdXNlZEJhdGNoTm9ybSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6YmF0Y2hOb3JtJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJhdGNoVG9TcGFjZU5EJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2Jsb2NrU2hhcGU6VGEsY3JvcHM6d2F9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2FdLCJiYXRjaFRvU3BhY2VORCIpO2NvbnN0IEVhPVRhLnJlZHVjZSgob2wsYWwpPT5vbCphbCksa2E9Z2V0UmVzaGFwZWQkMShTYS5zaGFwZSxUYSxFYSksQWE9Z2V0UGVybXV0ZWQkMShrYS5sZW5ndGgsVGEubGVuZ3RoKSxGYT1nZXRSZXNoYXBlZFBlcm11dGVkJDEoU2Euc2hhcGUsVGEsRWEpLExhPWdldFNsaWNlQmVnaW5Db29yZHMkMSh3YSxUYS5sZW5ndGgpLGVsPWdldFNsaWNlU2l6ZSQxKEZhLHdhLFRhLmxlbmd0aCksdGw9cmVzaGFwZSQzKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmthfX0pLG5sPXRyYW5zcG9zZSQyKHtpbnB1dHM6e3g6dGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06QWF9fSksc2w9cmVzaGFwZSQzKHtpbnB1dHM6e3g6bmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkZhfX0pLHJsPXNsaWNlJDIoe2lucHV0czp7eDpzbH0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46TGEsc2l6ZTplbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkscmx9Y29uc3QgYmF0Y2hUb1NwYWNlTkRDb25maWckMj17a2VybmVsTmFtZTpCYXRjaFRvU3BhY2VORCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6YmF0Y2hUb1NwYWNlTkQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYmluY291bnQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLHdlaWdodHM6VGF9PWFhLHtzaXplOndhfT1iYSxFYT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxrYT14YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyxBYT1iaW5jb3VudEltcGwkMShFYSxrYSxUYS5kdHlwZSxUYS5zaGFwZSx3YSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFt3YV0sVGEuZHR5cGUsQWEpfWNvbnN0IGJpbmNvdW50Q29uZmlnJDI9e2tlcm5lbE5hbWU6QmluY291bnQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmJpbmNvdW50JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJyb2FkY2FzdEFyZ3MkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtzMDpiYSxzMTpTYX09YWEsVGE9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsd2E9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsRWE9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShBcnJheS5mcm9tKFRhKSxBcnJheS5mcm9tKHdhKSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFtFYS5sZW5ndGhdLCJpbnQzMiIsSW50MzJBcnJheS5mcm9tKEVhKSl9Y29uc3QgYnJvYWRjYXN0QXJnc0NvbmZpZyQyPXtrZXJuZWxOYW1lOkJyb2FkY2FzdEFyZ3MkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmJyb2FkY2FzdEFyZ3MkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjbGlwQnlWYWx1ZSQyPXVuYXJ5S2VybmVsRnVuYyQyKENsaXBCeVZhbHVlJDEsKGhhLGFhKT0+e2NvbnN0IHhhPWFhO3JldHVybiBoYT54YS5jbGlwVmFsdWVNYXg/eGEuY2xpcFZhbHVlTWF4OmhhPHhhLmNsaXBWYWx1ZU1pbj94YS5jbGlwVmFsdWVNaW46aGF9KSxjbGlwQnlWYWx1ZUNvbmZpZyQyPXtrZXJuZWxOYW1lOkNsaXBCeVZhbHVlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpjbGlwQnlWYWx1ZSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNvbXBsZXhBYnMkMj1oYT0+e2NvbnN0e3g6YWF9PWhhLmlucHV0cyx4YT1oYS5iYWNrZW5kLGJhPW5ldyBGbG9hdDMyQXJyYXkoc2l6ZUZyb21TaGFwZSQxKGFhLnNoYXBlKSksU2E9eGEuZGF0YS5nZXQoYWEuZGF0YUlkKSxUYT1TYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbCx3YT1TYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZyxFYT14YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyxrYT14YS5kYXRhLmdldCh3YS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IEFhPTA7QWE8RWEubGVuZ3RoO0FhKyspe2NvbnN0IEZhPUVhW0FhXSxMYT1rYVtBYV07YmFbQWFdPU1hdGguaHlwb3QoRmEsTGEpfXJldHVybiB4YS5tYWtlT3V0cHV0KGJhLGFhLnNoYXBlLCJmbG9hdDMyIil9LGNvbXBsZXhBYnNDb25maWckMj17a2VybmVsTmFtZTpDb21wbGV4QWJzJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpjb21wbGV4QWJzJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGltYWckMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtpbnB1dDpiYX09YWEsU2E9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZyxUYT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcztyZXR1cm4geGEubWFrZVRlbnNvckluZm8oU2Euc2hhcGUsU2EuZHR5cGUsVGEpfWNvbnN0IGltYWdDb25maWckMj17a2VybmVsTmFtZTpJbWFnJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzppbWFnJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbmNhdCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2F4aXM6U2F9PWJhLFRhPXBhcnNlQXhpc1BhcmFtJDEoU2EsYWFbMF0uc2hhcGUpWzBdLHdhPWFhLm1hcChzbD0+c2wuc2hhcGUpO2Fzc2VydFBhcmFtc0NvbnNpc3RlbnQkMSh3YSxUYSk7bGV0IEVhPWNvbXB1dGVPdXRTaGFwZSQ0KGFhLm1hcChzbD0+c2wuc2hhcGUpLFRhKTtpZihzaXplRnJvbVNoYXBlJDEoRWEpPT09MClyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRWEsYWFbMF0uZHR5cGUsW10pO2NvbnN0IGthPWFhLmZpbHRlcihzbD0+c2l6ZUZyb21TaGFwZSQxKHNsLnNoYXBlKT4wKTtpZihrYS5sZW5ndGg9PT0xKXJldHVybiBpZGVudGl0eSQyKHtpbnB1dHM6e3g6a2FbMF19LGJhY2tlbmQ6eGF9KTtpZihrYVswXS5kdHlwZT09PSJjb21wbGV4NjQiKXtjb25zdCBzbD1rYS5tYXAoaWw9PnJlYWwkMih7aW5wdXRzOntpbnB1dDppbH0sYmFja2VuZDp4YX0pKSxybD1rYS5tYXAoaWw9PmltYWckMih7aW5wdXRzOntpbnB1dDppbH0sYmFja2VuZDp4YX0pKSxvbD1jb25jYXQkMih7aW5wdXRzOnNsLGJhY2tlbmQ6eGEsYXR0cnM6e2F4aXM6VGF9fSksYWw9Y29uY2F0JDIoe2lucHV0czpybCxiYWNrZW5kOnhhLGF0dHJzOntheGlzOlRhfX0pLGxsPWNvbXBsZXgkMyh7aW5wdXRzOntyZWFsOm9sLGltYWc6YWx9LGJhY2tlbmQ6eGF9KTtyZXR1cm4gc2wuZm9yRWFjaChpbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oaWwpKSxybC5mb3JFYWNoKGlsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhpbCkpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG9sKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhbCksbGx9Y29uc3QgQWE9a2EubWFwKHNsPT57Y29uc3Qgb2w9Wy0xLHNpemVGcm9tU2hhcGUkMShzbC5zaGFwZS5zbGljZShUYSkpXTtyZXR1cm4gcmVzaGFwZSQzKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOm9sfX0pfSksRmE9QWEubWFwKHNsPT4oe3ZhbHM6eGEuZGF0YS5nZXQoc2wuZGF0YUlkKS52YWx1ZXMsc2hhcGU6c2wuc2hhcGV9KSk7RWE9Y29tcHV0ZU91dFNoYXBlJDQoQWEubWFwKHNsPT5zbC5zaGFwZSksMSk7Y29uc3QgTGE9QWFbMF0uc2hhcGVbMF09PT0xLGVsPWNvbmNhdEltcGwkMyhGYSxFYSxhYVswXS5kdHlwZSxMYSksdGw9Y29tcHV0ZU91dFNoYXBlJDQoa2EubWFwKHNsPT5zbC5zaGFwZSksVGEpLG5sPXhhLm1ha2VUZW5zb3JJbmZvKHRsLGFhWzBdLmR0eXBlLGVsKTtyZXR1cm4gQWEuZm9yRWFjaChzbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpKSxubH1jb25zdCBjb25jYXRDb25maWckMj17a2VybmVsTmFtZTpDb25jYXQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmNvbmNhdCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252MkQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxmaWx0ZXI6VGF9PWFhLHtzdHJpZGVzOndhLHBhZDpFYSxkYXRhRm9ybWF0OmthLGRpbGF0aW9uczpBYSxkaW1Sb3VuZGluZ01vZGU6RmF9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJjb252MmQiKTtjb25zdCBMYT1jb252ZXJ0Q29udjJERGF0YUZvcm1hdCQxKGthKSxlbD1jb21wdXRlQ29udjJESW5mbyQxKFNhLnNoYXBlLFRhLnNoYXBlLHdhLEFhLEVhLEZhLCExLExhKSx0bD1lbC5maWx0ZXJIZWlnaHQsbmw9ZWwuZmlsdGVyV2lkdGgsc2w9ZWwuZGlsYXRpb25IZWlnaHQscmw9ZWwuZGlsYXRpb25XaWR0aCxvbD1lbC5wYWRJbmZvLmxlZnQsYWw9ZWwucGFkSW5mby50b3AsbGw9ZWwuZGF0YUZvcm1hdD09PSJjaGFubmVsc0xhc3QiLGlsPW5ldyBUZW5zb3JCdWZmZXIkMShlbC5vdXRTaGFwZSxTYS5kdHlwZSksY2w9Y29tcHV0ZVN0cmlkZXMkMShTYS5zaGFwZSksdWw9Y29tcHV0ZVN0cmlkZXMkMShUYS5zaGFwZSksZGw9Y2xbMF0saGw9bGw/Y2xbMV06Y2xbMl0scGw9bGw/Y2xbMl06MSxmbD1sbD8xOmNsWzFdLG1sPWlsLnN0cmlkZXNbMF0sZ2w9bGw/aWwuc3RyaWRlc1sxXTppbC5zdHJpZGVzWzJdLCRsPWxsP2lsLnN0cmlkZXNbMl06MSx4bD1sbD8xOmlsLnN0cmlkZXNbMV0seWw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsYmw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsU2w9aWwudmFsdWVzO2ZvcihsZXQgQ2w9MDtDbDxlbC5iYXRjaFNpemU7KytDbCl7Y29uc3QgVGw9Q2wqZGwsd2w9Q2wqbWw7Zm9yKGxldCBJbD0wO0lsPGVsLm91dEhlaWdodDsrK0lsKXtjb25zdCBObD13bCtJbCpnbCx2bD1JbCplbC5zdHJpZGVIZWlnaHQtYWw7Zm9yKGxldCBrbD0wO2tsPHRsOysra2wpe2NvbnN0IEVsPXZsK2tsKnNsO2lmKEVsPDB8fEVsPj1lbC5pbkhlaWdodCljb250aW51ZTtjb25zdCBBbD1rbCp1bFswXSxSbD1UbCtFbCpobDtmb3IobGV0IFBsPTA7UGw8ZWwub3V0V2lkdGg7KytQbCl7Y29uc3QgRGw9TmwrUGwqJGwsX2w9UGwqZWwuc3RyaWRlV2lkdGgtb2w7Zm9yKGxldCBGbD0wO0ZsPG5sOysrRmwpe2NvbnN0IE9sPV9sK0ZsKnJsO2lmKE9sPDB8fE9sPj1lbC5pbldpZHRoKWNvbnRpbnVlO2NvbnN0IE1sPUFsK0ZsKnVsWzFdLFVsPVJsK09sKnBsO2xldCBCbD1NbDtmb3IobGV0IExsPTA7TGw8ZWwuaW5DaGFubmVsczsrK0xsKXtjb25zdCB6bD15bFtVbCtMbCpmbF07Zm9yKGxldCBWbD0wO1ZsPGVsLm91dENoYW5uZWxzOysrVmwpU2xbRGwrVmwqeGxdKz16bCpibFtCbCtWbF07QmwrPWVsLm91dENoYW5uZWxzfX19fX19cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKGlsLnNoYXBlLGlsLmR0eXBlLFNsKX1jb25zdCBjb252MkRDb25maWckMj17a2VybmVsTmFtZTpDb252MkQkMixiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmNvbnYyRH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjJEQmFja3Byb3BGaWx0ZXIkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGF0YUZvcm1hdDprYSxkaW1Sb3VuZGluZ01vZGU6QWEsZmlsdGVyU2hhcGU6RmF9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJjb252MmRCYWNrcHJvcEZpbHRlciIpO2NvbnN0IExhPWNvbnZlcnRDb252MkREYXRhRm9ybWF0JDEoa2EpLGVsPWNvbXB1dGVDb252MkRJbmZvJDEoU2Euc2hhcGUsRmEsd2EsMSxFYSxBYSwhMSxMYSkse3N0cmlkZUhlaWdodDp0bCxzdHJpZGVXaWR0aDpubCxmaWx0ZXJIZWlnaHQ6c2wsZmlsdGVyV2lkdGg6cmx9PWVsLG9sPWVsLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNMYXN0IixhbD1uZXcgVGVuc29yQnVmZmVyJDEoZWwuZmlsdGVyU2hhcGUsImZsb2F0MzIiKSxsbD1lbC5wYWRJbmZvLmxlZnQsaWw9ZWwucGFkSW5mby50b3AsY2w9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsdWw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsZGw9bmV3IFRlbnNvckJ1ZmZlciQxKFNhLnNoYXBlLFNhLmR0eXBlLGNsKSxobD1uZXcgVGVuc29yQnVmZmVyJDEoVGEuc2hhcGUsVGEuZHR5cGUsdWwpO2ZvcihsZXQgcGw9MDtwbDxzbDsrK3BsKXtjb25zdCBmbD1NYXRoLm1heCgwLE1hdGguY2VpbCgoaWwtcGwpL3RsKSksbWw9TWF0aC5taW4oZWwub3V0SGVpZ2h0LChlbC5pbkhlaWdodCtpbC1wbCkvdGwpO2ZvcihsZXQgZ2w9MDtnbDxybDsrK2dsKXtjb25zdCAkbD1NYXRoLm1heCgwLE1hdGguY2VpbCgobGwtZ2wpL25sKSkseGw9TWF0aC5taW4oZWwub3V0V2lkdGgsKGVsLmluV2lkdGgrbGwtZ2wpL25sKTtmb3IobGV0IHlsPTA7eWw8ZWwuaW5DaGFubmVsczsrK3lsKWZvcihsZXQgYmw9MDtibDxlbC5vdXRDaGFubmVsczsrK2JsKXtsZXQgU2w9MDtmb3IobGV0IENsPTA7Q2w8ZWwuYmF0Y2hTaXplOysrQ2wpZm9yKGxldCBUbD1mbDtUbDxtbDsrK1RsKXtjb25zdCB3bD1wbCtUbCp0bC1pbDtmb3IobGV0IElsPSRsO0lsPHhsOysrSWwpe2NvbnN0IE5sPWdsK0lsKm5sLWxsO29sP1NsKz1kbC5nZXQoQ2wsd2wsTmwseWwpKmhsLmdldChDbCxUbCxJbCxibCk6U2wrPWRsLmdldChDbCx5bCx3bCxObCkqaGwuZ2V0KENsLGJsLFRsLElsKX19YWwuc2V0KFNsLHBsLGdsLHlsLGJsKX19fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhhbC5zaGFwZSxhbC5kdHlwZSxhbC52YWx1ZXMpfWNvbnN0IGNvbnYyREJhY2twcm9wRmlsdGVyQ29uZmlnJDI9e2tlcm5lbE5hbWU6Q29udjJEQmFja3Byb3BGaWx0ZXIkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmNvbnYyREJhY2twcm9wRmlsdGVyJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYyREJhY2twcm9wSW5wdXQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxmaWx0ZXI6VGF9PWFhLHtpbnB1dFNoYXBlOndhLHN0cmlkZXM6RWEscGFkOmthLGRhdGFGb3JtYXQ6QWEsZGltUm91bmRpbmdNb2RlOkZhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoW1NhLFRhXSwiY29udjJkQmFja3Byb3BJbnB1dCIpO2NvbnN0IExhPWNvbXB1dGVTdHJpZGVzJDEoVGEuc2hhcGUpLGVsPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpO2xldCB0bD1jb252ZXJ0Q29udjJERGF0YUZvcm1hdCQxKEFhKTtjb25zdCBubD1jb21wdXRlQ29udjJESW5mbyQxKHdhLFRhLnNoYXBlLEVhLDEsa2EsRmEsITEsdGwpLHNsPW5ldyBUZW5zb3JCdWZmZXIkMShubC5pblNoYXBlLCJmbG9hdDMyIikscmw9c2wudmFsdWVzLG9sPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGFsPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLFtsbCxpbCxjbF09TGEse2JhdGNoU2l6ZTp1bCxmaWx0ZXJIZWlnaHQ6ZGwsZmlsdGVyV2lkdGg6aGwsaW5DaGFubmVsczpwbCxpbkhlaWdodDpmbCxpbldpZHRoOm1sLG91dENoYW5uZWxzOmdsLG91dEhlaWdodDokbCxvdXRXaWR0aDp4bCxzdHJpZGVIZWlnaHQ6eWwsc3RyaWRlV2lkdGg6Ymx9PW5sO3RsPW5sLmRhdGFGb3JtYXQ7Y29uc3QgU2w9ZGwtMS1ubC5wYWRJbmZvLnRvcCxDbD1obC0xLW5sLnBhZEluZm8ubGVmdCxUbD10bD09PSJjaGFubmVsc0xhc3QiLHdsPXNsLnN0cmlkZXNbMF0sSWw9VGw/c2wuc3RyaWRlc1sxXTpzbC5zdHJpZGVzWzJdLE5sPVRsP3NsLnN0cmlkZXNbMl06MSx2bD1UbD8xOnNsLnN0cmlkZXNbMV0sa2w9ZWxbMF0sRWw9VGw/ZWxbMV06ZWxbMl0sQWw9VGw/ZWxbMl06MSxSbD1UbD8xOmVsWzFdO2ZvcihsZXQgUGw9MDtQbDx1bDsrK1BsKWZvcihsZXQgRGw9MDtEbDxwbDsrK0RsKWZvcihsZXQgX2w9MDtfbDxmbDsrK19sKXtjb25zdCBGbD1fbC1TbCxPbD1NYXRoLm1heCgwLE1hdGguY2VpbChGbC95bCkpLE1sPU1hdGgubWluKCRsLChkbCtGbCkveWwpO2ZvcihsZXQgVWw9MDtVbDxtbDsrK1VsKXtjb25zdCBCbD1VbC1DbCxMbD1NYXRoLm1heCgwLE1hdGguY2VpbChCbC9ibCkpLHpsPU1hdGgubWluKHhsLChobCtCbCkvYmwpO2xldCBWbD0wO2ZvcihsZXQgR2w9T2w7R2w8TWw7KytHbCl7Y29uc3QgWGw9R2wqeWwtRmw7Zm9yKGxldCBXbD1MbDtXbDx6bDsrK1dsKXtjb25zdCBlYz1XbCpibC1CbCxIbD1rbCpQbCtFbCpHbCtBbCpXbCxqbD1sbCooZGwtMS1YbCkraWwqKGhsLTEtZWMpK2NsKkRsO2ZvcihsZXQgWWw9MDtZbDxnbDsrK1lsKXtjb25zdCBabD1vbFtIbCtSbCpZbF0sSmw9YWxbamwrWWxdO1ZsKz1abCpKbH19fWNvbnN0IHFsPXdsKlBsK0lsKl9sK05sKlVsK3ZsKkRsO3JsW3FsXT1WbH19cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKHNsLnNoYXBlLHNsLmR0eXBlLHNsLnZhbHVlcyl9Y29uc3QgY29udjJEQmFja3Byb3BJbnB1dENvbmZpZyQyPXtrZXJuZWxOYW1lOkNvbnYyREJhY2twcm9wSW5wdXQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmNvbnYyREJhY2twcm9wSW5wdXQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjNEJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxmaWx0ZXI6VGF9PWFhLHtzdHJpZGVzOndhLHBhZDpFYSxkaWxhdGlvbnM6a2F9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJjb252M2QiKTtjb25zdCBBYT1jb21wdXRlQ29udjNESW5mbyQxKFNhLnNoYXBlLFRhLnNoYXBlLHdhLGthLEVhKSx7ZmlsdGVyRGVwdGg6RmEsZmlsdGVySGVpZ2h0OkxhLGZpbHRlcldpZHRoOmVsLGRpbGF0aW9uRGVwdGg6dGwsZGlsYXRpb25IZWlnaHQ6bmwsZGlsYXRpb25XaWR0aDpzbCxwYWRJbmZvOnJsfT1BYSxvbD1ybC5mcm9udCxhbD1ybC5sZWZ0LGxsPXJsLnRvcCxpbD1uZXcgVGVuc29yQnVmZmVyJDEoQWEub3V0U2hhcGUsU2EuZHR5cGUpLGNsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLHVsPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLGRsPWlsLnZhbHVlcyxobD1jb21wdXRlU3RyaWRlcyQxKFNhLnNoYXBlKSxwbD1jb21wdXRlU3RyaWRlcyQxKFRhLnNoYXBlKTtmb3IobGV0IGZsPTA7Zmw8QWEuYmF0Y2hTaXplOysrZmwpe2NvbnN0IG1sPWZsKmhsWzBdLGdsPWZsKmlsLnN0cmlkZXNbMF07Zm9yKGxldCAkbD0wOyRsPEFhLm91dERlcHRoOysrJGwpe2NvbnN0IHhsPWdsKyRsKmlsLnN0cmlkZXNbMV0seWw9JGwqQWEuc3RyaWRlRGVwdGgtb2w7Zm9yKGxldCBibD0wO2JsPEZhOysrYmwpe2NvbnN0IFNsPXlsK2JsKnRsO2lmKFNsPDB8fFNsPj1BYS5pbkRlcHRoKWNvbnRpbnVlO2NvbnN0IENsPWJsKnBsWzBdLFRsPW1sK1NsKmhsWzFdO2ZvcihsZXQgd2w9MDt3bDxBYS5vdXRIZWlnaHQ7Kyt3bCl7Y29uc3QgSWw9eGwrd2wqaWwuc3RyaWRlc1syXSxObD13bCpBYS5zdHJpZGVIZWlnaHQtbGw7Zm9yKGxldCB2bD0wO3ZsPExhOysrdmwpe2NvbnN0IGtsPU5sK3ZsKm5sO2lmKGtsPDB8fGtsPj1BYS5pbkhlaWdodCljb250aW51ZTtjb25zdCBFbD1DbCt2bCpwbFsxXSxBbD1UbCtrbCpobFsyXTtmb3IobGV0IFJsPTA7Umw8QWEub3V0V2lkdGg7KytSbCl7Y29uc3QgUGw9SWwrUmwqQWEub3V0Q2hhbm5lbHMsRGw9UmwqQWEuc3RyaWRlV2lkdGgtYWw7Zm9yKGxldCBfbD0wO19sPGVsOysrX2wpe2NvbnN0IEZsPURsK19sKnNsO2lmKEZsPDB8fEZsPj1BYS5pbldpZHRoKWNvbnRpbnVlO2NvbnN0IE9sPUVsK19sKnBsWzJdLE1sPUFsK0ZsKkFhLmluQ2hhbm5lbHM7bGV0IFVsPU9sO2ZvcihsZXQgQmw9MDtCbDxBYS5pbkNoYW5uZWxzOysrQmwpe2NvbnN0IExsPWNsW01sK0JsXTtmb3IobGV0IHpsPTA7emw8QWEub3V0Q2hhbm5lbHM7Kyt6bClkbFtQbCt6bF0rPUxsKnVsW1VsK3psXTtVbCs9QWEub3V0Q2hhbm5lbHN9fX19fX19fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhpbC5zaGFwZSxpbC5kdHlwZSxpbC52YWx1ZXMpfWNvbnN0IGNvbnYzRENvbmZpZyQyPXtrZXJuZWxOYW1lOkNvbnYzRCQyLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Y29udjNEJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYzREJhY2twcm9wRmlsdGVyVjIkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZmlsdGVyU2hhcGU6a2F9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJjb252M2RCYWNrcHJvcEZpbHRlclYyIik7Y29uc3QgQWE9Y29tcHV0ZVN0cmlkZXMkMShTYS5zaGFwZSksRmE9Y29tcHV0ZVN0cmlkZXMkMShUYS5zaGFwZSksTGE9Y29tcHV0ZUNvbnYzREluZm8kMShTYS5zaGFwZSxrYSx3YSwxLEVhKSxlbD1MYS5zdHJpZGVEZXB0aCx0bD1MYS5zdHJpZGVIZWlnaHQsbmw9TGEuc3RyaWRlV2lkdGgsc2w9TGEuZmlsdGVyRGVwdGgscmw9TGEuZmlsdGVySGVpZ2h0LG9sPUxhLmZpbHRlcldpZHRoLGFsPW5ldyBUZW5zb3JCdWZmZXIkMShMYS5maWx0ZXJTaGFwZSwiZmxvYXQzMiIpLGxsPWFsLnZhbHVlcyxbaWwsY2wsdWwsZGxdPWFsLnN0cmlkZXMsaGw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsW3BsLGZsLG1sLGdsXT1GYSwkbD14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxbeGwseWwsYmwsU2xdPUFhLENsPUxhLnBhZEluZm8uZnJvbnQsVGw9TGEucGFkSW5mby5sZWZ0LHdsPUxhLnBhZEluZm8udG9wO2ZvcihsZXQgSWw9MDtJbDxzbDsrK0lsKXtjb25zdCBObD1NYXRoLm1heCgwLE1hdGguY2VpbCgoQ2wtSWwpL2VsKSksdmw9TWF0aC5taW4oTGEub3V0RGVwdGgsKExhLmluRGVwdGgrQ2wtSWwpL2VsKSxrbD1JbCppbDtmb3IobGV0IEVsPTA7RWw8cmw7KytFbCl7Y29uc3QgQWw9TWF0aC5tYXgoMCxNYXRoLmNlaWwoKHdsLUVsKS90bCkpLFJsPU1hdGgubWluKExhLm91dEhlaWdodCwoTGEuaW5IZWlnaHQrd2wtRWwpL3RsKSxQbD1FbCpjbCtrbDtmb3IobGV0IERsPTA7RGw8b2w7KytEbCl7Y29uc3QgX2w9TWF0aC5tYXgoMCxNYXRoLmNlaWwoKFRsLURsKS9ubCkpLEZsPU1hdGgubWluKExhLm91dFdpZHRoLChMYS5pbldpZHRoK1RsLURsKS9ubCksT2w9RGwqdWwrUGw7Zm9yKGxldCBNbD0wO01sPExhLmluQ2hhbm5lbHM7KytNbCl7Y29uc3QgVWw9TWwqZGwrT2w7Zm9yKGxldCBCbD0wO0JsPExhLm91dENoYW5uZWxzOysrQmwpe2xldCBMbD0wO2ZvcihsZXQgemw9MDt6bDxMYS5iYXRjaFNpemU7Kyt6bCl7Y29uc3QgVmw9emwqeGwscWw9emwqcGw7Zm9yKGxldCBHbD1ObDtHbDx2bDsrK0dsKXtjb25zdCBXbD0oSWwrR2wqZWwtQ2wpKnlsK1ZsLGVjPUdsKmZsK3FsO2ZvcihsZXQgSGw9QWw7SGw8Umw7KytIbCl7Y29uc3QgWWw9KEVsK0hsKnRsLXdsKSpibCtXbCxabD1IbCptbCtlYztmb3IobGV0IEpsPV9sO0psPEZsOysrSmwpe2NvbnN0IHJjPShEbCtKbCpubC1UbCkqU2wrWWwsb2M9SmwqZ2wrWmw7TGwrPSRsW3JjK01sXSpobFtvYytCbF19fX19bGxbVWwrQmxdPUxsfX19fX1yZXR1cm4geGEubWFrZVRlbnNvckluZm8oYWwuc2hhcGUsYWwuZHR5cGUsYWwudmFsdWVzKX1jb25zdCBjb252M0RCYWNrcHJvcEZpbHRlclYyQ29uZmlnJDI9e2tlcm5lbE5hbWU6Q29udjNEQmFja3Byb3BGaWx0ZXJWMiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Y29udjNEQmFja3Byb3BGaWx0ZXJWMiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252M0RCYWNrcHJvcElucHV0VjIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsZmlsdGVyOlRhfT1hYSx7cGFkOndhLHN0cmlkZXM6RWEsaW5wdXRTaGFwZTprYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFtTYV0sImNvbnYzZEJhY2twcm9wSW5wdXRWMiIpO2NvbnN0IEFhPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLEZhPWNvbXB1dGVTdHJpZGVzJDEoVGEuc2hhcGUpLExhPWNvbXB1dGVDb252M0RJbmZvJDEoa2EsVGEuc2hhcGUsRWEsMSx3YSksZWw9bmV3IFRlbnNvckJ1ZmZlciQxKExhLmluU2hhcGUsImZsb2F0MzIiKSx0bD1lbC52YWx1ZXMsW25sLHNsLHJsLG9sXT1lbC5zdHJpZGVzLGFsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLFtsbCxpbCxjbCx1bF09QWEsZGw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsW2hsLHBsLGZsLG1sXT1GYSx7YmF0Y2hTaXplOmdsLGZpbHRlckRlcHRoOiRsLGZpbHRlckhlaWdodDp4bCxmaWx0ZXJXaWR0aDp5bCxpbkNoYW5uZWxzOmJsLGluRGVwdGg6U2wsaW5IZWlnaHQ6Q2wsaW5XaWR0aDpUbCxvdXRDaGFubmVsczp3bCxvdXREZXB0aDpJbCxvdXRIZWlnaHQ6Tmwsb3V0V2lkdGg6dmwsc3RyaWRlRGVwdGg6a2wsc3RyaWRlSGVpZ2h0OkVsLHN0cmlkZVdpZHRoOkFsfT1MYSxSbD0kbC0xLUxhLnBhZEluZm8uZnJvbnQsUGw9eGwtMS1MYS5wYWRJbmZvLnRvcCxEbD15bC0xLUxhLnBhZEluZm8ubGVmdDtmb3IobGV0IF9sPTA7X2w8Z2w7KytfbClmb3IobGV0IEZsPTA7Rmw8Ymw7KytGbClmb3IobGV0IE9sPTA7T2w8U2w7KytPbCl7Y29uc3QgTWw9T2wtUmwsVWw9TWF0aC5tYXgoMCxNYXRoLmNlaWwoTWwva2wpKSxCbD1NYXRoLm1pbihJbCwoJGwrTWwpL2tsKTtmb3IobGV0IExsPTA7TGw8Q2w7KytMbCl7Y29uc3Qgemw9TGwtUGwsVmw9TWF0aC5tYXgoMCxNYXRoLmNlaWwoemwvRWwpKSxxbD1NYXRoLm1pbihObCwoeGwremwpL0VsKTtmb3IobGV0IEdsPTA7R2w8VGw7KytHbCl7Y29uc3QgWGw9R2wtRGwsV2w9TWF0aC5tYXgoMCxNYXRoLmNlaWwoWGwvQWwpKSxlYz1NYXRoLm1pbih2bCwoeWwrWGwpL0FsKTtsZXQgSGw9MDtmb3IobGV0IGpsPVVsO2psPEJsOysramwpe2NvbnN0IFlsPWpsKmtsLU1sO2ZvcihsZXQgWmw9Vmw7Wmw8cWw7KytabCl7Y29uc3QgSmw9WmwqRWwtemw7Zm9yKGxldCBuYz1XbDtuYzxlYzsrK25jKXtjb25zdCByYz1uYypBbC1YbCxvYz1sbCpfbCtpbCpqbCtjbCpabCt1bCpuYyxwYz1obCooJGwtMS1ZbCkrcGwqKHhsLTEtSmwpK2ZsKih5bC0xLXJjKSttbCpGbDtmb3IobGV0IHNjPTA7c2M8d2w7KytzYyl7Y29uc3QgZmM9YWxbb2Mrc2NdLG1jPWRsW3BjK3NjXTtIbCs9ZmMqbWN9fX19dGxbbmwqX2wrc2wqT2wrcmwqTGwrb2wqR2wrRmxdPUhsfX19cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKGVsLnNoYXBlLGVsLmR0eXBlLGVsLnZhbHVlcyl9Y29uc3QgY29udjNEQmFja3Byb3BJbnB1dFYyQ29uZmlnPXtrZXJuZWxOYW1lOkNvbnYzREJhY2twcm9wSW5wdXRWMiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Y29udjNEQmFja3Byb3BJbnB1dFYyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjb3MkMj11bmFyeUtlcm5lbEZ1bmMkMihDb3MkMSxoYT0+TWF0aC5jb3MoaGEpKSxjb3NDb25maWckMj17a2VybmVsTmFtZTpDb3MkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmNvcyQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNvc2gkMj11bmFyeUtlcm5lbEZ1bmMkMihDb3NoJDEsaGE9Pk1hdGguY29zaChoYSkpLGNvc2hDb25maWckMj17a2VybmVsTmFtZTpDb3NoJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpjb3NoJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNyb3BBbmRSZXNpemUkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtpbWFnZTpTYSxib3hlczpUYSxib3hJbmQ6d2F9PWFhLHtjcm9wU2l6ZTpFYSxtZXRob2Q6a2EsZXh0cmFwb2xhdGlvblZhbHVlOkFhfT1iYSxbRmEsTGEsZWwsdGxdPVNhLnNoYXBlLG5sPVRhLnNoYXBlWzBdLFtzbCxybF09RWEsb2w9YnVmZmVyJDEoW25sLHNsLHJsLHRsXSwiZmxvYXQzMiIpLGFsPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLGxsPXhhLmRhdGEuZ2V0KHdhLmRhdGFJZCkudmFsdWVzLGlsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGNsPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLHVsPWNvbXB1dGVTdHJpZGVzJDEob2wuc2hhcGUpO2ZvcihsZXQgZGw9MDtkbDxubDtkbCsrKXtjb25zdCBobD1kbCo0LHBsPWFsW2hsXSxmbD1hbFtobCsxXSxtbD1hbFtobCsyXSxnbD1hbFtobCszXSwkbD1sbFtkbF07aWYoJGw+PUZhKWNvbnRpbnVlO2NvbnN0IHhsPXNsPjE/KG1sLXBsKSooTGEtMSkvKHNsLTEpOjAseWw9cmw+MT8oZ2wtZmwpKihlbC0xKS8ocmwtMSk6MDtmb3IobGV0IGJsPTA7Ymw8c2w7YmwrKyl7Y29uc3QgU2w9c2w+MT9wbCooTGEtMSkrYmwqeGw6LjUqKHBsK21sKSooTGEtMSk7aWYoU2w8MHx8U2w+TGEtMSl7Zm9yKGxldCBDbD0wO0NsPHJsO0NsKyspZm9yKGxldCBUbD0wO1RsPHRsO1RsKyspe2NvbnN0IHdsPVRsK0NsKnVsWzJdK2JsKnVsWzFdK2RsKnVsWzBdO29sLnZhbHVlc1t3bF09QWF9Y29udGludWV9aWYoa2E9PT0iYmlsaW5lYXIiKXtjb25zdCBDbD1NYXRoLmZsb29yKFNsKSxUbD1NYXRoLmNlaWwoU2wpLHdsPVNsLUNsO2ZvcihsZXQgSWw9MDtJbDxybDtJbCsrKXtjb25zdCBObD1ybD4xP2ZsKihlbC0xKStJbCp5bDouNSooZmwrZ2wpKihlbC0xKTtpZihObDwwfHxObD5lbC0xKXtmb3IobGV0IEFsPTA7QWw8dGw7QWwrKyl7Y29uc3QgUmw9QWwrSWwqdWxbMl0rYmwqdWxbMV0rZGwqdWxbMF07b2wudmFsdWVzW1JsXT1BYX1jb250aW51ZX1jb25zdCB2bD1NYXRoLmZsb29yKE5sKSxrbD1NYXRoLmNlaWwoTmwpLEVsPU5sLXZsO2ZvcihsZXQgQWw9MDtBbDx0bDtBbCsrKXtsZXQgUmw9QWwrdmwqY2xbMl0rQ2wqY2xbMV0rJGwqY2xbMF07Y29uc3QgUGw9aWxbUmxdO1JsPUFsK2tsKmNsWzJdK0NsKmNsWzFdKyRsKmNsWzBdO2NvbnN0IERsPWlsW1JsXTtSbD1BbCt2bCpjbFsyXStUbCpjbFsxXSskbCpjbFswXTtjb25zdCBfbD1pbFtSbF07Umw9QWwra2wqY2xbMl0rVGwqY2xbMV0rJGwqY2xbMF07Y29uc3QgRmw9aWxbUmxdLE9sPVBsKyhEbC1QbCkqRWwsTWw9X2wrKEZsLV9sKSpFbDtSbD1BbCtJbCp1bFsyXStibCp1bFsxXStkbCp1bFswXSxvbC52YWx1ZXNbUmxdPU9sKyhNbC1PbCkqd2x9fX1lbHNlIGZvcihsZXQgQ2w9MDtDbDxybDsrK0NsKXtjb25zdCBUbD1ybD4xP2ZsKihlbC0xKStDbCp5bDouNSooZmwrZ2wpKihlbC0xKTtpZihUbDwwfHxUbD5lbC0xKXtmb3IobGV0IE5sPTA7Tmw8dGw7TmwrKyl7Y29uc3Qgdmw9TmwrQ2wqdWxbMl0rYmwqdWxbMV0rZGwqdWxbMF07b2wudmFsdWVzW3ZsXT1BYX1jb250aW51ZX1jb25zdCB3bD1NYXRoLnJvdW5kKFRsKSxJbD1NYXRoLnJvdW5kKFNsKTtmb3IobGV0IE5sPTA7Tmw8dGw7TmwrKyl7Y29uc3Qgdmw9Tmwrd2wqY2xbMl0rSWwqY2xbMV0rJGwqY2xbMF0sa2w9TmwrQ2wqdWxbMl0rYmwqdWxbMV0rZGwqdWxbMF07b2wudmFsdWVzW2tsXT1pbFt2bF19fX19cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKG9sLnNoYXBlLG9sLmR0eXBlLG9sLnZhbHVlcyl9Y29uc3QgY3JvcEFuZFJlc2l6ZUNvbmZpZyQyPXtrZXJuZWxOYW1lOkNyb3BBbmRSZXNpemUkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmNyb3BBbmRSZXNpemUkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY3VtcHJvZCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGV4Y2x1c2l2ZTp3YSxyZXZlcnNlOkVhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsImN1bXByb2QiKTtjb25zdCBrYT1nZXRBeGVzUGVybXV0YXRpb24kMShbVGFdLFNhLnNoYXBlLmxlbmd0aCk7bGV0IEFhPVNhO2thIT1udWxsJiYoQWE9dHJhbnNwb3NlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTprYX19KSk7Y29uc3QgRmE9Z2V0SW5uZXJNb3N0QXhlcyQxKDEsU2Euc2hhcGUubGVuZ3RoKVswXTtpZihGYSE9PUFhLnNoYXBlLmxlbmd0aC0xKXRocm93IG5ldyBFcnJvcihgYmFja2VuZC5jdW1wcm9kIGluIENQVSBleHBlY3RzIGFuIGlubmVyLW1vc3QgYXhpcz0ke0FhLnNoYXBlLmxlbmd0aC0xfSBidXQgZ290IGF4aXM9JHtGYX1gKTtjb25zdCBMYT11cGNhc3RUeXBlJDEoQWEuZHR5cGUsImludDMyIiksZWw9bWFrZU9uZXNUeXBlZEFycmF5JDEoc2l6ZUZyb21TaGFwZSQxKEFhLnNoYXBlKSxMYSksdGw9eGEuZGF0YS5nZXQoQWEuZGF0YUlkKS52YWx1ZXMsbmw9QWEuc2hhcGVbQWEuc2hhcGUubGVuZ3RoLTFdLHNsPUVhPyhvbCxhbCk9Pm9sK25sLWFsLTE6KG9sLGFsKT0+b2wrYWw7Zm9yKGxldCBvbD0wO29sPHRsLmxlbmd0aDtvbCs9bmwpZm9yKGxldCBhbD0wO2FsPG5sO2FsKyspe2NvbnN0IGxsPXNsKG9sLGFsKTtpZihhbD09PTApZWxbbGxdPXdhPzE6dGxbbGxdO2Vsc2V7Y29uc3QgaWw9c2wob2wsYWwtMSk7ZWxbbGxdPXdhP3RsW2lsXSplbFtpbF06dGxbbGxdKmVsW2lsXX19Y29uc3Qgcmw9eGEubWFrZVRlbnNvckluZm8oQWEuc2hhcGUsTGEsZWwpO2lmKGthIT1udWxsKXtjb25zdCBvbD1nZXRVbmRvQXhlc1Blcm11dGF0aW9uJDEoa2EpLGFsPXRyYW5zcG9zZSQyKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06b2x9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhBYSksYWx9cmV0dXJuIHJsfWNvbnN0IGN1bXByb2RDb25maWckMj17a2VybmVsTmFtZTpDdW1wcm9kJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpjdW1wcm9kJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGN1bXN1bSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGV4Y2x1c2l2ZTp3YSxyZXZlcnNlOkVhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsImN1bXN1bSIpO2NvbnN0IGthPWdldEF4ZXNQZXJtdXRhdGlvbiQxKFtUYV0sU2Euc2hhcGUubGVuZ3RoKTtsZXQgQWE9U2E7a2EhPW51bGwmJihBYT10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOmthfX0pKTtjb25zdCBGYT1nZXRJbm5lck1vc3RBeGVzJDEoMSxTYS5zaGFwZS5sZW5ndGgpWzBdO2lmKEZhIT09QWEuc2hhcGUubGVuZ3RoLTEpdGhyb3cgbmV3IEVycm9yKGBiYWNrZW5kLmN1bXN1bSBpbiBDUFUgZXhwZWN0cyBhbiBpbm5lci1tb3N0IGF4aXM9JHtBYS5zaGFwZS5sZW5ndGgtMX0gYnV0IGdvdCBheGlzPSR7RmF9YCk7Y29uc3QgTGE9dXBjYXN0VHlwZSQxKEFhLmR0eXBlLCJpbnQzMiIpLGVsPW1ha2VaZXJvc1R5cGVkQXJyYXkkMShzaXplRnJvbVNoYXBlJDEoQWEuc2hhcGUpLExhKSx0bD14YS5kYXRhLmdldChBYS5kYXRhSWQpLnZhbHVlcyxubD1BYS5zaGFwZVtBYS5zaGFwZS5sZW5ndGgtMV0sc2w9RWE/KG9sLGFsKT0+b2wrbmwtYWwtMToob2wsYWwpPT5vbCthbDtmb3IobGV0IG9sPTA7b2w8dGwubGVuZ3RoO29sKz1ubClmb3IobGV0IGFsPTA7YWw8bmw7YWwrKyl7Y29uc3QgbGw9c2wob2wsYWwpO2lmKGFsPT09MCllbFtsbF09d2E/MDp0bFtsbF07ZWxzZXtjb25zdCBpbD1zbChvbCxhbC0xKTtlbFtsbF09d2E/dGxbaWxdK2VsW2lsXTp0bFtsbF0rZWxbaWxdfX1jb25zdCBybD14YS5tYWtlVGVuc29ySW5mbyhBYS5zaGFwZSxMYSxlbCk7aWYoa2EhPW51bGwpe2NvbnN0IG9sPWdldFVuZG9BeGVzUGVybXV0YXRpb24kMShrYSksYWw9dHJhbnNwb3NlJDIoe2lucHV0czp7eDpybH0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpvbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEFhKSxhbH1yZXR1cm4gcmx9Y29uc3QgY3Vtc3VtQ29uZmlnJDI9e2tlcm5lbE5hbWU6Q3Vtc3VtJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpjdW1zdW0kMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGVuc2VCaW5jb3VudCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2Esd2VpZ2h0czpUYX09YWEse3NpemU6d2EsYmluYXJ5T3V0cHV0OkVhfT1iYTtpZihTYS5zaGFwZS5sZW5ndGg9PT0xKXtjb25zdCBrYT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxBYT14YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyxGYT1iaW5jb3VudEltcGwkMShrYSxBYSxUYS5kdHlwZSxUYS5zaGFwZSx3YSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFt3YV0sVGEuZHR5cGUsRmEpfWVsc2UgaWYoU2Euc2hhcGUubGVuZ3RoPT09Mil7Y29uc3Qga2E9eGEuYnVmZmVyU3luYyhTYSksQWE9eGEuYnVmZmVyU3luYyhUYSksRmE9YmluY291bnRSZWR1Y2VJbXBsJDEoa2EsQWEsd2EsRWEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhGYS5zaGFwZSxUYS5kdHlwZSxGYS52YWx1ZXMpfXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gZGVuc2VCaW5jb3VudDogaW5wdXQgbXVzdCBiZSBhdCBtb3N0IHJhbmsgMiwgYnV0IGdvdCByYW5rJHtTYS5zaGFwZS5sZW5ndGh9LmApfWNvbnN0IGRlbnNlQmluY291bnRDb25maWckMj17a2VybmVsTmFtZTpEZW5zZUJpbmNvdW50JDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpkZW5zZUJpbmNvdW50JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRoVG9TcGFjZSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtibG9ja1NpemU6VGEsZGF0YUZvcm1hdDp3YX09YmE7YXNzZXJ0JDIod2E9PT0iTkhXQyIsKCk9PmBPbmx5IE5IV0MgZGF0YUZvcm1hdCBzdXBwb3J0ZWQgb24gQ1BVIGZvciBkZXB0aFRvU3BhY2UuIEdvdCAke3dhfWApO2NvbnN0IEVhPVNhLnNoYXBlWzBdLGthPVNhLnNoYXBlWzFdLEFhPVNhLnNoYXBlWzJdLEZhPVNhLnNoYXBlWzNdLExhPWthKlRhLGVsPUFhKlRhLHRsPUZhLyhUYSpUYSksbmw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsc2w9bmV3IEZsb2F0MzJBcnJheShFYSpMYSplbCp0bCk7bGV0IHJsPTA7Zm9yKGxldCBvbD0wO29sPEVhOysrb2wpZm9yKGxldCBhbD0wO2FsPExhOysrYWwpe2NvbnN0IGxsPU1hdGguZmxvb3IoYWwvVGEpLGlsPWFsJVRhO2ZvcihsZXQgY2w9MDtjbDxlbDsrK2NsKXtjb25zdCB1bD1NYXRoLmZsb29yKGNsL1RhKSxkbD1jbCVUYSxobD0oaWwqVGErZGwpKnRsO2ZvcihsZXQgcGw9MDtwbDx0bDsrK3BsKXtjb25zdCBtbD1wbCtobCtGYSoodWwrQWEqKGxsK2thKm9sKSk7c2xbcmwrK109bmxbbWxdfX19cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFtFYSxMYSxlbCx0bF0sU2EuZHR5cGUsc2wpfWNvbnN0IGRlcHRoVG9TcGFjZUNvbmZpZyQyPXtrZXJuZWxOYW1lOkRlcHRoVG9TcGFjZSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZGVwdGhUb1NwYWNlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZE5hdGl2ZSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGlsYXRpb25zOmthLGRpbVJvdW5kaW5nTW9kZTpBYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFtTYSxUYV0sImRlcHRod2lzZUNvbnYyRE5hdGl2ZSIpO2NvbnN0IEZhPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLExhPWNvbXB1dGVTdHJpZGVzJDEoVGEuc2hhcGUpO2xldCBlbD1rYTtlbD09bnVsbCYmKGVsPVsxLDFdKSxhc3NlcnQkMihlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUkMSh3YSxlbCksKCk9PmBFcnJvciBpbiBkZXB0aHdpc2VDb252MmQ6IEVpdGhlciBzdHJpZGVzIG9yIGRpbGF0aW9ucyBtdXN0IGJlIDEuIEdvdCBzdHJpZGVzICR7d2F9IGFuZCBkaWxhdGlvbnMgJyR7ZWx9J2ApO2NvbnN0IHRsPWNvbXB1dGVDb252MkRJbmZvJDEoU2Euc2hhcGUsVGEuc2hhcGUsd2EsZWwsRWEsQWEsITApLHtmaWx0ZXJIZWlnaHQ6bmwsZmlsdGVyV2lkdGg6c2wsZGlsYXRpb25IZWlnaHQ6cmwsZGlsYXRpb25XaWR0aDpvbCxwYWRJbmZvOmFsfT10bCxsbD1hbC5sZWZ0LGlsPWFsLnRvcCxjbD10bC5vdXRDaGFubmVscy90bC5pbkNoYW5uZWxzLHVsPW5ldyBUZW5zb3JCdWZmZXIkMSh0bC5vdXRTaGFwZSxTYS5kdHlwZSksZGw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsaGw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMscGw9dWwudmFsdWVzO2ZvcihsZXQgZmw9MDtmbDx0bC5iYXRjaFNpemU7KytmbCl7Y29uc3QgbWw9ZmwqRmFbMF0sZ2w9ZmwqdWwuc3RyaWRlc1swXTtmb3IobGV0ICRsPTA7JGw8dGwub3V0SGVpZ2h0OysrJGwpe2NvbnN0IHhsPWdsKyRsKnVsLnN0cmlkZXNbMV0seWw9JGwqdGwuc3RyaWRlSGVpZ2h0LWlsO2ZvcihsZXQgYmw9MDtibDxubDsrK2JsKXtjb25zdCBTbD15bCtibCpybDtpZihTbDwwfHxTbD49dGwuaW5IZWlnaHQpY29udGludWU7Y29uc3QgQ2w9YmwqTGFbMF0sVGw9bWwrU2wqRmFbMV07Zm9yKGxldCB3bD0wO3dsPHRsLm91dFdpZHRoOysrd2wpe2NvbnN0IElsPXhsK3dsKnVsLnN0cmlkZXNbMl0sTmw9d2wqdGwuc3RyaWRlV2lkdGgtbGw7Zm9yKGxldCB2bD0wO3ZsPHNsOysrdmwpe2NvbnN0IGtsPU5sK3ZsKm9sO2lmKGtsPDB8fGtsPj10bC5pbldpZHRoKWNvbnRpbnVlO2NvbnN0IEVsPUNsK3ZsKkxhWzFdLEFsPVRsK2tsKnRsLmluQ2hhbm5lbHM7bGV0IFJsPUlsLFBsPUVsO2ZvcihsZXQgRGw9MDtEbDx0bC5pbkNoYW5uZWxzOysrRGwpe2NvbnN0IF9sPWRsW0FsK0RsXTtmb3IobGV0IEZsPTA7Rmw8Y2w7KytGbClwbFtSbCtGbF0rPV9sKmhsW1BsK0ZsXTtSbCs9Y2wsUGwrPWNsfX19fX19cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKHVsLnNoYXBlLHVsLmR0eXBlLHVsLnZhbHVlcyl9Y29uc3QgZGVwdGh3aXNlQ29udjJkTmF0aXZlQ29uZmlnJDI9e2tlcm5lbE5hbWU6RGVwdGh3aXNlQ29udjJkTmF0aXZlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpkZXB0aHdpc2VDb252MmROYXRpdmUkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BGaWx0ZXIkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxkaWxhdGlvbnM6RWEscGFkOmthLGRpbVJvdW5kaW5nTW9kZTpBYSxmaWx0ZXJTaGFwZTpGYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFtTYSxUYV0sImRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyIik7Y29uc3QgTGE9Y29tcHV0ZUNvbnYyREluZm8kMShTYS5zaGFwZSxGYSx3YSxFYSxrYSxBYSwhMCkse3N0cmlkZUhlaWdodDplbCxzdHJpZGVXaWR0aDp0bCxmaWx0ZXJIZWlnaHQ6bmwsZmlsdGVyV2lkdGg6c2x9PUxhLHJsPW5ldyBUZW5zb3JCdWZmZXIkMShMYS5maWx0ZXJTaGFwZSwiZmxvYXQzMiIpLG9sPUxhLnBhZEluZm8ubGVmdCxhbD1MYS5wYWRJbmZvLnRvcCxsbD1MYS5vdXRDaGFubmVscy9MYS5pbkNoYW5uZWxzLGlsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGNsPW5ldyBUZW5zb3JCdWZmZXIkMShTYS5zaGFwZSxTYS5kdHlwZSxpbCksdWw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsZGw9bmV3IFRlbnNvckJ1ZmZlciQxKFRhLnNoYXBlLFRhLmR0eXBlLHVsKTtmb3IobGV0IGhsPTA7aGw8bmw7KytobCl7Y29uc3QgcGw9TWF0aC5tYXgoMCxNYXRoLmNlaWwoKGFsLWhsKS9lbCkpLGZsPU1hdGgubWluKExhLm91dEhlaWdodCwoTGEuaW5IZWlnaHQrYWwtaGwpL2VsKTtmb3IobGV0IG1sPTA7bWw8c2w7KyttbCl7Y29uc3QgZ2w9TWF0aC5tYXgoMCxNYXRoLmNlaWwoKG9sLW1sKS90bCkpLCRsPU1hdGgubWluKExhLm91dFdpZHRoLChMYS5pbldpZHRoK29sLW1sKS90bCk7Zm9yKGxldCB4bD0wO3hsPExhLm91dENoYW5uZWxzOysreGwpe2NvbnN0IHlsPU1hdGgudHJ1bmMoeGwvbGwpLGJsPXhsJWxsO2xldCBTbD0wO2ZvcihsZXQgQ2w9MDtDbDxMYS5iYXRjaFNpemU7KytDbClmb3IobGV0IFRsPXBsO1RsPGZsOysrVGwpe2NvbnN0IHdsPWhsK1RsKmVsLWFsO2ZvcihsZXQgSWw9Z2w7SWw8JGw7KytJbCl7Y29uc3QgTmw9bWwrSWwqdGwtb2w7U2wrPWNsLmdldChDbCx3bCxObCx5bCkqZGwuZ2V0KENsLFRsLElsLHhsKX19cmwuc2V0KFNsLGhsLG1sLHlsLGJsKX19fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhybC5zaGFwZSxybC5kdHlwZSxybC52YWx1ZXMpfWNvbnN0IGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyQ29uZmlnJDI9e2tlcm5lbE5hbWU6RGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BGaWx0ZXIkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxmaWx0ZXI6VGF9PWFhLHtzdHJpZGVzOndhLGRpbGF0aW9uczpFYSxwYWQ6a2EsZGltUm91bmRpbmdNb2RlOkFhLGlucHV0U2hhcGU6RmF9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJkZXB0aHdpc2VDb252MkROYXRpdmVCYWNrcHJvcElucHV0Iik7Y29uc3QgTGE9Y29tcHV0ZVN0cmlkZXMkMShTYS5zaGFwZSksZWw9Y29tcHV0ZVN0cmlkZXMkMShUYS5zaGFwZSksdGw9Y29tcHV0ZUNvbnYyREluZm8kMShGYSxUYS5zaGFwZSx3YSxFYSxrYSxBYSwhMCksbmw9bmV3IFRlbnNvckJ1ZmZlciQxKHRsLmluU2hhcGUsImZsb2F0MzIiKSxzbD1ubC52YWx1ZXMsW3JsLG9sLGFsXT1ubC5zdHJpZGVzLGxsPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLFtpbCxjbCx1bF09TGEsZGw9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsW2hsLHBsLGZsXT1lbCx7YmF0Y2hTaXplOm1sLGZpbHRlckhlaWdodDpnbCxmaWx0ZXJXaWR0aDokbCxpbkNoYW5uZWxzOnhsLGluSGVpZ2h0OnlsLGluV2lkdGg6Ymwsb3V0Q2hhbm5lbHM6U2wsb3V0SGVpZ2h0OkNsLG91dFdpZHRoOlRsLHN0cmlkZUhlaWdodDp3bCxzdHJpZGVXaWR0aDpJbH09dGwsTmw9Z2wtMS10bC5wYWRJbmZvLnRvcCx2bD0kbC0xLXRsLnBhZEluZm8ubGVmdCxrbD1TbC94bDtmb3IobGV0IEVsPTA7RWw8bWw7KytFbClmb3IobGV0IEFsPTA7QWw8eGw7KytBbClmb3IobGV0IFJsPTA7Umw8eWw7KytSbCl7Y29uc3QgUGw9UmwtTmwsRGw9TWF0aC5tYXgoMCxNYXRoLmNlaWwoUGwvd2wpKSxfbD1NYXRoLm1pbihDbCwoZ2wrUGwpL3dsKTtmb3IobGV0IEZsPTA7Rmw8Ymw7KytGbCl7Y29uc3QgT2w9RmwtdmwsTWw9TWF0aC5tYXgoMCxNYXRoLmNlaWwoT2wvSWwpKSxVbD1NYXRoLm1pbihUbCwoJGwrT2wpL0lsKTtsZXQgQmw9MDtmb3IobGV0IExsPURsO0xsPF9sOysrTGwpe2NvbnN0IHpsPUxsKndsLVBsO2ZvcihsZXQgVmw9TWw7Vmw8VWw7KytWbCl7Y29uc3QgcWw9VmwqSWwtT2wsR2w9aWwqRWwrY2wqTGwrdWwqVmwsWGw9aGwqKGdsLTEtemwpK3BsKigkbC0xLXFsKStmbCpBbDtmb3IobGV0IFdsPTA7V2w8a2w7KytXbCl7Y29uc3QgZWM9QWwqa2wrV2wsSGw9bGxbR2wrZWNdLGpsPWRsW1hsK1dsXTtCbCs9SGwqamx9fX1zbFtybCpFbCtvbCpSbCthbCpGbCtBbF09Qmx9fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhubC5zaGFwZSxubC5kdHlwZSxubC52YWx1ZXMpfWNvbnN0IGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXRDb25maWckMj17a2VybmVsTmFtZTpEZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcElucHV0JDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcElucHV0JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRpYWckMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYSxTYT1zaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpLFRhPXhhLmRhdGEuZ2V0KGJhLmRhdGFJZCkudmFsdWVzLHdhPWJ1ZmZlciQxKFtTYSxTYV0sYmEuZHR5cGUpLEVhPXdhLnZhbHVlcztmb3IobGV0IEFhPTA7QWE8VGEubGVuZ3RoO0FhKyspRWFbQWEqU2ErQWFdPVRhW0FhXTtjb25zdCBrYT1bLi4uYmEuc2hhcGUsLi4uYmEuc2hhcGVdO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSx3YS5kdHlwZSx3YS52YWx1ZXMpfWNvbnN0IGRpYWdDb25maWckMj17a2VybmVsTmFtZTpEaWFnJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpkaWFnJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGRpbGF0aW9uMkRDb25maWckMj17a2VybmVsTmFtZTpEaWxhdGlvbjJEJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzooe2lucHV0czpoYSxiYWNrZW5kOmFhLGF0dHJzOnhhfSk9Pntjb25zdHt4OmJhLGZpbHRlcjpTYX09aGEse3N0cmlkZXM6VGEscGFkOndhLGRpbGF0aW9uczpFYX09eGEsa2E9YWEsQWE9a2EuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsRmE9YmEuc2hhcGUubGVuZ3RoLExhPWthLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGVsPVNhLnNoYXBlLmxlbmd0aCx7YmF0Y2hTaXplOnRsLGluSGVpZ2h0Om5sLGluV2lkdGg6c2wsaW5DaGFubmVsczpybCxvdXRIZWlnaHQ6b2wsb3V0V2lkdGg6YWwscGFkSW5mbzpsbCxzdHJpZGVIZWlnaHQ6aWwsc3RyaWRlV2lkdGg6Y2wsZmlsdGVySGVpZ2h0OnVsLGZpbHRlcldpZHRoOmRsLGRpbGF0aW9uSGVpZ2h0OmhsLGRpbGF0aW9uV2lkdGg6cGwsb3V0U2hhcGU6Zmx9PWNvbXB1dGVEaWxhdGlvbjJESW5mbyQxKGJhLnNoYXBlLFNhLnNoYXBlLFRhLHdhLCJOSFdDIixFYSksbWw9c2l6ZUZyb21TaGFwZSQxKGZsKSxnbD1mbC5sZW5ndGgsJGw9Z2V0QXJyYXlGcm9tRFR5cGUkMShiYS5kdHlwZSxtbCk7Zm9yKGxldCB5bD0wO3lsPHRsOysreWwpZm9yKGxldCBibD0wO2JsPG9sOysrYmwpe2NvbnN0IFNsPWJsKmlsLWxsLnRvcDtmb3IobGV0IENsPTA7Q2w8YWw7KytDbCl7Y29uc3QgVGw9Q2wqY2wtbGwubGVmdDtmb3IobGV0IHdsPTA7d2w8cmw7Kyt3bCl7bGV0IElsPU51bWJlci5NSU5fU0FGRV9JTlRFR0VSO2ZvcihsZXQgdmw9MDt2bDx1bDsrK3ZsKXtjb25zdCBrbD1TbCt2bCpobDtpZihrbD49MCYma2w8bmwpZm9yKGxldCBFbD0wO0VsPGRsOysrRWwpe2NvbnN0IEFsPVRsK0VsKnBsO2lmKEFsPj0wJiZBbDxzbCl7Y29uc3QgUmw9bG9jVG9JbmRleCQxKFt5bCxrbCxBbCx3bF0sRmEsY29tcHV0ZVN0cmlkZXMkMShiYS5zaGFwZSkpLFBsPWxvY1RvSW5kZXgkMShbdmwsRWwsd2xdLGVsLGNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpKSxEbD1BYVtSbF0rTGFbUGxdO0RsPklsJiYoSWw9RGwpfX19Y29uc3QgTmw9bG9jVG9JbmRleCQxKFt5bCxibCxDbCx3bF0sZ2wsY29tcHV0ZVN0cmlkZXMkMShmbCkpOyRsW05sXT1JbH19fXJldHVybntkYXRhSWQ6a2Eud3JpdGUodG9UeXBlZEFycmF5JDEoJGwsYmEuZHR5cGUpLGZsLGJhLmR0eXBlKSxzaGFwZTpmbCxkdHlwZTpiYS5kdHlwZX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBkaWxhdGlvbjJEQmFja3Byb3BGaWx0ZXJDb25maWc9e2tlcm5lbE5hbWU6RGlsYXRpb24yREJhY2twcm9wRmlsdGVyLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6KHtpbnB1dHM6aGEsYmFja2VuZDphYSxhdHRyczp4YX0pPT57Y29uc3R7eDpiYSxmaWx0ZXI6U2EsZHk6VGF9PWhhLHtzdHJpZGVzOndhLHBhZDpFYSxkaWxhdGlvbnM6a2F9PXhhLEFhPWFhLEZhPXRvTmVzdGVkQXJyYXkkMShiYS5zaGFwZSxBYS5kYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcyksTGE9dG9OZXN0ZWRBcnJheSQxKFNhLnNoYXBlLEFhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzKSx7YmF0Y2hTaXplOmVsLGluSGVpZ2h0OnRsLGluV2lkdGg6bmwsaW5DaGFubmVsczpzbCxvdXRIZWlnaHQ6cmwsb3V0V2lkdGg6b2wscGFkSW5mbzphbCxzdHJpZGVIZWlnaHQ6bGwsc3RyaWRlV2lkdGg6aWwsZmlsdGVySGVpZ2h0OmNsLGZpbHRlcldpZHRoOnVsLGRpbGF0aW9uSGVpZ2h0OmRsLGRpbGF0aW9uV2lkdGg6aGwsb3V0U2hhcGU6cGx9PWNvbXB1dGVEaWxhdGlvbjJESW5mbyQxKGJhLnNoYXBlLFNhLnNoYXBlLHdhLEVhLCJOSFdDIixrYSk7YXNzZXJ0JDIoVGEucmFuaz09PXBsLmxlbmd0aCwoKT0+YEVycm9yIGluICR7RGlsYXRpb24yREJhY2twcm9wRmlsdGVyfSwgZHkgbXVzdCBoYXZlIHRoZSBzYW1lIHJhbmsgYXMgb3V0cHV0ICR7cGwubGVuZ3RofSwgYnV0IGdvdCAke1RhLnJhbmt9YCk7Y29uc3QgZmw9dG9OZXN0ZWRBcnJheSQxKHBsLEFhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzKSxtbD1tYWtlWmVyb3NOZXN0ZWRUeXBlZEFycmF5KFNhLnNoYXBlLFNhLmR0eXBlKTtmb3IobGV0ICRsPTA7JGw8ZWw7KyskbClmb3IobGV0IHhsPTA7eGw8cmw7Kyt4bCl7Y29uc3QgeWw9eGwqbGwtYWwudG9wO2ZvcihsZXQgYmw9MDtibDxvbDsrK2JsKXtjb25zdCBTbD1ibCppbC1hbC5sZWZ0O2ZvcihsZXQgQ2w9MDtDbDxzbDsrK0NsKXtsZXQgVGw9TnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsd2w9MCxJbD0wO2ZvcihsZXQgTmw9MDtObDxjbDsrK05sKXtjb25zdCB2bD15bCtObCpkbDtpZih2bD49MCYmdmw8dGwpZm9yKGxldCBrbD0wO2tsPHVsOysra2wpe2NvbnN0IEVsPVNsK2tsKmhsO2lmKEVsPj0wJiZFbDxubCl7Y29uc3QgQWw9RmFbJGxdW3ZsXVtFbF1bQ2xdK0xhW05sXVtrbF1bQ2xdO0FsPlRsJiYoVGw9QWwsd2w9TmwsSWw9a2wpfX19bWxbd2xdW0lsXVtDbF0rPWZsWyRsXVt4bF1bYmxdW0NsXX19fXJldHVybntkYXRhSWQ6QWEud3JpdGUodG9UeXBlZEFycmF5JDEobWwsYmEuZHR5cGUpLFNhLnNoYXBlLFNhLmR0eXBlKSxzaGFwZTpTYS5zaGFwZSxkdHlwZTpTYS5kdHlwZX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBkaWxhdGlvbjJEQmFja3Byb3BJbnB1dENvbmZpZz17a2VybmVsTmFtZTpEaWxhdGlvbjJEQmFja3Byb3BJbnB1dCxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOih7aW5wdXRzOmhhLGJhY2tlbmQ6YWEsYXR0cnM6eGF9KT0+e2NvbnN0e3g6YmEsZmlsdGVyOlNhLGR5OlRhfT1oYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGlsYXRpb25zOmthfT14YSxBYT1hYSxGYT10b05lc3RlZEFycmF5JDEoYmEuc2hhcGUsQWEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMpLExhPXRvTmVzdGVkQXJyYXkkMShTYS5zaGFwZSxBYS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcykse2JhdGNoU2l6ZTplbCxpbkhlaWdodDp0bCxpbldpZHRoOm5sLGluQ2hhbm5lbHM6c2wsb3V0SGVpZ2h0OnJsLG91dFdpZHRoOm9sLHBhZEluZm86YWwsc3RyaWRlSGVpZ2h0OmxsLHN0cmlkZVdpZHRoOmlsLGZpbHRlckhlaWdodDpjbCxmaWx0ZXJXaWR0aDp1bCxkaWxhdGlvbkhlaWdodDpkbCxkaWxhdGlvbldpZHRoOmhsLG91dFNoYXBlOnBsfT1jb21wdXRlRGlsYXRpb24yREluZm8kMShiYS5zaGFwZSxTYS5zaGFwZSx3YSxFYSwiTkhXQyIsa2EpO2Fzc2VydCQyKFRhLnJhbms9PT1wbC5sZW5ndGgsKCk9PmBFcnJvciBpbiAke0RpbGF0aW9uMkRCYWNrcHJvcElucHV0fSwgZHkgbXVzdCBoYXZlIHRoZSBzYW1lIHJhbmsgYXMgb3V0cHV0ICR7cGwubGVuZ3RofSwgYnV0IGdvdCAke1RhLnJhbmt9YCk7Y29uc3QgZmw9dG9OZXN0ZWRBcnJheSQxKHBsLEFhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzKSxtbD1tYWtlWmVyb3NOZXN0ZWRUeXBlZEFycmF5KGJhLnNoYXBlLGJhLmR0eXBlKTtmb3IobGV0ICRsPTA7JGw8ZWw7KyskbClmb3IobGV0IHhsPTA7eGw8cmw7Kyt4bCl7Y29uc3QgeWw9eGwqbGwtYWwudG9wO2ZvcihsZXQgYmw9MDtibDxvbDsrK2JsKXtjb25zdCBTbD1ibCppbC1hbC5sZWZ0O2ZvcihsZXQgQ2w9MDtDbDxzbDsrK0NsKXtsZXQgVGw9TnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsd2w9eWw8MD8wOnlsLElsPVNsPDA/MDpTbDtmb3IobGV0IE5sPTA7Tmw8Y2w7KytObCl7Y29uc3Qgdmw9eWwrTmwqZGw7aWYodmw+PTAmJnZsPHRsKWZvcihsZXQga2w9MDtrbDx1bDsrK2tsKXtjb25zdCBFbD1TbCtrbCpobDtpZihFbD49MCYmRWw8bmwpe2NvbnN0IEFsPUZhWyRsXVt2bF1bRWxdW0NsXStMYVtObF1ba2xdW0NsXTtBbD5UbCYmKFRsPUFsLHdsPXZsLElsPUVsKX19fW1sWyRsXVt3bF1bSWxdW0NsXSs9ZmxbJGxdW3hsXVtibF1bQ2xdfX19cmV0dXJue2RhdGFJZDpBYS53cml0ZSh0b1R5cGVkQXJyYXkkMShtbCxiYS5kdHlwZSksYmEuc2hhcGUsYmEuZHR5cGUpLHNoYXBlOmJhLnNoYXBlLGR0eXBlOmJhLmR0eXBlfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRyYXcoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2U6U2F9PWFhLHtjYW52YXM6VGEsb3B0aW9uczp3YX09YmEse2NvbnRleHRPcHRpb25zOkVhLGltYWdlT3B0aW9uczprYX09d2F8fHt9LEFhPShrYT09bnVsbD92b2lkIDA6a2EuYWxwaGEpfHwxLEZhPShFYT09bnVsbD92b2lkIDA6RWEuY29udGV4dFR5cGUpfHwiMmQiO2lmKEZhIT09IjJkIil0aHJvdyBuZXcgRXJyb3IoYENvbnRleHQgdHlwZSAke0VhLmNvbnRleHRUeXBlfSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBDUFUgYmFja2VuZC5gKTtjb25zdCBMYT1UYS5nZXRDb250ZXh0KEZhLChFYT09bnVsbD92b2lkIDA6RWEuY29udGV4dEF0dHJpYnV0ZXMpfHx7fSk7aWYoTGE9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZ2V0IHRoZSBjb250ZXh0IHdpdGggJHtGYX0gdHlwZS5gKTtjb25zdFtlbCx0bF09U2Euc2hhcGUuc2xpY2UoMCwyKSxubD1TYS5zaGFwZS5sZW5ndGg9PT0yPzE6U2Euc2hhcGVbMl0sc2w9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMscmw9U2EuZHR5cGU9PT0iZmxvYXQzMiI/MjU1OjEsb2w9bmV3IFVpbnQ4Q2xhbXBlZEFycmF5KHRsKmVsKjQpO2ZvcihsZXQgbGw9MDtsbDxlbCp0bDsrK2xsKXtjb25zdCBpbD1bMCwwLDAsMjU1KkFhXTtmb3IobGV0IHVsPTA7dWw8bmw7dWwrKyl7Y29uc3QgZGw9c2xbbGwqbmwrdWxdO2lmKFNhLmR0eXBlPT09ImZsb2F0MzIiKXtpZihkbDwwfHxkbD4xKXRocm93IG5ldyBFcnJvcihgVGVuc29yIHZhbHVlcyBmb3IgYSBmbG9hdDMyIFRlbnNvciBtdXN0IGJlIGluIHRoZSByYW5nZSBbMCAtIDFdIGJ1dCBlbmNvdW50ZXJlZCAke2RsfS5gKX1lbHNlIGlmKFNhLmR0eXBlPT09ImludDMyIiYmKGRsPDB8fGRsPjI1NSkpdGhyb3cgbmV3IEVycm9yKGBUZW5zb3IgdmFsdWVzIGZvciBhIGludDMyIFRlbnNvciBtdXN0IGJlIGluIHRoZSByYW5nZSBbMCAtIDI1NV0gYnV0IGVuY291bnRlcmVkICR7ZGx9LmApO25sPT09MT8oaWxbMF09ZGwqcmwsaWxbMV09ZGwqcmwsaWxbMl09ZGwqcmwpOmlsW3VsXT1kbCpybH1jb25zdCBjbD1sbCo0O29sW2NsKzBdPU1hdGgucm91bmQoaWxbMF0pLG9sW2NsKzFdPU1hdGgucm91bmQoaWxbMV0pLG9sW2NsKzJdPU1hdGgucm91bmQoaWxbMl0pLG9sW2NsKzNdPU1hdGgucm91bmQoaWxbM10pfVRhLndpZHRoPXRsLFRhLmhlaWdodD1lbDtjb25zdCBhbD1uZXcgSW1hZ2VEYXRhKG9sLHRsLGVsKTtyZXR1cm4gTGEucHV0SW1hZ2VEYXRhKGFsLDAsMCksU2F9Y29uc3QgZHJhd0NvbmZpZz17a2VybmVsTmFtZTpEcmF3LGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZHJhd307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3VtJDQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGEsa2VlcERpbXM6d2F9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihTYSwic3VtIik7bGV0IEVhO1NhLmR0eXBlPT09ImJvb2wiP0VhPWNhc3QkMyh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntkdHlwZToiaW50MzIifX0pOkVhPWlkZW50aXR5JDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2NvbnN0IGthPUVhLnNoYXBlLmxlbmd0aCxBYT1wYXJzZUF4aXNQYXJhbSQxKFRhLEVhLnNoYXBlKSxGYT1nZXRBeGVzUGVybXV0YXRpb24kMShBYSxrYSk7bGV0IExhPUFhLGVsPUVhO0ZhIT1udWxsJiYoZWw9dHJhbnNwb3NlJDIoe2lucHV0czp7eDpFYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpGYX19KSxMYT1nZXRJbm5lck1vc3RBeGVzJDEoTGEubGVuZ3RoLGthKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgic3VtIixMYSxlbC5zaGFwZS5sZW5ndGgpO2NvbnN0W3RsLG5sXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoZWwuc2hhcGUsTGEpLHNsPXVwY2FzdFR5cGUkMShlbC5kdHlwZSwiaW50MzIiKTtsZXQgcmw9emVyb3MkMSh4YSx0bCxzbCk7Y29uc3Qgb2w9c2l6ZUZyb21TaGFwZSQxKG5sKSxhbD14YS5kYXRhLmdldChybC5kYXRhSWQpLnZhbHVlcyxsbD14YS5kYXRhLmdldChlbC5kYXRhSWQpLnZhbHVlcztmb3IobGV0IGlsPTA7aWw8YWwubGVuZ3RoOysraWwpe2NvbnN0IGNsPWlsKm9sO2xldCB1bD0wO2ZvcihsZXQgZGw9MDtkbDxvbDsrK2RsKXVsKz1sbFtjbCtkbF07YWxbaWxdPXVsfWlmKHdhKXtjb25zdCBpbD1leHBhbmRTaGFwZVRvS2VlcERpbSQxKHJsLnNoYXBlLEFhKSxjbD1ybDtybD1yZXNoYXBlJDMoe2lucHV0czp7eDpybH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6aWx9fSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oY2wpfXJldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSksRmEhPW51bGwmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGVsKSxybH1jb25zdCBzdW1Db25maWckMj17a2VybmVsTmFtZTpTdW0kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnN1bSQ0fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBlaW5zdW0kMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtlcXVhdGlvbjpTYX09YmEsVGE9YWEse2FsbERpbXM6d2Esc3VtbWVkRGltczpFYSxpZERpbXM6a2F9PWRlY29kZUVpbnN1bUVxdWF0aW9uJDEoU2EsVGEubGVuZ3RoKTtjaGVja0VpbnN1bURpbVNpemVzJDEod2EubGVuZ3RoLGthLFRhKTtjb25zdHtwYXRoOkFhLHN0ZXBzOkZhfT1nZXRFaW5zdW1Db21wdXRlUGF0aCQxKEVhLGthKSxMYT1GYS5sZW5ndGg7bGV0IGVsPW51bGwsdGw9d2EubGVuZ3RoO2NvbnN0IG5sPVtdO2ZvcihsZXQgc2w9MDtzbDxMYTsrK3NsKXtmb3IoY29uc3Qgcmwgb2YgRmFbc2xdKXtjb25zdHtwZXJtdXRhdGlvbkluZGljZXM6b2wsZXhwYW5kRGltczphbH09Z2V0RWluc3VtUGVybXV0YXRpb24kMSh0bCxrYVtybF0pO2xldCBsbDtpc0lkZW50aXR5UGVybXV0YXRpb24kMShvbCk/bGw9VGFbcmxdOihsbD10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlRhW3JsXX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpvbH19KSxubC5wdXNoKGxsKSk7Y29uc3QgaWw9bGwuc2hhcGUuc2xpY2UoKTtmb3IobGV0IGNsPTA7Y2w8YWwubGVuZ3RoOysrY2wpaWwuc3BsaWNlKGFsW2NsXSwwLDEpO2FycmF5c0VxdWFsJDEobGwuc2hhcGUsaWwpfHwobGw9cmVzaGFwZSQzKHtpbnB1dHM6e3g6bGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmlsfX0pLG5sLnB1c2gobGwpKSxlbD09PW51bGw/ZWw9bGw6KGVsPW11bHRpcGx5JDIoe2lucHV0czp7YTpsbCxiOmVsfSxiYWNrZW5kOnhhfSksbmwucHVzaChlbCkpfXNsPExhLTEmJihBYVtzbF0+PTAmJihlbD1zdW0kNCh7aW5wdXRzOnt4OmVsfSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOkFhW3NsXS0od2EubGVuZ3RoLXRsKSxrZWVwRGltczohMX19KSxubC5wdXNoKGVsKSksdGwtLSl9Zm9yKGNvbnN0IHNsIG9mIG5sKXNsIT09ZWwmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKTtyZXR1cm4gZWx9Y29uc3QgZWluc3VtQ29uZmlnJDI9e2tlcm5lbE5hbWU6RWluc3VtJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzplaW5zdW0kMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZWx1R3JhZCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2R5OmJhLHk6U2F9PWFhO2Fzc2VydE5vdENvbXBsZXgkMihbYmEsU2FdLCJlbHVHcmFkIik7Y29uc3QgVGE9bmV3IEZsb2F0MzJBcnJheShzaXplRnJvbVNoYXBlJDEoU2Euc2hhcGUpKSx3YT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxFYT14YS5kYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IGthPTA7a2E8d2EubGVuZ3RoOysra2Epe2NvbnN0IEFhPXdhW2thXTtBYT49MD9UYVtrYV09RWFba2FdOlRhW2thXT1FYVtrYV0qKEFhKzEpfXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhTYS5zaGFwZSwiZmxvYXQzMiIsVGEpfWNvbnN0IGVsdUdyYWRDb25maWckMj17a2VybmVsTmFtZTpFbHVHcmFkJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzplbHVHcmFkJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcCQxPUVSRl9QJDEsYTE9RVJGX0ExJDEsYTI9RVJGX0EyJDEsYTM9RVJGX0EzJDEsYTQ9RVJGX0E0JDEsYTU9RVJGX0E1JDEsZXJmJDI9dW5hcnlLZXJuZWxGdW5jJDIoRXJmJDEsaGE9Pntjb25zdCBhYT1NYXRoLnNpZ24oaGEpLHhhPU1hdGguYWJzKGhhKSxiYT0xLygxK3AkMSp4YSk7cmV0dXJuIGFhKigxLSgoKChhNSpiYSthNCkqYmErYTMpKmJhK2EyKSpiYSthMSkqYmEqTWF0aC5leHAoLXhhKnhhKSl9KSxlcmZDb25maWckMj17a2VybmVsTmFtZTpFcmYkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmVyZiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBleHBhbmREaW1zJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW5wdXQ6U2F9PWFhLHtkaW06VGF9PWJhLHdhPVNhLnNoYXBlLmxlbmd0aCxFYT1TYS5zaGFwZS5zbGljZSgpO2xldCBrYT1UYTtyZXR1cm4gVGE8MCYmKGFzc2VydCQyKC0od2ErMSk8PVRhLCgpPT5gQXhpcyBtdXN0IGJlIGluIHRoZSBpbnRlcnZhbCBbJHstKHdhKzEpfSwgJHt3YX1dYCksa2E9d2ErVGErMSksRWEuc3BsaWNlKGthLDAsMSkscmVzaGFwZSQzKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkVhfX0pfWNvbnN0IGV4cGFuZERpbXNDb25maWckMj17a2VybmVsTmFtZTpFeHBhbmREaW1zJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpleHBhbmREaW1zJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJlYWxEaXZJbXBsPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYS9hYSksZGl2JDE9YmluYXJ5S2VybmVsRnVuYyQyKFJlYWxEaXYkMSxyZWFsRGl2SW1wbCkscmVhbERpdkNvbmZpZyQyPXtrZXJuZWxOYW1lOlJlYWxEaXYkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmRpdiQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmZnRCYXRjaChoYSxhYSx4YSl7Y29uc3QgYmE9aGEuc2hhcGUsU2E9YmFbMF0sVGE9YmFbMV0sd2E9eGEuZGF0YS5nZXQoaGEuZGF0YUlkKSxFYT13YS5jb21wbGV4VGVuc29ySW5mb3MucmVhbCxrYT13YS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZyxBYT1bU2EsVGFdLEZhPXNpemVGcm9tU2hhcGUkMShBYSksTGE9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKCJmbG9hdDMyIixGYSksZWw9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKCJmbG9hdDMyIixGYSk7Zm9yKGxldCBybD0wO3JsPFNhO3JsKyspe2NvbnN0IG9sPXNsaWNlJDIoe2lucHV0czp7eDpFYX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46W3JsLDBdLHNpemU6WzEsVGFdfX0pLGFsPXNsaWNlJDIoe2lucHV0czp7eDprYX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46W3JsLDBdLHNpemU6WzEsVGFdfX0pLGxsPWNvbXBsZXgkMyh7aW5wdXRzOntyZWFsOm9sLGltYWc6YWx9LGJhY2tlbmQ6eGF9KSx7cmVhbDppbCxpbWFnOmNsfT1mZnRJbXBsJDIobGwsYWEseGEpLHVsPW1lcmdlUmVhbEFuZEltYWdBcnJheXMkMShpbCxjbCk7Zm9yKGxldCBkbD0wO2RsPFRhO2RsKyspe2NvbnN0IGhsPWdldENvbXBsZXhXaXRoSW5kZXgkMSh1bCxkbCk7TGFbcmwqVGErZGxdPWhsLnJlYWwsZWxbcmwqVGErZGxdPWhsLmltYWd9eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGFsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhsbCl9Y29uc3QgdGw9eGEubWFrZVRlbnNvckluZm8oQWEsImZsb2F0MzIiLExhKSxubD14YS5tYWtlVGVuc29ySW5mbyhBYSwiZmxvYXQzMiIsZWwpLHNsPWNvbXBsZXgkMyh7aW5wdXRzOntyZWFsOnRsLGltYWc6bmx9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSxzbH1mdW5jdGlvbiBmZnRJbXBsJDIoaGEsYWEseGEpe2NvbnN0IGJhPXNpemVGcm9tU2hhcGUkMShoYS5zaGFwZSksU2E9eGEuZGF0YS5nZXQoaGEuZGF0YUlkKSxUYT14YS5kYXRhLmdldChTYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbC5kYXRhSWQpLnZhbHVlcyx3YT14YS5kYXRhLmdldChTYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZy5kYXRhSWQpLnZhbHVlcztpZihpc0V4cG9uZW50T2YyKGJhKSl7Y29uc3QgRWE9ZmZ0UmFkaXgyKFRhLHdhLGJhLGFhLHhhKSxrYT1baGEuc2hhcGVbMF0saGEuc2hhcGVbMV1dO2lmKGFhKXtjb25zdCBBYT14YS5tYWtlVGVuc29ySW5mbyhrYSwiZmxvYXQzMiIsRWEucmVhbCksRmE9eGEubWFrZVRlbnNvckluZm8oa2EsImZsb2F0MzIiLEVhLmltYWcpLExhPXhhLm1ha2VUZW5zb3JJbmZvKFtdLCJmbG9hdDMyIixjcmVhdGVTY2FsYXJWYWx1ZSQxKGJhLCJmbG9hdDMyIikpLGVsPWlkZW50aXR5JDIoe2lucHV0czp7eDpMYX0sYmFja2VuZDp4YX0pLHRsPXJlYWxEaXZDb25maWckMi5rZXJuZWxGdW5jKHtpbnB1dHM6e2E6QWEsYjpMYX0sYmFja2VuZDp4YX0pLG5sPXJlYWxEaXZDb25maWckMi5rZXJuZWxGdW5jKHtpbnB1dHM6e2E6RmEsYjplbH0sYmFja2VuZDp4YX0pLHNsPXhhLmRhdGEuZ2V0KHRsLmRhdGFJZCkudmFsdWVzLHJsPXhhLmRhdGEuZ2V0KG5sLmRhdGFJZCkudmFsdWVzO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhBYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKExhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSx7cmVhbDpzbCxpbWFnOnJsfX1yZXR1cm4gRWF9ZWxzZXtjb25zdCBFYT1tZXJnZVJlYWxBbmRJbWFnQXJyYXlzJDEoVGEsd2EpLGthPWZvdXJpZXJUcmFuc2Zvcm1CeU1hdG11bChFYSxiYSxhYSk7cmV0dXJuIHNwbGl0UmVhbEFuZEltYWdBcnJheXMkMShrYSl9fWZ1bmN0aW9uIGlzRXhwb25lbnRPZjIoaGEpe3JldHVybihoYSZoYS0xKT09PTB9ZnVuY3Rpb24gZmZ0UmFkaXgyKGhhLGFhLHhhLGJhLFNhKXtpZih4YT09PTEpcmV0dXJue3JlYWw6aGEsaW1hZzphYX07Y29uc3QgVGE9bWVyZ2VSZWFsQW5kSW1hZ0FycmF5cyQxKGhhLGFhKSx3YT14YS8yLEVhPWNvbXBsZXhXaXRoRXZlbkluZGV4JDEoVGEpLGthPUVhLnJlYWwsQWE9RWEuaW1hZyxGYT1ba2EubGVuZ3RoXSxMYT1TYS5tYWtlVGVuc29ySW5mbyhGYSwiZmxvYXQzMiIsa2EpLGVsPVNhLm1ha2VUZW5zb3JJbmZvKEZhLCJmbG9hdDMyIixBYSksdGw9Y29tcGxleCQzKHtpbnB1dHM6e3JlYWw6TGEsaW1hZzplbH0sYmFja2VuZDpTYX0pLG5sPWNvbXBsZXhXaXRoT2RkSW5kZXgkMShUYSksc2w9bmwucmVhbCxybD1ubC5pbWFnLG9sPVtzbC5sZW5ndGhdLGFsPVNhLm1ha2VUZW5zb3JJbmZvKG9sLCJmbG9hdDMyIixzbCksbGw9U2EubWFrZVRlbnNvckluZm8ob2wsImZsb2F0MzIiLHJsKSxpbD1jb21wbGV4JDMoe2lucHV0czp7cmVhbDphbCxpbWFnOmxsfSxiYWNrZW5kOlNhfSksY2w9ZmZ0UmFkaXgyKGthLEFhLHdhLGJhLFNhKSx1bD1jbC5yZWFsLGRsPWNsLmltYWcsaGw9W3VsLmxlbmd0aF0scGw9U2EubWFrZVRlbnNvckluZm8oaGwsImZsb2F0MzIiLHVsKSxmbD1TYS5tYWtlVGVuc29ySW5mbyhobCwiZmxvYXQzMiIsZGwpLG1sPWNvbXBsZXgkMyh7aW5wdXRzOntyZWFsOnBsLGltYWc6Zmx9LGJhY2tlbmQ6U2F9KSxnbD1mZnRSYWRpeDIoc2wscmwsd2EsYmEsU2EpLCRsPWdsLnJlYWwseGw9Z2wuaW1hZyx5bD1bJGwubGVuZ3RoXSxibD1TYS5tYWtlVGVuc29ySW5mbyh5bCwiZmxvYXQzMiIsJGwpLFNsPVNhLm1ha2VUZW5zb3JJbmZvKHlsLCJmbG9hdDMyIix4bCksQ2w9Y29tcGxleCQzKHtpbnB1dHM6e3JlYWw6YmwsaW1hZzpTbH0sYmFja2VuZDpTYX0pLFRsPWV4cG9uZW50cyQxKHhhLGJhKSx3bD1bVGwucmVhbC5sZW5ndGhdLElsPVNhLm1ha2VUZW5zb3JJbmZvKHdsLCJmbG9hdDMyIixUbC5yZWFsKSxObD1TYS5tYWtlVGVuc29ySW5mbyh3bCwiZmxvYXQzMiIsVGwuaW1hZyksdmw9Y29tcGxleCQzKHtpbnB1dHM6e3JlYWw6SWwsaW1hZzpObH0sYmFja2VuZDpTYX0pLGtsPW11bHRpcGx5JDIoe2lucHV0czp7YTp2bCxiOkNsfSxiYWNrZW5kOlNhfSksRWw9YWRkJDIoe2lucHV0czp7YTptbCxiOmtsfSxiYWNrZW5kOlNhfSksQWw9c3ViJDMoe2lucHV0czp7YTptbCxiOmtsfSxiYWNrZW5kOlNhfSksUmw9cmVhbCQyKHtpbnB1dHM6e2lucHV0OkVsfSxiYWNrZW5kOlNhfSksUGw9cmVhbCQyKHtpbnB1dHM6e2lucHV0OkFsfSxiYWNrZW5kOlNhfSksRGw9aW1hZyQyKHtpbnB1dHM6e2lucHV0OkVsfSxiYWNrZW5kOlNhfSksX2w9aW1hZyQyKHtpbnB1dHM6e2lucHV0OkFsfSxiYWNrZW5kOlNhfSksRmw9Y29uY2F0JDIoe2lucHV0czpbUmwsUGxdLGJhY2tlbmQ6U2EsYXR0cnM6e2F4aXM6MH19KSxPbD1jb25jYXQkMih7aW5wdXRzOltEbCxfbF0sYmFja2VuZDpTYSxhdHRyczp7YXhpczowfX0pLE1sPVNhLmRhdGEuZ2V0KEZsLmRhdGFJZCkudmFsdWVzLFVsPVNhLmRhdGEuZ2V0KE9sLmRhdGFJZCkudmFsdWVzO3JldHVybiBTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oZWwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhbCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8obGwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGlsKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhwbCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oZmwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG1sKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhibCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oU2wpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKENsKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhJbCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTmwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHZsKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhrbCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEFsKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhSbCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRGwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKFBsKSxTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhfbCksU2EuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmwpLFNhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKE9sKSx7cmVhbDpNbCxpbWFnOlVsfX1mdW5jdGlvbiBmb3VyaWVyVHJhbnNmb3JtQnlNYXRtdWwoaGEsYWEseGEpe2NvbnN0IGJhPW5ldyBGbG9hdDMyQXJyYXkoYWEqMik7Zm9yKGxldCBTYT0wO1NhPGFhO1NhKyspe2xldCBUYT0wLHdhPTA7Zm9yKGxldCBFYT0wO0VhPGFhO0VhKyspe2NvbnN0IGthPWV4cG9uZW50JDEoU2EqRWEsYWEseGEpLEFhPWdldENvbXBsZXhXaXRoSW5kZXgkMShoYSxFYSk7VGErPUFhLnJlYWwqa2EucmVhbC1BYS5pbWFnKmthLmltYWcsd2ErPUFhLnJlYWwqa2EuaW1hZytBYS5pbWFnKmthLnJlYWx9eGEmJihUYS89YWEsd2EvPWFhKSxhc3NpZ25Ub1R5cGVkQXJyYXkkMShiYSxUYSx3YSxTYSl9cmV0dXJuIGJhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZmdCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2lucHV0OmJhfT1hYSxTYT1zaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpLFRhPWJhLnNoYXBlW2JhLnNoYXBlLmxlbmd0aC0xXSx3YT1TYS9UYSxFYT1yZXNoYXBlJDMoe2lucHV0czp7eDpiYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W3dhLFRhXX19KSxrYT1mZnRCYXRjaChFYSwhMSx4YSksQWE9cmVzaGFwZSQzKHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmJhLnNoYXBlfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oa2EpLEFhfWNvbnN0IGZmdENvbmZpZyQyPXtrZXJuZWxOYW1lOkZGVCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZmZ0JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZpbGwkMyhoYSl7Y29uc3R7YmFja2VuZDphYSxhdHRyczp4YX09aGEse3NoYXBlOmJhLHZhbHVlOlNhLGR0eXBlOlRhfT14YSx3YT1UYXx8aW5mZXJEdHlwZSQxKFNhKSxFYT1nZXRBcnJheUZyb21EVHlwZSQxKHdhLHNpemVGcm9tU2hhcGUkMShiYSkpO3JldHVybiBmaWxsVmFsdWVzKEVhLFNhLHdhKSxhYS5tYWtlVGVuc29ySW5mbyhiYSx3YSxFYSl9Y29uc3QgZmlsbENvbmZpZyQyPXtrZXJuZWxOYW1lOkZpbGwkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmZpbGwkM307ZnVuY3Rpb24gZmlsbFZhbHVlcyhoYSxhYSx4YSl7aGEuZmlsbChhYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZmxpcExlZnRSaWdodENvbmZpZyQyPXtrZXJuZWxOYW1lOkZsaXBMZWZ0UmlnaHQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOih7aW5wdXRzOmhhLGF0dHJzOmFhLGJhY2tlbmQ6eGF9KT0+e2NvbnN0e2ltYWdlOmJhfT1oYSxTYT14YSxUYT1nZXRUeXBlZEFycmF5RnJvbURUeXBlJDEoYmEuZHR5cGUsc2l6ZUZyb21TaGFwZSQxKGJhLnNoYXBlKSksW3dhLEVhLGthLEFhXT1iYS5zaGFwZSxGYT1TYS5kYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IGVsPTA7ZWw8d2E7ZWwrKyl7Y29uc3QgdGw9ZWwqa2EqRWEqQWE7Zm9yKGxldCBubD0wO25sPEVhO25sKyspe2NvbnN0IHNsPW5sKihrYSpBYSk7Zm9yKGxldCBybD0wO3JsPGthO3JsKyspe2NvbnN0IG9sPXJsKkFhO2ZvcihsZXQgYWw9MDthbDxBYTthbCsrKXtjb25zdCBsbD1NYXRoLnJvdW5kKGthLXJsLTEpLGlsPXRsK3NsK29sK2FsO2xldCBjbD1GYVtpbF07aWYobGw+PTAmJmxsPGthKXtjb25zdCB1bD1sbCpBYSxkbD10bCtzbCt1bCthbDtjbD1GYVtkbF19VGFbaWxdPWNsfX19fXJldHVybntkYXRhSWQ6U2Eud3JpdGUoVGEsYmEuc2hhcGUsYmEuZHR5cGUpLHNoYXBlOmJhLnNoYXBlLGR0eXBlOmJhLmR0eXBlfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZ1c2VkQ29udjJEKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhLGJpYXM6d2EscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpFYX09YWEse3N0cmlkZXM6a2EscGFkOkFhLGRhdGFGb3JtYXQ6RmEsZGlsYXRpb25zOkxhLGRpbVJvdW5kaW5nTW9kZTplbCxhY3RpdmF0aW9uOnRsLGxlYWt5cmVsdUFscGhhOm5sfT1iYTtsZXQgc2w9Y29udjJEKHtpbnB1dHM6e3g6U2EsZmlsdGVyOlRhfSxiYWNrZW5kOnhhLGF0dHJzOntzdHJpZGVzOmthLHBhZDpBYSxkYXRhRm9ybWF0OkZhLGRpbGF0aW9uczpMYSxkaW1Sb3VuZGluZ01vZGU6ZWx9fSk7aWYod2Epe2NvbnN0IHJsPXNsO2lmKEZhPT09Ik5DSFciJiZ3YS5zaGFwZS5sZW5ndGg9PT0xJiZ3YS5zaGFwZVswXSE9PTEpe2NvbnN0IG9sPXJlc2hhcGUkMyh7aW5wdXRzOnt4OndhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbd2Euc2hhcGVbMF0sMSwxXX19KTtzbD1hZGQkMih7aW5wdXRzOnthOnNsLGI6b2x9LGJhY2tlbmQ6eGF9KSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhvbCl9ZWxzZSBzbD1hZGQkMih7aW5wdXRzOnthOnNsLGI6d2F9LGJhY2tlbmQ6eGF9KTt4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhybCl9aWYodGwpe2NvbnN0IHJsPXNsO2lmKEZhPT09Ik5DSFciJiZ0bD09PSJwcmVsdSImJkVhLnNoYXBlLmxlbmd0aD09PTEmJkVhLnNoYXBlWzBdIT09MSl7Y29uc3Qgb2w9cmVzaGFwZSQzKHtpbnB1dHM6e3g6RWF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltFYS5zaGFwZVswXSwxLDFdfX0pO3NsPWFwcGx5QWN0aXZhdGlvbiQxKHhhLHNsLHRsLG9sLG5sKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhvbCl9ZWxzZSBzbD1hcHBseUFjdGl2YXRpb24kMSh4YSxzbCx0bCxFYSxubCk7eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpfXJldHVybiBzbH1jb25zdCBmdXNlZENvbnYyRENvbmZpZyQyPXtrZXJuZWxOYW1lOkZ1c2VkQ29udjJEJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpmdXNlZENvbnYyRH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZnVzZWREZXB0aHdpc2VDb252MkQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGZpbHRlcjpUYSxiaWFzOndhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWF9PWFhLHtzdHJpZGVzOmthLHBhZDpBYSxkYXRhRm9ybWF0OkZhLGRpbGF0aW9uczpMYSxkaW1Sb3VuZGluZ01vZGU6ZWwsYWN0aXZhdGlvbjp0bCxsZWFreXJlbHVBbHBoYTpubH09YmE7bGV0IHNsPWRlcHRod2lzZUNvbnYyZE5hdGl2ZSQyKHtpbnB1dHM6e3g6U2EsZmlsdGVyOlRhfSxiYWNrZW5kOnhhLGF0dHJzOntzdHJpZGVzOmthLHBhZDpBYSxkYXRhRm9ybWF0OkZhLGRpbGF0aW9uczpMYSxkaW1Sb3VuZGluZ01vZGU6ZWx9fSk7aWYod2Epe2NvbnN0IHJsPXNsO3NsPWFkZCQyKHtpbnB1dHM6e2E6c2wsYjp3YX0sYmFja2VuZDp4YX0pLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKX1pZih0bCl7Y29uc3Qgcmw9c2w7c2w9YXBwbHlBY3RpdmF0aW9uJDEoeGEsc2wsdGwsRWEsbmwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKX1yZXR1cm4gc2x9Y29uc3QgZnVzZWREZXB0aHdpc2VDb252MkRDb25maWckMj17a2VybmVsTmFtZTpGdXNlZERlcHRod2lzZUNvbnYyRCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6ZnVzZWREZXB0aHdpc2VDb252MkQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2F0aGVyTmQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtwYXJhbXM6YmEsaW5kaWNlczpTYX09YWEsVGE9c2l6ZUZyb21TaGFwZSQxKGJhLnNoYXBlKSx3YT1TYS5zaGFwZSxFYT13YVt3YS5sZW5ndGgtMV0sW2thLEFhLEZhLExhXT1wcmVwYXJlQW5kVmFsaWRhdGUkMShiYSxTYSk7aWYoQWE9PT0wKXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSxiYS5kdHlwZSxbXSk7Y29uc3QgZWw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsdGw9eGEuYnVmZmVyU3luYyhiYSksbmw9Z2F0aGVyTmRJbXBsJDEoZWwsdGwsYmEuZHR5cGUsQWEsRWEsRmEsTGEsYmEuc2hhcGUsVGEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSxiYS5kdHlwZSxubC52YWx1ZXMpfWNvbnN0IGdhdGhlck5kQ29uZmlnJDI9e2tlcm5lbE5hbWU6R2F0aGVyTmQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmdhdGhlck5kJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdhdGhlclYyJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxpbmRpY2VzOlRhfT1hYSx7YXhpczp3YSxiYXRjaERpbXM6RWF9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihbU2EsVGFdLCJnYXRoZXJWMiIpO2NvbnN0IGthPXBhcnNlQXhpc1BhcmFtJDEod2EsU2Euc2hhcGUpWzBdLEFhPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLEZhPVNhLnNoYXBlW2thXTtmb3IobGV0IGlsPTA7aWw8QWEubGVuZ3RoOysraWwpe2NvbnN0IGNsPUFhW2lsXTthc3NlcnQkMihjbDw9RmEtMSYmY2w+PTAsKCk9PmBHYXRoZXJWMjogdGhlIGluZGV4IHZhbHVlICR7Y2x9IGlzIG5vdCBpbiBbMCwgJHtGYS0xfV1gKX1sZXQgTGE9RWE7RWE9PW51bGwmJihMYT0wKTtjb25zdCBlbD1zaXplRnJvbVNoYXBlJDEoVGEuc2hhcGUpLHRsPWNvbGxlY3RHYXRoZXJPcFNoYXBlSW5mbyQxKFNhLFRhLGthLExhKSxubD1yZXNoYXBlJDMoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W3RsLmJhdGNoU2l6ZSx0bC5vdXRlclNpemUsdGwuZGltU2l6ZSx0bC5zbGljZVNpemVdfX0pLHNsPXJlc2hhcGUkMyh7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbdGwuYmF0Y2hTaXplLGVsL3RsLmJhdGNoU2l6ZV19fSkscmw9W3RsLmJhdGNoU2l6ZSx0bC5vdXRlclNpemUsZWwvdGwuYmF0Y2hTaXplLHRsLnNsaWNlU2l6ZV0sb2w9eGEuYnVmZmVyU3luYyhzbCksYWw9eGEuYnVmZmVyU3luYyhubCksbGw9Z2F0aGVyVjJJbXBsJDEoYWwsb2wscmwpO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhubCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLHhhLm1ha2VUZW5zb3JJbmZvKHRsLm91dHB1dFNoYXBlLGxsLmR0eXBlLGxsLnZhbHVlcyl9Y29uc3QgZ2F0aGVyVjJDb25maWckMj17a2VybmVsTmFtZTpHYXRoZXJWMiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6Z2F0aGVyVjIkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaWZmdCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2lucHV0OmJhfT1hYSxTYT1zaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpLFRhPWJhLnNoYXBlW2JhLnNoYXBlLmxlbmd0aC0xXSx3YT1TYS9UYSxFYT1yZXNoYXBlJDMoe2lucHV0czp7eDpiYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W3dhLFRhXX19KSxrYT1mZnRCYXRjaChFYSwhMCx4YSksQWE9cmVzaGFwZSQzKHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmJhLnNoYXBlfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oa2EpLEFhfWNvbnN0IGlmZnRDb25maWckMj17a2VybmVsTmFtZTpJRkZUJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzppZmZ0JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgaXNGaW5pdGUkMz11bmFyeUtlcm5lbEZ1bmMkMihJc0Zpbml0ZSQxLGhhPT5OdW1iZXIuaXNGaW5pdGUoaGEpPzE6MCwiYm9vbCIpLGlzRmluaXRlQ29uZmlnJDI9e2tlcm5lbE5hbWU6SXNGaW5pdGUkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmlzRmluaXRlJDN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgaXNJbmYkMj11bmFyeUtlcm5lbEZ1bmMkMihJc0luZiQxLGhhPT5NYXRoLmFicyhoYSk9PT0xLzA/MTowLCJib29sIiksaXNJbmZDb25maWckMj17a2VybmVsTmFtZTpJc0luZiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6aXNJbmYkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBpc05hTiQzPXVuYXJ5S2VybmVsRnVuYyQyKElzTmFuJDEsaGE9Pk51bWJlci5pc05hTihoYSk/MTowLCJib29sIiksaXNOYU5Db25maWckMj17a2VybmVsTmFtZTpJc05hbiQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6aXNOYU4kM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbGluU3BhY2UkMihoYSl7Y29uc3R7YmFja2VuZDphYSxhdHRyczp4YX09aGEse3N0YXJ0OmJhLHN0b3A6U2EsbnVtOlRhfT14YSx3YT1saW5TcGFjZUltcGwkMShiYSxTYSxUYSk7cmV0dXJuIGFhLm1ha2VUZW5zb3JJbmZvKFt3YS5sZW5ndGhdLCJmbG9hdDMyIix3YSl9Y29uc3QgbGluU3BhY2VDb25maWckMj17a2VybmVsTmFtZTpMaW5TcGFjZSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bGluU3BhY2UkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsb2cxcCQyPXVuYXJ5S2VybmVsRnVuYyQyKExvZzFwJDEsaGE9Pk1hdGgubG9nMXAoaGEpKSxsb2cxcENvbmZpZyQyPXtrZXJuZWxOYW1lOkxvZzFwJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpsb2cxcCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsb2dpY2FsQW5kSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsJDEoKGhhLGFhKT0+aGEmJmFhKSxsb2dpY2FsQW5kJDI9YmluYXJ5S2VybmVsRnVuYyQyKExvZ2ljYWxBbmQkMSxsb2dpY2FsQW5kSW1wbCxudWxsLCJib29sIiksbG9naWNhbEFuZENvbmZpZyQyPXtrZXJuZWxOYW1lOkxvZ2ljYWxBbmQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxvZ2ljYWxBbmQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsb2dpY2FsTm90JDI9dW5hcnlLZXJuZWxGdW5jJDIoTG9naWNhbE5vdCQxLGhhPT5oYT8wOjEsImJvb2wiKSxsb2dpY2FsTm90Q29uZmlnJDI9e2tlcm5lbE5hbWU6TG9naWNhbE5vdCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bG9naWNhbE5vdCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsb2dpY2FsT3JJbXBsPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwkMSgoaGEsYWEpPT5oYXx8YWEpLGxvZ2ljYWxPciQyPWJpbmFyeUtlcm5lbEZ1bmMkMihMb2dpY2FsT3IkMSxsb2dpY2FsT3JJbXBsLG51bGwsImJvb2wiKSxsb2dpY2FsT3JDb25maWckMj17a2VybmVsTmFtZTpMb2dpY2FsT3IkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxvZ2ljYWxPciQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBsUk4oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2RlcHRoUmFkaXVzOlRhLGJpYXM6d2EsYWxwaGE6RWEsYmV0YTprYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJMUk4iKTtjb25zdCBBYT1TYS5zaGFwZVszXSxGYT1BYS0xLExhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGVsPXNpemVGcm9tU2hhcGUkMShTYS5zaGFwZSksdGw9bmV3IEZsb2F0MzJBcnJheShlbCk7ZnVuY3Rpb24gbmwoc2wpe2NvbnN0IHJsPXNsJUFhO2xldCBvbD1zbC1ybCtNYXRoLm1heCgwLHJsLVRhKTtjb25zdCBhbD1zbC1ybCtNYXRoLm1pbihybCtUYSxGYSk7bGV0IGxsPTA7Zm9yKDtvbDw9YWw7b2wrKyl7Y29uc3QgaWw9TGFbb2xdO2xsKz1pbCppbH1yZXR1cm4gbGx9Zm9yKGxldCBzbD0wO3NsPGVsO3NsKyspe2NvbnN0IHJsPW5sKHNsKSxvbD1MYVtzbF0qTWF0aC5wb3cod2ErRWEqcmwsLWthKTt0bFtzbF09b2x9cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFNhLnNoYXBlLFNhLmR0eXBlLHRsKX1jb25zdCBMUk5Db25maWckMj17a2VybmVsTmFtZTpMUk4kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxSTn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbFJOR3JhZChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLHk6VGEsZHk6d2F9PWFhLHtkZXB0aFJhZGl1czpFYSxiaWFzOmthLGFscGhhOkFhLGJldGE6RmF9PWJhO2Fzc2VydE5vdENvbXBsZXgkMih3YSwiTFJOR3JhZCIpO2NvbnN0IExhPXNpemVGcm9tU2hhcGUkMSh3YS5zaGFwZSksZWw9d2Euc2hhcGVbM10sdGw9eGEuZGF0YS5nZXQod2EuZGF0YUlkKS52YWx1ZXMsbmw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsc2w9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMscmw9bmV3IEZsb2F0MzJBcnJheShMYSksb2w9TGE7Zm9yKGxldCBhbD0wO2FsPG9sO2FsKyspe2NvbnN0IGxsPWFsJWVsLGlsPWFsLWxsK01hdGgubWF4KDAsbGwtRWEpLGNsPWFsLWxsK01hdGgubWluKGVsLGxsK0VhKzEpO2xldCB1bD0wO2ZvcihsZXQgZGw9aWw7ZGw8Y2w7ZGwrKyl1bCs9TWF0aC5wb3cobmxbZGxdLDIpO3VsPUFhKnVsK2thO2ZvcihsZXQgZGw9aWw7ZGw8Y2w7ZGwrKyl7bGV0IGhsPS0yKkFhKkZhKm5sW2RsXSpzbFthbF0vdWw7YWw9PT1kbCYmKGhsKz1NYXRoLnBvdyh1bCwtRmEpKSxobCo9dGxbYWxdLHJsW2RsXSs9aGx9fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyh3YS5zaGFwZSxTYS5kdHlwZSxybCl9Y29uc3QgTFJOR3JhZENvbmZpZyQyPXtrZXJuZWxOYW1lOkxSTkdyYWQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOmxSTkdyYWR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtyZWR1Y3Rpb25JbmRpY2VzOlRhLGtlZXBEaW1zOndhfT1iYSxFYT14YTtsZXQga2E9U2Euc2hhcGU7Y29uc3QgQWE9a2EubGVuZ3RoLEZhPXBhcnNlQXhpc1BhcmFtJDEoVGEsa2EpO2xldCBMYT1GYTtjb25zdCBlbD1nZXRBeGVzUGVybXV0YXRpb24kMShMYSxBYSk7bGV0IHRsPUVhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzO2lmKGVsIT1udWxsKXtjb25zdCBpbD1uZXcgQXJyYXkoQWEpO2ZvcihsZXQgY2w9MDtjbDxpbC5sZW5ndGg7Y2wrKylpbFtjbF09a2FbZWxbY2xdXTt0bD10cmFuc3Bvc2VJbXBsJDModGwsa2EsU2EuZHR5cGUsZWwsaWwpLExhPWdldElubmVyTW9zdEF4ZXMkMShMYS5sZW5ndGgsQWEpLGthPWlsfWFzc2VydE5vdENvbXBsZXgkMihTYSwibWF4IiksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgibWF4IixMYSxBYSk7Y29uc3Rbbmwsc2xdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShrYSxMYSkscmw9c2l6ZUZyb21TaGFwZSQxKHNsKSxvbD1tYXhJbXBsJDModGwscmwsbmwsU2EuZHR5cGUpLGFsPUVhLndyaXRlKG9sLG5sLFNhLmR0eXBlKTtsZXQgbGw9bmw7cmV0dXJuIHdhJiYobGw9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShubCxGYSkpLHtkYXRhSWQ6YWwsc2hhcGU6bGwsZHR5cGU6U2EuZHR5cGV9fWNvbnN0IG1heENvbmZpZyQyPXtrZXJuZWxOYW1lOk1heCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bWF4JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2wkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYTthc3NlcnROb3RDb21wbGV4JDIoU2EsIm1heFBvb2wiKTtjb25zdHtmaWx0ZXJTaXplOlRhLHN0cmlkZXM6d2EscGFkOkVhLGRpbVJvdW5kaW5nTW9kZTprYX09YmEsQWE9MTthc3NlcnQkMihlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUkMSh3YSxBYSksKCk9PmBFcnJvciBpbiBtYXhQb29sOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke3dhfSBhbmQgZGlsYXRpb25zICcke0FhfSdgKTtjb25zdCBGYT1jb21wdXRlUG9vbDJESW5mbyQxKFNhLnNoYXBlLFRhLHdhLEFhLEVhLGthKTtsZXQgTGE7aWYoRmEuZmlsdGVyV2lkdGg9PT0xJiZGYS5maWx0ZXJIZWlnaHQ9PT0xJiZhcnJheXNFcXVhbCQxKEZhLmluU2hhcGUsRmEub3V0U2hhcGUpKUxhPWlkZW50aXR5JDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2Vsc2V7Y29uc3QgZWw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsdGw9Y29tcHV0ZVN0cmlkZXMkMShTYS5zaGFwZSksbmw9cG9vbChlbCxTYS5zaGFwZSxTYS5kdHlwZSx0bCxGYSwibWF4Iik7TGE9eGEubWFrZVRlbnNvckluZm8oRmEub3V0U2hhcGUsU2EuZHR5cGUsbmwudmFsdWVzKX1yZXR1cm4gTGF9Y29uc3QgbWF4UG9vbENvbmZpZyQyPXtrZXJuZWxOYW1lOk1heFBvb2wkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOm1heFBvb2wkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4UG9vbDNEKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtmaWx0ZXJTaXplOlRhLHN0cmlkZXM6d2EscGFkOkVhLGRpbVJvdW5kaW5nTW9kZTprYSxkYXRhRm9ybWF0OkFhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsIm1heFBvb2wzZCIpO2NvbnN0IEZhPWNvbXB1dGVQb29sM0RJbmZvJDEoU2Euc2hhcGUsVGEsd2EsMSxFYSxrYSxBYSksTGE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsZWw9cG9vbDNkKExhLFNhLnNoYXBlLFNhLmR0eXBlLGNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLEZhLCJtYXgiKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oZWwuc2hhcGUsImZsb2F0MzIiLGVsLnZhbHVlcyl9Y29uc3QgbWF4UG9vbDNEQ29uZmlnJDI9e2tlcm5lbE5hbWU6TWF4UG9vbDNEJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptYXhQb29sM0R9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2wzREdyYWQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxpbnB1dDpUYX09YWEse2ZpbHRlclNpemU6d2Esc3RyaWRlczpFYSxwYWQ6a2EsZGltUm91bmRpbmdNb2RlOkFhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoW1NhLFRhXSwibWF4UG9vbDNER3JhZCIpO2NvbnN0IEZhPWNvbXB1dGVQb29sM0RJbmZvJDEoVGEuc2hhcGUsd2EsRWEsMSxrYSxBYSksTGE9eGEuYnVmZmVyU3luYyhUYSksZWw9bWF4UG9vbDNkUG9zaXRpb25zKExhLEZhKSx0bD1GYS5zdHJpZGVEZXB0aCxubD1GYS5zdHJpZGVIZWlnaHQsc2w9RmEuc3RyaWRlV2lkdGgscmw9RmEuZGlsYXRpb25EZXB0aCxvbD1GYS5kaWxhdGlvbkhlaWdodCxhbD1GYS5kaWxhdGlvbldpZHRoLGxsPUZhLmVmZmVjdGl2ZUZpbHRlckRlcHRoLGlsPUZhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCxjbD1GYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCx1bD1sbC0xLUZhLnBhZEluZm8uZnJvbnQsZGw9Y2wtMS1GYS5wYWRJbmZvLmxlZnQsaGw9aWwtMS1GYS5wYWRJbmZvLnRvcCxwbD1idWZmZXIkMShUYS5zaGFwZSwiZmxvYXQzMiIpLGZsPXhhLmJ1ZmZlclN5bmMoU2EpO2ZvcihsZXQgbWw9MDttbDxGYS5iYXRjaFNpemU7KyttbClmb3IobGV0IGdsPTA7Z2w8RmEuaW5DaGFubmVsczsrK2dsKWZvcihsZXQgJGw9MDskbDxGYS5pbkRlcHRoOysrJGwpZm9yKGxldCB4bD0wO3hsPEZhLmluSGVpZ2h0OysreGwpZm9yKGxldCB5bD0wO3lsPEZhLmluV2lkdGg7Kyt5bCl7Y29uc3QgYmw9JGwtdWwsU2w9eGwtaGwsQ2w9eWwtZGw7bGV0IFRsPTA7Zm9yKGxldCB3bD0wO3dsPGxsO3dsKz1ybCl7Y29uc3QgSWw9KGJsK3dsKS90bDtpZighKElsPDB8fElsPj1GYS5vdXREZXB0aHx8TWF0aC5mbG9vcihJbCkhPT1JbCkpZm9yKGxldCBObD0wO05sPGlsO05sKz1vbCl7Y29uc3Qgdmw9KFNsK05sKS9ubDtpZighKHZsPDB8fHZsPj1GYS5vdXRIZWlnaHR8fE1hdGguZmxvb3IodmwpIT09dmwpKWZvcihsZXQga2w9MDtrbDxjbDtrbCs9YWwpe2NvbnN0IEVsPShDbCtrbCkvc2w7aWYoRWw8MHx8RWw+PUZhLm91dFdpZHRofHxNYXRoLmZsb29yKEVsKSE9PUVsKWNvbnRpbnVlO2NvbnN0IEFsPWxsKmlsKmNsLTEtZWwuZ2V0KG1sLElsLHZsLEVsLGdsKSxSbD13bCppbCpjbCtObCpjbCtrbCxQbD1BbD09PVJsPzE6MDtpZihQbD09PTApY29udGludWU7Y29uc3QgRGw9ZmwuZ2V0KG1sLElsLHZsLEVsLGdsKTtUbCs9RGwqUGx9fX1wbC5zZXQoVGwsbWwsJGwseGwseWwsZ2wpfXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhwbC5zaGFwZSxwbC5kdHlwZSxwbC52YWx1ZXMpfWNvbnN0IG1heFBvb2wzREdyYWRDb25maWckMj17a2VybmVsTmFtZTpNYXhQb29sM0RHcmFkJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptYXhQb29sM0RHcmFkJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2xHcmFkJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsaW5wdXQ6VGEsb3V0cHV0OndhfT1hYSxFYT1UYTthc3NlcnROb3RDb21wbGV4JDIoW1RhLHdhXSwibWF4UG9vbEdyYWQiKTtjb25zdHtmaWx0ZXJTaXplOmthLHN0cmlkZXM6QWEscGFkOkZhLGRpbVJvdW5kaW5nTW9kZTpMYX09YmEsZWw9Y29tcHV0ZVBvb2wyREluZm8kMShFYS5zaGFwZSxrYSxBYSwxLEZhLExhKSx0bD14YS5kYXRhLmdldChFYS5kYXRhSWQpLnZhbHVlcyxubD1idWZmZXIkMShlbC5vdXRTaGFwZSxFYS5kdHlwZSxtYXhQb29sUG9zaXRpb25zKHRsLEVhLnNoYXBlLEVhLmR0eXBlLGVsKS52YWx1ZXMpLHNsPWVsLnN0cmlkZUhlaWdodCxybD1lbC5zdHJpZGVXaWR0aCxvbD1lbC5kaWxhdGlvbkhlaWdodCxhbD1lbC5kaWxhdGlvbldpZHRoLGxsPWVsLmVmZmVjdGl2ZUZpbHRlckhlaWdodCxpbD1lbC5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxjbD1pbC0xLWVsLnBhZEluZm8ubGVmdCx1bD1sbC0xLWVsLnBhZEluZm8udG9wLGRsPWJ1ZmZlciQxKEVhLnNoYXBlLCJmbG9hdDMyIiksaGw9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMscGw9YnVmZmVyJDEoU2Euc2hhcGUsImZsb2F0MzIiLGhsKTtmb3IobGV0IGZsPTA7Zmw8ZWwuYmF0Y2hTaXplOysrZmwpZm9yKGxldCBtbD0wO21sPGVsLmluQ2hhbm5lbHM7KyttbClmb3IobGV0IGdsPTA7Z2w8ZWwuaW5IZWlnaHQ7KytnbClmb3IobGV0ICRsPTA7JGw8ZWwuaW5XaWR0aDsrKyRsKXtjb25zdCB4bD1nbC11bCx5bD0kbC1jbDtsZXQgYmw9MDtmb3IobGV0IFNsPTA7U2w8bGw7U2wrPW9sKXtjb25zdCBDbD0oeGwrU2wpL3NsO2lmKCEoQ2w8MHx8Q2w+PWVsLm91dEhlaWdodHx8TWF0aC5mbG9vcihDbCkhPT1DbCkpZm9yKGxldCBUbD0wO1RsPGlsO1RsKz1hbCl7Y29uc3Qgd2w9KHlsK1RsKS9ybDtpZih3bDwwfHx3bD49ZWwub3V0V2lkdGh8fE1hdGguZmxvb3Iod2wpIT09d2wpY29udGludWU7Y29uc3QgSWw9bGwqaWwtMS1ubC5nZXQoZmwsQ2wsd2wsbWwpLE5sPVNsKmlsK1RsLHZsPUlsPT09Tmw/MTowO2lmKHZsPT09MCljb250aW51ZTtjb25zdCBrbD1wbC5nZXQoZmwsQ2wsd2wsbWwpO2JsKz1rbCp2bH19ZGwuc2V0KGJsLGZsLGdsLCRsLG1sKX1yZXR1cm4geGEubWFrZVRlbnNvckluZm8oZGwuc2hhcGUsZGwuZHR5cGUsZGwudmFsdWVzKX1jb25zdCBtYXhQb29sR3JhZENvbmZpZyQyPXtrZXJuZWxOYW1lOk1heFBvb2xHcmFkJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptYXhQb29sR3JhZCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhQb29sV2l0aEFyZ21heEltcGwkMihoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9Y29tcHV0ZVN0cmlkZXMkMShhYSksd2E9cG9vbChoYSxhYSx4YSxUYSxTYSwibWF4IiksRWE9bWF4UG9vbFBvc2l0aW9ucyhoYSxhYSx4YSxTYSwhMCxiYSk7cmV0dXJuW3dhLnZhbHVlcyxFYS52YWx1ZXNdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG1heFBvb2xXaXRoQXJnbWF4Q29uZmlnJDI9e2tlcm5lbE5hbWU6TWF4UG9vbFdpdGhBcmdtYXgkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOih7aW5wdXRzOmhhLGF0dHJzOmFhLGJhY2tlbmQ6eGF9KT0+e2NvbnN0e3g6YmF9PWhhLHtmaWx0ZXJTaXplOlNhLHN0cmlkZXM6VGEscGFkOndhLGluY2x1ZGVCYXRjaEluSW5kZXg6RWF9PWFhLGthPXhhO2Fzc2VydE5vdENvbXBsZXgkMihiYSwiTWF4UG9vbFdpdGhBcmdtYXgiKTtjb25zdCBBYT1rYS5kYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcyxGYT1jb21wdXRlUG9vbDJESW5mbyQxKGJhLnNoYXBlLFNhLFRhLFsxLDFdLHdhKSxbTGEsZWxdPW1heFBvb2xXaXRoQXJnbWF4SW1wbCQyKEFhLGJhLnNoYXBlLGJhLmR0eXBlLEVhLEZhKSx0bD1rYS53cml0ZShMYSxGYS5vdXRTaGFwZSxiYS5kdHlwZSksbmw9a2Eud3JpdGUoZWwsRmEub3V0U2hhcGUsYmEuZHR5cGUpO3JldHVyblt7ZGF0YUlkOnRsLHNoYXBlOkZhLm91dFNoYXBlLGR0eXBlOmJhLmR0eXBlfSx7ZGF0YUlkOm5sLHNoYXBlOkZhLm91dFNoYXBlLGR0eXBlOiJpbnQzMiJ9XX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1lYW4oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGEsa2VlcERpbXM6d2F9PWJhLEVhPXBhcnNlQXhpc1BhcmFtJDEoVGEsU2Euc2hhcGUpLEFhPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShTYS5zaGFwZSxFYSlbMV0sRmE9c2l6ZUZyb21TaGFwZSQxKEFhKSxMYT1bXSxlbD14YS5tYWtlVGVuc29ySW5mbyhbXSwiZmxvYXQzMiIsbmV3IEZsb2F0MzJBcnJheShbRmFdKSk7TGEucHVzaChlbCk7Y29uc3QgdGw9Y2FzdCQzKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2R0eXBlOiJmbG9hdDMyIn19KTtMYS5wdXNoKHRsKTtjb25zdCBubD1kaXYkMSh7aW5wdXRzOnthOnRsLGI6ZWx9LGJhY2tlbmQ6eGF9KTtMYS5wdXNoKG5sKTtjb25zdCBzbD1zdW0kNCh7aW5wdXRzOnt4Om5sfSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOlRhLGtlZXBEaW1zOndhfX0pO3JldHVybiBMYS5mb3JFYWNoKHJsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhybCkpLHNsfWNvbnN0IG1lYW5Db25maWckMj17a2VybmVsTmFtZTpNZWFuJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptZWFufTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtaW4kMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJtaW4iKTtjb25zdCBFYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtsZXQga2E9RWE7Y29uc3QgQWE9Z2V0QXhlc1Blcm11dGF0aW9uJDEoa2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQgRmE9U2E7QWEhPW51bGwmJihGYT10cmFuc3Bvc2UkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkFhfX0pLGthPWdldElubmVyTW9zdEF4ZXMkMShrYS5sZW5ndGgsU2Euc2hhcGUubGVuZ3RoKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgibWluIixrYSxGYS5zaGFwZS5sZW5ndGgpO2NvbnN0W0xhLGVsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoRmEuc2hhcGUsa2EpLHRsPXNpemVGcm9tU2hhcGUkMShlbCksbmw9bWFrZVplcm9zVHlwZWRBcnJheSQxKHNpemVGcm9tU2hhcGUkMShMYSksRmEuZHR5cGUpLHNsPXhhLmRhdGEuZ2V0KEZhLmRhdGFJZCkudmFsdWVzO2ZvcihsZXQgb2w9MDtvbDxubC5sZW5ndGg7KytvbCl7Y29uc3QgYWw9b2wqdGw7bGV0IGxsPXNsW2FsXTtmb3IobGV0IGlsPTA7aWw8dGw7KytpbCl7Y29uc3QgY2w9c2xbYWwraWxdOyhOdW1iZXIuaXNOYU4oY2wpfHxjbDxsbCkmJihsbD1jbCl9bmxbb2xdPWxsfUFhIT1udWxsJiZ4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhGYSk7Y29uc3Qgcmw9eGEubWFrZVRlbnNvckluZm8oTGEsRmEuZHR5cGUsbmwpO2lmKHdhKXtjb25zdCBvbD1leHBhbmRTaGFwZVRvS2VlcERpbSQxKExhLEVhKSxhbD1yZXNoYXBlJDMoe2lucHV0czp7eDpybH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6b2x9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKSxhbH1yZXR1cm4gcmx9Y29uc3QgbWluQ29uZmlnJDI9e2tlcm5lbE5hbWU6TWluJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptaW4kMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWlycm9yUGFkKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtwYWRkaW5nczpUYSxtb2RlOndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsIm1pcnJvclBhZCIpO2NvbnN0IEVhPVRhLm1hcCgobGwsaWwpPT5sbFswXStTYS5zaGFwZVtpbF0rbGxbMV0pLGthPVRhLm1hcChsbD0+bGxbMF0pLEFhPVRhLm1hcCgobGwsaWwpPT5sbFswXStTYS5zaGFwZVtpbF0pLEZhPXdhPT09InJlZmxlY3QiPzA6MSxMYT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxlbD1TYS5zaGFwZS5sZW5ndGgsdGw9Y29tcHV0ZVN0cmlkZXMkMShTYS5zaGFwZSksbmw9c2l6ZUZyb21TaGFwZSQxKEVhKSxzbD1FYS5sZW5ndGgscmw9Y29tcHV0ZVN0cmlkZXMkMShFYSksb2w9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKFNhLmR0eXBlLG5sKTtmb3IobGV0IGxsPTA7bGw8bmw7bGwrKyl7bGV0IGlsPWluZGV4VG9Mb2MkMShsbCxzbCxybCk7Zm9yKGxldCB1bD0wO3VsPHNsO3VsKyspaWxbdWxdPGthW3VsXT9pbFt1bF09a2FbdWxdKjItaWxbdWxdLUZhOmlsW3VsXT49QWFbdWxdJiYoaWxbdWxdPShBYVt1bF0tMSkqMi1pbFt1bF0rRmEpO2lsPWlsLm1hcCgodWwsZGwpPT51bC1rYVtkbF0pO2NvbnN0IGNsPWxvY1RvSW5kZXgkMShpbCxlbCx0bCk7b2xbbGxdPUxhW2NsXX1yZXR1cm57ZGF0YUlkOnhhLndyaXRlKG9sLEVhLFNhLmR0eXBlKSxzaGFwZTpFYSxkdHlwZTpTYS5kdHlwZX19Y29uc3QgbWlycm9yUGFkQ29uZmlnJDI9e2tlcm5lbE5hbWU6TWlycm9yUGFkJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptaXJyb3JQYWR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG1vZEltcGw9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9Pntjb25zdCB4YT1oYSVhYTtyZXR1cm4gaGE8MCYmYWE8MHx8aGE+PTAmJmFhPj0wP3hhOih4YSthYSklYWF9KSxtb2QkMj1iaW5hcnlLZXJuZWxGdW5jJDIoTW9kJDEsbW9kSW1wbCksbW9kQ29uZmlnJDI9e2tlcm5lbE5hbWU6TW9kJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptb2QkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc29mdG1heCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2xvZ2l0czpTYX09YWEse2RpbTpUYX09YmEsd2E9U2Euc2hhcGUubGVuZ3RoO2xldCBFYT1UYTtpZihFYT09PS0xJiYoRWE9d2EtMSksRWEhPT13YS0xKXRocm93IEVycm9yKGBTb2Z0bWF4IGFsb25nIGEgbm9uLWxhc3QgZGltZW5zaW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkLiBMb2dpdHMgd2FzIHJhbmsgJHt3YX0gYW5kIGRpbSB3YXMgJHtFYX1gKTtjb25zdCBrYT1wYXJzZUF4aXNQYXJhbSQxKFtFYV0sU2Euc2hhcGUpLEFhPW1heCQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3JlZHVjdGlvbkluZGljZXM6a2Esa2VlcERpbXM6ITF9fSksRmE9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShBYS5zaGFwZSxrYSksTGE9cmVzaGFwZSQzKHtpbnB1dHM6e3g6QWF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkZhfX0pLGVsPXN1YiQzKHtpbnB1dHM6e2E6U2EsYjpMYX0sYmFja2VuZDp4YX0pLHRsPWV4cCQyKHtpbnB1dHM6e3g6ZWx9LGJhY2tlbmQ6eGF9KSxubD1zdW0kNCh7aW5wdXRzOnt4OnRsfSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOmthLGtlZXBEaW1zOiExfX0pLHNsPXJlc2hhcGUkMyh7aW5wdXRzOnt4Om5sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpGYX19KSxybD1kaXYkMSh7aW5wdXRzOnthOnRsLGI6c2x9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oQWEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKExhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkscmx9Y29uc3Qgc29mdG1heENvbmZpZyQyPXtrZXJuZWxOYW1lOlNvZnRtYXgkMyxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNvZnRtYXgkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbXVsdGlub21pYWwkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtsb2dpdHM6U2F9PWFhLHtudW1TYW1wbGVzOlRhLHNlZWQ6d2Esbm9ybWFsaXplZDpFYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJtdWx0aW5vbWlhbCIpO2NvbnN0IGthPUVhP1NhOnNvZnRtYXgkMih7aW5wdXRzOntsb2dpdHM6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2RpbTotMX19KSxBYT1rYS5zaGFwZVswXSxGYT1rYS5zaGFwZVsxXSxMYT14YS5kYXRhLmdldChrYS5kYXRhSWQpLnZhbHVlcyxlbD1bQWEsVGFdLHRsPW1ha2VaZXJvc1R5cGVkQXJyYXkkMShzaXplRnJvbVNoYXBlJDEoZWwpLCJpbnQzMiIpO2ZvcihsZXQgbmw9MDtubDxBYTsrK25sKXtjb25zdCBzbD1ubCpGYSxybD1uZXcgRmxvYXQzMkFycmF5KEZhLTEpO3JsWzBdPUxhW3NsXTtmb3IobGV0IGxsPTE7bGw8cmwubGVuZ3RoOysrbGwpcmxbbGxdPXJsW2xsLTFdK0xhW3NsK2xsXTtjb25zdCBvbD1zZWVkcmFuZG9tLmFsZWEod2EudG9TdHJpbmcoKSksYWw9bmwqVGE7Zm9yKGxldCBsbD0wO2xsPFRhOysrbGwpe2NvbnN0IGlsPW9sKCk7dGxbYWwrbGxdPXJsLmxlbmd0aDtmb3IobGV0IGNsPTA7Y2w8cmwubGVuZ3RoO2NsKyspaWYoaWw8cmxbY2xdKXt0bFthbCtsbF09Y2w7YnJlYWt9fX1yZXR1cm4gRWF8fHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGthKSx4YS5tYWtlVGVuc29ySW5mbyhlbCwiaW50MzIiLHRsKX1jb25zdCBtdWx0aW5vbWlhbENvbmZpZyQyPXtrZXJuZWxOYW1lOk11bHRpbm9taWFsJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzptdWx0aW5vbWlhbCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBub25NYXhTdXBwcmVzc2lvblYzSW1wbCQzPW5vbk1heFN1cHByZXNzaW9uVjNJbXBsJDQ7ZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25WMyQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2JveGVzOlNhLHNjb3JlczpUYX09YWEse21heE91dHB1dFNpemU6d2EsaW91VGhyZXNob2xkOkVhLHNjb3JlVGhyZXNob2xkOmthfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsIk5vbk1heFN1cHByZXNzaW9uIik7Y29uc3QgQWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsRmE9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMse3NlbGVjdGVkSW5kaWNlczpMYX09bm9uTWF4U3VwcHJlc3Npb25WM0ltcGwkMyhBYSxGYSx3YSxFYSxrYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFtMYS5sZW5ndGhdLCJpbnQzMiIsbmV3IEludDMyQXJyYXkoTGEpKX1jb25zdCBub25NYXhTdXBwcmVzc2lvblYzQ29uZmlnJDI9e2tlcm5lbE5hbWU6Tm9uTWF4U3VwcHJlc3Npb25WMyQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bm9uTWF4U3VwcHJlc3Npb25WMyQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBub25NYXhTdXBwcmVzc2lvblY0SW1wbCQzPW5vbk1heFN1cHByZXNzaW9uVjRJbXBsJDQ7ZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25WNCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2JveGVzOlNhLHNjb3JlczpUYX09YWEse21heE91dHB1dFNpemU6d2EsaW91VGhyZXNob2xkOkVhLHNjb3JlVGhyZXNob2xkOmthLHBhZFRvTWF4T3V0cHV0U2l6ZTpBYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJOb25NYXhTdXBwcmVzc2lvblBhZGRlZCIpO2NvbnN0IEZhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLExhPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLHtzZWxlY3RlZEluZGljZXM6ZWwsdmFsaWRPdXRwdXRzOnRsfT1ub25NYXhTdXBwcmVzc2lvblY0SW1wbCQzKEZhLExhLHdhLEVhLGthLEFhKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oW2VsLmxlbmd0aF0sImludDMyIixuZXcgSW50MzJBcnJheShlbCkpLHhhLm1ha2VUZW5zb3JJbmZvKFtdLCJpbnQzMiIsbmV3IEludDMyQXJyYXkoW3RsXSkpXX1jb25zdCBub25NYXhTdXBwcmVzc2lvblY0Q29uZmlnJDI9e2tlcm5lbE5hbWU6Tm9uTWF4U3VwcHJlc3Npb25WNCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6bm9uTWF4U3VwcHJlc3Npb25WNCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBub25NYXhTdXBwcmVzc2lvblY1SW1wbCQzPW5vbk1heFN1cHByZXNzaW9uVjVJbXBsJDQ7ZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25WNSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2JveGVzOlNhLHNjb3JlczpUYX09YWEse21heE91dHB1dFNpemU6d2EsaW91VGhyZXNob2xkOkVhLHNjb3JlVGhyZXNob2xkOmthLHNvZnRObXNTaWdtYTpBYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJOb25NYXhTdXBwcmVzc2lvbldpdGhTY29yZSIpO2NvbnN0IEZhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLExhPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLGVsPXdhLHRsPUVhLG5sPWthLHNsPUFhLHtzZWxlY3RlZEluZGljZXM6cmwsc2VsZWN0ZWRTY29yZXM6b2x9PW5vbk1heFN1cHByZXNzaW9uVjVJbXBsJDMoRmEsTGEsZWwsdGwsbmwsc2wpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhbcmwubGVuZ3RoXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KHJsKSkseGEubWFrZVRlbnNvckluZm8oW29sLmxlbmd0aF0sImZsb2F0MzIiLG5ldyBGbG9hdDMyQXJyYXkob2wpKV19Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25WNUNvbmZpZyQyPXtrZXJuZWxOYW1lOk5vbk1heFN1cHByZXNzaW9uVjUkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOm5vbk1heFN1cHByZXNzaW9uVjUkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gb25lSG90JDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW5kaWNlczpTYX09YWEse2R0eXBlOlRhLGRlcHRoOndhLG9uVmFsdWU6RWEsb2ZmVmFsdWU6a2F9PWJhO2Fzc2VydE5vdENvbXBsZXgkMihTYSwib25lSG90Iik7Y29uc3QgQWE9c2l6ZUZyb21TaGFwZSQxKFNhLnNoYXBlKSxGYT1uZXcgRmxvYXQzMkFycmF5KEFhKndhKTtGYS5maWxsKGthKTtjb25zdCBMYT14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IGVsPTA7ZWw8QWE7KytlbClMYVtlbF0+PTAmJkxhW2VsXTx3YSYmKEZhW2VsKndhK0xhW2VsXV09RWEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhbLi4uU2Euc2hhcGUsd2FdLFRhLEZhKX1jb25zdCBvbmVIb3RDb25maWckMj17a2VybmVsTmFtZTpPbmVIb3QkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOm9uZUhvdCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB6ZXJvc0xpa2UkMyhoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYTtpZihiYS5kdHlwZT09PSJzdHJpbmciKXRocm93IG5ldyBFcnJvcigiemVyb3NMaWtlIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHN0cmluZyB0ZW5zb3JzIik7aWYoYmEuZHR5cGU9PT0iY29tcGxleDY0Iil7Y29uc3QgU2E9cmVhbCQyKHtpbnB1dHM6e2lucHV0OmJhfSxiYWNrZW5kOnhhfSksVGE9emVyb3NMaWtlJDMoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pLHdhPWltYWckMih7aW5wdXRzOntpbnB1dDpiYX0sYmFja2VuZDp4YX0pLEVhPXplcm9zTGlrZSQzKHtpbnB1dHM6e3g6d2F9LGJhY2tlbmQ6eGF9KSxrYT1jb21wbGV4JDMoe2lucHV0czp7cmVhbDpUYSxpbWFnOkVhfSxiYWNrZW5kOnhhfSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKFNhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhUYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEVhKSxrYX1lbHNlIHJldHVybiBmaWxsJDMoe2JhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmJhLnNoYXBlLHZhbHVlOjAsZHR5cGU6YmEuZHR5cGV9fSl9Y29uc3QgemVyb3NMaWtlQ29uZmlnJDI9e2tlcm5lbE5hbWU6WmVyb3NMaWtlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzp6ZXJvc0xpa2UkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gb25lc0xpa2UkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYTtpZihiYS5kdHlwZT09PSJzdHJpbmciKXRocm93IG5ldyBFcnJvcigib25lc0xpa2UgaXMgbm90IHN1cHBvcnRlZCBmb3Igc3RyaW5nIHRlbnNvcnMiKTtpZihiYS5kdHlwZT09PSJjb21wbGV4NjQiKXtjb25zdCBTYT1yZWFsJDIoe2lucHV0czp7aW5wdXQ6YmF9LGJhY2tlbmQ6eGF9KSxUYT1vbmVzTGlrZSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KSx3YT1pbWFnJDIoe2lucHV0czp7aW5wdXQ6YmF9LGJhY2tlbmQ6eGF9KSxFYT16ZXJvc0xpa2UkMyh7aW5wdXRzOnt4OndhfSxiYWNrZW5kOnhhfSksa2E9Y29tcGxleCQzKHtpbnB1dHM6e3JlYWw6VGEsaW1hZzpFYX0sYmFja2VuZDp4YX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhTYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oVGEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHdhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSksa2F9ZWxzZSByZXR1cm4gZmlsbCQzKHtiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpiYS5zaGFwZSx2YWx1ZToxLGR0eXBlOmJhLmR0eXBlfX0pfWNvbnN0IG9uZXNMaWtlQ29uZmlnJDI9e2tlcm5lbE5hbWU6T25lc0xpa2UkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOm9uZXNMaWtlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHBhY2skMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtheGlzOlNhfT1iYTtpZihhYS5sZW5ndGg9PT0xKXJldHVybiBleHBhbmREaW1zJDIoe2lucHV0czp7aW5wdXQ6YWFbMF19LGJhY2tlbmQ6eGEsYXR0cnM6e2RpbTpTYX19KTtjb25zdCBUYT1hYVswXS5zaGFwZSx3YT1hYVswXS5kdHlwZTthYS5mb3JFYWNoKEZhPT57YXNzZXJ0U2hhcGVzTWF0Y2gkMShUYSxGYS5zaGFwZSwiQWxsIHRlbnNvcnMgcGFzc2VkIHRvIHN0YWNrIG11c3QgaGF2ZSBtYXRjaGluZyBzaGFwZXMiKSxhc3NlcnQkMih3YT09PUZhLmR0eXBlLCgpPT4iQWxsIHRlbnNvcnMgcGFzc2VkIHRvIHN0YWNrIG11c3QgaGF2ZSBtYXRjaGluZyBkdHlwZXMiKX0pO2NvbnN0IEVhPVtdLGthPWFhLm1hcChGYT0+e2NvbnN0IExhPWV4cGFuZERpbXMkMih7aW5wdXRzOntpbnB1dDpGYX0sYmFja2VuZDp4YSxhdHRyczp7ZGltOlNhfX0pO3JldHVybiBFYS5wdXNoKExhKSxMYX0pLEFhPWNvbmNhdCQyKHtpbnB1dHM6a2EsYmFja2VuZDp4YSxhdHRyczp7YXhpczpTYX19KTtyZXR1cm4gRWEuZm9yRWFjaChGYT0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpKSxBYX1jb25zdCBwYWNrQ29uZmlnJDI9e2tlcm5lbE5hbWU6UGFjayQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cGFjayQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwYWRWMiQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtwYWRkaW5nczpUYSxjb25zdGFudFZhbHVlOndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsInBhZCIpO2NvbnN0IEVhPVRhLm1hcCgoYWwsbGwpPT5hbFswXStTYS5zaGFwZVtsbF0rYWxbMV0pLGthPVRhLm1hcChhbD0+YWxbMF0pLEFhPXhhLmRhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLEZhPXNpemVGcm9tU2hhcGUkMShTYS5zaGFwZSksTGE9U2Euc2hhcGUubGVuZ3RoLGVsPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLHRsPXNpemVGcm9tU2hhcGUkMShFYSksbmw9RWEubGVuZ3RoLHNsPWNvbXB1dGVTdHJpZGVzJDEoRWEpLHJsPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMShTYS5kdHlwZSx0bCk7d2EhPT0wJiZybC5maWxsKHdhKTtmb3IobGV0IGFsPTA7YWw8RmE7YWwrKyl7Y29uc3QgaWw9aW5kZXhUb0xvYyQxKGFsLExhLGVsKS5tYXAoKHVsLGRsKT0+dWwra2FbZGxdKSxjbD1sb2NUb0luZGV4JDEoaWwsbmwsc2wpO3JsW2NsXT1BYVthbF19cmV0dXJue2RhdGFJZDp4YS53cml0ZShybCxFYSxTYS5kdHlwZSksc2hhcGU6RWEsZHR5cGU6U2EuZHR5cGV9fWNvbnN0IHBhZFYyQ29uZmlnJDI9e2tlcm5lbE5hbWU6UGFkVjIkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnBhZFYyJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHBvd0ltcGw9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCQxKChoYSxhYSk9Pk1hdGgucG93KGhhLGFhKSkscG93JDM9YmluYXJ5S2VybmVsRnVuYyQyKFBvdyQxLHBvd0ltcGwpLHBvd0NvbmZpZyQyPXtrZXJuZWxOYW1lOlBvdyQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cG93JDN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhZ2dlZEdhdGhlciQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3BhcmFtc05lc3RlZFNwbGl0czpTYSxwYXJhbXNEZW5zZVZhbHVlczpUYSxpbmRpY2VzOndhfT1hYSxFYT1TYS5tYXAocmw9PnhhLmRhdGEuZ2V0KHJsLmRhdGFJZCkudmFsdWVzKSxrYT1TYS5tYXAocmw9PnJsLnNoYXBlKSxBYT14YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyxGYT14YS5kYXRhLmdldCh3YS5kYXRhSWQpLnZhbHVlcyxbTGEsZWwsdGxdPXJhZ2dlZEdhdGhlckltcGwkMShFYSxrYSxBYSxUYS5zaGFwZSxUYS5kdHlwZSxGYSx3YS5zaGFwZSksbmw9TGEubWFwKHJsPT54YS5tYWtlVGVuc29ySW5mbyhbcmwubGVuZ3RoXSwiaW50MzIiLHJsKSksc2w9eGEubWFrZVRlbnNvckluZm8odGwsVGEuZHR5cGUsZWwpO3JldHVybiBubC5jb25jYXQoW3NsXSl9Y29uc3QgcmFnZ2VkR2F0aGVyQ29uZmlnJDI9e2tlcm5lbE5hbWU6UmFnZ2VkR2F0aGVyJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyYWdnZWRHYXRoZXIkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFnZ2VkUmFuZ2UkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtzdGFydHM6YmEsbGltaXRzOlNhLGRlbHRhczpUYX09YWEsd2E9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsRWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsW0FhLEZhXT1yYWdnZWRSYW5nZUltcGwkMSh3YSxiYS5zaGFwZSxiYS5kdHlwZSxFYSxTYS5zaGFwZSxrYSxUYS5zaGFwZSksTGE9eGEubWFrZVRlbnNvckluZm8oW0FhLmxlbmd0aF0sImludDMyIixBYSksZWw9eGEubWFrZVRlbnNvckluZm8oW0ZhLmxlbmd0aF0sYmEuZHR5cGUsRmEpO3JldHVybltMYSxlbF19Y29uc3QgcmFnZ2VkUmFuZ2VDb25maWckMj17a2VybmVsTmFtZTpSYWdnZWRSYW5nZSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cmFnZ2VkUmFuZ2UkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFnZ2VkVGVuc29yVG9UZW5zb3IkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzaGFwZTpTYSx2YWx1ZXM6VGEsZGVmYXVsdFZhbHVlOndhLHJvd1BhcnRpdGlvblRlbnNvcnM6RWF9PWFhLHtyb3dQYXJ0aXRpb25UeXBlczprYX09YmEsQWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsRmE9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsTGE9eGEuZGF0YS5nZXQod2EuZGF0YUlkKS52YWx1ZXMsZWw9RWEubWFwKHJsPT54YS5kYXRhLmdldChybC5kYXRhSWQpLnZhbHVlcyksdGw9RWEubWFwKHJsPT5ybC5zaGFwZSksW25sLHNsXT1yYWdnZWRUZW5zb3JUb1RlbnNvckltcGwkMShBYSxTYS5zaGFwZSxGYSxUYS5zaGFwZSxUYS5kdHlwZSxMYSx3YS5zaGFwZSxlbCx0bCxrYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKG5sLFRhLmR0eXBlLHNsKX1jb25zdCByYWdnZWRUZW5zb3JUb1RlbnNvckNvbmZpZyQyPXtrZXJuZWxOYW1lOlJhZ2dlZFRlbnNvclRvVGVuc29yJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyYWdnZWRUZW5zb3JUb1RlbnNvciQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByYW5nZSQyKGhhKXtjb25zdHtiYWNrZW5kOmFhLGF0dHJzOnhhfT1oYSx7c3RhcnQ6YmEsc3RvcDpTYSxkdHlwZTpUYSxzdGVwOndhfT14YSxFYT1yYW5nZUltcGwkMShiYSxTYSx3YSxUYSk7cmV0dXJuIGFhLm1ha2VUZW5zb3JJbmZvKFtFYS5sZW5ndGhdLFRhLEVhKX1jb25zdCByYW5nZUNvbmZpZyQyPXtrZXJuZWxOYW1lOlJhbmdlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyYW5nZSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJlY2lwcm9jYWwkMj11bmFyeUtlcm5lbEZ1bmMkMihSZWNpcHJvY2FsJDEsaGE9PjEvaGEpLHJlY2lwcm9jYWxDb25maWckMj17a2VybmVsTmFtZTpSZWNpcHJvY2FsJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyZWNpcHJvY2FsJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJlc2l6ZUJpbGluZWFyJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhfT1hYSx7YWxpZ25Db3JuZXJzOlRhLGhhbGZQaXhlbENlbnRlcnM6d2Esc2l6ZTpFYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJyZXNpemVCaWxpbmVhciIpO2NvbnN0IGthPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLFtBYSxGYV09RWEsW0xhLGVsLHRsLG5sXT1TYS5zaGFwZSxzbD14YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxybD1uZXcgRmxvYXQzMkFycmF5KHNpemVGcm9tU2hhcGUkMShbTGEsQWEsRmEsbmxdKSksb2w9W1RhJiZBYT4xP2VsLTE6ZWwsVGEmJkZhPjE/dGwtMTp0bF0sYWw9W1RhJiZBYT4xP0FhLTE6QWEsVGEmJkZhPjE/RmEtMTpGYV07bGV0IGxsPTA7Y29uc3QgaWw9b2xbMF0vYWxbMF0sY2w9b2xbMV0vYWxbMV07Zm9yKGxldCB1bD0wO3VsPExhO3VsKyspZm9yKGxldCBkbD0wO2RsPEFhO2RsKyspe2xldCBobDt3YT9obD1pbCooZGwrLjUpLS41OmhsPWlsKmRsO2NvbnN0IHBsPU1hdGgubWF4KDAsTWF0aC5mbG9vcihobCkpLGZsPWhsLXBsLG1sPU1hdGgubWluKGVsLTEsTWF0aC5jZWlsKGhsKSksZ2w9dWwqa2FbMF0rcGwqa2FbMV0sJGw9dWwqa2FbMF0rbWwqa2FbMV07Zm9yKGxldCB4bD0wO3hsPEZhO3hsKyspe2xldCB5bDt3YT95bD1jbCooeGwrLjUpLS41OnlsPWNsKnhsO2NvbnN0IGJsPU1hdGgubWF4KDAsTWF0aC5mbG9vcih5bCkpLFNsPXlsLWJsLENsPU1hdGgubWluKHRsLTEsTWF0aC5jZWlsKHlsKSksVGw9Z2wrYmwqa2FbMl0sd2w9JGwrYmwqa2FbMl0sSWw9Z2wrQ2wqa2FbMl0sTmw9JGwrQ2wqa2FbMl07Zm9yKGxldCB2bD0wO3ZsPG5sO3ZsKyspe2NvbnN0IGtsPXNsW1RsK3ZsXSxFbD1zbFt3bCt2bF0sQWw9c2xbSWwrdmxdLFJsPXNsW05sK3ZsXSxQbD1rbCsoQWwta2wpKlNsLERsPUVsKyhSbC1FbCkqU2wsX2w9UGwrKERsLVBsKSpmbDtybFtsbCsrXT1fbH19fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhbTGEsQWEsRmEsbmxdLCJmbG9hdDMyIixybCl9Y29uc3QgcmVzaXplQmlsaW5lYXJDb25maWckMj17a2VybmVsTmFtZTpSZXNpemVCaWxpbmVhciQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6cmVzaXplQmlsaW5lYXIkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplQmlsaW5lYXJHcmFkJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhLGR5OlRhfT1hYSx7YWxpZ25Db3JuZXJzOndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoW1RhLFNhXSwicmVzaXplQmlsaW5lYXJHcmFkIik7Y29uc3QgRWE9Y29tcHV0ZVN0cmlkZXMkMShTYS5zaGFwZSksW2thLEFhLEZhLExhXT1TYS5zaGFwZSxbLGVsLHRsXT1UYS5zaGFwZSxubD1uZXcgRmxvYXQzMkFycmF5KGthKkFhKkZhKkxhKSxzbD1bd2EmJmVsPjE/QWEtMTpBYSx3YSYmdGw+MT9GYS0xOkZhXSxybD1bd2EmJmVsPjE/ZWwtMTplbCx3YSYmdGw+MT90bC0xOnRsXSxvbD1zbFswXS9ybFswXSxhbD1zbFsxXS9ybFsxXSxsbD14YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcztsZXQgaWw9MDtmb3IobGV0IGNsPTA7Y2w8a2E7Y2wrKyl7Y29uc3QgdWw9Y2wqRWFbMF07Zm9yKGxldCBkbD0wO2RsPGVsO2RsKyspe2NvbnN0IGhsPWRsKm9sLHBsPU1hdGguZmxvb3IoaGwpLGZsPU1hdGgubWluKE1hdGguY2VpbChobCksQWEtMSksbWw9dWwrcGwqRWFbMV0sZ2w9dWwrZmwqRWFbMV0sJGw9aGwtcGwseGw9MS0kbDtmb3IobGV0IHlsPTA7eWw8dGw7eWwrKyl7Y29uc3QgYmw9eWwqYWwsU2w9TWF0aC5mbG9vcihibCksQ2w9TWF0aC5taW4oTWF0aC5jZWlsKGJsKSxGYS0xKSxUbD1ibC1TbCx3bD0xLVRsLElsPW1sK1NsKkVhWzJdLE5sPW1sK0NsKkVhWzJdLHZsPWdsK1NsKkVhWzJdLGtsPWdsK0NsKkVhWzJdLEVsPXhsKndsLEFsPXhsKlRsLFJsPSRsKndsLFBsPSRsKlRsO2ZvcihsZXQgRGw9MDtEbDxMYTtEbCsrKXtjb25zdCBfbD1sbFtpbCsrXTtubFtJbCtEbF0rPV9sKkVsLG5sW05sK0RsXSs9X2wqQWwsbmxbdmwrRGxdKz1fbCpSbCxubFtrbCtEbF0rPV9sKlBsfX19fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhba2EsRmEsQWEsTGFdLCJmbG9hdDMyIixubCl9Y29uc3QgcmVzaXplQmlsaW5lYXJHcmFkQ29uZmlnJDI9e2tlcm5lbE5hbWU6UmVzaXplQmlsaW5lYXJHcmFkJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyZXNpemVCaWxpbmVhckdyYWQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplTmVhcmVzdE5laWdoYm9yJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhfT1hYSx7YWxpZ25Db3JuZXJzOlRhLGhhbGZQaXhlbENlbnRlcnM6d2Esc2l6ZTpFYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJyZXNpemVOZWFyZXN0TmVpZ2hib3IiKTtjb25zdCBrYT1jb21wdXRlU3RyaWRlcyQxKFNhLnNoYXBlKSxbQWEsRmFdPUVhLFtMYSxlbCx0bCxubF09U2Euc2hhcGUsc2w9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMscmw9bmV3IEZsb2F0MzJBcnJheShMYSpBYSpGYSpubCksb2w9W1RhJiZBYT4xP2VsLTE6ZWwsVGEmJkZhPjE/dGwtMTp0bF0sYWw9W1RhJiZBYT4xP0FhLTE6QWEsVGEmJkZhPjE/RmEtMTpGYV0sbGw9b2xbMF0vYWxbMF0saWw9b2xbMV0vYWxbMV07bGV0IGNsPTA7Zm9yKGxldCB1bD0wO3VsPExhO3VsKyspe2NvbnN0IGRsPXVsKmthWzBdO2ZvcihsZXQgaGw9MDtobDxBYTtobCsrKXtjb25zdCBwbD13YT9sbCooaGwrLjUpOmxsKmhsO2xldCBmbD1NYXRoLm1pbihlbC0xLFRhP01hdGgucm91bmQocGwpOk1hdGguZmxvb3IocGwpKTt3YSYmKGZsPU1hdGgubWF4KDAsZmwpKTtjb25zdCBtbD1kbCtmbCprYVsxXTtmb3IobGV0IGdsPTA7Z2w8RmE7Z2wrKyl7Y29uc3QgJGw9d2E/aWwqKGdsKy41KTppbCpnbDtsZXQgeGw9TWF0aC5taW4odGwtMSxUYT9NYXRoLnJvdW5kKCRsKTpNYXRoLmZsb29yKCRsKSk7d2EmJih4bD1NYXRoLm1heCgwLHhsKSk7Y29uc3QgeWw9bWwreGwqa2FbMl07Zm9yKGxldCBibD0wO2JsPG5sO2JsKyspe2NvbnN0IFNsPXNsW3lsK2JsXTtybFtjbCsrXT1TbH19fX1yZXR1cm4geGEubWFrZVRlbnNvckluZm8oW0xhLEFhLEZhLG5sXSxTYS5kdHlwZSxybCl9Y29uc3QgcmVzaXplTmVhcmVzdE5laWdoYm9yQ29uZmlnJDI9e2tlcm5lbE5hbWU6UmVzaXplTmVhcmVzdE5laWdoYm9yJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyZXNpemVOZWFyZXN0TmVpZ2hib3IkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2ltYWdlczpTYSxkeTpUYX09YWEse2FsaWduQ29ybmVyczp3YX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFtUYSxTYV0sInJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWQiKTtjb25zdCBFYT1jb21wdXRlU3RyaWRlcyQxKFNhLnNoYXBlKSxrYT1jb21wdXRlU3RyaWRlcyQxKFRhLnNoYXBlKSxbQWEsRmEsTGEsZWxdPVNhLnNoYXBlLFssdGwsbmxdPVRhLnNoYXBlLHNsPW5ldyBGbG9hdDMyQXJyYXkoQWEqRmEqTGEqZWwpLHJsPXhhLmRhdGEuZ2V0KFRhLmRhdGFJZCkudmFsdWVzLG9sPVt3YSYmdGw+MT9GYS0xOkZhLHdhJiZubD4xP0xhLTE6TGFdLGFsPVt3YSYmdGw+MT90bC0xOnRsLHdhJiZubD4xP25sLTE6bmxdLGxsPW9sWzBdL2FsWzBdLGlsPW9sWzFdL2FsWzFdLGNsPTEvbGwsdWw9MS9pbCxkbD1NYXRoLmNlaWwoY2wpKjIrMixobD1NYXRoLmNlaWwodWwpKjIrMjtmb3IobGV0IHBsPTA7cGw8QWE7cGwrKyl7Y29uc3QgZmw9cGwqRWFbMF07Zm9yKGxldCBtbD0wO21sPEZhO21sKyspe2NvbnN0IGdsPWZsK21sKkVhWzFdLCRsPU1hdGguZmxvb3IobWwqY2wpLHhsPU1hdGguZmxvb3IoJGwtZGwvMik7Zm9yKGxldCB5bD0wO3lsPExhO3lsKyspe2NvbnN0IGJsPWdsK3lsKkVhWzJdLFNsPU1hdGguZmxvb3IoeWwqdWwpLENsPU1hdGguZmxvb3IoU2wtaGwvMik7Zm9yKGxldCBUbD0wO1RsPGVsO1RsKyspe2xldCB3bD0wO2ZvcihsZXQgSWw9MDtJbDxkbDtJbCsrKXtjb25zdCBObD1JbCt4bDtpZihObDwwfHxObD49dGwpY29udGludWU7Y29uc3Qgdmw9ZmwrTmwqa2FbMV0sa2w9TmwqbGwsRWw9TWF0aC5taW4oRmEtMSx3YT9NYXRoLnJvdW5kKGtsKTpNYXRoLmZsb29yKGtsKSk7aWYobWw9PT1FbClmb3IobGV0IEFsPTA7QWw8aGw7QWwrKyl7Y29uc3QgUmw9QWwrQ2w7aWYoUmw8MHx8Umw+PW5sKWNvbnRpbnVlO2NvbnN0IFBsPXZsK1JsKmthWzJdLERsPVJsKmlsLF9sPU1hdGgubWluKExhLTEsd2E/TWF0aC5yb3VuZChEbCk6TWF0aC5mbG9vcihEbCkpO3lsPT09X2wmJih3bCs9cmxbUGwrVGxdKX19c2xbYmwrVGxdPXdsfX19fXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhTYS5zaGFwZSxTYS5kdHlwZSxzbCl9Y29uc3QgcmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZENvbmZpZyQyPXtrZXJuZWxOYW1lOlJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmV2ZXJzZSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtkaW1zOlRhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsInJldmVyc2UiKTtjb25zdCB3YT1TYS5zaGFwZS5sZW5ndGgsRWE9cGFyc2VBeGlzUGFyYW0kMShUYSxTYS5zaGFwZSk7aWYod2E9PT0wKXJldHVybiBpZGVudGl0eSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtjb25zdCBrYT1uZXcgVGVuc29yQnVmZmVyJDEoU2Euc2hhcGUsU2EuZHR5cGUpLEFhPXhhLmJ1ZmZlclN5bmMoU2EpO2ZvcihsZXQgRmE9MDtGYTxrYS5zaXplO0ZhKyspe2NvbnN0IExhPWthLmluZGV4VG9Mb2MoRmEpLGVsPUxhLnNsaWNlKCk7RWEuZm9yRWFjaCh0bD0+ZWxbdGxdPVNhLnNoYXBlW3RsXS0xLWVsW3RsXSksa2Euc2V0KEFhLmdldCguLi5lbCksLi4uTGEpfXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYS5zaGFwZSxrYS5kdHlwZSxrYS52YWx1ZXMpfWNvbnN0IHJldmVyc2VDb25maWckMj17a2VybmVsTmFtZTpSZXZlcnNlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyZXZlcnNlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJvdGF0ZVdpdGhPZmZzZXRDb25maWckMj17a2VybmVsTmFtZTpSb3RhdGVXaXRoT2Zmc2V0JDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzooe2lucHV0czpoYSxhdHRyczphYSxiYWNrZW5kOnhhfSk9Pntjb25zdHtpbWFnZTpiYX09aGEse3JhZGlhbnM6U2EsZmlsbFZhbHVlOlRhLGNlbnRlcjp3YX09YWEsRWE9eGEsa2E9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSQxKGJhLmR0eXBlLHNpemVGcm9tU2hhcGUkMShiYS5zaGFwZSkpLFtBYSxGYSxMYSxlbF09YmEuc2hhcGUsW3RsLG5sXT1nZXRJbWFnZUNlbnRlciQxKHdhLEZhLExhKSxzbD0yNTUscmw9TWF0aC5zaW4oU2EpLG9sPU1hdGguY29zKFNhKSxhbD1FYS5kYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0IGlsPTA7aWw8QWE7aWwrKyl7Y29uc3QgY2w9aWwqTGEqRmEqZWw7Zm9yKGxldCB1bD0wO3VsPEZhO3VsKyspe2NvbnN0IGRsPXVsKihMYSplbCk7Zm9yKGxldCBobD0wO2hsPExhO2hsKyspe2NvbnN0IHBsPWhsKmVsO2ZvcihsZXQgZmw9MDtmbDxlbDtmbCsrKXtjb25zdCBtbD1bQWEsdWwsaGwsZmxdLGdsPW1sWzJdLCRsPW1sWzFdO2xldCB4bD0oZ2wtdGwpKm9sLSgkbC1ubCkqcmwseWw9KGdsLXRsKSpybCsoJGwtbmwpKm9sO3hsPU1hdGgucm91bmQoeGwrdGwpLHlsPU1hdGgucm91bmQoeWwrbmwpO2xldCBibD1UYTtpZih0eXBlb2YgVGEhPSJudW1iZXIiJiYoZmw9PT0zP2JsPXNsOmJsPVRhW2ZsXSkseGw+PTAmJnhsPExhJiZ5bD49MCYmeWw8RmEpe2NvbnN0IENsPXlsKihMYSplbCksVGw9eGwqZWwsd2w9Y2wrQ2wrVGwrZmw7Ymw9YWxbd2xdfWNvbnN0IFNsPWNsK2RsK3BsK2ZsO2thW1NsXT1ibH19fX1yZXR1cm57ZGF0YUlkOkVhLndyaXRlKGthLGJhLnNoYXBlLGJhLmR0eXBlKSxzaGFwZTpiYS5zaGFwZSxkdHlwZTpiYS5kdHlwZX19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJvdW5kJDM9dW5hcnlLZXJuZWxGdW5jJDIoUm91bmQkMSxoYT0+e2NvbnN0IGFhPU1hdGguZmxvb3IoaGEpO3JldHVybiBoYS1hYTwuNT9NYXRoLmZsb29yKGhhKTpoYS1hYT4uNT9NYXRoLmNlaWwoaGEpOmFhJTI9PT0wP2FhOmFhKzF9KSxyb3VuZENvbmZpZyQyPXtrZXJuZWxOYW1lOlJvdW5kJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpyb3VuZCQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzY2F0dGVyTmQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtpbmRpY2VzOlNhLHVwZGF0ZXM6VGF9PWFhLHtzaGFwZTp3YX09YmEse3NsaWNlUmFuazpFYSxudW1VcGRhdGVzOmthLHNsaWNlU2l6ZTpBYSxzdHJpZGVzOkZhLG91dHB1dFNpemU6TGF9PWNhbGN1bGF0ZVNoYXBlcyQxKFRhLFNhLHdhKSxlbD0hMCx0bD14YS5idWZmZXJTeW5jKFNhKSxubD14YS5idWZmZXJTeW5jKFRhKSxzbD1zY2F0dGVySW1wbCQxKHRsLG5sLHdhLExhLEFhLGthLEVhLEZhLDAsZWwpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyh3YSxzbC5kdHlwZSxzbC52YWx1ZXMpfWNvbnN0IHNjYXR0ZXJOZENvbmZpZyQyPXtrZXJuZWxOYW1lOlNjYXR0ZXJOZCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6c2NhdHRlck5kJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxvd2VyQm91bmQoaGEsYWEpe2xldCB4YT0wLGJhPWhhLmxlbmd0aCxTYT0wO2Zvcig7eGE8YmE7KVNhPU1hdGguZmxvb3IoKHhhK2JhKS8yKSxoYVtTYV08YWE/eGE9U2ErMTpiYT1TYTtyZXR1cm4gYmF9ZnVuY3Rpb24gdXBwZXJCb3VuZChoYSxhYSl7bGV0IHhhPTAsYmE9aGEubGVuZ3RoLFNhPTA7Zm9yKDt4YTxiYTspU2E9TWF0aC5mbG9vcigoeGErYmEpLzIpLGhhW1NhXTw9YWE/eGE9U2ErMTpiYT1TYTtyZXR1cm4gYmF9ZnVuY3Rpb24gc2VhcmNoU29ydGVkSW1wbChoYSxhYSx4YSxiYSxTYSxUYSl7Y29uc3Qgd2E9Z2V0QXJyYXlGcm9tRFR5cGUkMSgiaW50MzIiLHhhKlNhKTtmb3IobGV0IEVhPTA7RWE8eGE7KytFYSl7Y29uc3Qga2E9aGEuc2xpY2UoRWEqYmEsKEVhKzEpKmJhKSxBYT1FYSpTYTtmb3IobGV0IEZhPTA7RmE8U2E7KytGYSl3YVtBYStGYV09VGE9PT0ibGVmdCI/bG93ZXJCb3VuZChrYSxhYVtGYStBYV0pOnVwcGVyQm91bmQoa2EsYWFbRmErQWFdKX1yZXR1cm4gd2F9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2VhcmNoU29ydGVkJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7c29ydGVkU2VxdWVuY2U6U2EsdmFsdWVzOlRhfT1hYSx7c2lkZTp3YX09YmEsRWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsQWE9c2VhcmNoU29ydGVkSW1wbChFYSxrYSxTYS5zaGFwZVswXSxTYS5zaGFwZVsxXSxUYS5zaGFwZVsxXSx3YSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFRhLnNoYXBlLCJpbnQzMiIsQWEpfWNvbnN0IHNlYXJjaFNvcnRlZENvbmZpZyQyPXtrZXJuZWxOYW1lOlNlYXJjaFNvcnRlZCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6c2VhcmNoU29ydGVkJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNlbGVjdCQzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2NvbmRpdGlvbjpiYSx0OlNhLGU6VGF9PWFhO2Fzc2VydE5vdENvbXBsZXgkMihbYmEsU2EsVGFdLCJzZWxlY3QiKTtjb25zdCB3YT1iYS5zaGFwZS5sZW5ndGgsRWE9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsQWE9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsRmE9dXBjYXN0VHlwZSQxKFNhLmR0eXBlLFRhLmR0eXBlKSxMYT1tYWtlWmVyb3NUeXBlZEFycmF5JDEoc2l6ZUZyb21TaGFwZSQxKFNhLnNoYXBlKSxGYSk7bGV0IGVsPTA7Y29uc3QgdGw9d2E9PT0wfHx3YT4xfHxTYS5zaGFwZS5sZW5ndGg9PT0xPzE6c2l6ZUZyb21TaGFwZSQxKFNhLnNoYXBlLnNsaWNlKDEpKTtmb3IobGV0IG5sPTA7bmw8RWEubGVuZ3RoO25sKyspZm9yKGxldCBzbD0wO3NsPHRsO3NsKyspRWFbbmxdPT09MT9MYVtlbCsrXT1rYVtubF06TGFbZWwrK109QWFbbmxdO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhTYS5zaGFwZSxGYSxMYSl9Y29uc3Qgc2VsZWN0Q29uZmlnJDI9e2tlcm5lbE5hbWU6U2VsZWN0JDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzZWxlY3QkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzY2FsZUFscGhhPVNFTFVfU0NBTEVBTFBIQSQxLHNjYWxlPVNFTFVfU0NBTEUkMSxzZWx1JDI9dW5hcnlLZXJuZWxGdW5jJDIoU2VsdSQyLGhhPT5oYT49MD9zY2FsZSpoYTpzY2FsZUFscGhhKihNYXRoLmV4cChoYSktMSkpLHNlbHVDb25maWckMj17a2VybmVsTmFtZTpTZWx1JDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzZWx1JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc2lnbiQyPXVuYXJ5S2VybmVsRnVuYyQyKFNpZ24kMSxoYT0+aGE8MD8tMTpoYT4wPzE6MCksc2lnbkNvbmZpZyQyPXtrZXJuZWxOYW1lOlNpZ24kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNpZ24kMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzaW4kMj11bmFyeUtlcm5lbEZ1bmMkMihTaW4kMSxoYT0+TWF0aC5zaW4oaGEpKSxzaW5Db25maWckMj17a2VybmVsTmFtZTpTaW4kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNpbiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNpbmgkMj11bmFyeUtlcm5lbEZ1bmMkMihTaW5oJDEsaGE9Pk1hdGguc2luaChoYSkpLHNpbmhDb25maWckMj17a2VybmVsTmFtZTpTaW5oJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzaW5oJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXBzaWxvbj0xMTkyMDkyODk1NTA3ODEyNWUtMjMsdGhyZXNob2xkPU1hdGgubG9nKGVwc2lsb24pKzIsc29mdHBsdXMkMj11bmFyeUtlcm5lbEZ1bmMkMihTb2Z0cGx1cyQyLGhhPT57Y29uc3QgYWE9aGE+LXRocmVzaG9sZCx4YT1oYTx0aHJlc2hvbGQsYmE9TWF0aC5leHAoaGEpO2xldCBTYTtyZXR1cm4geGE/U2E9YmE6YWE/U2E9aGE6U2E9TWF0aC5sb2coMStiYSksU2F9KSxzb2Z0cGx1c0NvbmZpZyQyPXtrZXJuZWxOYW1lOlNvZnRwbHVzJDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzb2Z0cGx1cyQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFjZVRvQmF0Y2hORCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtibG9ja1NoYXBlOlRhLHBhZGRpbmdzOndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoW1NhXSwic3BhY2VUb0JhdGNoTkQiKTtjb25zdCBFYT1zaXplRnJvbVNoYXBlJDEoVGEpLGthPVtbMCwwXV07a2EucHVzaCguLi53YSk7Zm9yKGxldCB1bD0xK1RhLmxlbmd0aDt1bDxTYS5zaGFwZS5sZW5ndGg7Kyt1bClrYS5wdXNoKFswLDBdKTtjb25zdCBBYT1wYWRWMkNvbmZpZyQyLmtlcm5lbEZ1bmMoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGFkZGluZ3M6a2EsY29uc3RhbnRWYWx1ZTowfX0pLEZhPWdldFJlc2hhcGVkJDEoQWEuc2hhcGUsVGEsRWEsITEpLExhPWdldFBlcm11dGVkJDEoRmEubGVuZ3RoLFRhLmxlbmd0aCwhMSksZWw9Z2V0UmVzaGFwZWRQZXJtdXRlZCQxKEFhLnNoYXBlLFRhLEVhLCExKSxzbD1yZXNoYXBlJDMoe2lucHV0czp7eDpBYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6RmF9fSksYWw9dHJhbnNwb3NlJDIoe2lucHV0czp7eDpzbH0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpMYX19KSxjbD1yZXNoYXBlJDMoe2lucHV0czp7eDphbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6ZWx9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEFhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpLGNsfWNvbnN0IHNwYWNlVG9CYXRjaE5EQ29uZmlnJDI9e2tlcm5lbE5hbWU6U3BhY2VUb0JhdGNoTkQkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNwYWNlVG9CYXRjaE5EJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZUZpbGxFbXB0eVJvd3MkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtpbmRpY2VzOmJhLHZhbHVlczpTYSxkZW5zZVNoYXBlOlRhLGRlZmF1bHRWYWx1ZTp3YX09YWE7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYERlbnNlIHNoYXBlIG11c3QgYmUgYSB2ZWN0b3IsIHNhdzoKICAgICAgICAke1RhLnNoYXBlfWApO2lmKGJhLnNoYXBlLmxlbmd0aCE9PTIpdGhyb3cgbmV3IEVycm9yKGBJbmRpY2VzIG11c3QgYmUgYSBtYXRyaXgsIHNhdzoKICAgICAgICAke2JhLnNoYXBlfWApO2lmKFNhLnNoYXBlLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBWYWx1ZXMgbXVzdCBiZSBhIHZlY3Rvciwgc2F3OgogICAgICAgICR7U2Euc2hhcGV9YCk7aWYod2Euc2hhcGUubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoYERlZmF1bHQgdmFsdWUgbXVzdCBiZSBhIHNjYWxhciwgc2F3OgogICAgICAgICR7d2Euc2hhcGV9YCk7Y29uc3QgRWE9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsQWE9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsRmE9eGEuZGF0YS5nZXQod2EuZGF0YUlkKS52YWx1ZXNbMF0sW0xhLGVsLHRsLG5sLHNsXT1zcGFyc2VGaWxsRW1wdHlSb3dzSW1wbCQxKEVhLGJhLnNoYXBlLGJhLmR0eXBlLGthLFNhLmR0eXBlLEFhLEZhKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oZWwsYmEuZHR5cGUsTGEpLHhhLm1ha2VUZW5zb3JJbmZvKFtlbFswXV0sU2EuZHR5cGUsdGwpLHhhLm1ha2VUZW5zb3JJbmZvKFtubC5sZW5ndGhdLCJib29sIixuZXcgVWludDhBcnJheShubC5tYXAocmw9Pk51bWJlcihybCkpKSkseGEubWFrZVRlbnNvckluZm8oW3NsLmxlbmd0aF0sYmEuZHR5cGUsbmV3IEludDMyQXJyYXkoc2wpKV19Y29uc3Qgc3BhcnNlRmlsbEVtcHR5Um93c0NvbmZpZyQyPXtrZXJuZWxOYW1lOlNwYXJzZUZpbGxFbXB0eVJvd3MkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNwYXJzZUZpbGxFbXB0eVJvd3MkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlUmVzaGFwZSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2lucHV0SW5kaWNlczpiYSxpbnB1dFNoYXBlOlNhLG5ld1NoYXBlOlRhfT1hYTtpZihiYS5zaGFwZS5sZW5ndGghPT0yKXRocm93IG5ldyBFcnJvcihgSW5wdXQgaW5kaWNlcyBzaG91bGQgYmUgYSBtYXRyaXggYnV0IHJlY2VpdmVkIHNoYXBlCiAgICAgICAgJHtiYS5zaGFwZX1gKTtpZihTYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgSW5wdXQgc2hhcGUgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICR7U2Euc2hhcGV9YCk7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYFRhcmdldCBzaGFwZSBzaG91bGQgYmUgYSB2ZWN0b3IgYnV0IHJlY2VpdmVkIHNoYXBlICR7VGEuc2hhcGV9YCk7Y29uc3Qgd2E9QXJyYXkuZnJvbSh4YS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyksRWE9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsa2E9QXJyYXkuZnJvbSh4YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyksW0FhLEZhLExhXT1zcGFyc2VSZXNoYXBlSW1wbCQxKEVhLGJhLnNoYXBlLGJhLmR0eXBlLHdhLGthKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpLHhhLm1ha2VUZW5zb3JJbmZvKFtMYS5sZW5ndGhdLFRhLmR0eXBlLG5ldyBJbnQzMkFycmF5KExhKSldfWNvbnN0IHNwYXJzZVJlc2hhcGVDb25maWckMj17a2VybmVsTmFtZTpTcGFyc2VSZXNoYXBlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzcGFyc2VSZXNoYXBlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVNlZ21lbnRNZWFuJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7ZGF0YTpiYSxpbmRpY2VzOlNhLHNlZ21lbnRJZHM6VGF9PWFhO2lmKGJhLnNoYXBlLmxlbmd0aDwxKXRocm93IG5ldyBFcnJvcigiRGF0YSBzaG91bGQgYmUgYXQgbGVhc3QgMSBkaW1lbnNpb25hbCBidXQgcmVjZWl2ZWQgc2NhbGFyIik7aWYoU2Euc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgJHtTYS5zaGFwZX1gKTtpZihUYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgU2VnbWVudCBpZHMgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgJHtUYS5zaGFwZX1gKTtpZihTYS5zaGFwZVswXSE9PVRhLnNoYXBlWzBdKXRocm93IG5ldyBFcnJvcigic2VnbWVudElkcyBhbmQgaW5kaWNlcyBzaG91bGQgaGF2ZSBzYW1lIHNpemUuIik7Y29uc3Qgd2E9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsRWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsW0FhLEZhXT1zcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbCQxKHdhLGJhLnNoYXBlLGJhLmR0eXBlLEVhLGthLCEwKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpfWNvbnN0IHNwYXJzZVNlZ21lbnRNZWFuQ29uZmlnJDI9e2tlcm5lbE5hbWU6U3BhcnNlU2VnbWVudE1lYW4kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnNwYXJzZVNlZ21lbnRNZWFuJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVNlZ21lbnRTdW0kMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtkYXRhOmJhLGluZGljZXM6U2Esc2VnbWVudElkczpUYX09YWE7aWYoYmEuc2hhcGUubGVuZ3RoPDEpdGhyb3cgbmV3IEVycm9yKCJEYXRhIHNob3VsZCBiZSBhdCBsZWFzdCAxIGRpbWVuc2lvbmFsIGJ1dCByZWNlaXZlZCBzY2FsYXIiKTtpZihTYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgSW5kaWNlcyBzaG91bGQgYmUgYSB2ZWN0b3IgYnV0IHJlY2VpdmVkIHNoYXBlCiAgICAgICAgICR7U2Euc2hhcGV9YCk7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYFNlZ21lbnQgaWRzIHNob3VsZCBiZSBhIHZlY3RvciBidXQgcmVjZWl2ZWQgc2hhcGUKICAgICAgICAgJHtUYS5zaGFwZX1gKTtpZihTYS5zaGFwZVswXSE9PVRhLnNoYXBlWzBdKXRocm93IG5ldyBFcnJvcigic2VnbWVudElkcyBhbmQgaW5kaWNlcyBzaG91bGQgaGF2ZSBzYW1lIHNpemUuIik7Y29uc3Qgd2E9eGEuZGF0YS5nZXQoYmEuZGF0YUlkKS52YWx1ZXMsRWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsW0FhLEZhXT1zcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbCQxKHdhLGJhLnNoYXBlLGJhLmR0eXBlLEVhLGthKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpfWNvbnN0IHNwYXJzZVNlZ21lbnRTdW1Db25maWckMj17a2VybmVsTmFtZTpTcGFyc2VTZWdtZW50U3VtJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzcGFyc2VTZWdtZW50U3VtJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVRvRGVuc2UkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzcGFyc2VJbmRpY2VzOlNhLHNwYXJzZVZhbHVlczpUYSxkZWZhdWx0VmFsdWU6d2F9PWFhLHtvdXRwdXRTaGFwZTpFYX09YmEse3NsaWNlUmFuazprYSxudW1VcGRhdGVzOkFhLHNsaWNlU2l6ZTpGYSxzdHJpZGVzOkxhLG91dHB1dFNpemU6ZWx9PWNhbGN1bGF0ZVNoYXBlcyQxKFRhLFNhLEVhKSx0bD0hMSxubD14YS5idWZmZXJTeW5jKFNhKTtsZXQgc2w7c3dpdGNoKFRhLmR0eXBlKXtjYXNlImJvb2wiOntjb25zdCBybD14YS5idWZmZXJTeW5jKFRhKSxvbD0hIXhhLmRhdGEuZ2V0KHdhLmRhdGFJZCkudmFsdWVzWzBdO3NsPXNjYXR0ZXJJbXBsJDEobmwscmwsRWEsZWwsRmEsQWEsa2EsTGEsb2wsdGwpO2JyZWFrfWNhc2UiZmxvYXQzMiI6e2NvbnN0IHJsPXhhLmJ1ZmZlclN5bmMoVGEpLG9sPXhhLmRhdGEuZ2V0KHdhLmRhdGFJZCkudmFsdWVzWzBdO3NsPXNjYXR0ZXJJbXBsJDEobmwscmwsRWEsZWwsRmEsQWEsa2EsTGEsb2wsdGwpO2JyZWFrfWNhc2UiaW50MzIiOntjb25zdCBybD14YS5idWZmZXJTeW5jKFRhKSxvbD14YS5kYXRhLmdldCh3YS5kYXRhSWQpLnZhbHVlc1swXTtzbD1zY2F0dGVySW1wbCQxKG5sLHJsLEVhLGVsLEZhLEFhLGthLExhLG9sLHRsKTticmVha31jYXNlInN0cmluZyI6e2NvbnN0IHJsPXhhLmJ1ZmZlclN5bmMoVGEpLG9sPWRlY29kZVN0cmluZyQxKHhhLmRhdGEuZ2V0KHdhLmRhdGFJZCkudmFsdWVzWzBdKTtzbD1zY2F0dGVySW1wbCQxKG5sLHJsLEVhLGVsLEZhLEFhLGthLExhLG9sLHRsKTticmVha31kZWZhdWx0OnRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdHlwZSAke1RhLmR0eXBlfWApfXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhFYSxzbC5kdHlwZSxzbC52YWx1ZXMpfWNvbnN0IHNwYXJzZVRvRGVuc2VDb25maWckMj17a2VybmVsTmFtZTpTcGFyc2VUb0RlbnNlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzcGFyc2VUb0RlbnNlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwbGl0ViQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtudW1PclNpemVTcGxpdHM6VGEsYXhpczp3YX09YmEsRWE9cGFyc2VBeGlzUGFyYW0kMSh3YSxTYS5zaGFwZSlbMF0sa2E9cHJlcGFyZVNwbGl0U2l6ZSQxKFNhLFRhLEVhKSxBYT1uZXcgQXJyYXkoU2Euc2hhcGUubGVuZ3RoKS5maWxsKDApLEZhPVNhLnNoYXBlLnNsaWNlKCk7cmV0dXJuIGthLm1hcChMYT0+e2NvbnN0IGVsPVsuLi5GYV07ZWxbRWFdPUxhO2NvbnN0IHRsPXNsaWNlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46QWEsc2l6ZTplbH19KTtyZXR1cm4gQWFbRWFdKz1MYSx0bH0pfWNvbnN0IHNwbGl0VkNvbmZpZyQyPXtrZXJuZWxOYW1lOlNwbGl0ViQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6c3BsaXRWJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNxdWFyZUNvbmZpZyQyPXtrZXJuZWxOYW1lOlNxdWFyZSQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6KHtpbnB1dHM6aGEsYmFja2VuZDphYX0pPT57Y29uc3R7eDp4YX09aGEsYmE9YWE7YXNzZXJ0Tm90Q29tcGxleCQyKHhhLCJzcXVhcmUiKTtjb25zdCBTYT1iYS5kYXRhLmdldCh4YS5kYXRhSWQpLnZhbHVlcyxUYT1uZXcgRmxvYXQzMkFycmF5KFNhLmxlbmd0aCk7Zm9yKGxldCBFYT0wO0VhPFNhLmxlbmd0aDsrK0VhKXtjb25zdCBrYT1TYVtFYV07VGFbRWFdPWthKmthfXJldHVybntkYXRhSWQ6YmEud3JpdGUoVGEseGEuc2hhcGUseGEuZHR5cGUpLHNoYXBlOnhhLnNoYXBlLGR0eXBlOnhhLmR0eXBlfX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3RlcCQzPXVuYXJ5S2VybmVsRnVuYyQyKFN0ZXAkMSwoaGEsYWEpPT57Y29uc3QgeGE9YWE7cmV0dXJuIGlzTmFOKGhhKT9OYU46aGE+MD8xOnhhLmFscGhhfSksc3RlcENvbmZpZyQyPXtrZXJuZWxOYW1lOlN0ZXAkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnN0ZXAkM307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaWRlZFNsaWNlJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2JlZ2luOlRhLGVuZDp3YSxzdHJpZGVzOkVhLGJlZ2luTWFzazprYSxlbmRNYXNrOkFhLGVsbGlwc2lzTWFzazpGYSxuZXdBeGlzTWFzazpMYSxzaHJpbmtBeGlzTWFzazplbH09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJzdHJpZGVkU2xpY2UiKTtjb25zdHtmaW5hbFNoYXBlU3BhcnNlOnRsLGZpbmFsU2hhcGU6bmwsaXNJZGVudGl0eTpzbCxzbGljZURpbTA6cmwsaXNTaW1wbGVTbGljZTpvbCxiZWdpbjphbCxlbmQ6bGwsc3RyaWRlczppbH09c2xpY2VJbmZvJDEoU2Euc2hhcGUsVGEsd2EsRWEsa2EsQWEsRmEsTGEsZWwpO2xldCBjbDtpZihzbCljbD1yZXNoYXBlJDMoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSk7ZWxzZSBpZihybHx8b2wpe2Fzc2VydCQyKFNhLnNoYXBlLmxlbmd0aD49MSwoKT0+YElucHV0IG11c3QgaGF2ZSByYW5rIGF0IGxlYXN0IDEsIGdvdDogJHtTYS5zaGFwZS5sZW5ndGh9YCk7Y29uc3QgdWw9Y29tcHV0ZU91dFNoYXBlJDUoYWwsbGwsaWwpLGRsPXNsaWNlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46YWwsc2l6ZTp1bH19KTtjbD1yZXNoYXBlJDMoe2lucHV0czp7eDpkbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oZGwpfWVsc2V7Y29uc3QgdWw9eGEuYnVmZmVyU3luYyhTYSksZGw9c3RyaWRlZFNsaWNlSW1wbCQxKHRsLHVsLGlsLGFsKTtjbD14YS5tYWtlVGVuc29ySW5mbyhubCxkbC5kdHlwZSxkbC52YWx1ZXMpfXJldHVybiBjbH1jb25zdCBzdHJpZGVkU2xpY2VDb25maWckMj17a2VybmVsTmFtZTpTdHJpZGVkU2xpY2UkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnN0cmlkZWRTbGljZSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdHJpbmdOR3JhbXMkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzZXBhcmF0b3I6U2EsbkdyYW1XaWR0aHM6VGEsbGVmdFBhZDp3YSxyaWdodFBhZDpFYSxwYWRXaWR0aDprYSxwcmVzZXJ2ZVNob3J0U2VxdWVuY2VzOkFhfT1iYSx7ZGF0YTpGYSxkYXRhU3BsaXRzOkxhfT1hYSxlbD14YS5kYXRhLmdldChGYS5kYXRhSWQpLnZhbHVlcyx0bD14YS5kYXRhLmdldChMYS5kYXRhSWQpLnZhbHVlcyxbbmwsc2xdPXN0cmluZ05HcmFtc0ltcGwkMShlbCx0bCxTYSxUYSx3YSxFYSxrYSxBYSk7cmV0dXJuW3hhLm1ha2VUZW5zb3JJbmZvKFtubC5sZW5ndGhdLCJzdHJpbmciLG5sKSx4YS5tYWtlVGVuc29ySW5mbyhMYS5zaGFwZSwiaW50MzIiLHNsKV19Y29uc3Qgc3RyaW5nTkdyYW1zQ29uZmlnJDI9e2tlcm5lbE5hbWU6U3RyaW5nTkdyYW1zJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzpzdHJpbmdOR3JhbXMkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nU3BsaXQkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtza2lwRW1wdHk6U2F9PWJhLHtpbnB1dDpUYSxkZWxpbWl0ZXI6d2F9PWFhO2lmKFRhLmR0eXBlIT09InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKCJJbnB1dCBtdXN0IGJlIG9mIGRhdGF0eXBlIHN0cmluZyIpO2lmKFRhLnNoYXBlLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBtdXN0IGJlIGEgdmVjdG9yLCBnb3Qgc2hhcGU6ICR7VGEuc2hhcGV9YCk7aWYod2Euc2hhcGUubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoYERlbGltaXRlciBtdXN0IGJlIGEgc2NhbGFyLCBnb3Qgc2hhcGU6ICR7d2Euc2hhcGV9YCk7Y29uc3QgRWE9eGEuZGF0YS5nZXQoVGEuZGF0YUlkKS52YWx1ZXMsa2E9eGEuZGF0YS5nZXQod2EuZGF0YUlkKS52YWx1ZXNbMF0sW0FhLEZhLExhXT1zdHJpbmdTcGxpdEltcGwkMShFYSxrYSxTYSksZWw9RmEubGVuZ3RoO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhbZWwsMl0sImludDMyIixBYSkseGEubWFrZVRlbnNvckluZm8oW2VsXSwic3RyaW5nIixGYSkseGEubWFrZVRlbnNvckluZm8oWzJdLCJpbnQzMiIsbmV3IEludDMyQXJyYXkoTGEpKV19Y29uc3Qgc3RyaW5nU3BsaXRDb25maWckMj17a2VybmVsTmFtZTpTdHJpbmdTcGxpdCQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6c3RyaW5nU3BsaXQkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nVG9IYXNoQnVja2V0RmFzdCQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse251bUJ1Y2tldHM6U2F9PWJhLHtpbnB1dDpUYX09YWE7aWYoVGEuZHR5cGUhPT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIklucHV0IG11c3QgYmUgb2YgZGF0YXR5cGUgc3RyaW5nIik7aWYoU2E8PTApdGhyb3cgbmV3IEVycm9yKCJOdW1iZXIgb2YgYnVja2V0cyBtdXN0IGJlIGF0IGxlYXN0IDEiKTtjb25zdCB3YT14YS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyxFYT1zdHJpbmdUb0hhc2hCdWNrZXRGYXN0SW1wbCQxKHdhLFNhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oVGEuc2hhcGUsImludDMyIixFYSl9Y29uc3Qgc3RyaW5nVG9IYXNoQnVja2V0RmFzdENvbmZpZyQyPXtrZXJuZWxOYW1lOlN0cmluZ1RvSGFzaEJ1Y2tldEZhc3QkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnN0cmluZ1RvSGFzaEJ1Y2tldEZhc3QkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCB0YW4kMj11bmFyeUtlcm5lbEZ1bmMkMihUYW4kMSxoYT0+TWF0aC50YW4oaGEpKSx0YW5Db25maWckMj17a2VybmVsTmFtZTpUYW4kMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnRhbiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHRhbmgkMj11bmFyeUtlcm5lbEZ1bmMkMihUYW5oJDIsaGE9Pk1hdGgudGFuaChoYSkpLHRhbmhDb25maWckMj17a2VybmVsTmFtZTpUYW5oJDIsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzp0YW5oJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRlbnNvclNjYXR0ZXJVcGRhdGUkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt0ZW5zb3I6YmEsaW5kaWNlczpTYSx1cGRhdGVzOlRhfT1hYSx7c2xpY2VSYW5rOndhLG51bVVwZGF0ZXM6RWEsc2xpY2VTaXplOmthLHN0cmlkZXM6QWEsb3V0cHV0U2l6ZTpGYX09Y2FsY3VsYXRlU2hhcGVzJDEoVGEsU2EsYmEuc2hhcGUpLExhPSExLGVsPXhhLmJ1ZmZlclN5bmMoU2EpLHRsPXhhLmJ1ZmZlclN5bmMoVGEpLG5sPXhhLmJ1ZmZlclN5bmMoYmEpLHNsPXNjYXR0ZXJJbXBsJDEoZWwsdGwsYmEuc2hhcGUsRmEsa2EsRWEsd2EsQWEsbmwsTGEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhiYS5zaGFwZSxzbC5kdHlwZSxzbC52YWx1ZXMpfWNvbnN0IHRlbnNvclNjYXR0ZXJVcGRhdGVDb25maWckMj17a2VybmVsTmFtZTpUZW5zb3JTY2F0dGVyVXBkYXRlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzp0ZW5zb3JTY2F0dGVyVXBkYXRlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRpbGUkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7cmVwczpUYX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJ0aWxlIik7Y29uc3Qgd2E9dGlsZUltcGwkMSh4YS5idWZmZXJTeW5jKFNhKSxUYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKHdhLnNoYXBlLHdhLmR0eXBlLHdhLnZhbHVlcyl9Y29uc3QgdGlsZUNvbmZpZyQyPXtrZXJuZWxOYW1lOlRpbGUkMSxiYWNrZW5kTmFtZToiY3B1IixrZXJuZWxGdW5jOnRpbGUkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdG9wSyQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtrOlRhLHNvcnRlZDp3YX09YmE7YXNzZXJ0Tm90Q29tcGxleCQyKFNhLCJ0b3BrIik7Y29uc3QgRWE9eGEuZGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsW2thLEFhXT10b3BLSW1wbCQxKEVhLFNhLnNoYXBlLFNhLmR0eXBlLFRhLHdhKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oa2Euc2hhcGUsa2EuZHR5cGUsa2EudmFsdWVzKSx4YS5tYWtlVGVuc29ySW5mbyhBYS5zaGFwZSxBYS5kdHlwZSxBYS52YWx1ZXMpXX1jb25zdCB0b3BLQ29uZmlnJDI9e2tlcm5lbE5hbWU6VG9wSyQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6dG9wSyQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0cmFuc2Zvcm0kMihoYSl7Y29uc3R7aW5wdXRzOmFhLGF0dHJzOnhhLGJhY2tlbmQ6YmF9PWhhLHtpbWFnZTpTYSx0cmFuc2Zvcm1zOlRhfT1hYSx7aW50ZXJwb2xhdGlvbjp3YSxmaWxsTW9kZTpFYSxmaWxsVmFsdWU6a2Esb3V0cHV0U2hhcGU6QWF9PXhhLFtGYSxMYSxlbCx0bF09U2Euc2hhcGUsW25sLHNsXT1BYT8/W0xhLGVsXSxybD1bRmEsbmwsc2wsdGxdLG9sPWNvbXB1dGVTdHJpZGVzJDEoU2Euc2hhcGUpLGFsPW9sWzBdLGxsPW9sWzFdLGlsPW9sWzJdLGNsPWNvbXB1dGVTdHJpZGVzJDEocmwpLHVsPWNsWzBdLGRsPWNsWzFdLGhsPWNsWzJdLHBsPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMShTYS5kdHlwZSxzaXplRnJvbVNoYXBlJDEocmwpKTtwbC5maWxsKGthKTtjb25zdCBmbD1iYS5kYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxtbD1iYS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcztmb3IobGV0ICRsPTA7JGw8RmE7KyskbCl7Y29uc3QgeGw9VGEuc2hhcGVbMF09PT0xP21sOm1sLnN1YmFycmF5KCRsKjgsJGwqOCs4KTtmb3IobGV0IHlsPTA7eWw8bmw7Kyt5bClmb3IobGV0IGJsPTA7Ymw8c2w7KytibClmb3IobGV0IFNsPTA7U2w8dGw7KytTbCl7bGV0IENsO2NvbnN0IFRsPXhsWzZdKmJsK3hsWzddKnlsKzE7aWYoVGw9PT0wKWNvbnRpbnVlO2NvbnN0IHdsPSh4bFswXSpibCt4bFsxXSp5bCt4bFsyXSkvVGwsSWw9KHhsWzNdKmJsK3hsWzRdKnlsK3hsWzVdKS9UbCxObD1tYXBDb29yZCh3bCxlbCxFYSksdmw9bWFwQ29vcmQoSWwsTGEsRWEpO3N3aXRjaCh3YSl7Y2FzZSJuZWFyZXN0IjpDbD1uZWFyZXN0SW50ZXJwb2xhdGlvbihmbCxMYSxlbCxhbCxsbCxpbCwkbCx2bCxObCxTbCxrYSk7YnJlYWs7Y2FzZSJiaWxpbmVhciI6Q2w9YmlsaW5lYXJJbnRlcnBvbGF0aW9uKGZsLExhLGVsLGFsLGxsLGlsLCRsLHZsLE5sLFNsLGthKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gVHJhbnNmb3JtOiBFeHBlY3QgJ25lYXJlc3QnIG9yICdiaWxpbmVhcicsIGJ1dCBnb3QgJHt3YX1gKX1jb25zdCBrbD0kbCp1bCt5bCpkbCtibCpobCtTbDtwbFtrbF09Q2x9cmV0dXJuIGJhLm1ha2VUZW5zb3JJbmZvKHJsLFNhLmR0eXBlLHBsKX1yZXR1cm57ZGF0YUlkOmJhLndyaXRlKHBsLHJsLFNhLmR0eXBlKSxzaGFwZTpTYS5zaGFwZSxkdHlwZTpTYS5kdHlwZX19Y29uc3QgdHJhbnNmb3JtQ29uZmlnJDI9e2tlcm5lbE5hbWU6VHJhbnNmb3JtJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzp0cmFuc2Zvcm0kMn07ZnVuY3Rpb24gbWFwQ29vcmQoaGEsYWEseGEpe3N3aXRjaCh4YSl7Y2FzZSJyZWZsZWN0IjpyZXR1cm4gbWFwQ29vcmRSZWZsZWN0KGhhLGFhKTtjYXNlIndyYXAiOnJldHVybiBtYXBDb29yZFdyYXAoaGEsYWEpO2Nhc2UibmVhcmVzdCI6cmV0dXJuIG1hcENvb3JkTmVhcmVzdChoYSxhYSk7Y2FzZSJjb25zdGFudCI6ZGVmYXVsdDpyZXR1cm4gbWFwQ29vcmRDb25zdGFudChoYSl9fWZ1bmN0aW9uIG1hcENvb3JkUmVmbGVjdChoYSxhYSl7bGV0IHhhPWhhO2lmKHhhPDApaWYoYWE8PTEpeGE9MDtlbHNle2NvbnN0IGJhPTIqYWE7eGE8YmEmJih4YT1iYSpNYXRoLnRydW5jKC14YS9iYSkreGEpLHhhPXhhPC1hYT94YStiYToteGEtMX1lbHNlIGlmKHhhPmFhLTEpaWYoYWE8PTEpeGE9MDtlbHNle2NvbnN0IGJhPTIqYWE7eGEtPWJhKk1hdGgudHJ1bmMoeGEvYmEpLHhhPj1hYSYmKHhhPWJhLXhhLTEpfXJldHVybiBjbGFtcCQxKDAseGEsYWEtMSl9ZnVuY3Rpb24gbWFwQ29vcmRXcmFwKGhhLGFhKXtsZXQgeGE9aGE7aWYoeGE8MClpZihhYTw9MSl4YT0wO2Vsc2V7Y29uc3QgYmE9YWEtMTt4YSs9YWEqKE1hdGgudHJ1bmMoLXhhL2JhKSsxKX1lbHNlIGlmKHhhPmFhLTEpaWYoYWE8PTEpeGE9MDtlbHNle2NvbnN0IGJhPWFhLTE7eGEtPWFhKk1hdGgudHJ1bmMoeGEvYmEpfXJldHVybiBjbGFtcCQxKDAseGEsYWEtMSl9ZnVuY3Rpb24gbWFwQ29vcmRDb25zdGFudChoYSxhYSl7cmV0dXJuIGhhfWZ1bmN0aW9uIG1hcENvb3JkTmVhcmVzdChoYSxhYSl7cmV0dXJuIGNsYW1wJDEoMCxoYSxhYS0xKX1mdW5jdGlvbiByZWFkV2l0aEZpbGxWYWx1ZShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSxGYSl7Y29uc3QgTGE9d2EqYmErRWEqU2Era2EqVGErQWE7cmV0dXJuIDA8PUVhJiZFYTxhYSYmMDw9a2EmJmthPHhhP2hhW0xhXTpGYX1mdW5jdGlvbiBuZWFyZXN0SW50ZXJwb2xhdGlvbihoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSxGYSl7Y29uc3QgTGE9TWF0aC5yb3VuZChFYSksZWw9TWF0aC5yb3VuZChrYSk7cmV0dXJuIHJlYWRXaXRoRmlsbFZhbHVlKGhhLGFhLHhhLGJhLFNhLFRhLHdhLExhLGVsLEFhLEZhKX1mdW5jdGlvbiBiaWxpbmVhckludGVycG9sYXRpb24oaGEsYWEseGEsYmEsU2EsVGEsd2EsRWEsa2EsQWEsRmEpe2NvbnN0IExhPU1hdGguZmxvb3IoRWEpLGVsPU1hdGguZmxvb3Ioa2EpLHRsPUxhKzEsbmw9ZWwrMSxzbD0obmwta2EpKnJlYWRXaXRoRmlsbFZhbHVlKGhhLGFhLHhhLGJhLFNhLFRhLHdhLExhLGVsLEFhLEZhKSsoa2EtZWwpKnJlYWRXaXRoRmlsbFZhbHVlKGhhLGFhLHhhLGJhLFNhLFRhLHdhLExhLG5sLEFhLEZhKSxybD0obmwta2EpKnJlYWRXaXRoRmlsbFZhbHVlKGhhLGFhLHhhLGJhLFNhLFRhLHdhLHRsLGVsLEFhLEZhKSsoa2EtZWwpKnJlYWRXaXRoRmlsbFZhbHVlKGhhLGFhLHhhLGJhLFNhLFRhLHdhLHRsLG5sLEFhLEZhKTtyZXR1cm4odGwtRWEpKnNsKyhFYS1MYSkqcmx9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB1bmlxdWUkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGF0dHJzOnhhLGJhY2tlbmQ6YmF9PWhhLHtheGlzOlNhfT14YSx7eDpUYX09YWE7YXNzZXJ0Tm90Q29tcGxleCQyKFRhLCJ1bmlxdWUiKTtjb25zdCB3YT1iYS5kYXRhLmdldChUYS5kYXRhSWQpLnZhbHVlcyx7b3V0cHV0VmFsdWVzOkVhLG91dHB1dFNoYXBlOmthLGluZGljZXM6QWF9PXVuaXF1ZUltcGwkMSh3YSxTYSxUYS5zaGFwZSxUYS5kdHlwZSk7cmV0dXJuW2JhLm1ha2VUZW5zb3JJbmZvKGthLFRhLmR0eXBlLEVhKSxiYS5tYWtlVGVuc29ySW5mbyhbQWEubGVuZ3RoXSwiaW50MzIiLEFhKV19Y29uc3QgdW5pcXVlQ29uZmlnJDI9e2tlcm5lbE5hbWU6VW5pcXVlJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzp1bmlxdWUkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5wYWNrJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7dmFsdWU6U2F9PWFhO2xldHtheGlzOlRhfT1iYTtUYTwwJiYoVGErPVNhLnNoYXBlLmxlbmd0aCk7Y29uc3Qgd2E9U2Euc2hhcGUubGVuZ3RoLEVhPVNhLnNoYXBlW1RhXSxrYT1uZXcgQXJyYXkod2EtMSk7bGV0IEFhPTA7Zm9yKGxldCB0bD0wO3RsPHdhO3RsKyspdGwhPT1UYSYmKGthW0FhKytdPVNhLnNoYXBlW3RsXSk7Y29uc3QgRmE9bmV3IEFycmF5KHdhKS5maWxsKDApLExhPVNhLnNoYXBlLnNsaWNlKCk7TGFbVGFdPTE7Y29uc3QgZWw9bmV3IEFycmF5KEVhKTtmb3IobGV0IHRsPTA7dGw8ZWwubGVuZ3RoO3RsKyspe0ZhW1RhXT10bDtjb25zdCBubD1zbGljZSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2JlZ2luOkZhLHNpemU6TGF9fSk7ZWxbdGxdPXJlc2hhcGUkMyh7aW5wdXRzOnt4Om5sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTprYX19KSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhubCl9cmV0dXJuIGVsfWNvbnN0IHVucGFja0NvbmZpZyQyPXtrZXJuZWxOYW1lOlVucGFjayQxLGJhY2tlbmROYW1lOiJjcHUiLGtlcm5lbEZ1bmM6dW5wYWNrJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHVuc29ydGVkU2VnbWVudFN1bSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2Esc2VnbWVudElkczpUYX09YWEse251bVNlZ21lbnRzOndhfT1iYTthc3NlcnROb3RDb21wbGV4JDIoU2EsInVuc29ydGVkU2VnbWVudFN1bSIpO2NvbnN0IEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1UYS5zaGFwZS5sZW5ndGgsQWE9W10sRmE9W10sTGE9RWEta2E7bGV0IGVsPVRhO2ZvcihsZXQgbmw9MDtubDxMYTsrK25sKXtjb25zdCBzbD1leHBhbmREaW1zJDIoe2lucHV0czp7aW5wdXQ6ZWx9LGJhY2tlbmQ6eGEsYXR0cnM6e2RpbTpubCsxfX0pO2VsPXNsLEZhLnB1c2goc2wpfWZvcihsZXQgbmw9MDtubDx3YTsrK25sKXtjb25zdCBzbD1jcmVhdGVTY2FsYXJWYWx1ZSQxKG5sLCJpbnQzMiIpLHJsPXhhLm1ha2VUZW5zb3JJbmZvKFtdLCJpbnQzMiIsc2wpLG9sPWVxdWFsJDIoe2lucHV0czp7YTpybCxiOmVsfSxiYWNrZW5kOnhhfSksYWw9Y2FzdCQzKHtpbnB1dHM6e3g6b2x9LGJhY2tlbmQ6eGEsYXR0cnM6e2R0eXBlOiJmbG9hdDMyIn19KSxsbD1tdWx0aXBseSQyKHtpbnB1dHM6e2E6YWwsYjpTYX0sYmFja2VuZDp4YX0pLGlsPXN1bSQ0KHtpbnB1dHM6e3g6bGx9LGJhY2tlbmQ6eGEsYXR0cnM6e2F4aXM6MCxrZWVwRGltczohMX19KTtBYS5wdXNoKGlsKSxGYS5wdXNoKHJsKSxGYS5wdXNoKG9sKSxGYS5wdXNoKGFsKSxGYS5wdXNoKGxsKSxGYS5wdXNoKGlsKX1jb25zdCB0bD1wYWNrJDIoe2lucHV0czpBYSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOjB9fSk7cmV0dXJuIEZhLmZvckVhY2gobmw9PnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSksdGx9Y29uc3QgdW5zb3J0ZWRTZWdtZW50U3VtQ29uZmlnJDI9e2tlcm5lbE5hbWU6VW5zb3J0ZWRTZWdtZW50U3VtJDEsYmFja2VuZE5hbWU6ImNwdSIsa2VybmVsRnVuYzp1bnNvcnRlZFNlZ21lbnRTdW0kMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qga2VybmVsQ29uZmlncyQyPVtfZnVzZWRNYXRNdWxDb25maWckMixhYnNDb25maWckMixhY29zQ29uZmlnJDIsYWNvc2hDb25maWckMixhZGRDb25maWckMixhZGROQ29uZmlnJDIsYWxsQ29uZmlnJDIsYW55Q29uZmlnJDIsYXJnTWF4Q29uZmlnJDIsYXJnTWluQ29uZmlnJDIsYXNpbkNvbmZpZyQyLGFzaW5oQ29uZmlnJDIsYXRhbkNvbmZpZyQyLGF0YW4yQ29uZmlnJDIsYXRhbmhDb25maWckMixhdmdQb29sQ29uZmlnJDIsYXZnUG9vbDNEQ29uZmlnJDIsYXZnUG9vbDNER3JhZENvbmZpZyQyLGF2Z1Bvb2xHcmFkQ29uZmlnJDIsYmF0Y2hNYXRNdWxDb25maWckMixiYXRjaE5vcm1Db25maWckMixiYXRjaFRvU3BhY2VORENvbmZpZyQyLGJpbmNvdW50Q29uZmlnJDIsYml0d2lzZUFuZENvbmZpZyQyLGJyb2FkY2FzdEFyZ3NDb25maWckMixjYXN0Q29uZmlnJDIsY2VpbENvbmZpZyQyLGNsaXBCeVZhbHVlQ29uZmlnJDIsY29tcGxleENvbmZpZyQyLGNvbXBsZXhBYnNDb25maWckMixjb25jYXRDb25maWckMixjb252MkRDb25maWckMixjb252MkRCYWNrcHJvcEZpbHRlckNvbmZpZyQyLGNvbnYyREJhY2twcm9wSW5wdXRDb25maWckMixjb252M0RDb25maWckMixjb252M0RCYWNrcHJvcEZpbHRlclYyQ29uZmlnJDIsY29udjNEQmFja3Byb3BJbnB1dFYyQ29uZmlnLGNvc0NvbmZpZyQyLGNvc2hDb25maWckMixjcm9wQW5kUmVzaXplQ29uZmlnJDIsY3VtcHJvZENvbmZpZyQyLGN1bXN1bUNvbmZpZyQyLGRlbnNlQmluY291bnRDb25maWckMixkZXB0aFRvU3BhY2VDb25maWckMixkZXB0aHdpc2VDb252MmROYXRpdmVDb25maWckMixkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlckNvbmZpZyQyLGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXRDb25maWckMixkaWFnQ29uZmlnJDIsZGlsYXRpb24yRENvbmZpZyQyLGRpbGF0aW9uMkRCYWNrcHJvcEZpbHRlckNvbmZpZyxkaWxhdGlvbjJEQmFja3Byb3BJbnB1dENvbmZpZyxkcmF3Q29uZmlnLGVpbnN1bUNvbmZpZyQyLGVsdUNvbmZpZyQyLGVsdUdyYWRDb25maWckMixlcXVhbENvbmZpZyQyLGVyZkNvbmZpZyQyLGV4cENvbmZpZyQyLGV4cGFuZERpbXNDb25maWckMixleHBtMUNvbmZpZyQyLGZmdENvbmZpZyQyLGZpbGxDb25maWckMixmbGlwTGVmdFJpZ2h0Q29uZmlnJDIsZmxvb3JDb25maWckMixmbG9vckRpdkNvbmZpZyQyLGZ1c2VkQ29udjJEQ29uZmlnJDIsZnVzZWREZXB0aHdpc2VDb252MkRDb25maWckMixnYXRoZXJOZENvbmZpZyQyLGdhdGhlclYyQ29uZmlnJDIsZ3JlYXRlckNvbmZpZyQyLGdyZWF0ZXJFcXVhbENvbmZpZyQyLGlkZW50aXR5Q29uZmlnJDIsaWZmdENvbmZpZyQyLGltYWdDb25maWckMixpc0Zpbml0ZUNvbmZpZyQyLGlzSW5mQ29uZmlnJDIsaXNOYU5Db25maWckMixsZWFreVJlbHVDb25maWckMixsZXNzQ29uZmlnJDIsbGVzc0VxdWFsQ29uZmlnJDIsbGluU3BhY2VDb25maWckMixsb2dDb25maWckMixsb2cxcENvbmZpZyQyLGxvZ2ljYWxBbmRDb25maWckMixsb2dpY2FsTm90Q29uZmlnJDIsbG9naWNhbE9yQ29uZmlnJDIsTFJOQ29uZmlnJDIsTFJOR3JhZENvbmZpZyQyLG1heENvbmZpZyQyLG1heGltdW1Db25maWckMixtYXhQb29sQ29uZmlnJDIsbWF4UG9vbDNEQ29uZmlnJDIsbWF4UG9vbDNER3JhZENvbmZpZyQyLG1heFBvb2xHcmFkQ29uZmlnJDIsbWF4UG9vbFdpdGhBcmdtYXhDb25maWckMixtZWFuQ29uZmlnJDIsbWluQ29uZmlnJDIsbWluaW11bUNvbmZpZyQyLG1pcnJvclBhZENvbmZpZyQyLG1vZENvbmZpZyQyLG11bHRpbm9taWFsQ29uZmlnJDIsbXVsdGlwbHlDb25maWckMixuZWdDb25maWckMixub25NYXhTdXBwcmVzc2lvblYzQ29uZmlnJDIsbm9uTWF4U3VwcHJlc3Npb25WNENvbmZpZyQyLG5vbk1heFN1cHByZXNzaW9uVjVDb25maWckMixub3RFcXVhbENvbmZpZyQyLG9uZUhvdENvbmZpZyQyLG9uZXNMaWtlQ29uZmlnJDIscGFja0NvbmZpZyQyLHBhZFYyQ29uZmlnJDIscG93Q29uZmlnJDIscHJlbHVDb25maWckMixwcm9kQ29uZmlnJDIscmFnZ2VkR2F0aGVyQ29uZmlnJDIscmFnZ2VkUmFuZ2VDb25maWckMixyYWdnZWRUZW5zb3JUb1RlbnNvckNvbmZpZyQyLHJhbmdlQ29uZmlnJDIscmVhbENvbmZpZyQyLHJlYWxEaXZDb25maWckMixyZWNpcHJvY2FsQ29uZmlnJDIscmVsdUNvbmZpZyQyLHJlbHU2Q29uZmlnJDIscmVzaGFwZUNvbmZpZyQyLHJlc2l6ZUJpbGluZWFyQ29uZmlnJDIscmVzaXplQmlsaW5lYXJHcmFkQ29uZmlnJDIscmVzaXplTmVhcmVzdE5laWdoYm9yQ29uZmlnJDIscmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZENvbmZpZyQyLHJldmVyc2VDb25maWckMixyb3RhdGVXaXRoT2Zmc2V0Q29uZmlnJDIscm91bmRDb25maWckMixyc3FydENvbmZpZyQyLHNjYXR0ZXJOZENvbmZpZyQyLHNlYXJjaFNvcnRlZENvbmZpZyQyLHNlbGVjdENvbmZpZyQyLHNlbHVDb25maWckMixzaWdtb2lkQ29uZmlnJDIsc2lnbkNvbmZpZyQyLHNpbkNvbmZpZyQyLHNpbmhDb25maWckMixzbGljZUNvbmZpZyQyLHNvZnRtYXhDb25maWckMixzb2Z0cGx1c0NvbmZpZyQyLHNwYWNlVG9CYXRjaE5EQ29uZmlnJDIsc3BhcnNlRmlsbEVtcHR5Um93c0NvbmZpZyQyLHNwYXJzZVJlc2hhcGVDb25maWckMixzcGFyc2VTZWdtZW50TWVhbkNvbmZpZyQyLHNwYXJzZVNlZ21lbnRTdW1Db25maWckMixzcGFyc2VUb0RlbnNlQ29uZmlnJDIsc3BsaXRWQ29uZmlnJDIsc3FydENvbmZpZyQyLHNxdWFyZUNvbmZpZyQyLHNxdWFyZWREaWZmZXJlbmNlQ29uZmlnJDIsc3RhdGljUmVnZXhSZXBsYWNlQ29uZmlnJDIsc3RlcENvbmZpZyQyLHN0cmlkZWRTbGljZUNvbmZpZyQyLHN0cmluZ05HcmFtc0NvbmZpZyQyLHN0cmluZ1NwbGl0Q29uZmlnJDIsc3RyaW5nVG9IYXNoQnVja2V0RmFzdENvbmZpZyQyLHN1YkNvbmZpZyQyLHN1bUNvbmZpZyQyLHRhbkNvbmZpZyQyLHRhbmhDb25maWckMix0ZW5zb3JTY2F0dGVyVXBkYXRlQ29uZmlnJDIsdGlsZUNvbmZpZyQyLHRvcEtDb25maWckMix0cmFuc2Zvcm1Db25maWckMix0cmFuc3Bvc2VDb25maWckMix1bmlxdWVDb25maWckMix1bnBhY2tDb25maWckMix1bnNvcnRlZFNlZ21lbnRTdW1Db25maWckMix6ZXJvc0xpa2VDb25maWckMl07Zm9yKGNvbnN0IGhhIG9mIGtlcm5lbENvbmZpZ3MkMilyZWdpc3Rlcktlcm5lbCQxKGhhKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjb250ZXh0cyQxPXt9LFdFQkdMX0FUVFJJQlVURVMkMT17YWxwaGE6ITEsYW50aWFsaWFzOiExLHByZW11bHRpcGxpZWRBbHBoYTohMSxwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6ITEsZGVwdGg6ITEsc3RlbmNpbDohMSxmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0OiEwfTtmdW5jdGlvbiBzZXRXZWJHTENvbnRleHQkMShoYSxhYSl7Y29udGV4dHMkMVtoYV09YWF9ZnVuY3Rpb24gZ2V0V2ViR0xDb250ZXh0JDEoaGEsYWEpe2lmKCEoaGEgaW4gY29udGV4dHMkMSl8fGFhIT1udWxsKXtjb25zdCBiYT1nZXRXZWJHTFJlbmRlcmluZ0NvbnRleHQkMShoYSxhYSk7aWYoYmEhPT1udWxsKWNvbnRleHRzJDFbaGFdPWJhO2Vsc2UgcmV0dXJuIGNvbnNvbGUubG9nKCJDb3VsZCBub3QgZ2V0IGNvbnRleHQgZm9yIFdlYkdMIHZlcnNpb24iLGhhKSxudWxsfWNvbnN0IHhhPWNvbnRleHRzJDFbaGFdO3JldHVybiB4YT09bnVsbHx8eGEuaXNDb250ZXh0TG9zdCgpPyhkZWxldGUgY29udGV4dHMkMVtoYV0sZ2V0V2ViR0xDb250ZXh0JDEoaGEpKTooeGEuZGlzYWJsZSh4YS5ERVBUSF9URVNUKSx4YS5kaXNhYmxlKHhhLlNURU5DSUxfVEVTVCkseGEuZGlzYWJsZSh4YS5CTEVORCkseGEuZGlzYWJsZSh4YS5ESVRIRVIpLHhhLmRpc2FibGUoeGEuUE9MWUdPTl9PRkZTRVRfRklMTCkseGEuZGlzYWJsZSh4YS5TQU1QTEVfQ09WRVJBR0UpLHhhLmVuYWJsZSh4YS5TQ0lTU09SX1RFU1QpLHhhLmVuYWJsZSh4YS5DVUxMX0ZBQ0UpLHhhLmN1bGxGYWNlKHhhLkJBQ0spLGNvbnRleHRzJDFbaGFdKX1mdW5jdGlvbiBjcmVhdGVDYW52YXMkMShoYSl7aWYoIWVudiQxKCkuZ2V0Qm9vbCgiSVNfU0FGQVJJIikmJnR5cGVvZiBPZmZzY3JlZW5DYW52YXM8InUiJiZoYT09PTIpcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMzAwLDE1MCk7aWYodHlwZW9mIGRvY3VtZW50PCJ1IilyZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2FudmFzIik7dGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgY3JlYXRlIGEgY2FudmFzIGluIHRoaXMgY29udGV4dCIpfWZ1bmN0aW9uIGdldFdlYkdMUmVuZGVyaW5nQ29udGV4dCQxKGhhLGFhKXtpZihoYSE9PTEmJmhhIT09Mil0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBnZXQgV2ViR0wgcmVuZGVyaW5nIGNvbnRleHQsIFdlYkdMIGlzIGRpc2FibGVkLiIpO2NvbnN0IHhhPWFhPz9jcmVhdGVDYW52YXMkMShoYSk7cmV0dXJuIHhhLmFkZEV2ZW50TGlzdGVuZXIoIndlYmdsY29udGV4dGxvc3QiLGJhPT57YmEucHJldmVudERlZmF1bHQoKSxkZWxldGUgY29udGV4dHMkMVtoYV19LCExKSxlbnYkMSgpLmdldEJvb2woIlNPRlRXQVJFX1dFQkdMX0VOQUJMRUQiKSYmKFdFQkdMX0FUVFJJQlVURVMkMS5mYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0PSExKSxoYT09PTE/eGEuZ2V0Q29udGV4dCgid2ViZ2wiLFdFQkdMX0FUVFJJQlVURVMkMSl8fHhhLmdldENvbnRleHQoImV4cGVyaW1lbnRhbC13ZWJnbCIsV0VCR0xfQVRUUklCVVRFUyQxKTp4YS5nZXRDb250ZXh0KCJ3ZWJnbDIiLFdFQkdMX0FUVFJJQlVURVMkMSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovdmFyIFBhY2tpbmdTY2hlbWUkMTsoZnVuY3Rpb24oaGEpe2hhW2hhLkRFTlNFPTBdPSJERU5TRSIsaGFbaGEuU0hBUkVEX0JBVENIPTFdPSJTSEFSRURfQkFUQ0gifSkoUGFja2luZ1NjaGVtZSQxfHwoUGFja2luZ1NjaGVtZSQxPXt9KSk7dmFyIFRleHR1cmVVc2FnZSQxOyhmdW5jdGlvbihoYSl7aGFbaGEuUkVOREVSPTBdPSJSRU5ERVIiLGhhW2hhLlVQTE9BRD0xXT0iVVBMT0FEIixoYVtoYS5QSVhFTFM9Ml09IlBJWEVMUyIsaGFbaGEuRE9XTkxPQUQ9M109IkRPV05MT0FEIn0pKFRleHR1cmVVc2FnZSQxfHwoVGV4dHVyZVVzYWdlJDE9e30pKTt2YXIgUGh5c2ljYWxUZXh0dXJlVHlwZSQxOyhmdW5jdGlvbihoYSl7aGFbaGEuVU5QQUNLRURfRkxPQVQxNj0wXT0iVU5QQUNLRURfRkxPQVQxNiIsaGFbaGEuVU5QQUNLRURfRkxPQVQzMj0xXT0iVU5QQUNLRURfRkxPQVQzMiIsaGFbaGEuUEFDS0VEXzRYMV9VTlNJR05FRF9CWVRFPTJdPSJQQUNLRURfNFgxX1VOU0lHTkVEX0JZVEUiLGhhW2hhLlBBQ0tFRF8yWDJfRkxPQVQzMj0zXT0iUEFDS0VEXzJYMl9GTE9BVDMyIixoYVtoYS5QQUNLRURfMlgyX0ZMT0FUMTY9NF09IlBBQ0tFRF8yWDJfRkxPQVQxNiJ9KShQaHlzaWNhbFRleHR1cmVUeXBlJDF8fChQaHlzaWNhbFRleHR1cmVUeXBlJDE9e30pKTtmdW5jdGlvbiBnZXRVbnBhY2tlZE1hdHJpeFRleHR1cmVTaGFwZVdpZHRoSGVpZ2h0JDEoaGEsYWEpe3JldHVyblthYSxoYV19ZnVuY3Rpb24gZ2V0VW5wYWNrZWRBcnJheVNpemVGcm9tTWF0cml4U2l6ZSQxKGhhLGFhKXtyZXR1cm4gaGEqYWF9ZnVuY3Rpb24gZ2V0RGVuc2VUZXhTaGFwZSQxKGhhKXtjb25zdCBhYT1zaXplRnJvbVNoYXBlJDEoaGEpLHhhPU1hdGguY2VpbChhYS80KTtyZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZSQxKHhhKX1mdW5jdGlvbiBnZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodCQxKGhhLGFhKXtyZXR1cm5bTWF0aC5tYXgoMSxNYXRoLmNlaWwoYWEvMikpLE1hdGgubWF4KDEsTWF0aC5jZWlsKGhhLzIpKV19ZnVuY3Rpb24gZ2V0UGFja2VkUkdCQUFycmF5U2l6ZUZyb21NYXRyaXhTaGFwZSQxKGhhLGFhKXtjb25zdFt4YSxiYV09Z2V0UGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQkMShoYSxhYSk7cmV0dXJuIHhhKmJhKjR9ZnVuY3Rpb24gZ2V0VGV4dHVyZUNvbmZpZyQxKGhhLGFhKXtjb25zdCB4YT1oYTtsZXQgYmEsU2EsVGEsd2EsRWEsa2EsQWEsRmEsTGEsZWw7cmV0dXJuIGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yPyhiYT14YS5SMzJGLFNhPXhhLlIxNkYsVGE9eGEuUkdCQTE2Rix3YT14YS5SR0JBMzJGLEVhPXhhLlJFRCxBYT00LEZhPTEsTGE9eGEuSEFMRl9GTE9BVCxlbD14YS5GTE9BVCxrYT14YS5SR0JBOCk6KGJhPWhhLlJHQkEsU2E9aGEuUkdCQSxUYT1oYS5SR0JBLHdhPXhhLlJHQkEsRWE9aGEuUkdCQSxBYT00LEZhPTQsTGE9YWEhPW51bGw/YWEuSEFMRl9GTE9BVF9PRVM6bnVsbCxlbD1oYS5GTE9BVCxrYT1oYS5SR0JBKSx7aW50ZXJuYWxGb3JtYXRGbG9hdDpiYSxpbnRlcm5hbEZvcm1hdEhhbGZGbG9hdDpTYSxpbnRlcm5hbEZvcm1hdFBhY2tlZEhhbGZGbG9hdDpUYSxpbnRlcm5hbEZvcm1hdFBhY2tlZEZsb2F0OndhLHRleHR1cmVGb3JtYXRGbG9hdDpFYSxkb3dubG9hZFRleHR1cmVGb3JtYXQ6a2EsZG93bmxvYWRVbnBhY2tOdW1DaGFubmVsczpBYSxkZWZhdWx0TnVtQ2hhbm5lbHM6RmEsdGV4dHVyZVR5cGVIYWxmRmxvYXQ6TGEsdGV4dHVyZVR5cGVGbG9hdDplbH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2FsbEFuZENoZWNrJDEoaGEsYWEpe2NvbnN0IHhhPWFhKCk7cmV0dXJuIGVudiQxKCkuZ2V0Qm9vbCgiREVCVUciKSYmY2hlY2tXZWJHTEVycm9yJDEoaGEpLHhhfWZ1bmN0aW9uIGNoZWNrV2ViR0xFcnJvciQxKGhhKXtjb25zdCBhYT1oYS5nZXRFcnJvcigpO2lmKGFhIT09aGEuTk9fRVJST1IpdGhyb3cgbmV3IEVycm9yKCJXZWJHTCBFcnJvcjogIitnZXRXZWJHTEVycm9yTWVzc2FnZSQxKGhhLGFhKSl9Y29uc3QgTUlOX0ZMT0FUMTYkMT01OTZlLTEwLE1BWF9GTE9BVDE2JDE9NjU1MDQ7ZnVuY3Rpb24gY2FuQmVSZXByZXNlbnRlZCQxKGhhKXtyZXR1cm4hIShlbnYkMSgpLmdldEJvb2woIldFQkdMX1JFTkRFUl9GTE9BVDMyX0VOQUJMRUQiKXx8aGE9PT0wfHxNSU5fRkxPQVQxNiQxPE1hdGguYWJzKGhhKSYmTWF0aC5hYnMoaGEpPE1BWF9GTE9BVDE2JDEpfWZ1bmN0aW9uIGdldFdlYkdMRXJyb3JNZXNzYWdlJDEoaGEsYWEpe3N3aXRjaChhYSl7Y2FzZSBoYS5OT19FUlJPUjpyZXR1cm4iTk9fRVJST1IiO2Nhc2UgaGEuSU5WQUxJRF9FTlVNOnJldHVybiJJTlZBTElEX0VOVU0iO2Nhc2UgaGEuSU5WQUxJRF9WQUxVRTpyZXR1cm4iSU5WQUxJRF9WQUxVRSI7Y2FzZSBoYS5JTlZBTElEX09QRVJBVElPTjpyZXR1cm4iSU5WQUxJRF9PUEVSQVRJT04iO2Nhc2UgaGEuSU5WQUxJRF9GUkFNRUJVRkZFUl9PUEVSQVRJT046cmV0dXJuIklOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OIjtjYXNlIGhhLk9VVF9PRl9NRU1PUlk6cmV0dXJuIk9VVF9PRl9NRU1PUlkiO2Nhc2UgaGEuQ09OVEVYVF9MT1NUX1dFQkdMOnJldHVybiJDT05URVhUX0xPU1RfV0VCR0wiO2RlZmF1bHQ6cmV0dXJuYFVua25vd24gZXJyb3IgY29kZSAke2FhfWB9fWZ1bmN0aW9uIGdldEV4dGVuc2lvbk9yVGhyb3ckMShoYSxhYSl7cmV0dXJuIHRocm93SWZOdWxsJDEoaGEsKCk9PmhhLmdldEV4dGVuc2lvbihhYSksJ0V4dGVuc2lvbiAiJythYSsnIiBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYnJvd3Nlci4nKX1mdW5jdGlvbiBjcmVhdGVWZXJ0ZXhTaGFkZXIkMyhoYSxhYSl7Y29uc3QgeGE9dGhyb3dJZk51bGwkMShoYSwoKT0+aGEuY3JlYXRlU2hhZGVyKGhhLlZFUlRFWF9TSEFERVIpLCJVbmFibGUgdG8gY3JlYXRlIHZlcnRleCBXZWJHTFNoYWRlci4iKTtpZihjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuc2hhZGVyU291cmNlKHhhLGFhKSksY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmNvbXBpbGVTaGFkZXIoeGEpKSxoYS5nZXRTaGFkZXJQYXJhbWV0ZXIoeGEsaGEuQ09NUElMRV9TVEFUVVMpPT09ITEpdGhyb3cgY29uc29sZS5sb2coaGEuZ2V0U2hhZGVySW5mb0xvZyh4YSkpLG5ldyBFcnJvcigiRmFpbGVkIHRvIGNvbXBpbGUgdmVydGV4IHNoYWRlci4iKTtyZXR1cm4geGF9ZnVuY3Rpb24gY3JlYXRlRnJhZ21lbnRTaGFkZXIkMShoYSxhYSl7Y29uc3QgeGE9dGhyb3dJZk51bGwkMShoYSwoKT0+aGEuY3JlYXRlU2hhZGVyKGhhLkZSQUdNRU5UX1NIQURFUiksIlVuYWJsZSB0byBjcmVhdGUgZnJhZ21lbnQgV2ViR0xTaGFkZXIuIik7aWYoY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLnNoYWRlclNvdXJjZSh4YSxhYSkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5jb21waWxlU2hhZGVyKHhhKSksZW52JDEoKS5nZXQoIkVOR0lORV9DT01QSUxFX09OTFkiKSlyZXR1cm4geGE7aWYoaGEuZ2V0U2hhZGVyUGFyYW1ldGVyKHhhLGhhLkNPTVBJTEVfU1RBVFVTKT09PSExKXRocm93IGxvZ1NoYWRlclNvdXJjZUFuZEluZm9Mb2ckMShhYSxoYS5nZXRTaGFkZXJJbmZvTG9nKHhhKSksbmV3IEVycm9yKCJGYWlsZWQgdG8gY29tcGlsZSBmcmFnbWVudCBzaGFkZXIuIik7cmV0dXJuIHhhfWNvbnN0IGxpbmVOdW1iZXJSZWdleCQxPS9FUlJPUjogWzAtOV0rOihbMC05XSspOi9nO2Z1bmN0aW9uIGxvZ1NoYWRlclNvdXJjZUFuZEluZm9Mb2ckMShoYSxhYSl7Y29uc3QgeGE9bGluZU51bWJlclJlZ2V4JDEuZXhlYyhhYSk7aWYoeGE9PW51bGwpe2NvbnNvbGUubG9nKGBDb3VsZG4ndCBwYXJzZSBsaW5lIG51bWJlciBpbiBlcnJvcjogJHthYX1gKSxjb25zb2xlLmxvZyhoYSk7cmV0dXJufWNvbnN0IGJhPSt4YVsxXSxTYT1oYS5zcGxpdChgCmApLFRhPVNhLmxlbmd0aC50b1N0cmluZygpLmxlbmd0aCsyLHdhPVNhLm1hcCgoTGEsZWwpPT5yaWdodFBhZCQxKChlbCsxKS50b1N0cmluZygpLFRhKStMYSk7bGV0IEVhPTA7Zm9yKGxldCBMYT0wO0xhPHdhLmxlbmd0aDtMYSsrKUVhPU1hdGgubWF4KHdhW0xhXS5sZW5ndGgsRWEpO2NvbnN0IGthPXdhLnNsaWNlKDAsYmEtMSksQWE9d2Euc2xpY2UoYmEtMSxiYSksRmE9d2Euc2xpY2UoYmEpO2NvbnNvbGUubG9nKGthLmpvaW4oYApgKSksY29uc29sZS5sb2coYWEuc3BsaXQoYApgKVswXSksY29uc29sZS5sb2coYCVjICR7cmlnaHRQYWQkMShBYVswXSxFYSl9YCwiYm9yZGVyOjFweCBzb2xpZCByZWQ7IGJhY2tncm91bmQtY29sb3I6I2UzZDJkMjsgY29sb3I6I2E2MTcxNyIpLGNvbnNvbGUubG9nKEZhLmpvaW4oYApgKSl9ZnVuY3Rpb24gY3JlYXRlUHJvZ3JhbSQxKGhhKXtyZXR1cm4gdGhyb3dJZk51bGwkMShoYSwoKT0+aGEuY3JlYXRlUHJvZ3JhbSgpLCJVbmFibGUgdG8gY3JlYXRlIFdlYkdMUHJvZ3JhbS4iKX1mdW5jdGlvbiBsaW5rUHJvZ3JhbSQxKGhhLGFhKXtpZihjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEubGlua1Byb2dyYW0oYWEpKSwhZW52JDEoKS5nZXQoIkVOR0lORV9DT01QSUxFX09OTFkiKSYmaGEuZ2V0UHJvZ3JhbVBhcmFtZXRlcihhYSxoYS5MSU5LX1NUQVRVUyk9PT0hMSl0aHJvdyBjb25zb2xlLmxvZyhoYS5nZXRQcm9ncmFtSW5mb0xvZyhhYSkpLG5ldyBFcnJvcigiRmFpbGVkIHRvIGxpbmsgdmVydGV4IGFuZCBmcmFnbWVudCBzaGFkZXJzLiIpfWZ1bmN0aW9uIHZhbGlkYXRlUHJvZ3JhbSQxKGhhLGFhKXtpZihjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEudmFsaWRhdGVQcm9ncmFtKGFhKSksaGEuZ2V0UHJvZ3JhbVBhcmFtZXRlcihhYSxoYS5WQUxJREFURV9TVEFUVVMpPT09ITEpdGhyb3cgY29uc29sZS5sb2coaGEuZ2V0UHJvZ3JhbUluZm9Mb2coYWEpKSxuZXcgRXJyb3IoIlNoYWRlciBwcm9ncmFtIHZhbGlkYXRpb24gZmFpbGVkLiIpfWZ1bmN0aW9uIGNyZWF0ZVN0YXRpY1ZlcnRleEJ1ZmZlciQxKGhhLGFhKXtjb25zdCB4YT10aHJvd0lmTnVsbCQxKGhhLCgpPT5oYS5jcmVhdGVCdWZmZXIoKSwiVW5hYmxlIHRvIGNyZWF0ZSBXZWJHTEJ1ZmZlciIpO3JldHVybiBjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuYmluZEJ1ZmZlcihoYS5BUlJBWV9CVUZGRVIseGEpKSxjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuYnVmZmVyRGF0YShoYS5BUlJBWV9CVUZGRVIsYWEsaGEuU1RBVElDX0RSQVcpKSx4YX1mdW5jdGlvbiBjcmVhdGVTdGF0aWNJbmRleEJ1ZmZlciQxKGhhLGFhKXtjb25zdCB4YT10aHJvd0lmTnVsbCQxKGhhLCgpPT5oYS5jcmVhdGVCdWZmZXIoKSwiVW5hYmxlIHRvIGNyZWF0ZSBXZWJHTEJ1ZmZlciIpO3JldHVybiBjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuYmluZEJ1ZmZlcihoYS5FTEVNRU5UX0FSUkFZX0JVRkZFUix4YSkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5idWZmZXJEYXRhKGhhLkVMRU1FTlRfQVJSQVlfQlVGRkVSLGFhLGhhLlNUQVRJQ19EUkFXKSkseGF9ZnVuY3Rpb24gY3JlYXRlVGV4dHVyZSQxKGhhKXtyZXR1cm4gdGhyb3dJZk51bGwkMShoYSwoKT0+aGEuY3JlYXRlVGV4dHVyZSgpLCJVbmFibGUgdG8gY3JlYXRlIFdlYkdMVGV4dHVyZS4iKX1mdW5jdGlvbiB2YWxpZGF0ZVRleHR1cmVTaXplJDEoaGEsYWEpe2NvbnN0IHhhPWVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9NQVhfVEVYVFVSRV9TSVpFIik7aWYoaGE8PTB8fGFhPD0wKXtjb25zdCBiYT1gWyR7aGF9eCR7YWF9XWA7dGhyb3cgbmV3IEVycm9yKCJSZXF1ZXN0ZWQgdGV4dHVyZSBzaXplICIrYmErIiBpcyBpbnZhbGlkLiIpfWlmKGhhPnhhfHxhYT54YSl7Y29uc3QgYmE9YFske2hhfXgke2FhfV1gLFNhPWBbJHt4YX14JHt4YX1dYDt0aHJvdyBuZXcgRXJyb3IoIlJlcXVlc3RlZCB0ZXh0dXJlIHNpemUgIitiYSsiIGdyZWF0ZXIgdGhhbiBXZWJHTCBtYXhpbXVtIG9uIHRoaXMgYnJvd3NlciAvIEdQVSAiK1NhKyIuIil9fWZ1bmN0aW9uIGNyZWF0ZUZyYW1lYnVmZmVyJDEoaGEpe3JldHVybiB0aHJvd0lmTnVsbCQxKGhhLCgpPT5oYS5jcmVhdGVGcmFtZWJ1ZmZlcigpLCJVbmFibGUgdG8gY3JlYXRlIFdlYkdMRnJhbWVidWZmZXIuIil9ZnVuY3Rpb24gYmluZFZlcnRleEJ1ZmZlclRvUHJvZ3JhbUF0dHJpYnV0ZSQxKGhhLGFhLHhhLGJhLFNhLFRhLHdhKXtjb25zdCBFYT1oYS5nZXRBdHRyaWJMb2NhdGlvbihhYSx4YSk7cmV0dXJuIEVhPT09LTE/ITE6KGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5iaW5kQnVmZmVyKGhhLkFSUkFZX0JVRkZFUixiYSkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS52ZXJ0ZXhBdHRyaWJQb2ludGVyKEVhLFNhLGhhLkZMT0FULCExLFRhLHdhKSksY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KEVhKSksITApfWZ1bmN0aW9uIGJpbmRUZXh0dXJlVW5pdCQxKGhhLGFhLHhhKXt2YWxpZGF0ZVRleHR1cmVVbml0JDEoaGEseGEpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5hY3RpdmVUZXh0dXJlKGhhLlRFWFRVUkUwK3hhKSksY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsYWEpKX1mdW5jdGlvbiBnZXRQcm9ncmFtVW5pZm9ybUxvY2F0aW9uT3JUaHJvdyQxKGhhLGFhLHhhKXtyZXR1cm4gdGhyb3dJZk51bGwkMShoYSwoKT0+aGEuZ2V0VW5pZm9ybUxvY2F0aW9uKGFhLHhhKSwndW5pZm9ybSAiJyt4YSsnIiBub3QgcHJlc2VudCBpbiBwcm9ncmFtLicpfWZ1bmN0aW9uIGdldFByb2dyYW1Vbmlmb3JtTG9jYXRpb24kMShoYSxhYSx4YSl7cmV0dXJuIGhhLmdldFVuaWZvcm1Mb2NhdGlvbihhYSx4YSl9ZnVuY3Rpb24gYmluZFRleHR1cmVUb1Byb2dyYW1Vbmlmb3JtU2FtcGxlciQxKGhhLGFhLHhhLGJhKXtjYWxsQW5kQ2hlY2skMShoYSwoKT0+YmluZFRleHR1cmVVbml0JDEoaGEsYWEsYmEpKSxjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEudW5pZm9ybTFpKHhhLGJhKSl9ZnVuY3Rpb24gYmluZENvbG9yVGV4dHVyZVRvRnJhbWVidWZmZXIkMShoYSxhYSx4YSl7Y2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmJpbmRGcmFtZWJ1ZmZlcihoYS5GUkFNRUJVRkZFUix4YSkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5mcmFtZWJ1ZmZlclRleHR1cmUyRChoYS5GUkFNRUJVRkZFUixoYS5DT0xPUl9BVFRBQ0hNRU5UMCxoYS5URVhUVVJFXzJELGFhLDApKX1mdW5jdGlvbiB1bmJpbmRDb2xvclRleHR1cmVGcm9tRnJhbWVidWZmZXIkMShoYSxhYSl7Y2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmJpbmRGcmFtZWJ1ZmZlcihoYS5GUkFNRUJVRkZFUixhYSkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5mcmFtZWJ1ZmZlclRleHR1cmUyRChoYS5GUkFNRUJVRkZFUixoYS5DT0xPUl9BVFRBQ0hNRU5UMCxoYS5URVhUVVJFXzJELG51bGwsMCkpfWZ1bmN0aW9uIHZhbGlkYXRlRnJhbWVidWZmZXIkMShoYSl7Y29uc3QgYWE9aGEuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhoYS5GUkFNRUJVRkZFUik7aWYoYWEhPT1oYS5GUkFNRUJVRkZFUl9DT01QTEVURSl0aHJvdyBuZXcgRXJyb3IoIkVycm9yIGJpbmRpbmcgZnJhbWVidWZmZXI6ICIrZ2V0RnJhbWVidWZmZXJFcnJvck1lc3NhZ2UkMShoYSxhYSkpfWZ1bmN0aW9uIGdldEZyYW1lYnVmZmVyRXJyb3JNZXNzYWdlJDEoaGEsYWEpe3N3aXRjaChhYSl7Y2FzZSBoYS5GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0FUVEFDSE1FTlQ6cmV0dXJuIkZSQU1FQlVGRkVSX0lOQ09NUExFVEVfQVRUQUNITUVOVCI7Y2FzZSBoYS5GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX01JU1NJTkdfQVRUQUNITUVOVDpyZXR1cm4iRlJBTUVCVUZGRVJfSU5DT01QTEVURV9NSVNTSU5HX0FUVEFDSE1FTlQiO2Nhc2UgaGEuRlJBTUVCVUZGRVJfSU5DT01QTEVURV9ESU1FTlNJT05TOnJldHVybiJGUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0RJTUVOU0lPTlMiO2Nhc2UgaGEuRlJBTUVCVUZGRVJfVU5TVVBQT1JURUQ6cmV0dXJuIkZSQU1FQlVGRkVSX1VOU1VQUE9SVEVEIjtkZWZhdWx0OnJldHVybmB1bmtub3duIGVycm9yICR7YWF9YH19ZnVuY3Rpb24gdGhyb3dJZk51bGwkMShoYSxhYSx4YSl7Y29uc3QgYmE9Y2FsbEFuZENoZWNrJDEoaGEsKCk9PmFhKCkpO2lmKGJhPT1udWxsKXRocm93IG5ldyBFcnJvcih4YSk7cmV0dXJuIGJhfWZ1bmN0aW9uIHZhbGlkYXRlVGV4dHVyZVVuaXQkMShoYSxhYSl7Y29uc3QgeGE9aGEuTUFYX0NPTUJJTkVEX1RFWFRVUkVfSU1BR0VfVU5JVFMtMSxiYT1hYStoYS5URVhUVVJFMDtpZihiYTxoYS5URVhUVVJFMHx8YmE+eGEpe2NvbnN0IFNhPWBbZ2wuVEVYVFVSRTAsIGdsLlRFWFRVUkUke3hhfV1gO3Rocm93IG5ldyBFcnJvcihgdGV4dHVyZVVuaXQgbXVzdCBiZSBpbiAke1NhfS5gKX19ZnVuY3Rpb24gZ2V0QmF0Y2hEaW0kMShoYSxhYT0yKXtyZXR1cm4gc2l6ZUZyb21TaGFwZSQxKGhhLnNsaWNlKDAsaGEubGVuZ3RoLWFhKSl9ZnVuY3Rpb24gZ2V0Um93c0NvbHMkMShoYSl7aWYoaGEubGVuZ3RoPT09MCl0aHJvdyBFcnJvcigiQ2Fubm90IGdldCByb3dzIGFuZCBjb2x1bW5zIG9mIGFuIGVtcHR5IHNoYXBlIGFycmF5LiIpO3JldHVybltoYS5sZW5ndGg+MT9oYVtoYS5sZW5ndGgtMl06MSxoYVtoYS5sZW5ndGgtMV1dfWZ1bmN0aW9uIGdldFNoYXBlQXMzRCQxKGhhKXtsZXQgYWE9WzEsMSwxXTtyZXR1cm4gaGEubGVuZ3RoPT09MHx8aGEubGVuZ3RoPT09MSYmaGFbMF09PT0xfHwoYWE9W2dldEJhdGNoRGltJDEoaGEpLC4uLmdldFJvd3NDb2xzJDEoaGEpXSksYWF9ZnVuY3Rpb24gZ2V0VGV4dHVyZVNoYXBlRnJvbUxvZ2ljYWxTaGFwZSQxKGhhLGFhPSExKXtsZXQgeGE9ZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX01BWF9URVhUVVJFX1NJWkUiKSxiYT1lbnYkMSgpLmdldE51bWJlcigiV0VCR0xfTUFYX1NJWkVfRk9SX05BUlJPV19URVhUVVJFIik7YmE9PT0xLzAmJmVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfQVVUT19TUVVBUklGWV9OQVJST1dfVEVYVFVSRV9TSEFQRSIpJiYoYmE9eGEvMiksYWEmJih4YT14YSoyLGJhPWJhKjIsaGE9aGEubWFwKChFYSxrYSk9PmthPj1oYS5sZW5ndGgtMj9uZWFyZXN0TGFyZ2VyRXZlbiQxKGhhW2thXSk6aGFba2FdKSxoYS5sZW5ndGg9PT0xJiYoaGE9WzIsaGFbMF1dKSksaGEubGVuZ3RoIT09MiYmKGhhPXNxdWVlemVTaGFwZSQxKGhhKS5uZXdTaGFwZSk7bGV0IFNhPXNpemVGcm9tU2hhcGUkMShoYSksVGE9bnVsbDtoYS5sZW5ndGg8PTEmJlNhPD14YT9UYT1bMSxTYV06aGEubGVuZ3RoPT09MiYmaGFbMF08PXhhJiZoYVsxXTw9eGE/VGE9aGE6aGEubGVuZ3RoPT09MyYmaGFbMF0qaGFbMV08PXhhJiZoYVsyXTw9eGE/VGE9W2hhWzBdKmhhWzFdLGhhWzJdXTpoYS5sZW5ndGg9PT0zJiZoYVswXTw9eGEmJmhhWzFdKmhhWzJdPD14YT9UYT1baGFbMF0saGFbMV0qaGFbMl1dOmhhLmxlbmd0aD09PTQmJmhhWzBdKmhhWzFdKmhhWzJdPD14YSYmaGFbM108PXhhP1RhPVtoYVswXSpoYVsxXSpoYVsyXSxoYVszXV06aGEubGVuZ3RoPT09NCYmaGFbMF08PXhhJiZoYVsxXSpoYVsyXSpoYVszXTw9eGEmJihUYT1baGFbMF0saGFbMV0qaGFbMl0qaGFbM11dKTtjb25zdCB3YT1UYSE9bnVsbCYmTWF0aC5tYXgoLi4uVGEpPmJhJiZNYXRoLm1pbiguLi5UYSk8PShhYT8yOjEpJiZNYXRoLm1pbiguLi5UYSk+MDtpZihUYT09bnVsbHx8d2EpaWYoYWEpe2NvbnN0IEVhPWdldEJhdGNoRGltJDEoaGEpO2xldCBrYT0yLEFhPTI7aGEubGVuZ3RoJiYoW2thLEFhXT1nZXRSb3dzQ29scyQxKGhhKSksU2E9RWEqKGthLzIpKihBYS8yKSxUYT1zaXplVG9TcXVhcmlzaFNoYXBlJDEoU2EpLm1hcChGYT0+RmEqMil9ZWxzZSBUYT1zaXplVG9TcXVhcmlzaFNoYXBlJDEoU2EpO3JldHVybiBUYX1mdW5jdGlvbiBpc0V2ZW4kMShoYSl7cmV0dXJuIGhhJTI9PT0wfWZ1bmN0aW9uIGlzUmVzaGFwZUZyZWUkMShoYSxhYSl7aWYoaGE9aGEuc2xpY2UoLTIpLGFhPWFhLnNsaWNlKC0yKSxhcnJheXNFcXVhbCQxKGhhLGFhKXx8IWhhLmxlbmd0aHx8IWFhLmxlbmd0aHx8aGFbMF09PT0wfHxoYVsxXT09PTB8fGFhWzBdPT09MHx8YWFbMV09PT0wKXJldHVybiEwO2lmKGhhLmxlbmd0aCE9PWFhLmxlbmd0aCl7Y29uc3QgeGE9aGFbaGEubGVuZ3RoLTFdLGJhPWFhW2FhLmxlbmd0aC0xXTtpZih4YT09PWJhfHxpc0V2ZW4kMSh4YSkmJmlzRXZlbiQxKGJhKSYmKGhhWzBdPT09MXx8YWFbMF09PT0xKSlyZXR1cm4hMH1yZXR1cm4gaGFbMV09PT1hYVsxXSYmaXNFdmVuJDEoaGFbMF0pJiZpc0V2ZW4kMShhYVswXSl9bGV0IE1BWF9URVhUVVJFX1NJWkUkMSxNQVhfVEVYVFVSRVNfSU5fU0hBREVSJDE7ZnVuY3Rpb24gZ2V0V2ViR0xNYXhUZXh0dXJlU2l6ZSQxKGhhKXtpZihNQVhfVEVYVFVSRV9TSVpFJDE9PW51bGwpe2NvbnN0IGFhPWdldFdlYkdMQ29udGV4dCQxKGhhKTtNQVhfVEVYVFVSRV9TSVpFJDE9YWEuZ2V0UGFyYW1ldGVyKGFhLk1BWF9URVhUVVJFX1NJWkUpfXJldHVybiBNQVhfVEVYVFVSRV9TSVpFJDF9ZnVuY3Rpb24gZ2V0TWF4VGV4dHVyZXNJblNoYWRlciQxKGhhKXtpZihNQVhfVEVYVFVSRVNfSU5fU0hBREVSJDE9PW51bGwpe2NvbnN0IGFhPWdldFdlYkdMQ29udGV4dCQxKGhhKTtNQVhfVEVYVFVSRVNfSU5fU0hBREVSJDE9YWEuZ2V0UGFyYW1ldGVyKGFhLk1BWF9URVhUVVJFX0lNQUdFX1VOSVRTKX1yZXR1cm4gTWF0aC5taW4oMTYsTUFYX1RFWFRVUkVTX0lOX1NIQURFUiQxKX1mdW5jdGlvbiBnZXRXZWJHTERpc2pvaW50UXVlcnlUaW1lclZlcnNpb24kMShoYSl7aWYoaGE9PT0wKXJldHVybiAwO2xldCBhYTtjb25zdCB4YT1nZXRXZWJHTENvbnRleHQkMShoYSk7cmV0dXJuIGhhc0V4dGVuc2lvbiQxKHhhLCJFWFRfZGlzam9pbnRfdGltZXJfcXVlcnlfd2ViZ2wyIikmJmhhPT09Mj9hYT0yOmhhc0V4dGVuc2lvbiQxKHhhLCJFWFRfZGlzam9pbnRfdGltZXJfcXVlcnkiKT9hYT0xOmFhPTAsYWF9ZnVuY3Rpb24gaGFzRXh0ZW5zaW9uJDEoaGEsYWEpe3JldHVybiBoYS5nZXRFeHRlbnNpb24oYWEpIT1udWxsfWZ1bmN0aW9uIGlzV2ViR0xWZXJzaW9uRW5hYmxlZCQxKGhhKXt0cnl7aWYoZ2V0V2ViR0xDb250ZXh0JDEoaGEpIT1udWxsKXJldHVybiEwfWNhdGNoKGFhKXtyZXR1cm4gY29uc29sZS5sb2coIkVycm9yIHdoZW4gZ2V0dGluZyBXZWJHTCBjb250ZXh0OiAiLGFhKSwhMX1yZXR1cm4hMX1mdW5jdGlvbiBpc0NhcGFibGVPZlJlbmRlcmluZ1RvRmxvYXRUZXh0dXJlJDEoaGEpe2lmKGhhPT09MClyZXR1cm4hMTtjb25zdCBhYT1nZXRXZWJHTENvbnRleHQkMShoYSk7aWYoaGE9PT0xKXtpZighaGFzRXh0ZW5zaW9uJDEoYWEsIk9FU190ZXh0dXJlX2Zsb2F0IikpcmV0dXJuITF9ZWxzZSBpZighaGFzRXh0ZW5zaW9uJDEoYWEsIkVYVF9jb2xvcl9idWZmZXJfZmxvYXQiKSlyZXR1cm4hMTtyZXR1cm4gY3JlYXRlRmxvYXRUZXh0dXJlQW5kQmluZFRvRnJhbWVidWZmZXIkMShhYSl9ZnVuY3Rpb24gaXNEb3dubG9hZEZsb2F0VGV4dHVyZUVuYWJsZWQkMShoYSl7aWYoaGE9PT0wKXJldHVybiExO2NvbnN0IGFhPWdldFdlYkdMQ29udGV4dCQxKGhhKTtpZihoYT09PTEpe2lmKCFoYXNFeHRlbnNpb24kMShhYSwiT0VTX3RleHR1cmVfZmxvYXQiKXx8IWhhc0V4dGVuc2lvbiQxKGFhLCJXRUJHTF9jb2xvcl9idWZmZXJfZmxvYXQiKSlyZXR1cm4hMX1lbHNle2lmKGhhc0V4dGVuc2lvbiQxKGFhLCJFWFRfY29sb3JfYnVmZmVyX2Zsb2F0IikpcmV0dXJuIGNyZWF0ZUZsb2F0VGV4dHVyZUFuZEJpbmRUb0ZyYW1lYnVmZmVyJDEoYWEpO2NvbnN0IGJhPSJFWFRfY29sb3JfYnVmZmVyX2hhbGZfZmxvYXQiO2lmKGhhc0V4dGVuc2lvbiQxKGFhLGJhKSl7Y29uc3QgU2E9YWEuZ2V0RXh0ZW5zaW9uKGJhKTtyZXR1cm4gY3JlYXRlSGFsZkZsb2F0VGV4dHVyZUFuZEJpbmRUb0ZyYW1lYnVmZmVyJDEoYWEsU2EpfXJldHVybiExfXJldHVybiBjcmVhdGVGbG9hdFRleHR1cmVBbmRCaW5kVG9GcmFtZWJ1ZmZlciQxKGFhKX1mdW5jdGlvbiBjcmVhdGVGbG9hdFRleHR1cmVBbmRCaW5kVG9GcmFtZWJ1ZmZlciQxKGhhKXtjb25zdCBhYT1nZXRUZXh0dXJlQ29uZmlnJDEoaGEpLHhhPWhhLmNyZWF0ZVRleHR1cmUoKTtoYS5iaW5kVGV4dHVyZShoYS5URVhUVVJFXzJELHhhKSxoYS50ZXhJbWFnZTJEKGhhLlRFWFRVUkVfMkQsMCxhYS5pbnRlcm5hbEZvcm1hdEZsb2F0LDEsMSwwLGFhLnRleHR1cmVGb3JtYXRGbG9hdCxhYS50ZXh0dXJlVHlwZUZsb2F0LG51bGwpO2NvbnN0IFRhPWhhLmNyZWF0ZUZyYW1lYnVmZmVyKCk7aGEuYmluZEZyYW1lYnVmZmVyKGhhLkZSQU1FQlVGRkVSLFRhKSxoYS5mcmFtZWJ1ZmZlclRleHR1cmUyRChoYS5GUkFNRUJVRkZFUixoYS5DT0xPUl9BVFRBQ0hNRU5UMCxoYS5URVhUVVJFXzJELHhhLDApO2NvbnN0IHdhPWhhLmNoZWNrRnJhbWVidWZmZXJTdGF0dXMoaGEuRlJBTUVCVUZGRVIpPT09aGEuRlJBTUVCVUZGRVJfQ09NUExFVEU7cmV0dXJuIGhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsbnVsbCksaGEuYmluZEZyYW1lYnVmZmVyKGhhLkZSQU1FQlVGRkVSLG51bGwpLGhhLmRlbGV0ZVRleHR1cmUoeGEpLGhhLmRlbGV0ZUZyYW1lYnVmZmVyKFRhKSx3YX1mdW5jdGlvbiBjcmVhdGVIYWxmRmxvYXRUZXh0dXJlQW5kQmluZFRvRnJhbWVidWZmZXIkMShoYSxhYSl7Y29uc3QgeGE9Z2V0VGV4dHVyZUNvbmZpZyQxKGhhLGFhKSxiYT1oYS5jcmVhdGVUZXh0dXJlKCk7aGEuYmluZFRleHR1cmUoaGEuVEVYVFVSRV8yRCxiYSksaGEudGV4SW1hZ2UyRChoYS5URVhUVVJFXzJELDAseGEuaW50ZXJuYWxGb3JtYXRIYWxmRmxvYXQsMSwxLDAseGEudGV4dHVyZUZvcm1hdEZsb2F0LHhhLnRleHR1cmVUeXBlSGFsZkZsb2F0LG51bGwpO2NvbnN0IHdhPWhhLmNyZWF0ZUZyYW1lYnVmZmVyKCk7aGEuYmluZEZyYW1lYnVmZmVyKGhhLkZSQU1FQlVGRkVSLHdhKSxoYS5mcmFtZWJ1ZmZlclRleHR1cmUyRChoYS5GUkFNRUJVRkZFUixoYS5DT0xPUl9BVFRBQ0hNRU5UMCxoYS5URVhUVVJFXzJELGJhLDApO2NvbnN0IEVhPWhhLmNoZWNrRnJhbWVidWZmZXJTdGF0dXMoaGEuRlJBTUVCVUZGRVIpPT09aGEuRlJBTUVCVUZGRVJfQ09NUExFVEU7cmV0dXJuIGhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsbnVsbCksaGEuYmluZEZyYW1lYnVmZmVyKGhhLkZSQU1FQlVGRkVSLG51bGwpLGhhLmRlbGV0ZVRleHR1cmUoYmEpLGhhLmRlbGV0ZUZyYW1lYnVmZmVyKHdhKSxFYX1mdW5jdGlvbiBpc1dlYkdMRmVuY2VFbmFibGVkJDEoaGEpe3JldHVybiBoYSE9PTI/ITE6Z2V0V2ViR0xDb250ZXh0JDEoaGEpLmZlbmNlU3luYyE9bnVsbH1mdW5jdGlvbiBhc3NlcnROb3RDb21wbGV4JDEoaGEsYWEpe0FycmF5LmlzQXJyYXkoaGEpfHwoaGE9W2hhXSksaGEuZm9yRWFjaCh4YT0+e3hhIT1udWxsJiZhc3NlcnQkMih4YS5kdHlwZSE9PSJjb21wbGV4NjQiLCgpPT5gJHthYX0gZG9lcyBub3Qgc3VwcG9ydCBjb21wbGV4NjQgdGVuc29ycyBpbiB0aGUgV2ViR0wgYmFja2VuZC5gKX0pfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVOViQzPWVudiQxKCk7RU5WJDMucmVnaXN0ZXJGbGFnKCJIQVNfV0VCR0wiLCgpPT5FTlYkMy5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT4wKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX1ZFUlNJT04iLCgpPT5pc1dlYkdMVmVyc2lvbkVuYWJsZWQkMSgyKT8yOmlzV2ViR0xWZXJzaW9uRW5hYmxlZCQxKDEpPzE6MCksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9DSEVDS19OVU1FUklDQUxfUFJPQkxFTVMiLCgpPT4hMSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9CVUZGRVJfU1VQUE9SVEVEIiwoKT0+RU5WJDMuZ2V0KCJXRUJHTF9WRVJTSU9OIik9PT0yKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX0NQVV9GT1JXQVJEIiwoKT0+ITApLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfRk9SQ0VfRjE2X1RFWFRVUkVTIiwoKT0+ITEpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDSyIsKCk9PkVOViQzLmdldEJvb2woIkhBU19XRUJHTCIpKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfTk9STUFMSVpBVElPTiIsKCk9PkVOViQzLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9QQUNLX0NMSVAiLCgpPT5FTlYkMy5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19ERVBUSFdJU0VDT05WIiwoKT0+RU5WJDMuZ2V0Qm9vbCgiV0VCR0xfUEFDSyIpKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfQklOQVJZX09QRVJBVElPTlMiLCgpPT5FTlYkMy5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19VTkFSWV9PUEVSQVRJT05TIiwoKT0+RU5WJDMuZ2V0Qm9vbCgiV0VCR0xfUEFDSyIpKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfQVJSQVlfT1BFUkFUSU9OUyIsKCk9PkVOViQzLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9QQUNLX0lNQUdFX09QRVJBVElPTlMiLCgpPT5FTlYkMy5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19SRURVQ0UiLCgpPT5FTlYkMy5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfTEFaSUxZX1VOUEFDSyIsKCk9PkVOViQzLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9DT05WX0lNMkNPTCIsKCk9PkVOViQzLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9QQUNLX0NPTlYyRFRSQU5TUE9TRSIsKCk9PkVOViQzLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9NQVhfVEVYVFVSRV9TSVpFIiwoKT0+Z2V0V2ViR0xNYXhUZXh0dXJlU2l6ZSQxKEVOViQzLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9NQVhfVEVYVFVSRVNfSU5fU0hBREVSIiwoKT0+Z2V0TWF4VGV4dHVyZXNJblNoYWRlciQxKEVOViQzLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fVkVSU0lPTiIsKCk9Pntjb25zdCBoYT1FTlYkMy5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKTtyZXR1cm4gaGE9PT0wPzA6Z2V0V2ViR0xEaXNqb2ludFF1ZXJ5VGltZXJWZXJzaW9uJDEoaGEpfSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiLCgpPT5FTlYkMy5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIik+MCYmIWlzTW9iaWxlJDEoKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9DQVBBQkxFIiwoKT0+aXNDYXBhYmxlT2ZSZW5kZXJpbmdUb0Zsb2F0VGV4dHVyZSQxKEVOViQzLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9FTkFCTEVEIiwoKT0+RU5WJDMuZ2V0Qm9vbCgiV0VCR0xfRk9SQ0VfRjE2X1RFWFRVUkVTIik/ITE6RU5WJDMuZ2V0Qm9vbCgiV0VCR0xfUkVOREVSX0ZMT0FUMzJfQ0FQQUJMRSIpKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX0RPV05MT0FEX0ZMT0FUX0VOQUJMRUQiLCgpPT5pc0Rvd25sb2FkRmxvYXRUZXh0dXJlRW5hYmxlZCQxKEVOViQzLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpKSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9GRU5DRV9BUElfRU5BQkxFRCIsKCk9PmlzV2ViR0xGZW5jZUVuYWJsZWQkMShFTlYkMy5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKSkpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfU0laRV9VUExPQURfVU5JRk9STSIsKCk9PkVOViQzLmdldEJvb2woIldFQkdMX1JFTkRFUl9GTE9BVDMyX0VOQUJMRUQiKT80OjApLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfREVMRVRFX1RFWFRVUkVfVEhSRVNIT0xEIiwoKT0+LTEsaGE9PntpZih0eXBlb2YgaGEhPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcihgV0VCR0xfREVMRVRFX1RFWFRVUkVfVEhSRVNIT0xEIG11c3QgYmUgYSBudW1iZXIgYnV0IGdvdCAke2hhfS5gKTtpZihoYTwwJiZoYSE9PS0xKXRocm93IG5ldyBFcnJvcihgV0VCR0xfREVMRVRFX1RFWFRVUkVfVEhSRVNIT0xEIG11c3QgYmUgLTEgKGluZGljYXRpbmcgbmV2ZXIgZGVsZXRlKSBvciBhdCBsZWFzdCAwLCBidXQgZ290ICR7aGF9LmApfSksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9GTFVTSF9USFJFU0hPTEQiLCgpPT5pc01vYmlsZSQxKCk/MTotMSxoYT0+e2lmKHR5cGVvZiBoYSE9Im51bWJlciIpdGhyb3cgbmV3IEVycm9yKGBXRUJHTF9GTFVTSF9USFJFU0hPTEQgbXVzdCBiZSBhIG51bWJlciBidXQgZ290ICR7aGF9LmApO2lmKGhhPDAmJmhhIT09LTEpdGhyb3cgbmV3IEVycm9yKGBXRUJHTF9GTFVTSF9USFJFU0hPTEQgbXVzdCBiZSAtMSAoaW5kaWNhdGluZyBuZXZlciBtYW51YWwgZmx1c2gpIG9yIGF0IGxlYXN0IDAsIGJ1dCBnb3QgJHtoYX0uYCl9KSxFTlYkMy5yZWdpc3RlckZsYWcoIkNQVV9IQU5ET0ZGX1NJWkVfVEhSRVNIT0xEIiwoKT0+MTI4KSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX1VTRV9TSEFQRVNfVU5JRk9STVMiLCgpPT4hMSksRU5WJDMucmVnaXN0ZXJGbGFnKCJUT1BLX0xBU1RfRElNX0NQVV9IQU5ET0ZGX1NJWkVfVEhSRVNIT0xEIiwoKT0+MWU1KSxFTlYkMy5yZWdpc3RlckZsYWcoIlRPUEtfS19DUFVfSEFORE9GRl9USFJFU0hPTEQiLCgpPT4xMjgpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0xfRVhQX0NPTlYiLCgpPT4hMSksRU5WJDMucmVnaXN0ZXJGbGFnKCJTT0ZUV0FSRV9XRUJHTF9FTkFCTEVEIiwoKT0+RU5WJDMuZ2V0Qm9vbCgiSVNfVEVTVCIpKSxFTlYkMy5yZWdpc3RlckZsYWcoIldFQkdMX01BWF9TSVpFX0ZPUl9OQVJST1dfVEVYVFVSRSIsKCk9PjEvMCksRU5WJDMucmVnaXN0ZXJGbGFnKCJXRUJHTF9BVVRPX1NRVUFSSUZZX05BUlJPV19URVhUVVJFX1NIQVBFIiwoKT0+ITEpLEVOViQzLnJlZ2lzdGVyRmxhZygiV0VCR0wyX0lTTkFOX0NVU1RPTSIsKCk9PiExKSxFTlYkMy5yZWdpc3RlckZsYWcoIkVOR0lORV9DT01QSUxFX09OTFkiLCgpPT4hMSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0R2xzbERpZmZlcmVuY2VzJDEoKXtsZXQgaGEsYWEseGEsYmEsU2EsVGEsd2EsRWEsa2EsQWE7cmV0dXJuIGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yPyhoYT0iI3ZlcnNpb24gMzAwIGVzIixhYT0iaW4iLHhhPSJvdXQiLGJhPSJpbiIsU2E9InRleHR1cmUiLFRhPSJvdXRwdXRDb2xvciIsd2E9Im91dCB2ZWM0IG91dHB1dENvbG9yOyIsRWE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTDJfSVNOQU5fQ1VTVE9NIik/YAogICAgICBib29sIGlzbmFuX2N1c3RvbShmbG9hdCB2YWwpIHsKICAgICAgICB1aW50IGZsb2F0VG9VaW50ID0gZmxvYXRCaXRzVG9VaW50KHZhbCk7CiAgICAgICAgcmV0dXJuIChmbG9hdFRvVWludCAmIDB4N2ZmZmZmZmZ1KSA+IDB4N2Y4MDAwMDB1OwogICAgICB9CgogICAgICBidmVjNCBpc25hbl9jdXN0b20odmVjNCB2YWwpIHsKICAgICAgICByZXR1cm4gYnZlYzQoaXNuYW5fY3VzdG9tKHZhbC54KSwKICAgICAgICAgIGlzbmFuX2N1c3RvbSh2YWwueSksIGlzbmFuX2N1c3RvbSh2YWwueiksIGlzbmFuX2N1c3RvbSh2YWwudykpOwogICAgICB9CgogICAgICAjZGVmaW5lIGlzbmFuKHZhbHVlKSBpc25hbl9jdXN0b20odmFsdWUpCiAgICBgOiIiLGthPSIiLEFhPWAKICAgICAgI2RlZmluZSByb3VuZCh2YWx1ZSkgbmV3Um91bmQodmFsdWUpCiAgICAgIGludCBuZXdSb3VuZChmbG9hdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBpbnQoZmxvb3IodmFsdWUgKyAwLjUpKTsKICAgICAgfQoKICAgICAgaXZlYzQgbmV3Um91bmQodmVjNCB2YWx1ZSkgewogICAgICAgIHJldHVybiBpdmVjNChmbG9vcih2YWx1ZSArIHZlYzQoMC41KSkpOwogICAgICB9CiAgICBgKTooaGE9IiIsYWE9ImF0dHJpYnV0ZSIseGE9InZhcnlpbmciLGJhPSJ2YXJ5aW5nIixTYT0idGV4dHVyZTJEIixUYT0iZ2xfRnJhZ0NvbG9yIix3YT0iIixFYT1gCiAgICAgICNkZWZpbmUgaXNuYW4odmFsdWUpIGlzbmFuX2N1c3RvbSh2YWx1ZSkKICAgICAgYm9vbCBpc25hbl9jdXN0b20oZmxvYXQgdmFsKSB7CiAgICAgICAgcmV0dXJuICh2YWwgPiAwLiB8fCB2YWwgPCAxLiB8fCB2YWwgPT0gMC4pID8gZmFsc2UgOiB0cnVlOwogICAgICB9CiAgICAgIGJ2ZWM0IGlzbmFuX2N1c3RvbSh2ZWM0IHZhbCkgewogICAgICAgIHJldHVybiBidmVjNChpc25hbih2YWwueCksIGlzbmFuKHZhbC55KSwgaXNuYW4odmFsLnopLCBpc25hbih2YWwudykpOwogICAgICB9CiAgICBgLGthPWAKICAgICAgdW5pZm9ybSBmbG9hdCBJTkZJTklUWTsKCiAgICAgIGJvb2wgaXNpbmYoZmxvYXQgdmFsKSB7CiAgICAgICAgcmV0dXJuIGFicyh2YWwpID09IElORklOSVRZOwogICAgICB9CiAgICAgIGJ2ZWM0IGlzaW5mKHZlYzQgdmFsKSB7CiAgICAgICAgcmV0dXJuIGVxdWFsKGFicyh2YWwpLCB2ZWM0KElORklOSVRZKSk7CiAgICAgIH0KICAgIGAsQWE9YAogICAgICBpbnQgcm91bmQoZmxvYXQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gaW50KGZsb29yKHZhbHVlICsgMC41KSk7CiAgICAgIH0KCiAgICAgIGl2ZWM0IHJvdW5kKHZlYzQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gaXZlYzQoZmxvb3IodmFsdWUgKyB2ZWM0KDAuNSkpKTsKICAgICAgfQogICAgYCkse3ZlcnNpb246aGEsYXR0cmlidXRlOmFhLHZhcnlpbmdWczp4YSx2YXJ5aW5nRnM6YmEsdGV4dHVyZTJEOlNhLG91dHB1dDpUYSxkZWZpbmVPdXRwdXQ6d2EsZGVmaW5lU3BlY2lhbE5hTjpFYSxkZWZpbmVTcGVjaWFsSW5mOmthLGRlZmluZVJvdW5kOkFhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4JDEoaGEsYWEseGE9ImluZGV4Iil7Y29uc3QgYmE9Y29tcHV0ZVN0cmlkZXMkMShhYSk7cmV0dXJuIGJhLm1hcCgoU2EsVGEpPT57Y29uc3Qgd2E9YGludCAke2hhW1RhXX0gPSAke3hhfSAvICR7U2F9YCxFYT1UYT09PWJhLmxlbmd0aC0xP2BpbnQgJHtoYVtUYSsxXX0gPSAke3hhfSAtICR7aGFbVGFdfSAqICR7U2F9YDpgaW5kZXggLT0gJHtoYVtUYV19ICogJHtTYX1gO3JldHVybmAke3dhfTsgJHtFYX07YH0pLmpvaW4oIiIpfWZ1bmN0aW9uIGdldE91dHB1dExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXhCeVVuaWZvcm0kMShoYSxhYSx4YT0iaW5kZXgiKXtjb25zdCBiYT1jb21wdXRlU3RyaWRlcyQxKGFhKTtyZXR1cm4gYmEubWFwKChTYSxUYSk9Pntjb25zdCB3YT1gaW50ICR7aGFbVGFdfSA9ICR7eGF9IC8gb3V0U2hhcGVTdHJpZGVzWyR7VGF9XWAsRWE9VGE9PT1iYS5sZW5ndGgtMT9gaW50ICR7aGFbVGErMV19ID0gJHt4YX0gLSAke2hhW1RhXX0gKiBvdXRTaGFwZVN0cmlkZXNbJHtUYX1dYDpgaW5kZXggLT0gJHtoYVtUYV19ICogb3V0U2hhcGVTdHJpZGVzWyR7VGF9XWA7cmV0dXJuYCR7d2F9OyAke0VhfTtgfSkuam9pbigiIil9ZnVuY3Rpb24gc3ltYm9saWNhbGx5Q29tcHV0ZVN0cmlkZXMkMShoYSxhYSl7Y29uc3QgeGE9aGEubGVuZ3RoLGJhPWhhLm1hcChUYT0+YCR7YWF9WyR7VGF9XWApLFNhPW5ldyBBcnJheSh4YS0xKTtTYVt4YS0yXT1iYVt4YS0xXTtmb3IobGV0IFRhPXhhLTM7VGE+PTA7LS1UYSlTYVtUYV09YCgke1NhW1RhKzFdfSAqICR7YmFbVGErMV19KWA7cmV0dXJuIFNhfWZ1bmN0aW9uIGdldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXhCeVVuaWZvcm0kMShoYSxhYSx4YT0iaW5kZXgiKXtjb25zdCBiYT1oYS5tYXAoKFRhLHdhKT0+d2EpLFNhPXN5bWJvbGljYWxseUNvbXB1dGVTdHJpZGVzJDEoYmEsYWEpO3JldHVybiBTYS5tYXAoKFRhLHdhKT0+e2NvbnN0IEVhPWBpbnQgJHtoYVt3YV19ID0gJHt4YX0gLyAke1NhW3dhXX1gLGthPXdhPT09U2EubGVuZ3RoLTE/YGludCAke2hhW3dhKzFdfSA9ICR7eGF9IC0gJHtoYVt3YV19ICogJHtTYVt3YV19YDpgaW5kZXggLT0gJHtoYVt3YV19ICogJHtTYVt3YV19YDtyZXR1cm5gJHtFYX07ICR7a2F9O2B9KS5qb2luKCIiKX1mdW5jdGlvbiBnZXRGbGF0SW5kZXhGcm9tM0QkMShoYSl7Y29uc3QgYWE9Y29tcHV0ZVN0cmlkZXMkMShoYSkubWFwKHhhPT54YS50b1N0cmluZygpKTtyZXR1cm5gCiAgaW50IGdldEZsYXRJbmRleChpdmVjMyBjb29yZHMpIHsKICAgIHJldHVybiBjb29yZHMueCAqICR7YWFbMF19ICsgY29vcmRzLnkgKiAke2FhWzFdfSArIGNvb3Jkcy56OwogIH0KYH1mdW5jdGlvbiBnZXRGbGF0SW5kZXhGcm9tM0RPdXRwdXQkMSgpe3JldHVybmAKICBpbnQgZ2V0RmxhdEluZGV4KGl2ZWMzIGNvb3JkcykgewogICAgcmV0dXJuIGNvb3Jkcy54ICogb3V0U2hhcGVTdHJpZGVzWzBdICsgY29vcmRzLnkgKiBvdXRTaGFwZVN0cmlkZXNbMV0gKyBjb29yZHMuejsKICB9CmB9Y29uc3QgRU5DT0RFX0ZMT0FUX1NOSVBQRVQkMT1gCiAgY29uc3QgZmxvYXQgRkxPQVRfTUFYID0gMS43MDE0MTE4NGUzODsKICBjb25zdCBmbG9hdCBGTE9BVF9NSU4gPSAxLjE3NTQ5NDM1ZS0zODsKCiAgbG93cCB2ZWM0IGVuY29kZV9mbG9hdChoaWdocCBmbG9hdCB2KSB7CiAgICBpZiAoaXNuYW4odikpIHsKICAgICAgcmV0dXJuIHZlYzQoMjU1LCAyNTUsIDI1NSwgMjU1KTsKICAgIH0KCiAgICBoaWdocCBmbG9hdCBhdiA9IGFicyh2KTsKCiAgICBpZihhdiA8IEZMT0FUX01JTikgewogICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApOwogICAgfSBlbHNlIGlmKHYgPiBGTE9BVF9NQVgpIHsKICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsIDEyOC4wLCAxMjcuMCkgLyAyNTUuMDsKICAgIH0gZWxzZSBpZih2IDwgLUZMT0FUX01BWCkgewogICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgIDEyOC4wLCAyNTUuMCkgLyAyNTUuMDsKICAgIH0KCiAgICBoaWdocCB2ZWM0IGMgPSB2ZWM0KDAsMCwwLDApOwoKICAgIGhpZ2hwIGZsb2F0IGUgPSBmbG9vcihsb2cyKGF2KSk7CiAgICBoaWdocCBmbG9hdCBtID0gZXhwMihmcmFjdChsb2cyKGF2KSkpIC0gMS4wOwoKICAgIGNbMl0gPSBmbG9vcigxMjguMCAqIG0pOwogICAgbSAtPSBjWzJdIC8gMTI4LjA7CiAgICBjWzFdID0gZmxvb3IoMzI3NjguMCAqIG0pOwogICAgbSAtPSBjWzFdIC8gMzI3NjguMDsKICAgIGNbMF0gPSBmbG9vcig4Mzg4NjA4LjAgKiBtKTsKCiAgICBoaWdocCBmbG9hdCBlYmlhcyA9IGUgKyAxMjcuMDsKICAgIGNbM10gPSBmbG9vcihlYmlhcyAvIDIuMCk7CiAgICBlYmlhcyAtPSBjWzNdICogMi4wOwogICAgY1syXSArPSBmbG9vcihlYmlhcykgKiAxMjguMDsKCiAgICBjWzNdICs9IDEyOC4wICogc3RlcCgwLjAsIC12KTsKCiAgICByZXR1cm4gYyAvIDI1NS4wOwogIH0KYDsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdHtnZXRCcm9hZGNhc3REaW1zOmdldEJyb2FkY2FzdERpbXMkMn09YmFja2VuZF91dGlsJDE7ZnVuY3Rpb24gbWFrZVNoYWRlciQxKGhhLGFhLHhhKXtjb25zdCBiYT1bXTtpZihoYS5mb3JFYWNoKHRsPT57Y29uc3Qgbmw9c2l6ZUZyb21TaGFwZSQxKHRsLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUpO2lmKHRsLnNoYXBlSW5mby5pc1VuaWZvcm0/YmEucHVzaChgdW5pZm9ybSBmbG9hdCAke3RsLm5hbWV9JHtubD4xP2BbJHtubH1dYDoiIn07YCk6KGJhLnB1c2goYHVuaWZvcm0gc2FtcGxlcjJEICR7dGwubmFtZX07YCksYmEucHVzaChgdW5pZm9ybSBpbnQgb2Zmc2V0JHt0bC5uYW1lfTtgKSkseGEuZW5hYmxlU2hhcGVVbmlmb3Jtcyl7Y29uc3R7dW5pZm9ybVNoYXBlOnNsfT1nZXRVbmlmb3JtSW5mb0Zyb21TaGFwZSQxKHhhLnBhY2tlZElucHV0cyx0bC5zaGFwZUluZm8ubG9naWNhbFNoYXBlLHRsLnNoYXBlSW5mby50ZXhTaGFwZSk7c3dpdGNoKHNsLmxlbmd0aCl7Y2FzZSAxOmJhLnB1c2goYHVuaWZvcm0gaW50ICR7dGwubmFtZX1TaGFwZTtgKTticmVhaztjYXNlIDI6YmEucHVzaChgdW5pZm9ybSBpdmVjMiAke3RsLm5hbWV9U2hhcGU7YCk7YnJlYWs7Y2FzZSAzOmJhLnB1c2goYHVuaWZvcm0gaXZlYzMgJHt0bC5uYW1lfVNoYXBlO2ApO2JyZWFrO2Nhc2UgNDpiYS5wdXNoKGB1bmlmb3JtIGl2ZWM0ICR7dGwubmFtZX1TaGFwZTtgKTticmVha31iYS5wdXNoKGB1bmlmb3JtIGl2ZWMyICR7dGwubmFtZX1UZXhTaGFwZTtgKX19KSx4YS5lbmFibGVTaGFwZVVuaWZvcm1zKXtzd2l0Y2goYWEubG9naWNhbFNoYXBlLmxlbmd0aCl7Y2FzZSAxOmJhLnB1c2goInVuaWZvcm0gaW50IG91dFNoYXBlOyIpO2JyZWFrO2Nhc2UgMjpiYS5wdXNoKCJ1bmlmb3JtIGl2ZWMyIG91dFNoYXBlOyIpLGJhLnB1c2goInVuaWZvcm0gaW50IG91dFNoYXBlU3RyaWRlczsiKTticmVhaztjYXNlIDM6YmEucHVzaCgidW5pZm9ybSBpdmVjMyBvdXRTaGFwZTsiKSxiYS5wdXNoKCJ1bmlmb3JtIGl2ZWMyIG91dFNoYXBlU3RyaWRlczsiKTticmVhaztjYXNlIDQ6YmEucHVzaCgidW5pZm9ybSBpdmVjNCBvdXRTaGFwZTsiKSxiYS5wdXNoKCJ1bmlmb3JtIGl2ZWMzIG91dFNoYXBlU3RyaWRlczsiKTticmVha31iYS5wdXNoKCJ1bmlmb3JtIGl2ZWMyIG91dFRleFNoYXBlOyIpfXhhLmN1c3RvbVVuaWZvcm1zJiZ4YS5jdXN0b21Vbmlmb3Jtcy5mb3JFYWNoKHRsPT57YmEucHVzaChgdW5pZm9ybSAke3RsLnR5cGV9ICR7dGwubmFtZX0ke3RsLmFycmF5SW5kZXg/YFske3RsLmFycmF5SW5kZXh9XWA6IiJ9O2ApfSk7Y29uc3QgU2E9YmEuam9pbihgCmApLFRhPWhhLm1hcCh0bD0+Z2V0SW5wdXRTYW1wbGluZ1NuaXBwZXQkMSh0bCxhYSx4YS5wYWNrZWRJbnB1dHMseGEuZW5hYmxlU2hhcGVVbmlmb3JtcykpLmpvaW4oYApgKSx3YT1hYS50ZXhTaGFwZSxFYT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpLGthPWdldEZsb2F0VGV4dHVyZVNhbXBsZVNuaXBwZXQkMShFYSk7bGV0IEFhLEZhLExhPWdldFNoYWRlclByZWZpeCQxKEVhKTtyZXR1cm4gYWEuaXNQYWNrZWQ/KEFhPWdldFBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldCQxKGFhLmxvZ2ljYWxTaGFwZSx3YSx4YS5lbmFibGVTaGFwZVVuaWZvcm1zKSxGYT1nZXRGbG9hdFRleHR1cmVTZXRSR0JBU25pcHBldCQxKEVhKSk6KEFhPWdldE91dHB1dFNhbXBsaW5nU25pcHBldCQxKGFhLmxvZ2ljYWxTaGFwZSx3YSx4YS5lbmFibGVTaGFwZVVuaWZvcm1zKSxGYT1nZXRGbG9hdFRleHR1cmVTZXRSU25pcHBldCQxKEVhKSkseGEucGFja2VkSW5wdXRzJiYoTGErPVNIQURFUl9QQUNLRURfUFJFRklYJDEpLFtMYSxrYSxGYSxTYSxBYSxUYSx4YS51c2VyQ29kZV0uam9pbihgCmApfWZ1bmN0aW9uIGdldFNhbXBsZXJGcm9tSW5JbmZvJDEoaGEsYWE9ITEpe2NvbnN0IHhhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGU7c3dpdGNoKHhhLmxlbmd0aCl7Y2FzZSAwOnJldHVybiBnZXRTYW1wbGVyU2NhbGFyJDEoaGEsYWEpO2Nhc2UgMTpyZXR1cm4gZ2V0U2FtcGxlcjFEJDEoaGEsYWEpO2Nhc2UgMjpyZXR1cm4gZ2V0U2FtcGxlcjJEJDEoaGEsYWEpO2Nhc2UgMzpyZXR1cm4gZ2V0U2FtcGxlcjNEJDEoaGEsYWEpO2Nhc2UgNDpyZXR1cm4gZ2V0U2FtcGxlcjREJDEoaGEsYWEpO2Nhc2UgNTpyZXR1cm4gZ2V0U2FtcGxlcjVEJDEoaGEpO2Nhc2UgNjpyZXR1cm4gZ2V0U2FtcGxlcjZEJDEoaGEpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGAke3hhLmxlbmd0aH0tRCBpbnB1dCBzYW1wbGluZyBpcyBub3QgeWV0IHN1cHBvcnRlZGApfX1mdW5jdGlvbiBnZXRQYWNrZWRTYW1wbGVyRnJvbUluSW5mbyQxKGhhLGFhKXtzd2l0Y2goaGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZS5sZW5ndGgpe2Nhc2UgMDpyZXR1cm4gZ2V0UGFja2VkU2FtcGxlclNjYWxhciQxKGhhKTtjYXNlIDE6cmV0dXJuIGdldFBhY2tlZFNhbXBsZXIxRCQxKGhhLGFhKTtjYXNlIDI6cmV0dXJuIGdldFBhY2tlZFNhbXBsZXIyRCQxKGhhLGFhKTtjYXNlIDM6cmV0dXJuIGdldFBhY2tlZFNhbXBsZXIzRCQxKGhhLGFhKTtkZWZhdWx0OnJldHVybiBnZXRQYWNrZWRTYW1wbGVyTkQkMShoYSxhYSl9fWZ1bmN0aW9uIGdldElucHV0U2FtcGxpbmdTbmlwcGV0JDEoaGEsYWEseGE9ITEsYmEpe2xldCBTYT0iIjt4YT9TYSs9Z2V0UGFja2VkU2FtcGxlckZyb21JbkluZm8kMShoYSxiYSk6U2ErPWdldFNhbXBsZXJGcm9tSW5JbmZvJDEoaGEsYmEpO2NvbnN0IFRhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsd2E9YWEubG9naWNhbFNoYXBlO3JldHVybiBUYS5sZW5ndGg8PXdhLmxlbmd0aCYmKHhhP1NhKz1nZXRQYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMkMShoYSxhYSk6U2ErPWdldFNhbXBsZXJBdE91dHB1dENvb3JkcyQxKGhhLGFhKSksU2F9ZnVuY3Rpb24gZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0JDEoaGEsYWEseGEpe3N3aXRjaChoYS5sZW5ndGgpe2Nhc2UgMDpyZXR1cm4gZ2V0T3V0cHV0U2NhbGFyQ29vcmRzJDEoKTtjYXNlIDE6cmV0dXJuIGdldE91dHB1dFBhY2tlZDFEQ29vcmRzJDEoaGEsYWEseGEpO2Nhc2UgMjpyZXR1cm4gZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMkMShoYSxhYSx4YSk7Y2FzZSAzOnJldHVybiBnZXRPdXRwdXRQYWNrZWQzRENvb3JkcyQxKGhhLGFhLHhhKTtkZWZhdWx0OnJldHVybiBnZXRPdXRwdXRQYWNrZWRORENvb3JkcyQxKGhhLGFhLHhhKX19ZnVuY3Rpb24gZ2V0T3V0cHV0U2FtcGxpbmdTbmlwcGV0JDEoaGEsYWEseGEpe3N3aXRjaChoYS5sZW5ndGgpe2Nhc2UgMDpyZXR1cm4gZ2V0T3V0cHV0U2NhbGFyQ29vcmRzJDEoKTtjYXNlIDE6cmV0dXJuIGdldE91dHB1dDFEQ29vcmRzJDEoaGEsYWEseGEpO2Nhc2UgMjpyZXR1cm4gZ2V0T3V0cHV0MkRDb29yZHMkMShoYSxhYSx4YSk7Y2FzZSAzOnJldHVybiBnZXRPdXRwdXQzRENvb3JkcyQxKGhhLGFhLHhhKTtjYXNlIDQ6cmV0dXJuIGdldE91dHB1dDREQ29vcmRzJDEoaGEsYWEseGEpO2Nhc2UgNTpyZXR1cm4gZ2V0T3V0cHV0NURDb29yZHMkMShoYSxhYSk7Y2FzZSA2OnJldHVybiBnZXRPdXRwdXQ2RENvb3JkcyQxKGhhLGFhKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgJHtoYS5sZW5ndGh9LUQgb3V0cHV0IHNhbXBsaW5nIGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCl9fWZ1bmN0aW9uIGdldEZsb2F0VGV4dHVyZVNhbXBsZVNuaXBwZXQkMShoYSl7cmV0dXJuYAogICAgZmxvYXQgc2FtcGxlVGV4dHVyZShzYW1wbGVyMkQgdGV4dHVyZVNhbXBsZXIsIHZlYzIgdXYpIHsKICAgICAgcmV0dXJuICR7aGEudGV4dHVyZTJEfSh0ZXh0dXJlU2FtcGxlciwgdXYpLnI7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRGbG9hdFRleHR1cmVTZXRSU25pcHBldCQxKGhhKXtyZXR1cm5gCiAgICB2b2lkIHNldE91dHB1dChmbG9hdCB2YWwpIHsKICAgICAgJHtoYS5vdXRwdXR9ID0gdmVjNCh2YWwsIDAsIDAsIDApOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0RmxvYXRUZXh0dXJlU2V0UkdCQVNuaXBwZXQkMShoYSl7cmV0dXJuYAogICAgdm9pZCBzZXRPdXRwdXQodmVjNCB2YWwpIHsKICAgICAgJHtoYS5vdXRwdXR9ID0gdmFsOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0U2hhZGVyUHJlZml4JDEoaGEpe3JldHVybmAke2hhLnZlcnNpb259CiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgICBwcmVjaXNpb24gaGlnaHAgaW50OwogICAgcHJlY2lzaW9uIGhpZ2hwIHNhbXBsZXIyRDsKICAgICR7aGEudmFyeWluZ0ZzfSB2ZWMyIHJlc3VsdFVWOwogICAgJHtoYS5kZWZpbmVPdXRwdXR9CiAgICBjb25zdCB2ZWMyIGhhbGZDUiA9IHZlYzIoMC41LCAwLjUpOwoKICAgIHN0cnVjdCBpdmVjNQogICAgewogICAgICBpbnQgeDsKICAgICAgaW50IHk7CiAgICAgIGludCB6OwogICAgICBpbnQgdzsKICAgICAgaW50IHU7CiAgICB9OwoKICAgIHN0cnVjdCBpdmVjNgogICAgewogICAgICBpbnQgeDsKICAgICAgaW50IHk7CiAgICAgIGludCB6OwogICAgICBpbnQgdzsKICAgICAgaW50IHU7CiAgICAgIGludCB2OwogICAgfTsKCiAgICB1bmlmb3JtIGZsb2F0IE5BTjsKICAgICR7aGEuZGVmaW5lU3BlY2lhbE5hTn0KICAgICR7aGEuZGVmaW5lU3BlY2lhbEluZn0KICAgICR7aGEuZGVmaW5lUm91bmR9CgogICAgaW50IGltb2QoaW50IHgsIGludCB5KSB7CiAgICAgIHJldHVybiB4IC0geSAqICh4IC8geSk7CiAgICB9CgogICAgaW50IGlkaXYoaW50IGEsIGludCBiLCBmbG9hdCBzaWduKSB7CiAgICAgIGludCByZXMgPSBhIC8gYjsKICAgICAgaW50IG1vZCA9IGltb2QoYSwgYik7CiAgICAgIGlmIChzaWduIDwgMC4gJiYgbW9kICE9IDApIHsKICAgICAgICByZXMgLT0gMTsKICAgICAgfQogICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIC8vQmFzZWQgb24gdGhlIHdvcmsgb2YgRGF2ZSBIb3NraW5zCiAgICAvL2h0dHBzOi8vd3d3LnNoYWRlcnRveS5jb20vdmlldy80ZGpTUlcKICAgICNkZWZpbmUgSEFTSFNDQUxFMSA0NDMuODk3NQogICAgZmxvYXQgcmFuZG9tKGZsb2F0IHNlZWQpewogICAgICB2ZWMyIHAgPSByZXN1bHRVViAqIHNlZWQ7CiAgICAgIHZlYzMgcDMgID0gZnJhY3QodmVjMyhwLnh5eCkgKiBIQVNIU0NBTEUxKTsKICAgICAgcDMgKz0gZG90KHAzLCBwMy55enggKyAxOS4xOSk7CiAgICAgIHJldHVybiBmcmFjdCgocDMueCArIHAzLnkpICogcDMueik7CiAgICB9CgogICAgJHtTQU1QTEVfMURfU05JUFBFVCQxfQogICAgJHtTQU1QTEVfMkRfU05JUFBFVCQxfQogICAgJHtTQU1QTEVfM0RfU05JUFBFVCQxfQogIGB9Y29uc3QgU0FNUExFXzFEX1NOSVBQRVQkMT1gCnZlYzIgdXZGcm9tRmxhdChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkgewogIGludCB0ZXhSID0gaW5kZXggLyB0ZXhOdW1DOwogIGludCB0ZXhDID0gaW5kZXggLSB0ZXhSICogdGV4TnVtQzsKICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTsKfQp2ZWMyIHBhY2tlZFVWZnJvbTFEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IGluZGV4KSB7CiAgaW50IHRleGVsSW5kZXggPSBpbmRleCAvIDI7CiAgaW50IHRleFIgPSB0ZXhlbEluZGV4IC8gdGV4TnVtQzsKICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQzsKICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTsKfQpgLFNBTVBMRV8yRF9TTklQUEVUJDE9YAp2ZWMyIHBhY2tlZFVWZnJvbTJEKGludCB0ZXhlbHNJbkxvZ2ljYWxSb3csIGludCB0ZXhOdW1SLAogIGludCB0ZXhOdW1DLCBpbnQgcm93LCBpbnQgY29sKSB7CiAgaW50IHRleGVsSW5kZXggPSAocm93IC8gMikgKiB0ZXhlbHNJbkxvZ2ljYWxSb3cgKyAoY29sIC8gMik7CiAgaW50IHRleFIgPSB0ZXhlbEluZGV4IC8gdGV4TnVtQzsKICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQzsKICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTsKfQpgLFNBTVBMRV8zRF9TTklQUEVUJDE9YAp2ZWMyIHBhY2tlZFVWZnJvbTNEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywKICAgIGludCB0ZXhlbHNJbkJhdGNoLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgYiwKICAgIGludCByb3csIGludCBjb2wpIHsKICBpbnQgaW5kZXggPSBiICogdGV4ZWxzSW5CYXRjaCArIChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTsKICBpbnQgdGV4UiA9IGluZGV4IC8gdGV4TnVtQzsKICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqIHRleE51bUM7CiAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7Cn0KYCxTSEFERVJfUEFDS0VEX1BSRUZJWCQxPWAKICBmbG9hdCBnZXRDaGFubmVsKHZlYzQgZnJhZywgdmVjMiBpbm5lckRpbXMpIHsKICAgIHZlYzIgbW9kQ29vcmQgPSBtb2QoaW5uZXJEaW1zLCAyLik7CiAgICByZXR1cm4gbW9kQ29vcmQueCA9PSAwLiA/CiAgICAgIChtb2RDb29yZC55ID09IDAuID8gZnJhZy5yIDogZnJhZy5nKSA6CiAgICAgIChtb2RDb29yZC55ID09IDAuID8gZnJhZy5iIDogZnJhZy5hKTsKICB9CiAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIGludCBkaW0pIHsKICAgIGZsb2F0IG1vZENvb3JkID0gbW9kKGZsb2F0KGRpbSksIDIuKTsKICAgIHJldHVybiBtb2RDb29yZCA9PSAwLiA/IGZyYWcuciA6IGZyYWcuZzsKICB9CmA7ZnVuY3Rpb24gZ2V0T3V0cHV0U2NhbGFyQ29vcmRzJDEoKXtyZXR1cm5gCiAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICByZXR1cm4gMDsKICAgIH0KICBgfWZ1bmN0aW9uIGdldE91dHB1dFBhY2tlZDFEQ29vcmRzJDEoaGEsYWEseGEpe2NvbnN0IGJhPVtNYXRoLmNlaWwoYWFbMF0vMiksTWF0aC5jZWlsKGFhWzFdLzIpXTtyZXR1cm4gYmFbMF09PT0xP3hhP2AKICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICByZXR1cm4gMiAqIGludChyZXN1bHRVVi54ICogY2VpbChmbG9hdChvdXRUZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgfQogICAgYDpgCiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIDIgKiBpbnQocmVzdWx0VVYueCAqICR7YmFbMV19LjApOwogICAgICB9CiAgICBgOmJhWzFdPT09MT94YT9gCiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIDIgKiBpbnQocmVzdWx0VVYueSAqIGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMF0pIC8gMi4wKSk7CiAgICAgIH0KICAgIGA6YAogICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiAyICogaW50KHJlc3VsdFVWLnkgKiAke2JhWzBdfS4wKTsKICAgICAgfQogICAgYDp4YT9gCiAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiBwYWNrZWRUZXhTaGFwZSA9IGl2ZWMyKGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMF0pIC8gMi4wKSwgY2VpbChmbG9hdChvdXRUZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihwYWNrZWRUZXhTaGFwZVswXSwgcGFja2VkVGV4U2hhcGVbMV0pKTsKICAgICAgcmV0dXJuIDIgKiAocmVzVGV4UkMueCAqIHBhY2tlZFRleFNoYXBlWzFdICsgcmVzVGV4UkMueSk7CiAgICB9CiAgYDpgCiAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YmFbMF19LCAke2JhWzFdfSkpOwogICAgICByZXR1cm4gMiAqIChyZXNUZXhSQy54ICogJHtiYVsxXX0gKyByZXNUZXhSQy55KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldE91dHB1dDFEQ29vcmRzJDEoaGEsYWEseGEpe3JldHVybiBhYVswXT09PTE/eGE/YAogICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiBpbnQocmVzdWx0VVYueCAqIGZsb2F0KG91dFRleFNoYXBlWzFdKSk7CiAgICAgIH0KICAgIGA6YAogICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiBpbnQocmVzdWx0VVYueCAqICR7YWFbMV19LjApOwogICAgICB9CiAgICBgOmFhWzFdPT09MT94YT9gCiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIGludChyZXN1bHRVVi55ICogZmxvYXQob3V0VGV4U2hhcGVbMF0pKTsKICAgICAgfQogICAgYDpgCiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIGludChyZXN1bHRVVi55ICogJHthYVswXX0uMCk7CiAgICAgIH0KICAgIGA6eGE/YAogICAgaW50IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihvdXRUZXhTaGFwZVswXSwgb3V0VGV4U2hhcGVbMV0pKTsKICAgICAgcmV0dXJuIHJlc1RleFJDLnggKiBvdXRUZXhTaGFwZVsxXSArIHJlc1RleFJDLnk7CiAgICB9CiAgYDpgCiAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICByZXR1cm4gcmVzVGV4UkMueCAqICR7YWFbMV19ICsgcmVzVGV4UkMueTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldE91dHB1dFBhY2tlZDNEQ29vcmRzJDEoaGEsYWEseGEpe2lmKHhhKXJldHVybmAKICAgIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcGFja2VkVGV4U2hhcGUgPSBpdmVjMihjZWlsKGZsb2F0KG91dFRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIGludCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBpbnQoY2VpbChmbG9hdChvdXRTaGFwZVsyXSkgLyAyLjApKTsKICAgICAgaW50IHRleGVsc0luQmF0Y2ggPSB0ZXhlbHNJbkxvZ2ljYWxSb3cgKiBpbnQoY2VpbChmbG9hdChvdXRTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihwYWNrZWRUZXhTaGFwZVswXSwgcGFja2VkVGV4U2hhcGVbMV0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqIHBhY2tlZFRleFNoYXBlWzFdICsgcmVzVGV4UkMueTsKCiAgICAgIGludCBiID0gaW5kZXggLyB0ZXhlbHNJbkJhdGNoOwogICAgICBpbmRleCAtPSBiICogdGV4ZWxzSW5CYXRjaDsKCiAgICAgIGludCByID0gMiAqIChpbmRleCAvIHRleGVsc0luTG9naWNhbFJvdyk7CiAgICAgIGludCBjID0gaW1vZChpbmRleCwgdGV4ZWxzSW5Mb2dpY2FsUm93KSAqIDI7CgogICAgICByZXR1cm4gaXZlYzMoYiwgciwgYyk7CiAgICB9CiAgYDtjb25zdCBiYT1bTWF0aC5jZWlsKGFhWzBdLzIpLE1hdGguY2VpbChhYVsxXS8yKV0sU2E9TWF0aC5jZWlsKGhhWzJdLzIpLFRhPVNhKk1hdGguY2VpbChoYVsxXS8yKTtyZXR1cm5gCiAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtiYVswXX0sICR7YmFbMV19KSk7CiAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2JhWzFdfSArIHJlc1RleFJDLnk7CgogICAgICBpbnQgYiA9IGluZGV4IC8gJHtUYX07CiAgICAgIGluZGV4IC09IGIgKiAke1RhfTsKCiAgICAgIGludCByID0gMiAqIChpbmRleCAvICR7U2F9KTsKICAgICAgaW50IGMgPSBpbW9kKGluZGV4LCAke1NhfSkgKiAyOwoKICAgICAgcmV0dXJuIGl2ZWMzKGIsIHIsIGMpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0M0RDb29yZHMkMShoYSxhYSx4YSl7aWYoeGEpcmV0dXJuYAogIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHsKICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKG91dFRleFNoYXBlWzBdLCBvdXRUZXhTaGFwZVsxXSkpOwogICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqIG91dFRleFNoYXBlWzFdICsgcmVzVGV4UkMueTsKICAgICR7Z2V0T3V0cHV0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybSQxKFsiciIsImMiLCJkIl0saGEpfQogICAgcmV0dXJuIGl2ZWMzKHIsIGMsIGQpOwogIH0KYDtjb25zdCBiYT1nZXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4JDEoWyJyIiwiYyIsImQiXSxoYSk7cmV0dXJuYAogICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogJHthYVsxXX0gKyByZXNUZXhSQy55OwogICAgICAke2JhfQogICAgICByZXR1cm4gaXZlYzMociwgYywgZCk7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXRQYWNrZWRORENvb3JkcyQxKGhhLGFhLHhhKXtpZih4YSlyZXR1cm5gCiAgICBpdmVjNCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdChvdXRUZXhTaGFwZVswXSkgLyAyLjApLCBjZWlsKGZsb2F0KG91dFRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKHBhY2tlZFRleFNoYXBlWzBdLCBwYWNrZWRUZXhTaGFwZVsxXSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogcGFja2VkVGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwoKICAgICAgaW50IHRleGVsc0luTG9naWNhbFJvdyA9IGludChjZWlsKGZsb2F0KG91dFNoYXBlWzNdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIGludChjZWlsKGZsb2F0KG91dFNoYXBlWzJdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaE4gPSB0ZXhlbHNJbkJhdGNoICogb3V0U2hhcGVbMV07CgogICAgICBpbnQgYjIgPSBpbmRleCAvIHRleGVsc0luQmF0Y2hOOwogICAgICBpbmRleCAtPSBiMiAqIHRleGVsc0luQmF0Y2hOOwoKICAgICAgaW50IGIgPSBpbmRleCAvIHRleGVsc0luQmF0Y2g7CiAgICAgIGluZGV4IC09IGIgKiB0ZXhlbHNJbkJhdGNoOwoKICAgICAgaW50IHIgPSAyICogKGluZGV4IC8gdGV4ZWxzSW5Mb2dpY2FsUm93KTsKICAgICAgaW50IGMgPSBpbW9kKGluZGV4LCB0ZXhlbHNJbkxvZ2ljYWxSb3cpICogMjsKCiAgICAgIHJldHVybiBpdmVjNChiMiwgYiwgciwgYyk7CiAgICB9CiAgYDtjb25zdCBiYT1bTWF0aC5jZWlsKGFhWzBdLzIpLE1hdGguY2VpbChhYVsxXS8yKV0sU2E9TWF0aC5jZWlsKGhhW2hhLmxlbmd0aC0xXS8yKSxUYT1TYSpNYXRoLmNlaWwoaGFbaGEubGVuZ3RoLTJdLzIpO2xldCB3YT1UYSxFYT0iIixrYT0iYiwgciwgYyI7Zm9yKGxldCBBYT0yO0FhPGhhLmxlbmd0aC0xO0FhKyspd2EqPWhhW2hhLmxlbmd0aC1BYS0xXSxFYT1gCiAgICAgIGludCBiJHtBYX0gPSBpbmRleCAvICR7d2F9OwogICAgICBpbmRleCAtPSBiJHtBYX0gKiAke3dhfTsKICAgIGArRWEsa2E9YGIke0FhfSwgYCtrYTtyZXR1cm5gCiAgICBpdmVjJHtoYS5sZW5ndGh9IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke2JhWzBdfSwgJHtiYVsxXX0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YmFbMV19ICsgcmVzVGV4UkMueTsKCiAgICAgICR7RWF9CgogICAgICBpbnQgYiA9IGluZGV4IC8gJHtUYX07CiAgICAgIGluZGV4IC09IGIgKiAke1RhfTsKCiAgICAgIGludCByID0gMiAqIChpbmRleCAvICR7U2F9KTsKICAgICAgaW50IGMgPSBpbW9kKGluZGV4LCAke1NhfSkgKiAyOwoKICAgICAgcmV0dXJuIGl2ZWMke2hhLmxlbmd0aH0oJHtrYX0pOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0NERDb29yZHMkMShoYSxhYSx4YSl7aWYoeGEpcmV0dXJuYAogICAgaXZlYzQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICB2ZWMyKG91dFRleFNoYXBlWzBdLCBvdXRUZXhTaGFwZVsxXSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogb3V0VGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwogICAgICAke2dldE91dHB1dExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXhCeVVuaWZvcm0kMShbInIiLCJjIiwiZCIsImQyIl0saGEpfQogICAgICByZXR1cm4gaXZlYzQociwgYywgZCwgZDIpOwogICAgfQogIGA7Y29uc3QgYmE9Z2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleCQxKFsiciIsImMiLCJkIiwiZDIiXSxoYSk7cmV0dXJuYAogICAgaXZlYzQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogJHthYVsxXX0gKyByZXNUZXhSQy55OwogICAgICAke2JhfQogICAgICByZXR1cm4gaXZlYzQociwgYywgZCwgZDIpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0NURDb29yZHMkMShoYSxhYSl7Y29uc3QgeGE9Z2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleCQxKFsiciIsImMiLCJkIiwiZDIiLCJkMyJdLGhhKTtyZXR1cm5gCiAgICBpdmVjNSBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKiB2ZWMyKCR7YWFbMF19LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7YWFbMV19KSk7CgogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogJHthYVsxXX0gKyByZXNUZXhSQy55OwoKICAgICAgJHt4YX0KCiAgICAgIGl2ZWM1IG91dFNoYXBlID0gaXZlYzUociwgYywgZCwgZDIsIGQzKTsKICAgICAgcmV0dXJuIG91dFNoYXBlOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0NkRDb29yZHMkMShoYSxhYSl7Y29uc3QgeGE9Z2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleCQxKFsiciIsImMiLCJkIiwiZDIiLCJkMyIsImQ0Il0saGEpO3JldHVybmAKICAgIGl2ZWM2IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgdmVjMigke2FhWzBdfSwgJHthYVsxXX0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YWFbMV19ICsgcmVzVGV4UkMueTsKCiAgICAgICR7eGF9CgogICAgICBpdmVjNiByZXN1bHQgPSBpdmVjNihyLCBjLCBkLCBkMiwgZDMsIGQ0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICBgfWZ1bmN0aW9uIGdldE91dHB1dFBhY2tlZDJEQ29vcmRzJDEoaGEsYWEseGEpe2NvbnN0IGJhPVtNYXRoLmNlaWwoYWFbMF0vMiksTWF0aC5jZWlsKGFhWzFdLzIpXTtpZihhcnJheXNFcXVhbCQxKGhhLGFhKSlyZXR1cm4geGE/YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgaXZlYzIgcGFja2VkVGV4U2hhcGUgPSBpdmVjMihjZWlsKGZsb2F0KG91dFRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgICAgcmV0dXJuIDIgKiBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIocGFja2VkVGV4U2hhcGVbMF0sIHBhY2tlZFRleFNoYXBlWzFdKSk7CiAgICAgIH0KICAgIGA6YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIDIgKiBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIoJHtiYVswXX0sICR7YmFbMV19KSk7CiAgICAgIH0KICAgIGA7Y29uc3QgU2E9TWF0aC5jZWlsKGhhWzFdLzIpO3JldHVybiB4YT9gCiAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdChvdXRUZXhTaGFwZVswXSkgLyAyLjApLCBjZWlsKGZsb2F0KG91dFRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gaW50KGNlaWwoZmxvYXQob3V0U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIocGFja2VkVGV4U2hhcGVbMF0sIHBhY2tlZFRleFNoYXBlWzFdKSk7CgogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogcGFja2VkVGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwogICAgICBpbnQgciA9IDIgKiAoaW5kZXggLyB0ZXhlbHNJbkxvZ2ljYWxSb3cpOwogICAgICBpbnQgYyA9IGltb2QoaW5kZXgsIHRleGVsc0luTG9naWNhbFJvdykgKiAyOwoKICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpOwogICAgfQogIGA6YAogICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YmFbMF19LCAke2JhWzFdfSkpOwoKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YmFbMV19ICsgcmVzVGV4UkMueTsKICAgICAgaW50IHIgPSAyICogKGluZGV4IC8gJHtTYX0pOwogICAgICBpbnQgYyA9IGltb2QoaW5kZXgsICR7U2F9KSAqIDI7CgogICAgICByZXR1cm4gaXZlYzIociwgYyk7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXQyRENvb3JkcyQxKGhhLGFhLHhhKXtyZXR1cm4gYXJyYXlzRXF1YWwkMShoYSxhYSk/eGE/YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIGl2ZWMyKHJlc3VsdFVWLnl4ICogdmVjMihvdXRUZXhTaGFwZVswXSwgb3V0VGV4U2hhcGVbMV0pKTsKICAgICAgfQogICAgYDpgCiAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICByZXR1cm4gaXZlYzIocmVzdWx0VVYueXggKiB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICB9CiAgICBgOmhhWzFdPT09MT94YT9gCiAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIob3V0VGV4U2hhcGVbMF0sIG91dFRleFNoYXBlWzFdKSk7CiAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqIG91dFRleFNoYXBlWzFdICsgcmVzVGV4UkMueTsKICAgICAgICByZXR1cm4gaXZlYzIoaW5kZXgsIDApOwogICAgICB9CiAgICBgOmAKICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke2FhWzBdfSwgJHthYVsxXX0pKTsKICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogJHthYVsxXX0gKyByZXNUZXhSQy55OwogICAgICAgIHJldHVybiBpdmVjMihpbmRleCwgMCk7CiAgICAgIH0KICAgIGA6aGFbMF09PT0xP3hhP2AKICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihvdXRUZXhTaGFwZVswXSwgb3V0VGV4U2hhcGVbMV0pKTsKICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogb3V0VGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwogICAgICAgIHJldHVybiBpdmVjMigwLCBpbmRleCk7CiAgICAgIH0KICAgIGA6YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CiAgICAgICAgcmV0dXJuIGl2ZWMyKDAsIGluZGV4KTsKICAgICAgfQogICAgYDp4YT9gCiAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIob3V0VGV4U2hhcGVbMF0sIG91dFRleFNoYXBlWzFdKSk7CiAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiBvdXRUZXhTaGFwZVsxXSArIHJlc1RleFJDLnk7CiAgICAgIGludCByID0gaW5kZXggLyBvdXRTaGFwZVsxXTsKICAgICAgaW50IGMgPSBpbmRleCAtIHIgKiBvdXRTaGFwZVsxXTsKICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpOwogICAgfQogIGA6YAogICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogJHthYVsxXX0gKyByZXNUZXhSQy55OwogICAgICBpbnQgciA9IGluZGV4IC8gJHtoYVsxXX07CiAgICAgIGludCBjID0gaW5kZXggLSByICogJHtoYVsxXX07CiAgICAgIHJldHVybiBpdmVjMihyLCBjKTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSQxKGhhKXtyZXR1cm5gb2Zmc2V0JHtoYX1gfWZ1bmN0aW9uIGdldFBhY2tlZFNhbXBsZXJTY2FsYXIkMShoYSl7Y29uc3QgYWE9aGEubmFtZSx4YT0iZ2V0IithYS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSthYS5zbGljZSgxKSxiYT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpO3JldHVybmAKICAgIHZlYzQgJHt4YX0oKSB7CiAgICAgIHJldHVybiAke2JhLnRleHR1cmUyRH0oJHthYX0sIGhhbGZDUik7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRTYW1wbGVyU2NhbGFyJDEoaGEsYWEpe2NvbnN0IHhhPWhhLm5hbWUsYmE9ImdldCIreGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSk7aWYoaGEuc2hhcGVJbmZvLmlzVW5pZm9ybSlyZXR1cm5gZmxvYXQgJHtiYX0oKSB7cmV0dXJuICR7eGF9O31gO2NvbnN0W1NhLFRhXT1oYS5zaGFwZUluZm8udGV4U2hhcGU7aWYoU2E9PT0xJiZUYT09PTEpcmV0dXJuYAogICAgICBmbG9hdCAke2JhfSgpIHsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgaGFsZkNSKTsKICAgICAgfQogICAgYDtjb25zdCB3YT1nZXRGbGF0T2Zmc2V0VW5pZm9ybU5hbWUkMSh4YSk7aWYoYWEpcmV0dXJuYAogICAgZmxvYXQgJHtiYX0oKSB7CiAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7eGF9VGV4U2hhcGVbMF0sICR7eGF9VGV4U2hhcGVbMV0sICR7d2F9KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgO2NvbnN0W0VhLGthXT1oYS5zaGFwZUluZm8udGV4U2hhcGU7cmV0dXJuYAogICAgZmxvYXQgJHtiYX0oKSB7CiAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7RWF9LCAke2thfSwgJHt3YX0pOwogICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0UGFja2VkU2FtcGxlcjFEJDEoaGEsYWEpe2NvbnN0IHhhPWhhLm5hbWUsYmE9ImdldCIreGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSksU2E9aGEuc2hhcGVJbmZvLnRleFNoYXBlLFRhPWdldEdsc2xEaWZmZXJlbmNlcyQxKCk7aWYoYWEpcmV0dXJuYAogICAgdmVjNCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgaXZlYzIgcGFja2VkVGV4U2hhcGUgPSBpdmVjMihjZWlsKGZsb2F0KCR7eGF9VGV4U2hhcGVbMF0pIC8gMi4wKSwgY2VpbChmbG9hdCgke3hhfVRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoCiAgICAgICAgcGFja2VkVGV4U2hhcGVbMF0sIHBhY2tlZFRleFNoYXBlWzFdLCBpbmRleCk7CiAgICAgIHJldHVybiAke1RhLnRleHR1cmUyRH0oJHt4YX0sIHV2KTsKICAgIH0KICBgO2NvbnN0IHdhPVtNYXRoLmNlaWwoU2FbMF0vMiksTWF0aC5jZWlsKFNhWzFdLzIpXTtyZXR1cm5gCiAgICB2ZWM0ICR7YmF9KGludCBpbmRleCkgewogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoCiAgICAgICAgJHt3YVswXX0sICR7d2FbMV19LCBpbmRleCk7CiAgICAgIHJldHVybiAke1RhLnRleHR1cmUyRH0oJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXIxRCQxKGhhLGFhKXtjb25zdCB4YT1oYS5uYW1lLGJhPSJnZXQiK3hhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpO2lmKGhhLnNoYXBlSW5mby5pc1VuaWZvcm0pcmV0dXJuYAogICAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgICAke2dldFVuaWZvcm1TYW1wbGVyJDEoaGEpfQogICAgICB9CiAgICBgO2NvbnN0IFNhPWhhLnNoYXBlSW5mby50ZXhTaGFwZSxUYT1TYVswXSx3YT1TYVsxXTtpZih3YT09PTEmJlRhPT09MSlyZXR1cm5gCiAgICAgIGZsb2F0ICR7YmF9KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCBoYWxmQ1IpOwogICAgICB9CiAgICBgO2NvbnN0IEVhPWdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSQxKHhhKTtyZXR1cm4gd2E9PT0xP2FhP2AKICAgICAgZmxvYXQgJHtiYX0oaW50IGluZGV4KSB7CiAgICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoZmxvYXQoaW5kZXggKyAke0VhfSkgKyAwLjUpIC8gZmxvYXQoJHt4YX1UZXhTaGFwZVswXSkpOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICAgIH0KICAgIGA6YAogICAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChmbG9hdChpbmRleCArICR7RWF9KSArIDAuNSkgLyAke1RhfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgOlRhPT09MT9hYT9gCiAgICAgIGZsb2F0ICR7YmF9KGludCBpbmRleCkgewogICAgICAgIHZlYzIgdXYgPSB2ZWMyKChmbG9hdChpbmRleCArICR7RWF9KSArIDAuNSkgLyBmbG9hdCgke3hhfVRleFNoYXBlWzFdKSwgMC41KTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgZmxvYXQgJHtiYX0oaW50IGluZGV4KSB7CiAgICAgICAgdmVjMiB1diA9IHZlYzIoKGZsb2F0KGluZGV4ICsgJHtFYX0pICsgMC41KSAvICR7d2F9LjAsIDAuNSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgICAgfQogICAgYDphYT9gCiAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt4YX1UZXhTaGFwZVswXSwgJHt4YX1UZXhTaGFwZVsxXSwgaW5kZXggKyAke0VhfSk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICB9CiAgYDpgCiAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtUYX0sICR7d2F9LCBpbmRleCArICR7RWF9KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFBhY2tlZFNhbXBsZXIyRCQxKGhhLGFhKXtjb25zdCB4YT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLGJhPWhhLm5hbWUsU2E9ImdldCIrYmEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYmEuc2xpY2UoMSksVGE9aGEuc2hhcGVJbmZvLnRleFNoYXBlLHdhPVRhWzBdLEVhPVRhWzFdLGthPWdldEdsc2xEaWZmZXJlbmNlcyQxKCk7aWYoVGEhPW51bGwmJmFycmF5c0VxdWFsJDEoeGEsVGEpKXJldHVybiBhYT9gCiAgICAgIHZlYzQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke2JhfVRleFNoYXBlWzFdLCAke2JhfVRleFNoYXBlWzBdKTsKCiAgICAgICAgcmV0dXJuICR7a2EudGV4dHVyZTJEfSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgdmVjNCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKGNvbCwgcm93KSArIGhhbGZDUikgLyB2ZWMyKCR7RWF9LjAsICR7d2F9LjApOwoKICAgICAgICByZXR1cm4gJHtrYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA7aWYoYWEpcmV0dXJuYAogICAgdmVjNCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdCgke2JhfVRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQoJHtiYX1UZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaW50IHZhbHVlc1BlclJvdyA9IGludChjZWlsKGZsb2F0KCR7YmF9U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20yRCh2YWx1ZXNQZXJSb3csIHBhY2tlZFRleFNoYXBlWzBdLCBwYWNrZWRUZXhTaGFwZVsxXSwgcm93LCBjb2wpOwogICAgICByZXR1cm4gJHtrYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICB9CiAgYDtjb25zdCBBYT1bTWF0aC5jZWlsKFRhWzBdLzIpLE1hdGguY2VpbChUYVsxXS8yKV0sRmE9TWF0aC5jZWlsKHhhWzFdLzIpO3JldHVybmAKICAgIHZlYzQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMkQoJHtGYX0sICR7QWFbMF19LCAke0FhWzFdfSwgcm93LCBjb2wpOwogICAgICByZXR1cm4gJHtrYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRTYW1wbGVyMkQkMShoYSxhYSl7Y29uc3QgeGE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSxiYT1oYS5uYW1lLFNhPSJnZXQiK2JhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2JhLnNsaWNlKDEpLFRhPWhhLnNoYXBlSW5mby50ZXhTaGFwZTtpZihUYSE9bnVsbCYmYXJyYXlzRXF1YWwkMSh4YSxUYSkpe2lmKGFhKXJldHVybmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke2JhfVRleFNoYXBlWzFdLCAke2JhfVRleFNoYXBlWzBdKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgO2NvbnN0IGVsPVRhWzBdLHRsPVRhWzFdO3JldHVybmAKICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wpIHsKICAgICAgdmVjMiB1diA9ICh2ZWMyKGNvbCwgcm93KSArIGhhbGZDUikgLyB2ZWMyKCR7dGx9LjAsICR7ZWx9LjApOwogICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgfQogIGB9Y29uc3R7bmV3U2hhcGU6d2Esa2VwdERpbXM6RWF9PXNxdWVlemVTaGFwZSQxKHhhKSxrYT13YTtpZihrYS5sZW5ndGg8eGEubGVuZ3RoKXtjb25zdCBlbD1zcXVlZXplSW5wdXRJbmZvJDEoaGEsa2EpLHRsPVsicm93IiwiY29sIl07cmV0dXJuYAogICAgICAke2dldFNhbXBsZXJGcm9tSW5JbmZvJDEoZWwsYWEpfQogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgcmV0dXJuICR7U2F9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMkMSh0bCxFYSl9KTsKICAgICAgfQogICAgYH1pZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIGludCBpbmRleCA9IHJvdW5kKGRvdCh2ZWMyKHJvdywgY29sKSwgdmVjMigke3hhWzFdfSwgMSkpKTsKICAgICAgICAke2dldFVuaWZvcm1TYW1wbGVyJDEoaGEpfQogICAgICB9CiAgICBgO2NvbnN0IEFhPVRhWzBdLEZhPVRhWzFdLExhPWdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSQxKGJhKTtyZXR1cm4gRmE9PT0xP2FhP2AKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsICR7TGF9KSwgdmVjMygke2JhfVNoYXBlWzFdLCAxLCAxKSk7CiAgICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoaW5kZXggKyAwLjUpIC8gZmxvYXQoJHtiYX1UZXhTaGFwZVswXSkpOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA6YAogICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCAke0xhfSksIHZlYzMoJHt4YVsxXX0sIDEsIDEpKTsKICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoaW5kZXggKyAwLjUpIC8gJHtBYX0uMCk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICB9CiAgYDpBYT09PTE/YWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgZmxvYXQgaW5kZXggPSBkb3QodmVjMyhyb3csIGNvbCwgJHtMYX0pLCB2ZWMzKCR7YmF9U2hhcGVbMV0sIDEsIDEpKTsKICAgICAgICB2ZWMyIHV2ID0gdmVjMigoaW5kZXggKyAwLjUpIC8gZmxvYXQoJHtiYX1UZXhTaGFwZVsxXSksIDAuNSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDpgCiAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsICR7TGF9KSwgdmVjMygke3hhWzFdfSwgMSwgMSkpOwogICAgICB2ZWMyIHV2ID0gdmVjMigoaW5kZXggKyAwLjUpIC8gJHtGYX0uMCwgMC41KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgIH0KICBgOmFhP2AKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy4KICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke2JhfVNoYXBlWzFdICsgY29sICsgJHtMYX07CiAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtiYX1UZXhTaGFwZVswXSwgJHtiYX1UZXhTaGFwZVsxXSwgaW5kZXgpOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA6YAogIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wpIHsKICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy4KICAgIGludCBpbmRleCA9IHJvdyAqICR7eGFbMV19ICsgY29sICsgJHtMYX07CiAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke0FhfSwgJHtGYX0sIGluZGV4KTsKICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgfQpgfWZ1bmN0aW9uIGdldFBhY2tlZFNhbXBsZXIzRCQxKGhhLGFhKXtjb25zdCB4YT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLGJhPWhhLm5hbWUsU2E9ImdldCIrYmEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYmEuc2xpY2UoMSksVGE9aGEuc2hhcGVJbmZvLnRleFNoYXBlLHdhPVtNYXRoLmNlaWwoVGFbMF0vMiksTWF0aC5jZWlsKFRhWzFdLzIpXTtpZih4YVswXT09PTEpe2NvbnN0IGVsPXhhLnNsaWNlKDEpLHRsPVsxLDJdLG5sPXNxdWVlemVJbnB1dEluZm8kMShoYSxlbCksc2w9WyJiIiwicm93IiwiY29sIl07cmV0dXJuYAogICAgICAgICR7Z2V0UGFja2VkU2FtcGxlckZyb21JbkluZm8kMShubCxhYSl9CiAgICAgICAgdmVjNCAke1NhfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkgewogICAgICAgICAgcmV0dXJuICR7U2F9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMkMShzbCx0bCl9KTsKICAgICAgICB9CiAgICAgIGB9Y29uc3QgRWE9Z2V0R2xzbERpZmZlcmVuY2VzJDEoKTtpZihhYSlyZXR1cm5gCiAgICB2ZWM0ICR7U2F9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdCgke2JhfVRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQoJHtiYX1UZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaW50IHZhbHVlc1BlclJvdyA9IGludChjZWlsKGZsb2F0KCR7YmF9U2hhcGVbMl0pIC8gMi4wKSk7CiAgICAgIGludCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogaW50KGNlaWwoZmxvYXQoJHtiYX1TaGFwZVsxXSkgLyAyLjApKTsKICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTNEKAogICAgICAgIHBhY2tlZFRleFNoYXBlWzBdLCBwYWNrZWRUZXhTaGFwZVsxXSwgdGV4ZWxzSW5CYXRjaCwgdmFsdWVzUGVyUm93LCBiLCByb3csIGNvbCk7CiAgICAgIHJldHVybiAke0VhLnRleHR1cmUyRH0oJHtiYX0sIHV2KTsKICAgIH0KICBgO2NvbnN0IGthPXdhWzBdLEFhPXdhWzFdLEZhPU1hdGguY2VpbCh4YVsyXS8yKSxMYT1GYSpNYXRoLmNlaWwoeGFbMV0vMik7cmV0dXJuYAogICAgdmVjNCAke1NhfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkgewogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tM0QoCiAgICAgICAgJHtrYX0sICR7QWF9LCAke0xhfSwgJHtGYX0sIGIsIHJvdywgY29sKTsKICAgICAgcmV0dXJuICR7RWEudGV4dHVyZTJEfSgke2JhfSwgdXYpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0U2FtcGxlcjNEJDEoaGEsYWEpe2NvbnN0IHhhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsYmE9aGEubmFtZSxTYT0iZ2V0IitiYS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKStiYS5zbGljZSgxKSxUYT14YVsxXSp4YVsyXSx3YT14YVsyXSx7bmV3U2hhcGU6RWEsa2VwdERpbXM6a2F9PXNxdWVlemVTaGFwZSQxKHhhKSxBYT1FYTtpZihBYS5sZW5ndGg8eGEubGVuZ3RoKXtjb25zdCBzbD1zcXVlZXplSW5wdXRJbmZvJDEoaGEsQWEpLHJsPVsicm93IiwiY29sIiwiZGVwdGgiXTtyZXR1cm5gCiAgICAgICAgJHtnZXRTYW1wbGVyRnJvbUluSW5mbyQxKHNsLGFhKX0KICAgICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICAgIHJldHVybiAke1NhfSgke2dldFNxdWVlemVkUGFyYW1zJDEocmwsa2EpfSk7CiAgICAgICAgfQogICAgICBgfWlmKGhhLnNoYXBlSW5mby5pc1VuaWZvcm0pcmV0dXJuYAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICBpbnQgaW5kZXggPSByb3VuZChkb3QodmVjMyhyb3csIGNvbCwgZGVwdGgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzMoJHtUYX0sICR7d2F9LCAxKSkpOwogICAgICAgICR7Z2V0VW5pZm9ybVNhbXBsZXIkMShoYSl9CiAgICAgIH0KICAgIGA7Y29uc3QgRmE9aGEuc2hhcGVJbmZvLnRleFNoYXBlLExhPUZhWzBdLGVsPUZhWzFdLHRsPWhhLnNoYXBlSW5mby5mbGF0T2Zmc2V0O2lmKGVsPT09VGEmJnRsPT1udWxsKXJldHVybiBhYT9gCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCkgewogICAgICAgIGludCBzdHJpZGUxID0gJHtiYX1TaGFwZVsyXTsKICAgICAgICBmbG9hdCB0ZXhSID0gZmxvYXQocm93KTsKICAgICAgICBmbG9hdCB0ZXhDID0gZG90KHZlYzIoY29sLCBkZXB0aCksIHZlYzIoc3RyaWRlMSwgMSkpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgdmVjMigke2JhfVRleFNoYXBlWzFdLCAke2JhfVRleFNoYXBlWzBdKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICAgIGZsb2F0IHRleFIgPSBmbG9hdChyb3cpOwogICAgICAgICAgZmxvYXQgdGV4QyA9IGRvdCh2ZWMyKGNvbCwgZGVwdGgpLCB2ZWMyKCR7d2F9LCAxKSk7CiAgICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgICAgdmVjMigke2VsfS4wLCAke0xhfS4wKTsKICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgICAgfQogICAgICBgO2lmKGVsPT09d2EmJnRsPT1udWxsKXJldHVybiBhYT9gCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCkgewogICAgICAgIGZsb2F0IHRleFIgPSBkb3QodmVjMihyb3csIGNvbCksIHZlYzIoJHtiYX1TaGFwZVsxXSwgMSkpOwogICAgICAgIGZsb2F0IHRleEMgPSBmbG9hdChkZXB0aCk7CiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHtiYX1UZXhTaGFwZVsxXSwgJHtiYX1UZXhTaGFwZVswXSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDpgCiAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgZmxvYXQgdGV4UiA9IGRvdCh2ZWMyKHJvdywgY29sKSwgdmVjMigke3hhWzFdfSwgMSkpOwogICAgICBmbG9hdCB0ZXhDID0gZmxvYXQoZGVwdGgpOwogICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMigke2VsfS4wLCAke0xhfS4wKTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgIH0KICBgO2NvbnN0IG5sPWdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSQxKGJhKTtyZXR1cm4gYWE/YAogICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoKSB7CiAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy4KICAgICAgaW50IHN0cmlkZTAgPSAke2JhfVNoYXBlWzFdICogJHtiYX1TaGFwZVsyXTsKICAgICAgaW50IHN0cmlkZTEgPSAke2JhfVNoYXBlWzJdOwogICAgICBpbnQgaW5kZXggPSByb3cgKiBzdHJpZGUwICsgY29sICogc3RyaWRlMSArIGRlcHRoICsgJHtubH07CiAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7YmF9VGV4U2hhcGVbMF0sICR7YmF9VGV4U2hhcGVbMV0sIGluZGV4KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgIH0KICAgIGA6YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuCiAgICAgICAgaW50IGluZGV4ID0gcm93ICogJHtUYX0gKyBjb2wgKiAke3dhfSArIGRlcHRoICsgJHtubH07CiAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtMYX0sICR7ZWx9LCBpbmRleCk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogIGB9ZnVuY3Rpb24gZ2V0UGFja2VkU2FtcGxlck5EJDEoaGEsYWEpe2NvbnN0IHhhPWhhLm5hbWUsYmE9ImdldCIreGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSksU2E9Z2V0R2xzbERpZmZlcmVuY2VzJDEoKTtpZihhYSlyZXR1cm5gCiAgICB2ZWM0ICR7YmF9KGludCBiMiwgaW50IGIsIGludCByb3csIGludCBjb2wpIHsKICAgICAgaW50IHZhbHVlc1BlclJvdyA9IGludChjZWlsKGZsb2F0KCR7eGF9U2hhcGVbM10pIC8gMi4wKSk7CiAgICAgIGludCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogaW50KGNlaWwoZmxvYXQoJHt4YX1TaGFwZVsyXSkgLyAyLjApKTsKICAgICAgaW50IGluZGV4ID0gYiAqIHRleGVsc0luQmF0Y2ggKyAocm93IC8gMikgKiB2YWx1ZXNQZXJSb3cgKyAoY29sIC8gMik7CiAgICAgIHRleGVsc0luQmF0Y2ggKj0gJHt4YX1TaGFwZVsxXTsKICAgICAgaW5kZXggPSBiMiAqIHRleGVsc0luQmF0Y2ggKyBpbmRleDsKICAgICAgaXZlYzIgcGFja2VkVGV4U2hhcGUgPSBpdmVjMihjZWlsKGZsb2F0KCR7eGF9VGV4U2hhcGVbMF0pIC8gMi4wKSwgY2VpbChmbG9hdCgke3hhfVRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4UiA9IGluZGV4IC8gcGFja2VkVGV4U2hhcGVbMV07CiAgICAgIGludCB0ZXhDID0gaW5kZXggLSB0ZXhSICogcGFja2VkVGV4U2hhcGVbMV07CiAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHBhY2tlZFRleFNoYXBlWzFdLCBwYWNrZWRUZXhTaGFwZVswXSk7IHJldHVybiAke1NhLnRleHR1cmUyRH0oJHt4YX0sIHV2KTsKICAgIH0KICBgO2NvbnN0IFRhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsd2E9VGEubGVuZ3RoLEVhPWhhLnNoYXBlSW5mby50ZXhTaGFwZSxrYT1bTWF0aC5jZWlsKEVhWzBdLzIpLE1hdGguY2VpbChFYVsxXS8yKV0sQWE9a2FbMF0sRmE9a2FbMV0sTGE9TWF0aC5jZWlsKFRhW3dhLTFdLzIpO2xldCBlbD1MYSpNYXRoLmNlaWwoVGFbd2EtMl0vMiksdGw9ImludCBiLCBpbnQgcm93LCBpbnQgY29sIixubD1gYiAqICR7ZWx9ICsgKHJvdyAvIDIpICogJHtMYX0gKyAoY29sIC8gMilgO2ZvcihsZXQgc2w9MjtzbDx3YS0xO3NsKyspdGw9YGludCBiJHtzbH0sIGArdGwsZWwqPVRhW3dhLXNsLTFdLG5sPWBiJHtzbH0gKiAke2VsfSArIGArbmw7cmV0dXJuYAogICAgdmVjNCAke2JhfSgke3RsfSkgewogICAgICBpbnQgaW5kZXggPSAke25sfTsKICAgICAgaW50IHRleFIgPSBpbmRleCAvICR7RmF9OwogICAgICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqICR7RmF9OwogICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMigke0ZhfSwgJHtBYX0pOwogICAgICByZXR1cm4gJHtTYS50ZXh0dXJlMkR9KCR7eGF9LCB1dik7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRTYW1wbGVyNEQkMShoYSxhYSl7Y29uc3QgeGE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSxiYT1oYS5uYW1lLFNhPSJnZXQiK2JhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2JhLnNsaWNlKDEpLFRhPXhhWzNdLHdhPXhhWzJdKlRhLEVhPXhhWzFdKndhLHtuZXdTaGFwZTprYSxrZXB0RGltczpBYX09c3F1ZWV6ZVNoYXBlJDEoeGEpO2lmKGthLmxlbmd0aDx4YS5sZW5ndGgpe2NvbnN0IGFsPXNxdWVlemVJbnB1dEluZm8kMShoYSxrYSksbGw9WyJyb3ciLCJjb2wiLCJkZXB0aCIsImRlcHRoMiJdO3JldHVybmAKICAgICAgJHtnZXRTYW1wbGVyRnJvbUluSW5mbyQxKGFsLGFhKX0KICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7CiAgICAgICAgcmV0dXJuICR7U2F9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMkMShsbCxBYSl9KTsKICAgICAgfQogICAgYH1pZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7CiAgICAgICAgaW50IGluZGV4ID0gcm91bmQoZG90KHZlYzQocm93LCBjb2wsIGRlcHRoLCBkZXB0aDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQoJHtFYX0sICR7d2F9LCAke1RhfSwgMSkpKTsKICAgICAgICAke2dldFVuaWZvcm1TYW1wbGVyJDEoaGEpfQogICAgICB9CiAgICBgO2NvbnN0IEZhPWhhLnNoYXBlSW5mby5mbGF0T2Zmc2V0LExhPWhhLnNoYXBlSW5mby50ZXhTaGFwZSxlbD1MYVswXSx0bD1MYVsxXSxubD1gaW50IHN0cmlkZTIgPSAke2JhfVNoYXBlWzNdO2Asc2w9YGludCBzdHJpZGUxID0gJHtiYX1TaGFwZVsyXSAqIHN0cmlkZTI7YCxybD1gaW50IHN0cmlkZTAgPSAke2JhfVNoYXBlWzFdICogc3RyaWRlMTtgO2lmKHRsPT09RWEmJkZhPT1udWxsKXJldHVybiBhYT9gCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikgewogICAgICAgICR7bmx9CiAgICAgICAgJHtzbH0KICAgICAgICBmbG9hdCB0ZXhSID0gZmxvYXQocm93KTsKICAgICAgICBmbG9hdCB0ZXhDID0KICAgICAgICAgICAgZG90KHZlYzMoY29sLCBkZXB0aCwgZGVwdGgyKSwKICAgICAgICAgICAgICAgIHZlYzMoc3RyaWRlMSwgc3RyaWRlMiwgMSkpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgdmVjMigke2JhfVRleFNoYXBlWzFdLCAke2JhfVRleFNoYXBlWzBdKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7CiAgICAgICAgZmxvYXQgdGV4UiA9IGZsb2F0KHJvdyk7CiAgICAgICAgZmxvYXQgdGV4QyA9CiAgICAgICAgICAgIGRvdCh2ZWMzKGNvbCwgZGVwdGgsIGRlcHRoMiksCiAgICAgICAgICAgICAgICB2ZWMzKCR7d2F9LCAke1RhfSwgMSkpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgdmVjMigke3RsfS4wLCAke2VsfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgO2lmKHRsPT09VGEmJkZhPT1udWxsKXJldHVybiBhYT9gCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikgewogICAgICAgIGZsb2F0IHRleFIgPSBkb3QodmVjMyhyb3csIGNvbCwgZGVwdGgpLAogICAgICAgICAgICAgICAgICAgICAgICAgdmVjMygke2JhfVNoYXBlWzFdICogJHtiYX1TaGFwZVsyXSwgJHtiYX1TaGFwZVsyXSwgMSkpOwogICAgICAgIGZsb2F0IHRleEMgPSBmbG9hdChkZXB0aDIpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICB2ZWMyKCR7YmF9VGV4U2hhcGVbMV0sICR7YmF9VGV4U2hhcGVbMF0pOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA6YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHsKICAgICAgICBmbG9hdCB0ZXhSID0gZG90KHZlYzMocm93LCBjb2wsIGRlcHRoKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzMoJHt4YVsxXSp4YVsyXX0sICR7eGFbMl19LCAxKSk7CiAgICAgICAgZmxvYXQgdGV4QyA9IGZsb2F0KGRlcHRoMik7CiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvCiAgICAgICAgICAgICAgICAgIHZlYzIoJHt0bH0uMCwgJHtlbH0uMCk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDtjb25zdCBvbD1nZXRGbGF0T2Zmc2V0VW5pZm9ybU5hbWUkMShiYSk7cmV0dXJuIGFhP2AKICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikgewogICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuCiAgICAgICR7bmx9CiAgICAgICR7c2x9CiAgICAgICR7cmx9CiAgICAgIGludCBpbmRleCA9IHJvdyAqIHN0cmlkZTAgKyBjb2wgKiBzdHJpZGUxICsKICAgICAgICAgIGRlcHRoICogc3RyaWRlMiArIGRlcHRoMjsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtiYX1UZXhTaGFwZVswXSwgJHtiYX1UZXhTaGFwZVsxXSwgaW5kZXggKyAke29sfSk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICB9CiAgYDpgCiAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHsKICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgICBpbnQgaW5kZXggPSByb3cgKiAke0VhfSArIGNvbCAqICR7d2F9ICsKICAgICAgICAgIGRlcHRoICogJHtUYX0gKyBkZXB0aDI7CiAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7ZWx9LCAke3RsfSwgaW5kZXggKyAke29sfSk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRTYW1wbGVyNUQkMShoYSl7Y29uc3QgYWE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSx4YT1oYS5uYW1lLGJhPSJnZXQiK3hhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpLFNhPWFhWzRdLFRhPWFhWzNdKlNhLHdhPWFhWzJdKlRhLEVhPWFhWzFdKndhLHtuZXdTaGFwZTprYSxrZXB0RGltczpBYX09c3F1ZWV6ZVNoYXBlJDEoYWEpO2lmKGthLmxlbmd0aDxhYS5sZW5ndGgpe2NvbnN0IHNsPXNxdWVlemVJbnB1dEluZm8kMShoYSxrYSkscmw9WyJyb3ciLCJjb2wiLCJkZXB0aCIsImRlcHRoMiIsImRlcHRoMyJdO3JldHVybmAKICAgICAgJHtnZXRTYW1wbGVyRnJvbUluSW5mbyQxKHNsKX0KICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7CiAgICAgICAgcmV0dXJuICR7YmF9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMkMShybCxBYSl9KTsKICAgICAgfQogICAgYH1pZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7CiAgICAgICAgZmxvYXQgaW5kZXggPSBkb3QoCiAgICAgICAgICB2ZWM0KHJvdywgY29sLCBkZXB0aCwgZGVwdGgyKSwKICAgICAgICAgIHZlYzQoJHtFYX0sICR7d2F9LCAke1RhfSwgJHtTYX0pKSArCiAgICAgICAgICBkZXB0aDM7CiAgICAgICAgJHtnZXRVbmlmb3JtU2FtcGxlciQxKGhhKX0KICAgICAgfQogICAgYDtjb25zdCBGYT1oYS5zaGFwZUluZm8uZmxhdE9mZnNldCxMYT1oYS5zaGFwZUluZm8udGV4U2hhcGUsZWw9TGFbMF0sdGw9TGFbMV07aWYodGw9PT1FYSYmRmE9PW51bGwpcmV0dXJuYAogICAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHsKICAgICAgICBpbnQgdGV4UiA9IHJvdzsKICAgICAgICBmbG9hdCB0ZXhDID0gZG90KHZlYzQoY29sLCBkZXB0aCwgZGVwdGgyLCBkZXB0aDMpLAogICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCgke3dhfSwgJHtUYX0sICR7U2F9LCAxKSk7CiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvCiAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGx9LjAsICR7ZWx9LjApOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICAgIH0KICAgIGA7aWYodGw9PT1TYSYmRmE9PW51bGwpcmV0dXJuYAogICAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHsKICAgICAgICBmbG9hdCB0ZXhSID0gZG90KAogICAgICAgICAgdmVjNChyb3csIGNvbCwgZGVwdGgsIGRlcHRoMiksCiAgICAgICAgICB2ZWM0KCR7YWFbMV0qYWFbMl0qYWFbM119LAogICAgICAgICAgICAgICAke2FhWzJdKmFhWzNdfSwgJHthYVszXX0sIDEpKTsKICAgICAgICBpbnQgdGV4QyA9IGRlcHRoMzsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgdmVjMigke3RsfS4wLCAke2VsfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgO2NvbnN0IG5sPWdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSQxKHhhKTtyZXR1cm5gCiAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHsKICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgICBpbnQgaW5kZXggPSByb3cgKiAke0VhfSArIGNvbCAqICR7d2F9ICsgZGVwdGggKiAke1RhfSArCiAgICAgICAgICBkZXB0aDIgKiAke1NhfSArIGRlcHRoMyArICR7bmx9OwogICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke2VsfSwgJHt0bH0sIGluZGV4KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXI2RCQxKGhhKXtjb25zdCBhYT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLHhhPWhhLm5hbWUsYmE9ImdldCIreGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSkse25ld1NoYXBlOlNhLGtlcHREaW1zOlRhfT1zcXVlZXplU2hhcGUkMShhYSk7aWYoU2EubGVuZ3RoPGFhLmxlbmd0aCl7Y29uc3Qgcmw9c3F1ZWV6ZUlucHV0SW5mbyQxKGhhLFNhKSxvbD1bInJvdyIsImNvbCIsImRlcHRoIiwiZGVwdGgyIiwiZGVwdGgzIiwiZGVwdGg0Il07cmV0dXJuYAogICAgICAke2dldFNhbXBsZXJGcm9tSW5JbmZvJDEocmwpfQogICAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsCiAgICAgICAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkgewogICAgICAgIHJldHVybiAke2JhfSgke2dldFNxdWVlemVkUGFyYW1zJDEob2wsVGEpfSk7CiAgICAgIH0KICAgIGB9Y29uc3Qgd2E9YWFbNV0sRWE9YWFbNF0qd2Esa2E9YWFbM10qRWEsQWE9YWFbMl0qa2EsRmE9YWFbMV0qQWE7aWYoaGEuc2hhcGVJbmZvLmlzVW5pZm9ybSlyZXR1cm5gCiAgICAgIGZsb2F0ICR7YmF9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwKICAgICAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkgewogICAgICAgIGludCBpbmRleCA9IHJvdW5kKGRvdCgKICAgICAgICAgIHZlYzQocm93LCBjb2wsIGRlcHRoLCBkZXB0aDIpLAogICAgICAgICAgdmVjNCgke0ZhfSwgJHtBYX0sICR7a2F9LCAke0VhfSkpICsKICAgICAgICAgIGRvdCgKICAgICAgICAgICAgdmVjMihkZXB0aDMsIGRlcHRoNCksCiAgICAgICAgICAgIHZlYzIoJHt3YX0sIDEpKSk7CiAgICAgICAgJHtnZXRVbmlmb3JtU2FtcGxlciQxKGhhKX0KICAgICAgfQogICAgYDtjb25zdCBMYT1oYS5zaGFwZUluZm8uZmxhdE9mZnNldCxlbD1oYS5zaGFwZUluZm8udGV4U2hhcGUsdGw9ZWxbMF0sbmw9ZWxbMV07aWYobmw9PT1GYSYmTGE9PW51bGwpcmV0dXJuYAogICAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsCiAgICAgICAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkgewogICAgICAgIGludCB0ZXhSID0gcm93OwogICAgICAgIGZsb2F0IHRleEMgPSBkb3QodmVjNChjb2wsIGRlcHRoLCBkZXB0aDIsIGRlcHRoMyksCiAgICAgICAgICB2ZWM0KCR7QWF9LCAke2thfSwgJHtFYX0sICR7d2F9KSkgKwogICAgICAgICAgICAgICBmbG9hdChkZXB0aDQpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgdmVjMigke25sfS4wLCAke3RsfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgO2lmKG5sPT09d2EmJkxhPT1udWxsKXJldHVybmAKICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLAogICAgICAgICAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHsKICAgICAgICBmbG9hdCB0ZXhSID0gZG90KHZlYzQocm93LCBjb2wsIGRlcHRoLCBkZXB0aDIpLAogICAgICAgICAgdmVjNCgke2FhWzFdKmFhWzJdKmFhWzNdKmFhWzRdfSwKICAgICAgICAgICAgICAgJHthYVsyXSphYVszXSphYVs0XX0sCiAgICAgICAgICAgICAgICR7YWFbM10qYWFbNF19LAogICAgICAgICAgICAgICAke2FhWzRdfSkpICsgZmxvYXQoZGVwdGgzKTsKICAgICAgICBpbnQgdGV4QyA9IGRlcHRoNDsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgdmVjMigke25sfS4wLCAke3RsfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgO2NvbnN0IHNsPWdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSQxKHhhKTtyZXR1cm5gCiAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsCiAgICAgICAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHsKICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgICBpbnQgaW5kZXggPSByb3cgKiAke0ZhfSArIGNvbCAqICR7QWF9ICsgZGVwdGggKiAke2thfSArCiAgICAgICAgICBkZXB0aDIgKiAke0VhfSArIGRlcHRoMyAqICR7d2F9ICsgZGVwdGg0ICsgJHtzbH07CiAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGx9LCAke25sfSwgaW5kZXgpOwogICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0VW5pZm9ybVNhbXBsZXIkMShoYSl7Y29uc3QgYWE9aGEubmFtZSx4YT1zaXplRnJvbVNoYXBlJDEoaGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSk7cmV0dXJuIHhhPDI/YHJldHVybiAke2FhfTtgOmAKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHt4YX07IGkrKykgewogICAgICBpZiAoaSA9PSBpbmRleCkgewogICAgICAgIHJldHVybiAke2FhfVtpXTsKICAgICAgfQogICAgfQogIGB9ZnVuY3Rpb24gZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzJDEoaGEsYWEpe2NvbnN0IHhhPWhhLm5hbWUsYmE9eGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSksU2E9ImdldCIrYmErIkF0T3V0Q29vcmRzIixUYT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLmxlbmd0aCx3YT1hYS5sb2dpY2FsU2hhcGUubGVuZ3RoLEVhPWdldEJyb2FkY2FzdERpbXMkMihoYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLGFhLmxvZ2ljYWxTaGFwZSksa2E9Z2V0Q29vcmRzRGF0YVR5cGUkMSh3YSksQWE9d2EtVGE7bGV0IEZhO2NvbnN0IExhPVsieCIsInkiLCJ6IiwidyIsInUiLCJ2Il07VGE9PT0wP0ZhPSIiOndhPDImJkVhLmxlbmd0aD49MT9GYT0iY29vcmRzID0gMDsiOkZhPUVhLm1hcChhbD0+YGNvb3Jkcy4ke0xhW2FsK0FhXX0gPSAwO2ApLmpvaW4oYApgKTtsZXQgZWw9IiI7d2E8MiYmVGE+MD9lbD0iY29vcmRzIjplbD1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLm1hcCgoYWwsbGwpPT5gY29vcmRzLiR7TGFbbGwrQWFdfWApLmpvaW4oIiwgIik7bGV0IHRsPSJyZXR1cm4gb3V0cHV0VmFsdWU7Ijtjb25zdCBzbD1zaXplRnJvbVNoYXBlJDEoaGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSk9PT0xLG9sPXNpemVGcm9tU2hhcGUkMShhYS5sb2dpY2FsU2hhcGUpPT09MTtpZihUYT09PTEmJiFzbCYmIW9sKXRsPWAKICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHksIG91dHB1dFZhbHVlLnh5KTsKICAgIGA7ZWxzZSBpZihzbCYmIW9sKXdhPT09MT90bD1gCiAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueCwgMC4sIDAuKTsKICAgICAgYDp0bD1gCiAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7CiAgICAgIGA7ZWxzZSBpZihFYS5sZW5ndGgpe2NvbnN0IGFsPVRhLTIsbGw9VGEtMTtFYS5pbmRleE9mKGFsKT4tMSYmRWEuaW5kZXhPZihsbCk+LTE/dGw9InJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngpOyI6RWEuaW5kZXhPZihhbCk+LTE/dGw9InJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLnksIG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLnkpOyI6RWEuaW5kZXhPZihsbCk+LTEmJih0bD0icmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnp6KTsiKX1yZXR1cm5gCiAgICB2ZWM0ICR7U2F9KCkgewogICAgICAke2thfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgJHtGYX0KICAgICAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldCR7YmF9KCR7ZWx9KTsKICAgICAgJHt0bH0KICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXJBdE91dHB1dENvb3JkcyQxKGhhLGFhKXtjb25zdCB4YT1oYS5uYW1lLGJhPXhhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpLFNhPSJnZXQiK2JhKyJBdE91dENvb3JkcyIsVGE9YWEudGV4U2hhcGUsd2E9aGEuc2hhcGVJbmZvLnRleFNoYXBlLEVhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUubGVuZ3RoLGthPWFhLmxvZ2ljYWxTaGFwZS5sZW5ndGg7aWYoIWhhLnNoYXBlSW5mby5pc1VuaWZvcm0mJkVhPT09a2EmJmhhLnNoYXBlSW5mby5mbGF0T2Zmc2V0PT1udWxsJiZhcnJheXNFcXVhbCQxKHdhLFRhKSlyZXR1cm5gCiAgICAgIGZsb2F0ICR7U2F9KCkgewogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCByZXN1bHRVVik7CiAgICAgIH0KICAgIGA7Y29uc3QgQWE9Z2V0Q29vcmRzRGF0YVR5cGUkMShrYSksRmE9Z2V0QnJvYWRjYXN0RGltcyQyKGhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsYWEubG9naWNhbFNoYXBlKSxMYT1rYS1FYTtsZXQgZWw7Y29uc3QgdGw9WyJ4IiwieSIsInoiLCJ3IiwidSIsInYiXTtFYT09PTA/ZWw9IiI6a2E8MiYmRmEubGVuZ3RoPj0xP2VsPSJjb29yZHMgPSAwOyI6ZWw9RmEubWFwKHNsPT5gY29vcmRzLiR7dGxbc2wrTGFdfSA9IDA7YCkuam9pbihgCmApO2xldCBubD0iIjtyZXR1cm4ga2E8MiYmRWE+MD9ubD0iY29vcmRzIjpubD1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLm1hcCgoc2wscmwpPT5gY29vcmRzLiR7dGxbcmwrTGFdfWApLmpvaW4oIiwgIiksYAogICAgZmxvYXQgJHtTYX0oKSB7CiAgICAgICR7QWF9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAke2VsfQogICAgICByZXR1cm4gZ2V0JHtiYX0oJHtubH0pOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0Q29vcmRzRGF0YVR5cGUkMShoYSl7aWYoaGE8PTEpcmV0dXJuImludCI7aWYoaGE9PT0yKXJldHVybiJpdmVjMiI7aWYoaGE9PT0zKXJldHVybiJpdmVjMyI7aWYoaGE9PT00KXJldHVybiJpdmVjNCI7aWYoaGE9PT01KXJldHVybiJpdmVjNSI7aWYoaGE9PT02KXJldHVybiJpdmVjNiI7dGhyb3cgRXJyb3IoYEdQVSBmb3IgcmFuayAke2hhfSBpcyBub3QgeWV0IHN1cHBvcnRlZGApfWZ1bmN0aW9uIGdldFVuaWZvcm1JbmZvRnJvbVNoYXBlJDEoaGEsYWEseGEpe2NvbnN0e25ld1NoYXBlOmJhLGtlcHREaW1zOlNhfT1zcXVlZXplU2hhcGUkMShhYSksVGE9YWEubGVuZ3RoLHdhPWhhJiZUYT09PTMmJmFhWzBdPT09MSxFYT13YT9hYS5zbGljZSgxKTpiYSxrYT0haGEmJlRhPjEmJiFhcnJheXNFcXVhbCQxKGFhLHhhKSYmYmEubGVuZ3RoPFRhfHx3YTtyZXR1cm57dXNlU3F1ZWV6ZVNoYXBlOmthLHVuaWZvcm1TaGFwZTprYT9FYTphYSxrZXB0RGltczpTYX19ZnVuY3Rpb24gc3F1ZWV6ZUlucHV0SW5mbyQxKGhhLGFhKXtjb25zdCB4YT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGhhKSk7cmV0dXJuIHhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGU9YWEseGF9ZnVuY3Rpb24gZ2V0U3F1ZWV6ZWRQYXJhbXMkMShoYSxhYSl7cmV0dXJuIGFhLm1hcCh4YT0+aGFbeGFdKS5qb2luKCIsICIpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbXBpbGVQcm9ncmFtJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPXhhLm1hcCgoRmEsTGEpPT57Y29uc3QgZWw9e2xvZ2ljYWxTaGFwZTpGYS5zaGFwZSx0ZXhTaGFwZTpGYS5pc1VuaWZvcm0/bnVsbDpGYS50ZXhEYXRhLnRleFNoYXBlLGlzVW5pZm9ybTpGYS5pc1VuaWZvcm0saXNQYWNrZWQ6RmEuaXNVbmlmb3JtPyExOkZhLnRleERhdGEuaXNQYWNrZWQsZmxhdE9mZnNldDpudWxsfTtyZXR1cm4gRmEudGV4RGF0YSE9bnVsbCYmRmEudGV4RGF0YS5zbGljZSE9bnVsbCYmRmEudGV4RGF0YS5zbGljZS5mbGF0T2Zmc2V0PjAmJihlbC5mbGF0T2Zmc2V0PUZhLnRleERhdGEuc2xpY2UuZmxhdE9mZnNldCkse25hbWU6YWEudmFyaWFibGVOYW1lc1tMYV0sc2hhcGVJbmZvOmVsfX0pLFRhPVNhLm1hcChGYT0+RmEuc2hhcGVJbmZvKSx3YT17bG9naWNhbFNoYXBlOmJhLnNoYXBlLHRleFNoYXBlOmJhLnRleERhdGEudGV4U2hhcGUsaXNVbmlmb3JtOiExLGlzUGFja2VkOmJhLnRleERhdGEuaXNQYWNrZWQsZmxhdE9mZnNldDpudWxsfSxFYT1tYWtlU2hhZGVyJDEoU2Esd2EsYWEpLGthPWNyZWF0ZUZyYWdtZW50U2hhZGVyJDEoaGEuZ2wsRWEpLEFhPWhhLmNyZWF0ZVByb2dyYW0oa2EpO3JldHVybiBlbnYkMSgpLmdldCgiRU5HSU5FX0NPTVBJTEVfT05MWSIpP3twcm9ncmFtOmFhLGZyYWdtZW50U2hhZGVyOmthLHNvdXJjZTpFYSx3ZWJHTFByb2dyYW06QWEsaW5TaGFwZUluZm9zOlRhLG91dFNoYXBlSW5mbzp3YSx2YXJpYWJsZXNMb2NhdGlvbnM6bnVsbCxjdXN0b21Vbmlmb3JtTG9jYXRpb25zOm51bGwsaW5mTG9jOm51bGwsbmFuTG9jOm51bGwsb3V0U2hhcGVMb2NhdGlvbjpudWxsLG91dFNoYXBlU3RyaWRlc0xvY2F0aW9uOm51bGwsb3V0VGV4U2hhcGVMb2NhdGlvbjpudWxsfTooaGEuYnVpbGRWYW8oQWEpLE9iamVjdC5hc3NpZ24oe3Byb2dyYW06YWEsZnJhZ21lbnRTaGFkZXI6a2Esc291cmNlOkVhLHdlYkdMUHJvZ3JhbTpBYSxpblNoYXBlSW5mb3M6VGEsb3V0U2hhcGVJbmZvOndhfSxnZXRVbmlmb3JtTG9jYXRpb25zJDEoaGEsYWEsQWEpKSl9ZnVuY3Rpb24gZ2V0VW5pZm9ybUxvY2F0aW9ucyQxKGhhLGFhLHhhKXtjb25zdCBiYT1bXSxTYT1bXTtsZXQgVGEsd2EsRWEsa2E9bnVsbCxBYT1udWxsO0FhPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSwiTkFOIiwhMSksZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTEmJihrYT1oYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsIklORklOSVRZIiwhMSkpO2NvbnN0IEZhPSExO2Zvcihjb25zdCBMYSBvZiBhYS52YXJpYWJsZU5hbWVzKXtjb25zdCBlbD17bmFtZTpMYSx1bmlmb3JtOmhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSxMYSxGYSksb2Zmc2V0OmhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSxgb2Zmc2V0JHtMYX1gLEZhKX07YWEuZW5hYmxlU2hhcGVVbmlmb3JtcyYmKGVsLnNoYXBlPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSxgJHtMYX1TaGFwZWAsRmEpLGVsLnRleFNoYXBlPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSxgJHtMYX1UZXhTaGFwZWAsRmEpKSxiYS5wdXNoKGVsKX1pZihhYS5lbmFibGVTaGFwZVVuaWZvcm1zJiYoVGE9aGEuZ2V0VW5pZm9ybUxvY2F0aW9uKHhhLCJvdXRTaGFwZSIsRmEpLEVhPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSwib3V0U2hhcGVTdHJpZGVzIixGYSksd2E9aGEuZ2V0VW5pZm9ybUxvY2F0aW9uKHhhLCJvdXRUZXhTaGFwZSIsRmEpKSxhYS5jdXN0b21Vbmlmb3Jtcylmb3IoY29uc3QgTGEgb2YgYWEuY3VzdG9tVW5pZm9ybXMpU2EucHVzaChoYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsTGEubmFtZSxGYSkpO3JldHVybnt2YXJpYWJsZXNMb2NhdGlvbnM6YmEsY3VzdG9tVW5pZm9ybUxvY2F0aW9uczpTYSxpbmZMb2M6a2EsbmFuTG9jOkFhLG91dFNoYXBlTG9jYXRpb246VGEsb3V0U2hhcGVTdHJpZGVzTG9jYXRpb246RWEsb3V0VGV4U2hhcGVMb2NhdGlvbjp3YX19ZnVuY3Rpb24gdmFsaWRhdGVCaW5hcnlBbmRQcm9ncmFtJDEoaGEsYWEpe2lmKGhhLmxlbmd0aCE9PWFhLmxlbmd0aCl0aHJvdyBFcnJvcihgQmluYXJ5IHdhcyBjb21waWxlZCB3aXRoICR7aGEubGVuZ3RofSBpbnB1dHMsIGJ1dCB3YXMgZXhlY3V0ZWQgd2l0aCAke2FhLmxlbmd0aH0gaW5wdXRzYCk7aGEuZm9yRWFjaCgoeGEsYmEpPT57Y29uc3QgU2E9eGEubG9naWNhbFNoYXBlLFRhPWFhW2JhXSx3YT1UYS5zaGFwZTtpZighYXJyYXlzRXF1YWwkMShTYSx3YSkpdGhyb3cgRXJyb3IoYEJpbmFyeSB3YXMgY29tcGlsZWQgd2l0aCBkaWZmZXJlbnQgc2hhcGVzIHRoYW4gdGhlIGN1cnJlbnQgYXJncy4gU2hhcGVzICR7U2F9IGFuZCAke3dhfSBtdXN0IG1hdGNoYCk7aWYoeGEuaXNVbmlmb3JtJiZUYS5pc1VuaWZvcm0pcmV0dXJuO2NvbnN0IEVhPXhhLnRleFNoYXBlLGthPVRhLmlzVW5pZm9ybT9udWxsOlRhLnRleERhdGEudGV4U2hhcGU7aWYoIWFycmF5c0VxdWFsJDEoRWEsa2EpKXRocm93IEVycm9yKGBCaW5hcnkgd2FzIGNvbXBpbGVkIHdpdGggZGlmZmVyZW50IHRleHR1cmUgc2hhcGVzIHRoYW4gdGhlIGN1cnJlbnQgYXJncy4gU2hhcGUgJHtFYX0gYW5kICR7a2F9IG11c3QgbWF0Y2hgKX0pfWZ1bmN0aW9uIHJ1blByb2dyYW0kMShoYSxhYSx4YSxiYSxTYSl7YWEucHJvZ3JhbS5lbmFibGVTaGFwZVVuaWZvcm1zfHwodmFsaWRhdGVCaW5hcnlBbmRQcm9ncmFtJDEoYWEuaW5TaGFwZUluZm9zLHhhKSx2YWxpZGF0ZUJpbmFyeUFuZFByb2dyYW0kMShbYWEub3V0U2hhcGVJbmZvXSxbYmFdKSk7Y29uc3QgVGE9YmEudGV4RGF0YS50ZXh0dXJlLHdhPWJhLnRleERhdGEudGV4U2hhcGU7YmEudGV4RGF0YS5pc1BhY2tlZD9oYS5zZXRPdXRwdXRQYWNrZWRNYXRyaXhUZXh0dXJlKFRhLnRleHR1cmUsd2FbMF0sd2FbMV0pOmhhLnNldE91dHB1dE1hdHJpeFRleHR1cmUoVGEudGV4dHVyZSx3YVswXSx3YVsxXSksaGEuc2V0UHJvZ3JhbShhYS53ZWJHTFByb2dyYW0pLGhhLmJpbmRWZXJ0ZXhBcnJheShhYS53ZWJHTFByb2dyYW0udmFvKSxlbnYkMSgpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpPT09MSYmYWEuaW5mTG9jIT09bnVsbCYmaGEuZ2wudW5pZm9ybTFmKGFhLmluZkxvYywxLzApLGFhLm5hbkxvYyE9PW51bGwmJmhhLmdsLnVuaWZvcm0xZihhYS5uYW5Mb2MsTmFOKTtmb3IobGV0IGthPTA7a2E8eGEubGVuZ3RoOysra2Epe2NvbnN0IEFhPXhhW2thXSx7dW5pZm9ybTpGYSxvZmZzZXQ6TGEsc2hhcGU6ZWwsdGV4U2hhcGU6dGx9PWFhLnZhcmlhYmxlc0xvY2F0aW9uc1trYV07aWYoZWwpe2NvbnN0e3VuaWZvcm1TaGFwZTpubH09Z2V0VW5pZm9ybUluZm9Gcm9tU2hhcGUkMShhYS5wcm9ncmFtLnBhY2tlZElucHV0cyxBYS5zaGFwZSxBYS50ZXhEYXRhLnRleFNoYXBlKTtzd2l0Y2gobmwubGVuZ3RoKXtjYXNlIDE6aGEuZ2wudW5pZm9ybTFpdihlbCxuZXcgSW50MzJBcnJheShubCkpO2JyZWFrO2Nhc2UgMjpoYS5nbC51bmlmb3JtMml2KGVsLG5ldyBJbnQzMkFycmF5KG5sKSk7YnJlYWs7Y2FzZSAzOmhhLmdsLnVuaWZvcm0zaXYoZWwsbmV3IEludDMyQXJyYXkobmwpKTticmVhaztjYXNlIDQ6aGEuZ2wudW5pZm9ybTRpdihlbCxuZXcgSW50MzJBcnJheShubCkpO2JyZWFrfX1pZih0bCYmaGEuZ2wudW5pZm9ybTJpKHRsLEFhLnRleERhdGEudGV4U2hhcGVbMF0sQWEudGV4RGF0YS50ZXhTaGFwZVsxXSksRmEhPW51bGwpe2lmKEFhLmlzVW5pZm9ybSl7aWYoc2l6ZUZyb21TaGFwZSQxKEFhLnNoYXBlKTwyKWhhLmdsLnVuaWZvcm0xZihGYSxBYS51bmlmb3JtVmFsdWVzWzBdKTtlbHNle2xldCBubD1BYS51bmlmb3JtVmFsdWVzO25sIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5fHwobmw9bmV3IEZsb2F0MzJBcnJheShubCkpLGhhLmdsLnVuaWZvcm0xZnYoRmEsbmwpfWNvbnRpbnVlfUFhLnRleERhdGEuc2xpY2UhPW51bGwmJkxhIT1udWxsJiZoYS5nbC51bmlmb3JtMWkoTGEsQWEudGV4RGF0YS5zbGljZS5mbGF0T2Zmc2V0KSxoYS5zZXRJbnB1dE1hdHJpeFRleHR1cmUoQWEudGV4RGF0YS50ZXh0dXJlLnRleHR1cmUsRmEsa2EpfX1jb25zdCBFYT1hYS5vdXRTaGFwZUxvY2F0aW9uO2lmKEVhKXN3aXRjaChiYS5zaGFwZS5sZW5ndGgpe2Nhc2UgMTpoYS5nbC51bmlmb3JtMWl2KEVhLG5ldyBJbnQzMkFycmF5KGJhLnNoYXBlKSk7YnJlYWs7Y2FzZSAyOmhhLmdsLnVuaWZvcm0yaXYoRWEsbmV3IEludDMyQXJyYXkoYmEuc2hhcGUpKTticmVhaztjYXNlIDM6aGEuZ2wudW5pZm9ybTNpdihFYSxuZXcgSW50MzJBcnJheShiYS5zaGFwZSkpO2JyZWFrO2Nhc2UgNDpoYS5nbC51bmlmb3JtNGl2KEVhLG5ldyBJbnQzMkFycmF5KGJhLnNoYXBlKSk7YnJlYWt9aWYoYWEub3V0U2hhcGVTdHJpZGVzTG9jYXRpb24pe2NvbnN0IGthPWNvbXB1dGVTdHJpZGVzJDEoYmEuc2hhcGUpO3N3aXRjaChiYS5zaGFwZS5sZW5ndGgpe2Nhc2UgMjpoYS5nbC51bmlmb3JtMWl2KGFhLm91dFNoYXBlU3RyaWRlc0xvY2F0aW9uLG5ldyBJbnQzMkFycmF5KGthKSk7YnJlYWs7Y2FzZSAzOmhhLmdsLnVuaWZvcm0yaXYoYWEub3V0U2hhcGVTdHJpZGVzTG9jYXRpb24sbmV3IEludDMyQXJyYXkoa2EpKTticmVhaztjYXNlIDQ6aGEuZ2wudW5pZm9ybTNpdihhYS5vdXRTaGFwZVN0cmlkZXNMb2NhdGlvbixuZXcgSW50MzJBcnJheShrYSkpO2JyZWFrfX1pZihhYS5vdXRUZXhTaGFwZUxvY2F0aW9uJiZoYS5nbC51bmlmb3JtMmkoYWEub3V0VGV4U2hhcGVMb2NhdGlvbixiYS50ZXhEYXRhLnRleFNoYXBlWzBdLGJhLnRleERhdGEudGV4U2hhcGVbMV0pLGFhLnByb2dyYW0uY3VzdG9tVW5pZm9ybXMmJlNhKWZvcihsZXQga2E9MDtrYTxhYS5wcm9ncmFtLmN1c3RvbVVuaWZvcm1zLmxlbmd0aDsrK2thKXtjb25zdCBBYT1hYS5wcm9ncmFtLmN1c3RvbVVuaWZvcm1zW2thXSxGYT1hYS5jdXN0b21Vbmlmb3JtTG9jYXRpb25zW2thXSxMYT1TYVtrYV07aWYoQWEudHlwZT09PSJmbG9hdCIpaGEuZ2wudW5pZm9ybTFmdihGYSxMYSk7ZWxzZSBpZihBYS50eXBlPT09InZlYzIiKWhhLmdsLnVuaWZvcm0yZnYoRmEsTGEpO2Vsc2UgaWYoQWEudHlwZT09PSJ2ZWMzIiloYS5nbC51bmlmb3JtM2Z2KEZhLExhKTtlbHNlIGlmKEFhLnR5cGU9PT0idmVjNCIpaGEuZ2wudW5pZm9ybTRmdihGYSxMYSk7ZWxzZSBpZihBYS50eXBlPT09ImludCIpaGEuZ2wudW5pZm9ybTFpdihGYSxMYSk7ZWxzZSBpZihBYS50eXBlPT09Iml2ZWMyIiloYS5nbC51bmlmb3JtMml2KEZhLExhKTtlbHNlIGlmKEFhLnR5cGU9PT0iaXZlYzMiKWhhLmdsLnVuaWZvcm0zaXYoRmEsTGEpO2Vsc2UgaWYoQWEudHlwZT09PSJpdmVjNCIpaGEuZ2wudW5pZm9ybTRpdihGYSxMYSk7ZWxzZSB0aHJvdyBFcnJvcihgdW5pZm9ybSB0eXBlICR7QWEudHlwZX0gaXMgbm90IHN1cHBvcnRlZCB5ZXQuYCl9aGEuZXhlY3V0ZVByb2dyYW0oKX1mdW5jdGlvbiBtYWtlU2hhZGVyS2V5JDEoaGEsYWEseGEpe2xldCBiYT0iIjthYS5jb25jYXQoeGEpLmZvckVhY2god2E9Pntjb25zdCBFYT13YS50ZXhEYXRhIT1udWxsJiZ3YS50ZXhEYXRhLnNsaWNlIT1udWxsJiZ3YS50ZXhEYXRhLnNsaWNlLmZsYXRPZmZzZXQ+MDtpZihoYS5lbmFibGVTaGFwZVVuaWZvcm1zJiYhd2EuaXNVbmlmb3JtKXtjb25zdCBrYT13YS50ZXhEYXRhLnRleFNoYXBlLHt1c2VTcXVlZXplU2hhcGU6QWEsdW5pZm9ybVNoYXBlOkZhLGtlcHREaW1zOkxhfT1nZXRVbmlmb3JtSW5mb0Zyb21TaGFwZSQxKGhhLnBhY2tlZElucHV0cyx3YS5zaGFwZSxrYSk7bGV0IGVsPSIiLHRsPSIiLG5sPSIiO2lmKEZhLmxlbmd0aD09PTEmJmhhLnBhY2tlZElucHV0cyl7Y29uc3QgY2w9W01hdGguY2VpbChrYVswXS8yKSxNYXRoLmNlaWwoa2FbMV0vMildO2VsPWAke2NsWzBdPjF9XyR7Y2xbMV0+MX1gfWVsc2UgaWYoRmEubGVuZ3RoPT09MiYmIWhhLnBhY2tlZElucHV0cyl0bD1gJHtGYVswXT4xfV8ke0ZhWzFdPjF9YDtlbHNlIGlmKEZhLmxlbmd0aD4yJiYhaGEucGFja2VkSW5wdXRzKXtjb25zdCBjbD1jb21wdXRlU3RyaWRlcyQxKEZhKTtubD1gJHtjbFswXT09PWthWzFdfV8ke2NsW2NsLmxlbmd0aC0xXT09PWthWzFdfWB9Y29uc3Qgc2w9d2Euc2hhcGUubGVuZ3RoLHJsPUZhLmxlbmd0aD09PTImJmFycmF5c0VxdWFsJDEod2Euc2hhcGUsa2EpLG9sPXNpemVGcm9tU2hhcGUkMSh3YS5zaGFwZSk9PT0xLGFsPWdldEJyb2FkY2FzdERpbXMkMyh3YS5zaGFwZSx4YS5zaGFwZSksbGw9IWhhLnBhY2tlZElucHV0cyYmc2w9PT14YS5zaGFwZS5sZW5ndGgmJmFycmF5c0VxdWFsJDEoa2EseGEudGV4RGF0YS50ZXhTaGFwZSksaWw9aGEucGFja2VkSW5wdXRzfHxGYS5sZW5ndGg+Mj8iIjpgJHtrYVswXT4xfV8ke2thWzFdPjF9YDtiYSs9YCR7c2x9XyR7bGx9XyR7QWE/TGE6IiJ9XyR7RmEubGVuZ3RofV8ke29sfV8ke2FsfV8ke3JsfV8ke2VsfV8ke3RsfV8ke25sfV8ke2lsfV8ke0VhfWB9ZWxzZXtjb25zdCBrYT13YS5pc1VuaWZvcm0/InVuaWZvcm0iOndhLnRleERhdGEudGV4U2hhcGU7YmErPWAke3dhLnNoYXBlfV8ke2thfV8ke0VhfWB9fSk7Y29uc3QgU2E9aGEudXNlckNvZGU7bGV0IFRhPWhhLmNvbnN0cnVjdG9yLm5hbWU7cmV0dXJuIFRhKz0iXyIrYmErIl8iK1NhK2Ake2VudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIil9YCxUYX1mdW5jdGlvbiB1c2VTaGFwZVVuaWZvcm1zJDEoaGEpe3JldHVybiBlbnYkMSgpLmdldEJvb2woIldFQkdMX1VTRV9TSEFQRVNfVU5JRk9STVMiKSYmaGE8PTR9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IERlY29kZU1hdHJpeFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSExLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0UGFja2luZ1NjaGVtZT1QYWNraW5nU2NoZW1lJDEuREVOU0UsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InRleFNoYXBlIix0eXBlOiJpdmVjMiJ9XTtjb25zdCB4YT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy51c2VyQ29kZT1gCiAgICAgIGl2ZWMzIG91dENvb3Jkc0Zyb21GbGF0SW5kZXgoaW50IGluZGV4KSB7CiAgICAgICAgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Z2V0T3V0cHV0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybSQxKFsiciIsImMiLCJkIl0sYWEpOmdldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXgkMShbInIiLCJjIiwiZCJdLGFhKX0KICAgICAgICByZXR1cm4gaXZlYzMociwgYywgZCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICogdmVjMih0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV0pKTsKICAgICAgICBpbnQgaW5kZXggPSA0ICogKHJlc1RleFJDLnggKiB0ZXhTaGFwZVsxXSArIHJlc1RleFJDLnkpOwoKICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwoKICAgICAgICBmb3IgKGludCBpPTA7IGk8NDsgaSsrKSB7CiAgICAgICAgICBpbnQgZmxhdEluZGV4ID0gaW5kZXggKyBpOwogICAgICAgICAgaXZlYzMgcmMgPSBvdXRDb29yZHNGcm9tRmxhdEluZGV4KGZsYXRJbmRleCk7CiAgICAgICAgICByZXN1bHRbaV0gPSBnZXRBKHJjLngsIHJjLnksIHJjLnopOwogICAgICAgIH0KCiAgICAgICAgJHt4YS5vdXRwdXR9ID0gcmVzdWx0OwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IERlY29kZU1hdHJpeFBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0UGFja2luZ1NjaGVtZT1QYWNraW5nU2NoZW1lJDEuREVOU0UsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InRleFNoYXBlIix0eXBlOiJpdmVjMiJ9XTtjb25zdCB4YT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy51c2VyQ29kZT1gCiAgICAgIGl2ZWMzIG91dENvb3Jkc0Zyb21GbGF0SW5kZXgoaW50IGluZGV4KSB7CiAgICAgICAgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Z2V0T3V0cHV0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybSQxKFsiciIsImMiLCJkIl0sYWEpOmdldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXgkMShbInIiLCJjIiwiZCJdLGFhKX0KICAgICAgICByZXR1cm4gaXZlYzMociwgYywgZCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICogdmVjMih0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV0pKTsKICAgICAgICBpbnQgaW5kZXggPSA0ICogKHJlc1RleFJDLnggKiB0ZXhTaGFwZVsxXSArIHJlc1RleFJDLnkpOwoKICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwoKICAgICAgICBmb3IgKGludCBpPTA7IGk8NDsgaSsrKSB7CiAgICAgICAgICBpbnQgZmxhdEluZGV4ID0gaW5kZXggKyBpOwogICAgICAgICAgaXZlYzMgcmMgPSBvdXRDb29yZHNGcm9tRmxhdEluZGV4KGZsYXRJbmRleCk7CiAgICAgICAgICByZXN1bHRbaV0gPSBnZXRDaGFubmVsKGdldEEocmMueCwgcmMueSwgcmMueiksIHZlYzIocmMueSwgcmMueikpOwogICAgICAgIH0KCiAgICAgICAgJHt4YS5vdXRwdXR9ID0gcmVzdWx0OwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IEVuY29kZUZsb2F0UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5vdXRUZXhVc2FnZT1UZXh0dXJlVXNhZ2UkMS5ET1dOTE9BRDtjb25zdCB4YT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgICR7RU5DT0RFX0ZMT0FUX1NOSVBQRVQkMX0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBmbG9hdCB4ID0gZ2V0QUF0T3V0Q29vcmRzKCk7CiAgICAgICAgJHt4YS5vdXRwdXR9ID0gZW5jb2RlX2Zsb2F0KHgpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IEVuY29kZUZsb2F0UGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITEsdGhpcy5vdXRUZXhVc2FnZT1UZXh0dXJlVXNhZ2UkMS5ET1dOTE9BRDtjb25zdCB4YT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgICR7RU5DT0RFX0ZMT0FUX1NOSVBQRVQkMX0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMyBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBmbG9hdCB4ID0gZ2V0Q2hhbm5lbChnZXRBQXRPdXRDb29yZHMoKSwgdmVjMihjb29yZHMueSwgY29vcmRzLnopKTsKICAgICAgICAke3hhLm91dHB1dH0gPSBlbmNvZGVfZmxvYXQoeCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDSEFOTkVMX0NIQVJfVE9fSU5ERVhfTUFQJDE9e1I6MCxHOjEsQjoyLEE6M307bGV0IEVuY29kZU1hdHJpeFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YT0hMSxiYT0iUkdCQSIpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToidGV4U2hhcGUiLHR5cGU6Iml2ZWMyIn1dO2NvbnN0IFNhPWdldEdsc2xEaWZmZXJlbmNlcyQxKCk7dGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtsZXQgVGE9InJlc3VsdCI7eGEmJihUYT0iZmxvb3IocmVzdWx0ICogMjU1LiArIDAuNSkiKTtsZXQgd2E9IiI7Zm9yKGxldCBFYT0wO0VhPGJhLmxlbmd0aDtFYSsrKXtjb25zdCBrYT1iYVtFYV07d2ErPWAKICAgICAgICAgIGlmKG9mZnNldCA9PSAke0VhfSkgewogICAgICAgICAgICByZXN1bHQgPSB2YWx1ZXNbJHtDSEFOTkVMX0NIQVJfVE9fSU5ERVhfTUFQJDFba2FdfV07CiAgICAgICAgICB9YH10aGlzLnVzZXJDb2RlPWAKICAgICAgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Z2V0RmxhdEluZGV4RnJvbTNET3V0cHV0JDEoKTpnZXRGbGF0SW5kZXhGcm9tM0QkMShhYSl9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzMgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGZsYXRJbmRleCA9IGdldEZsYXRJbmRleChjb29yZHMpOwogICAgICAgIGZsb2F0IHJlc3VsdCA9IDAuOwogICAgICAgIGludCBvZmZzZXQgPSBpbW9kKGZsYXRJbmRleCwgJHtiYS5sZW5ndGh9KTsKCiAgICAgICAgZmxhdEluZGV4ID0gaWRpdihmbGF0SW5kZXgsICR7YmEubGVuZ3RofSwgMS4pOwoKICAgICAgICBpbnQgciA9IGZsYXRJbmRleCAvIHRleFNoYXBlWzFdOwogICAgICAgIGlmIChyIDwgdGV4U2hhcGVbMF0pIHsKICAgICAgICAgIGludCBjID0gaW1vZChmbGF0SW5kZXgsIHRleFNoYXBlWzFdKTsKICAgICAgICAgIHZlYzIgdXYgPSAodmVjMihjLCByKSArIGhhbGZDUikgLyB2ZWMyKHRleFNoYXBlWzFdLCB0ZXhTaGFwZVswXSk7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9ICR7U2EudGV4dHVyZTJEfShBLCB1dik7CiAgICAgICAgICAke3dhfQogICAgICAgIH0KICAgICAgICAke1NhLm91dHB1dH0gPSB2ZWM0KCR7VGF9LCAwLiwgMC4sIDAuKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBFbmNvZGVNYXRyaXhQYWNrZWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGE9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMSx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToidGV4U2hhcGUiLHR5cGU6Iml2ZWMyIn1dO2NvbnN0IGJhPWdldEdsc2xEaWZmZXJlbmNlcyQxKCk7dGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtsZXQgU2E9IiIsVGE9InJlc3VsdCI7eGEmJihUYT0iZmxvb3IocmVzdWx0ICogMjU1LiArIDAuNSkiKTtmb3IobGV0IHdhPTA7d2E8PTE7d2ErKylmb3IobGV0IEVhPTA7RWE8PTE7RWErKyl7Y29uc3Qga2E9d2EqMitFYTtTYSs9YAogICAgICAgICAgbG9jYWxDb29yZHMgPSBjb29yZHM7CiAgICAgICAgICBpZihsb2NhbENvb3Jkc1syXSArICR7RWF9IDwgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlWzJdIjpgJHthYVsyXX1gfSkgewogICAgICAgICAgbG9jYWxDb29yZHNbMl0gKz0gJHtFYX07CiAgICAgICAgICBpZiAobG9jYWxDb29yZHNbMV0gKyAke3dhfSA8ICR7dGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPyJvdXRTaGFwZVsxXSI6YCR7YWFbMV19YH0pIHsKICAgICAgICAgICAgbG9jYWxDb29yZHNbMV0gKz0gJHt3YX07CgogICAgICAgICAgICBmbGF0SW5kZXggPSBnZXRGbGF0SW5kZXgobG9jYWxDb29yZHMpOwogICAgICAgICAgICBvZmZzZXQgPSBpbW9kKGZsYXRJbmRleCwgNCk7CgogICAgICAgICAgICBmbGF0SW5kZXggPSBpZGl2KGZsYXRJbmRleCwgNCwgMS4pOwoKICAgICAgICAgICAgaW50IHIgPSBmbGF0SW5kZXggLyB0ZXhTaGFwZVsxXTsKICAgICAgICAgICAgaW50IGMgPSBpbW9kKGZsYXRJbmRleCwgdGV4U2hhcGVbMV0pOwogICAgICAgICAgICB2ZWMyIHV2ID0gKHZlYzIoYywgcikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhTaGFwZVsxXSwgdGV4U2hhcGVbMF0pOwogICAgICAgICAgICB2YWx1ZXMgPSAke2JhLnRleHR1cmUyRH0oQSwgdXYpOwoKICAgICAgICAgICAgaWYgKG9mZnNldCA9PSAwKSB7CiAgICAgICAgICAgICAgcmVzdWx0WyR7a2F9XSA9IHZhbHVlc1swXTsKICAgICAgICAgICAgfSBlbHNlIGlmIChvZmZzZXQgPT0gMSkgewogICAgICAgICAgICAgIHJlc3VsdFske2thfV0gPSB2YWx1ZXNbMV07CiAgICAgICAgICAgIH0gZWxzZSBpZiAob2Zmc2V0ID09IDIpIHsKICAgICAgICAgICAgICByZXN1bHRbJHtrYX1dID0gdmFsdWVzWzJdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlc3VsdFske2thfV0gPSB2YWx1ZXNbM107CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYH10aGlzLnVzZXJDb2RlPWAKICAgICAgICAke3RoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9nZXRGbGF0SW5kZXhGcm9tM0RPdXRwdXQkMSgpOmdldEZsYXRJbmRleEZyb20zRCQxKGFhKX0KCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzMgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CgogICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICAgIGludCBmbGF0SW5kZXgsIHIsIGMsIG9mZnNldDsKICAgICAgICAgIGl2ZWMzIGxvY2FsQ29vcmRzOwogICAgICAgICAgdmVjMiB1djsKICAgICAgICAgIHZlYzQgdmFsdWVzOwoKICAgICAgICAgICR7U2F9CgogICAgICAgICAgJHtiYS5vdXRwdXR9ID0gJHtUYX07CiAgICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNyZWF0ZVZlcnRleFNoYWRlciQyKGhhKXtjb25zdCBhYT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpLHhhPWAke2FhLnZlcnNpb259CiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgICAke2FhLmF0dHJpYnV0ZX0gdmVjMyBjbGlwU3BhY2VQb3M7CiAgICAke2FhLmF0dHJpYnV0ZX0gdmVjMiB1djsKICAgICR7YWEudmFyeWluZ1ZzfSB2ZWMyIHJlc3VsdFVWOwoKICAgIHZvaWQgbWFpbigpIHsKICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KGNsaXBTcGFjZVBvcywgMSk7CiAgICAgIHJlc3VsdFVWID0gdXY7CiAgICB9YDtyZXR1cm4gY3JlYXRlVmVydGV4U2hhZGVyJDMoaGEseGEpfWZ1bmN0aW9uIGNyZWF0ZVZlcnRleEJ1ZmZlciQxKGhhKXtjb25zdCBhYT1uZXcgRmxvYXQzMkFycmF5KFstMSwxLDAsMCwxLC0xLC0xLDAsMCwwLDEsMSwwLDEsMSwxLC0xLDAsMSwwXSk7cmV0dXJuIGNyZWF0ZVN0YXRpY1ZlcnRleEJ1ZmZlciQxKGhhLGFhKX1mdW5jdGlvbiBjcmVhdGVJbmRleEJ1ZmZlciQxKGhhKXtjb25zdCBhYT1uZXcgVWludDE2QXJyYXkoWzAsMSwyLDIsMSwzXSk7cmV0dXJuIGNyZWF0ZVN0YXRpY0luZGV4QnVmZmVyJDEoaGEsYWEpfWZ1bmN0aW9uIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUkMShoYSxhYSx4YSxiYSxTYSxUYSl7dmFsaWRhdGVUZXh0dXJlU2l6ZSQxKGFhLHhhKTtjb25zdCB3YT1jcmVhdGVUZXh0dXJlJDEoaGEpLEVhPWhhLlRFWFRVUkVfMkQ7cmV0dXJuIGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5iaW5kVGV4dHVyZShFYSx3YSkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS50ZXhQYXJhbWV0ZXJpKEVhLGhhLlRFWFRVUkVfV1JBUF9TLGhhLkNMQU1QX1RPX0VER0UpKSxjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEudGV4UGFyYW1ldGVyaShFYSxoYS5URVhUVVJFX1dSQVBfVCxoYS5DTEFNUF9UT19FREdFKSksY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLnRleFBhcmFtZXRlcmkoRWEsaGEuVEVYVFVSRV9NSU5fRklMVEVSLGhhLk5FQVJFU1QpKSxjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEudGV4UGFyYW1ldGVyaShFYSxoYS5URVhUVVJFX01BR19GSUxURVIsaGEuTkVBUkVTVCkpLGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0xP2NhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS50ZXhJbWFnZTJEKEVhLDAsYmEsYWEseGEsMCxTYSxUYSxudWxsKSk6Y2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLnRleFN0b3JhZ2UyRChFYSwxLGJhLGFhLHhhKSksY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsbnVsbCkpLHt0ZXh0dXJlOndhLHRleFNoYXBlOlt4YSxhYV19fWZ1bmN0aW9uIGdldEludGVybmFsRm9ybWF0Rm9yRmxvYXQzMk1hdHJpeFRleHR1cmUkMShoYSl7cmV0dXJuIGhhLmludGVybmFsRm9ybWF0RmxvYXR9ZnVuY3Rpb24gY3JlYXRlRmxvYXQzMk1hdHJpeFRleHR1cmUkMShoYSxhYSx4YSxiYSl7Y29uc3RbU2EsVGFdPWdldFVucGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQkMShhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUkMShoYSxTYSxUYSxnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MzJNYXRyaXhUZXh0dXJlJDEoYmEpLGJhLnRleHR1cmVGb3JtYXRGbG9hdCxoYS5GTE9BVCl9ZnVuY3Rpb24gZ2V0SW50ZXJuYWxGb3JtYXRGb3JGbG9hdDE2TWF0cml4VGV4dHVyZSQxKGhhKXtyZXR1cm4gaGEuaW50ZXJuYWxGb3JtYXRIYWxmRmxvYXR9ZnVuY3Rpb24gY3JlYXRlRmxvYXQxNk1hdHJpeFRleHR1cmUkMShoYSxhYSx4YSxiYSl7Y29uc3RbU2EsVGFdPWdldFVucGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQkMShhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUkMShoYSxTYSxUYSxnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MTZNYXRyaXhUZXh0dXJlJDEoYmEpLGJhLnRleHR1cmVGb3JtYXRGbG9hdCxiYS50ZXh0dXJlVHlwZUhhbGZGbG9hdCl9ZnVuY3Rpb24gZ2V0SW50ZXJuYWxGb3JtYXRGb3JVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZSQxKGhhKXtyZXR1cm4gaGEuZG93bmxvYWRUZXh0dXJlRm9ybWF0fWZ1bmN0aW9uIGNyZWF0ZVVuc2lnbmVkQnl0ZXNNYXRyaXhUZXh0dXJlJDEoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1nZXRVbnBhY2tlZE1hdHJpeFRleHR1cmVTaGFwZVdpZHRoSGVpZ2h0JDEoYWEseGEpO3JldHVybiBjcmVhdGVBbmRDb25maWd1cmVUZXh0dXJlJDEoaGEsU2EsVGEsZ2V0SW50ZXJuYWxGb3JtYXRGb3JVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZSQxKGJhKSxoYS5SR0JBLGhhLlVOU0lHTkVEX0JZVEUpfWZ1bmN0aW9uIGdldEludGVybmFsRm9ybWF0Rm9yUGFja2VkTWF0cml4VGV4dHVyZSQxKGhhKXtyZXR1cm4gaGEuaW50ZXJuYWxGb3JtYXRQYWNrZWRGbG9hdH1mdW5jdGlvbiBjcmVhdGVQYWNrZWRNYXRyaXhUZXh0dXJlJDEoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodCQxKGFhLHhhKTtyZXR1cm4gY3JlYXRlQW5kQ29uZmlndXJlVGV4dHVyZSQxKGhhLFNhLFRhLGdldEludGVybmFsRm9ybWF0Rm9yUGFja2VkTWF0cml4VGV4dHVyZSQxKGJhKSxoYS5SR0JBLGhhLkZMT0FUKX1mdW5jdGlvbiBnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlJDEoaGEpe3JldHVybiBoYS5pbnRlcm5hbEZvcm1hdFBhY2tlZEhhbGZGbG9hdH1mdW5jdGlvbiBjcmVhdGVGbG9hdDE2UGFja2VkTWF0cml4VGV4dHVyZSQxKGhhLGFhLHhhLGJhKXtjb25zdFtTYSxUYV09Z2V0UGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQkMShhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUkMShoYSxTYSxUYSxnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlJDEoYmEpLGhhLlJHQkEsYmEudGV4dHVyZVR5cGVIYWxmRmxvYXQpfWZ1bmN0aW9uIGJpbmRWZXJ0ZXhQcm9ncmFtQXR0cmlidXRlU3RyZWFtcyQxKGhhLGFhLHhhKXtyZXR1cm4gY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmJpbmRCdWZmZXIoaGEuQVJSQVlfQlVGRkVSLHhhKSksYmluZFZlcnRleEJ1ZmZlclRvUHJvZ3JhbUF0dHJpYnV0ZSQxKGhhLGFhLCJjbGlwU3BhY2VQb3MiLHhhLDMsMjAsMCkmJmJpbmRWZXJ0ZXhCdWZmZXJUb1Byb2dyYW1BdHRyaWJ1dGUkMShoYSxhYSwidXYiLHhhLDIsMjAsMTIpfWZ1bmN0aW9uIHVwbG9hZERlbnNlTWF0cml4VG9UZXh0dXJlJDEoaGEsYWEseGEsYmEsU2EsVGEpe2NhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5iaW5kVGV4dHVyZShoYS5URVhUVVJFXzJELGFhKSk7bGV0IHdhLEVhLGthO1NhIGluc3RhbmNlb2YgVWludDhBcnJheT8od2E9bmV3IFVpbnQ4QXJyYXkoeGEqYmEqNCksRWE9aGEuVU5TSUdORURfQllURSxrYT1oYS5SR0JBKTood2E9bmV3IEZsb2F0MzJBcnJheSh4YSpiYSo0KSxFYT1oYS5GTE9BVCxrYT1UYS5pbnRlcm5hbEZvcm1hdFBhY2tlZEZsb2F0KSx3YS5zZXQoU2EpLGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yP2NhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS50ZXhTdWJJbWFnZTJEKGhhLlRFWFRVUkVfMkQsMCwwLDAseGEsYmEsaGEuUkdCQSxFYSx3YSkpOmNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS50ZXhJbWFnZTJEKGhhLlRFWFRVUkVfMkQsMCxrYSx4YSxiYSwwLGhhLlJHQkEsRWEsd2EpKSxjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuYmluZFRleHR1cmUoaGEuVEVYVFVSRV8yRCxudWxsKSl9ZnVuY3Rpb24gdXBsb2FkUGl4ZWxEYXRhVG9UZXh0dXJlJDEoaGEsYWEseGEpe2NhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5iaW5kVGV4dHVyZShoYS5URVhUVVJFXzJELGFhKSkseGEuZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk/ZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTI/Y2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLnRleFN1YkltYWdlMkQoaGEuVEVYVFVSRV8yRCwwLDAsMCx4YS53aWR0aCx4YS5oZWlnaHQsaGEuUkdCQSxoYS5VTlNJR05FRF9CWVRFLHhhLmRhdGEpKTpjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEudGV4SW1hZ2UyRChoYS5URVhUVVJFXzJELDAsaGEuUkdCQSx4YS53aWR0aCx4YS5oZWlnaHQsMCxoYS5SR0JBLGhhLlVOU0lHTkVEX0JZVEUseGEuZGF0YSkpOmVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yP2NhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS50ZXhTdWJJbWFnZTJEKGhhLlRFWFRVUkVfMkQsMCwwLDAsaGEuUkdCQSxoYS5VTlNJR05FRF9CWVRFLHhhKSk6Y2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLnRleEltYWdlMkQoaGEuVEVYVFVSRV8yRCwwLGhhLlJHQkEsaGEuUkdCQSxoYS5VTlNJR05FRF9CWVRFLHhhKSksY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsbnVsbCkpfWZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlckZyb21PdXRwdXRUZXh0dXJlJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWhhLmNyZWF0ZUJ1ZmZlcigpO2NhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5iaW5kQnVmZmVyKGhhLlBJWEVMX1BBQ0tfQlVGRkVSLFNhKSk7Y29uc3QgRWE9NCo0KmFhKnhhO3JldHVybiBjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuYnVmZmVyRGF0YShoYS5QSVhFTF9QQUNLX0JVRkZFUixFYSxoYS5TVFJFQU1fUkVBRCkpLGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5yZWFkUGl4ZWxzKDAsMCx4YSxhYSxoYS5SR0JBLGhhLkZMT0FULDApKSxjYWxsQW5kQ2hlY2skMShoYSwoKT0+aGEuYmluZEJ1ZmZlcihoYS5QSVhFTF9QQUNLX0JVRkZFUixudWxsKSksU2F9ZnVuY3Rpb24gZG93bmxvYWRGbG9hdDMyTWF0cml4RnJvbUJ1ZmZlciQxKGhhLGFhLHhhKXtjb25zdCBiYT1oYSxTYT1uZXcgRmxvYXQzMkFycmF5KHhhKTtyZXR1cm4gYmEuYmluZEJ1ZmZlcihiYS5QSVhFTF9QQUNLX0JVRkZFUixhYSksYmEuZ2V0QnVmZmVyU3ViRGF0YShiYS5QSVhFTF9QQUNLX0JVRkZFUiwwLFNhKSxiYS5iaW5kQnVmZmVyKGJhLlBJWEVMX1BBQ0tfQlVGRkVSLG51bGwpLFNhfWZ1bmN0aW9uIGRvd25sb2FkQnl0ZUVuY29kZWRGbG9hdE1hdHJpeEZyb21PdXRwdXRUZXh0dXJlJDEoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1nZXRVbnBhY2tlZE1hdHJpeFRleHR1cmVTaGFwZVdpZHRoSGVpZ2h0JDEoYWEseGEpLHdhPTQsRWE9bmV3IFVpbnQ4QXJyYXkoZ2V0VW5wYWNrZWRBcnJheVNpemVGcm9tTWF0cml4U2l6ZSQxKGFhKnhhLHdhKSk7cmV0dXJuIGNhbGxBbmRDaGVjayQxKGhhLCgpPT5oYS5yZWFkUGl4ZWxzKDAsMCxTYSxUYSxiYS5kb3dubG9hZFRleHR1cmVGb3JtYXQsaGEuVU5TSUdORURfQllURSxFYSkpLG5ldyBGbG9hdDMyQXJyYXkoRWEuYnVmZmVyKX1mdW5jdGlvbiBkb3dubG9hZFBhY2tlZE1hdHJpeEZyb21CdWZmZXIkMShoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSl7Y29uc3Qga2E9aGEsQWE9bmV3IEZsb2F0MzJBcnJheShnZXRQYWNrZWRSR0JBQXJyYXlTaXplRnJvbU1hdHJpeFNoYXBlJDEoVGEsd2EpKTtyZXR1cm4ga2EuYmluZEJ1ZmZlcihrYS5QSVhFTF9QQUNLX0JVRkZFUixhYSksa2EuZ2V0QnVmZmVyU3ViRGF0YShrYS5QSVhFTF9QQUNLX0JVRkZFUiwwLEFhKSxrYS5iaW5kQnVmZmVyKGthLlBJWEVMX1BBQ0tfQlVGRkVSLG51bGwpLEFhfWZ1bmN0aW9uIGRvd25sb2FkTWF0cml4RnJvbVBhY2tlZE91dHB1dFRleHR1cmUkMShoYSxhYSx4YSl7Y29uc3QgYmE9bmV3IEZsb2F0MzJBcnJheShhYSp4YSo0KTtyZXR1cm4gY2FsbEFuZENoZWNrJDEoaGEsKCk9PmhhLnJlYWRQaXhlbHMoMCwwLHhhLGFhLGhhLlJHQkEsaGEuRkxPQVQsYmEpKSxiYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgR1BHUFVDb250ZXh0JDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMub3V0cHV0VGV4dHVyZT1udWxsLHRoaXMucHJvZ3JhbT1udWxsLHRoaXMuZGlzcG9zZWQ9ITEsdGhpcy5pdGVtc1RvUG9sbD1bXTtjb25zdCB4YT1lbnYkMSgpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpO2lmKGFhIT1udWxsPyh0aGlzLmdsPWFhLHNldFdlYkdMQ29udGV4dCQxKHhhLGFhKSk6dGhpcy5nbD1nZXRXZWJHTENvbnRleHQkMSh4YSksYWE9dGhpcy5nbCxlbnYkMSgpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpPT09Mil7Y29uc3QgVGE9YWE7dGhpcy5jcmVhdGVWZXJ0ZXhBcnJheT0oKT0+Y2FsbEFuZENoZWNrJDEoVGEsKCk9PlRhLmNyZWF0ZVZlcnRleEFycmF5KCkpLHRoaXMuYmluZFZlcnRleEFycmF5PXdhPT5jYWxsQW5kQ2hlY2skMShUYSwoKT0+VGEuYmluZFZlcnRleEFycmF5KHdhKSksdGhpcy5kZWxldGVWZXJ0ZXhBcnJheT13YT0+Y2FsbEFuZENoZWNrJDEoVGEsKCk9PlRhLmRlbGV0ZVZlcnRleEFycmF5KHdhKSksdGhpcy5nZXRWZXJ0ZXhBcnJheT0oKT0+Y2FsbEFuZENoZWNrJDEoVGEsKCk9PlRhLmdldFBhcmFtZXRlcihUYS5WRVJURVhfQVJSQVlfQklORElORykpfWVsc2UgaWYoYWEhPW51bGwpe2NvbnN0IFRhPWFhLmdldEV4dGVuc2lvbigiT0VTX3ZlcnRleF9hcnJheV9vYmplY3QiKTtpZihUYT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoIkFsbCBXZWJHTDEgaW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZCB0byBvZmZlciBPRVNfdmVydGV4X2FycmF5X29iamVjdC4iKTt0aGlzLmNyZWF0ZVZlcnRleEFycmF5PSgpPT5jYWxsQW5kQ2hlY2skMShhYSwoKT0+VGEuY3JlYXRlVmVydGV4QXJyYXlPRVMoKSksdGhpcy5iaW5kVmVydGV4QXJyYXk9d2E9PmNhbGxBbmRDaGVjayQxKGFhLCgpPT5UYS5iaW5kVmVydGV4QXJyYXlPRVMod2EpKSx0aGlzLmRlbGV0ZVZlcnRleEFycmF5PXdhPT5jYWxsQW5kQ2hlY2skMShhYSwoKT0+VGEuZGVsZXRlVmVydGV4QXJyYXlPRVMod2EpKSx0aGlzLmdldFZlcnRleEFycmF5PSgpPT5jYWxsQW5kQ2hlY2skMShhYSwoKT0+YWEuZ2V0UGFyYW1ldGVyKFRhLlZFUlRFWF9BUlJBWV9CSU5ESU5HX09FUykpfWxldCBiYT0iV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0Ijtjb25zdCBTYT0iRVhUX2NvbG9yX2J1ZmZlcl9oYWxmX2Zsb2F0IjtpZih0aGlzLnBhcmFsbGVsQ29tcGlsYXRpb25FeHRlbnNpb249dGhpcy5nbC5nZXRFeHRlbnNpb24oIktIUl9wYXJhbGxlbF9zaGFkZXJfY29tcGlsZSIpLGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0xKXtjb25zdCBUYT0iT0VTX3RleHR1cmVfZmxvYXQiLHdhPSJPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IjtpZih0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbj1nZXRFeHRlbnNpb25PclRocm93JDEodGhpcy5nbCxUYSksaGFzRXh0ZW5zaW9uJDEodGhpcy5nbCx3YSkpdGhpcy50ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uPWdldEV4dGVuc2lvbk9yVGhyb3ckMSh0aGlzLmdsLHdhKTtlbHNlIGlmKGVudiQxKCkuZ2V0KCJXRUJHTF9GT1JDRV9GMTZfVEVYVFVSRVMiKSl0aHJvdyBuZXcgRXJyb3IoIkdMIGNvbnRleHQgZG9lcyBub3Qgc3VwcG9ydCBoYWxmIGZsb2F0IHRleHR1cmVzLCB5ZXQgdGhlIGVudmlyb25tZW50IGZsYWcgV0VCR0xfRk9SQ0VfRjE2X1RFWFRVUkVTIGlzIHNldCB0byB0cnVlLiIpO2lmKHRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbj10aGlzLmdsLmdldEV4dGVuc2lvbihiYSksaGFzRXh0ZW5zaW9uJDEodGhpcy5nbCxTYSkpdGhpcy5jb2xvckJ1ZmZlckhhbGZGbG9hdEV4dGVuc2lvbj1nZXRFeHRlbnNpb25PclRocm93JDEodGhpcy5nbCxTYSk7ZWxzZSBpZihlbnYkMSgpLmdldCgiV0VCR0xfRk9SQ0VfRjE2X1RFWFRVUkVTIikpdGhyb3cgbmV3IEVycm9yKCJHTCBjb250ZXh0IGRvZXMgbm90IHN1cHBvcnQgY29sb3IgcmVuZGVyYWJsZSBoYWxmIGZsb2F0cywgeWV0IHRoZSBlbnZpcm9ubWVudCBmbGFnIFdFQkdMX0ZPUkNFX0YxNl9URVhUVVJFUyBpcyBzZXQgdG8gdHJ1ZS4iKX1lbHNlIGlmKGJhPSJFWFRfY29sb3JfYnVmZmVyX2Zsb2F0IixoYXNFeHRlbnNpb24kMSh0aGlzLmdsLGJhKSl0aGlzLmNvbG9yQnVmZmVyRmxvYXRFeHRlbnNpb249dGhpcy5nbC5nZXRFeHRlbnNpb24oYmEpO2Vsc2UgaWYoaGFzRXh0ZW5zaW9uJDEodGhpcy5nbCxTYSkpdGhpcy5jb2xvckJ1ZmZlckhhbGZGbG9hdEV4dGVuc2lvbj10aGlzLmdsLmdldEV4dGVuc2lvbihTYSk7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIkdMIGNvbnRleHQgZG9lcyBub3Qgc3VwcG9ydCBjb2xvciByZW5kZXJhYmxlIGZsb2F0cyIpO3RoaXMudmVydGV4QnVmZmVyPWNyZWF0ZVZlcnRleEJ1ZmZlciQxKHRoaXMuZ2wpLHRoaXMuaW5kZXhCdWZmZXI9Y3JlYXRlSW5kZXhCdWZmZXIkMSh0aGlzLmdsKSx0aGlzLmZyYW1lYnVmZmVyPWNyZWF0ZUZyYW1lYnVmZmVyJDEodGhpcy5nbCksdGhpcy50ZXh0dXJlQ29uZmlnPWdldFRleHR1cmVDb25maWckMSh0aGlzLmdsLHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbil9Z2V0IGRlYnVnKCl7cmV0dXJuIGVudiQxKCkuZ2V0Qm9vbCgiREVCVUciKX1kaXNwb3NlKCl7aWYodGhpcy5kaXNwb3NlZClyZXR1cm47dGhpcy5wcm9ncmFtIT1udWxsJiZjb25zb2xlLndhcm4oIkRpc3Bvc2luZyBhIEdQR1BVQ29udGV4dCB0aGF0IHN0aWxsIGhhcyBhIGJvdW5kIFdlYkdMUHJvZ3JhbS4gVGhpcyBpcyBwcm9iYWJseSBhIHJlc291cmNlIGxlYWssIGRlbGV0ZSB0aGUgcHJvZ3JhbSB3aXRoIEdQR1BVQ29udGV4dC5kZWxldGVQcm9ncmFtIGJlZm9yZSBkaXNwb3NpbmcuIiksdGhpcy5vdXRwdXRUZXh0dXJlIT1udWxsJiZjb25zb2xlLndhcm4oIkRpc3Bvc2luZyBhIEdQR1BVQ29udGV4dCB0aGF0IHN0aWxsIGhhcyBhIGJvdW5kIG91dHB1dCBtYXRyaXggdGV4dHVyZS4gIFRoaXMgaXMgcHJvYmFibHkgYSByZXNvdXJjZSBsZWFrLCBkZWxldGUgdGhlIG91dHB1dCBtYXRyaXggdGV4dHVyZSB3aXRoIEdQR1BVQ29udGV4dC5kZWxldGVNYXRyaXhUZXh0dXJlIGJlZm9yZSBkaXNwb3NpbmcuIik7Y29uc3QgYWE9dGhpcy5nbDtjYWxsQW5kQ2hlY2skMShhYSwoKT0+YWEuZmluaXNoKCkpLGNhbGxBbmRDaGVjayQxKGFhLCgpPT5hYS5iaW5kRnJhbWVidWZmZXIoYWEuRlJBTUVCVUZGRVIsbnVsbCkpLGNhbGxBbmRDaGVjayQxKGFhLCgpPT5hYS5kZWxldGVGcmFtZWJ1ZmZlcih0aGlzLmZyYW1lYnVmZmVyKSksY2FsbEFuZENoZWNrJDEoYWEsKCk9PmFhLmJpbmRCdWZmZXIoYWEuQVJSQVlfQlVGRkVSLG51bGwpKSxjYWxsQW5kQ2hlY2skMShhYSwoKT0+YWEuYmluZEJ1ZmZlcihhYS5FTEVNRU5UX0FSUkFZX0JVRkZFUixudWxsKSksY2FsbEFuZENoZWNrJDEoYWEsKCk9PmFhLmRlbGV0ZUJ1ZmZlcih0aGlzLmluZGV4QnVmZmVyKSksdGhpcy5kaXNwb3NlZD0hMH1jcmVhdGVGbG9hdDMyTWF0cml4VGV4dHVyZShhYSx4YSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY3JlYXRlRmxvYXQzMk1hdHJpeFRleHR1cmUkMSh0aGlzLmdsLGFhLHhhLHRoaXMudGV4dHVyZUNvbmZpZyl9Y3JlYXRlRmxvYXQxNk1hdHJpeFRleHR1cmUoYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNyZWF0ZUZsb2F0MTZNYXRyaXhUZXh0dXJlJDEodGhpcy5nbCxhYSx4YSx0aGlzLnRleHR1cmVDb25maWcpfWNyZWF0ZVVuc2lnbmVkQnl0ZXNNYXRyaXhUZXh0dXJlKGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjcmVhdGVVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZSQxKHRoaXMuZ2wsYWEseGEsdGhpcy50ZXh0dXJlQ29uZmlnKX11cGxvYWRQaXhlbERhdGFUb1RleHR1cmUoYWEseGEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksdXBsb2FkUGl4ZWxEYXRhVG9UZXh0dXJlJDEodGhpcy5nbCxhYSx4YSl9dXBsb2FkRGVuc2VNYXRyaXhUb1RleHR1cmUoYWEseGEsYmEsU2Epe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksdXBsb2FkRGVuc2VNYXRyaXhUb1RleHR1cmUkMSh0aGlzLmdsLGFhLHhhLGJhLFNhLHRoaXMudGV4dHVyZUNvbmZpZyl9Y3JlYXRlRmxvYXQxNlBhY2tlZE1hdHJpeFRleHR1cmUoYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNyZWF0ZUZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlJDEodGhpcy5nbCxhYSx4YSx0aGlzLnRleHR1cmVDb25maWcpfWNyZWF0ZVBhY2tlZE1hdHJpeFRleHR1cmUoYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNyZWF0ZVBhY2tlZE1hdHJpeFRleHR1cmUkMSh0aGlzLmdsLGFhLHhhLHRoaXMudGV4dHVyZUNvbmZpZyl9ZGVsZXRlTWF0cml4VGV4dHVyZShhYSl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0aGlzLm91dHB1dFRleHR1cmU9PT1hYSYmKHVuYmluZENvbG9yVGV4dHVyZUZyb21GcmFtZWJ1ZmZlciQxKHRoaXMuZ2wsdGhpcy5mcmFtZWJ1ZmZlciksdGhpcy5vdXRwdXRUZXh0dXJlPW51bGwpLGNhbGxBbmRDaGVjayQxKHRoaXMuZ2wsKCk9PnRoaXMuZ2wuZGVsZXRlVGV4dHVyZShhYSkpfWRvd25sb2FkQnl0ZUVuY29kZWRGbG9hdE1hdHJpeEZyb21PdXRwdXRUZXh0dXJlKGFhLHhhLGJhKXtyZXR1cm4gdGhpcy5kb3dubG9hZE1hdHJpeERyaXZlcihhYSwoKT0+ZG93bmxvYWRCeXRlRW5jb2RlZEZsb2F0TWF0cml4RnJvbU91dHB1dFRleHR1cmUkMSh0aGlzLmdsLHhhLGJhLHRoaXMudGV4dHVyZUNvbmZpZykpfWRvd25sb2FkUGFja2VkTWF0cml4RnJvbUJ1ZmZlcihhYSx4YSxiYSxTYSxUYSx3YSl7cmV0dXJuIGRvd25sb2FkUGFja2VkTWF0cml4RnJvbUJ1ZmZlciQxKHRoaXMuZ2wsYWEseGEsYmEsU2EsVGEsd2EsdGhpcy50ZXh0dXJlQ29uZmlnKX1kb3dubG9hZEZsb2F0MzJNYXRyaXhGcm9tQnVmZmVyKGFhLHhhKXtyZXR1cm4gZG93bmxvYWRGbG9hdDMyTWF0cml4RnJvbUJ1ZmZlciQxKHRoaXMuZ2wsYWEseGEpfWNyZWF0ZUJ1ZmZlckZyb21UZXh0dXJlKGFhLHhhLGJhKXt0aGlzLmJpbmRUZXh0dXJlVG9GcmFtZUJ1ZmZlcihhYSk7Y29uc3QgU2E9Y3JlYXRlQnVmZmVyRnJvbU91dHB1dFRleHR1cmUkMSh0aGlzLmdsLHhhLGJhLHRoaXMudGV4dHVyZUNvbmZpZyk7cmV0dXJuIHRoaXMudW5iaW5kVGV4dHVyZVRvRnJhbWVCdWZmZXIoKSxTYX1jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKXtjb25zdCBhYT10aGlzLmNyZWF0ZUZlbmNlKHRoaXMuZ2wpO3JldHVybiB0aGlzLnBvbGxGZW5jZShhYSl9Y3JlYXRlRmVuY2UoYWEpe2xldCB4YSxiYTtpZihlbnYkMSgpLmdldEJvb2woIldFQkdMX0ZFTkNFX0FQSV9FTkFCTEVEIikpe2NvbnN0IFNhPWFhLFRhPVNhLmZlbmNlU3luYyhTYS5TWU5DX0dQVV9DT01NQU5EU19DT01QTEVURSwwKTthYS5mbHVzaCgpLGJhPSgpPT57Y29uc3Qgd2E9U2EuY2xpZW50V2FpdFN5bmMoVGEsMCwwKTtyZXR1cm4gd2E9PT1TYS5BTFJFQURZX1NJR05BTEVEfHx3YT09PVNhLkNPTkRJVElPTl9TQVRJU0ZJRUR9LHhhPVRhfWVsc2UgZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIik+MD8oeGE9dGhpcy5iZWdpblF1ZXJ5KCksdGhpcy5lbmRRdWVyeSgpLGJhPSgpPT50aGlzLmlzUXVlcnlBdmFpbGFibGUoeGEsZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIikpKTpiYT0oKT0+ITA7cmV0dXJue3F1ZXJ5OnhhLGlzRmVuY2VQYXNzZWQ6YmF9fWRvd25sb2FkTWF0cml4RnJvbVBhY2tlZFRleHR1cmUoYWEseGEsYmEpe3JldHVybiB0aGlzLmRvd25sb2FkTWF0cml4RHJpdmVyKGFhLCgpPT5kb3dubG9hZE1hdHJpeEZyb21QYWNrZWRPdXRwdXRUZXh0dXJlJDEodGhpcy5nbCx4YSxiYSkpfWNyZWF0ZVByb2dyYW0oYWEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCk7Y29uc3QgeGE9dGhpcy5nbDt0aGlzLnZlcnRleFNoYWRlcj09bnVsbCYmKHRoaXMudmVydGV4U2hhZGVyPWNyZWF0ZVZlcnRleFNoYWRlciQyKHhhKSk7Y29uc3QgYmE9Y3JlYXRlUHJvZ3JhbSQxKHhhKTtjYWxsQW5kQ2hlY2skMSh4YSwoKT0+eGEuYXR0YWNoU2hhZGVyKGJhLHRoaXMudmVydGV4U2hhZGVyKSksY2FsbEFuZENoZWNrJDEoeGEsKCk9PnhhLmF0dGFjaFNoYWRlcihiYSxhYSkpLGxpbmtQcm9ncmFtJDEoeGEsYmEpO2NvbnN0IFNhPU9iamVjdC5hc3NpZ24oYmEse3Zhbzp0aGlzLmNyZWF0ZVZlcnRleEFycmF5KCl9KTtyZXR1cm4gdGhpcy5kZWJ1ZyYmdmFsaWRhdGVQcm9ncmFtJDEoeGEsU2EpLFNhfWJ1aWxkVmFvKGFhKXt0aGlzLnNldFByb2dyYW0oYWEpLHRoaXMuYmluZFZlcnRleEFycmF5KGFhLnZhbyk7Y29uc3QgeGE9dGhpcy5nbDtjYWxsQW5kQ2hlY2skMSh4YSwoKT0+eGEuYmluZEJ1ZmZlcih4YS5FTEVNRU5UX0FSUkFZX0JVRkZFUix0aGlzLmluZGV4QnVmZmVyKSksYmluZFZlcnRleFByb2dyYW1BdHRyaWJ1dGVTdHJlYW1zJDEoeGEsYWEsdGhpcy52ZXJ0ZXhCdWZmZXIpfWRlbGV0ZVByb2dyYW0oYWEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksYWE9PT10aGlzLnByb2dyYW0mJih0aGlzLnByb2dyYW09bnVsbCksYWEhPW51bGwmJihjYWxsQW5kQ2hlY2skMSh0aGlzLmdsLCgpPT50aGlzLmdsLmRlbGV0ZVByb2dyYW0oYWEpKSx0aGlzLmRlbGV0ZVZlcnRleEFycmF5KGFhLnZhbykpfXNldFByb2dyYW0oYWEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksdGhpcy5wcm9ncmFtPWFhLHRoaXMucHJvZ3JhbSE9bnVsbCYmdGhpcy5kZWJ1ZyYmdmFsaWRhdGVQcm9ncmFtJDEodGhpcy5nbCx0aGlzLnByb2dyYW0pLGNhbGxBbmRDaGVjayQxKHRoaXMuZ2wsKCk9PnRoaXMuZ2wudXNlUHJvZ3JhbShhYSkpfWdldFVuaWZvcm1Mb2NhdGlvbihhYSx4YSxiYT0hMCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYmE/Z2V0UHJvZ3JhbVVuaWZvcm1Mb2NhdGlvbk9yVGhyb3ckMSh0aGlzLmdsLGFhLHhhKTpnZXRQcm9ncmFtVW5pZm9ybUxvY2F0aW9uJDEodGhpcy5nbCxhYSx4YSl9Z2V0QXR0cmlidXRlTG9jYXRpb24oYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNhbGxBbmRDaGVjayQxKHRoaXMuZ2wsKCk9PnRoaXMuZ2wuZ2V0QXR0cmliTG9jYXRpb24oYWEseGEpKX1nZXRVbmlmb3JtTG9jYXRpb25Ob1Rocm93KGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0aGlzLmdsLmdldFVuaWZvcm1Mb2NhdGlvbihhYSx4YSl9c2V0SW5wdXRNYXRyaXhUZXh0dXJlKGFhLHhhLGJhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRoaXMudGhyb3dJZk5vUHJvZ3JhbSgpLGJpbmRUZXh0dXJlVG9Qcm9ncmFtVW5pZm9ybVNhbXBsZXIkMSh0aGlzLmdsLGFhLHhhLGJhKX1zZXRPdXRwdXRNYXRyaXhUZXh0dXJlKGFhLHhhLGJhKXt0aGlzLnNldE91dHB1dE1hdHJpeFRleHR1cmVEcml2ZXIoYWEsYmEseGEpfXNldE91dHB1dFBhY2tlZE1hdHJpeFRleHR1cmUoYWEseGEsYmEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCk7Y29uc3RbU2EsVGFdPWdldFBhY2tlZE1hdHJpeFRleHR1cmVTaGFwZVdpZHRoSGVpZ2h0JDEoeGEsYmEpO3RoaXMuc2V0T3V0cHV0TWF0cml4VGV4dHVyZURyaXZlcihhYSxTYSxUYSl9c2V0T3V0cHV0TWF0cml4V3JpdGVSZWdpb24oYWEseGEsYmEsU2Epe3RoaXMuc2V0T3V0cHV0TWF0cml4V3JpdGVSZWdpb25Ecml2ZXIoYmEsYWEsU2EseGEpfXNldE91dHB1dFBhY2tlZE1hdHJpeFdyaXRlUmVnaW9uKGFhLHhhLGJhLFNhKXt0aHJvdyBuZXcgRXJyb3IoInNldE91dHB1dFBhY2tlZE1hdHJpeFdyaXRlUmVnaW9uIG5vdCBpbXBsZW1lbnRlZC4iKX1kZWJ1Z1ZhbGlkYXRlKCl7dGhpcy5wcm9ncmFtIT1udWxsJiZ2YWxpZGF0ZVByb2dyYW0kMSh0aGlzLmdsLHRoaXMucHJvZ3JhbSksdmFsaWRhdGVGcmFtZWJ1ZmZlciQxKHRoaXMuZ2wpfWV4ZWN1dGVQcm9ncmFtKCl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0aGlzLnRocm93SWZOb1Byb2dyYW0oKTtjb25zdCBhYT10aGlzLmdsO2lmKHRoaXMuZGVidWcpe2NvbnN0IHhhPXRoaXMuZ2V0VmVydGV4QXJyYXkoKTtjb25zb2xlLmFzc2VydCh4YT09PXRoaXMucHJvZ3JhbS52YW8sIlZBTyBjaGFuZ2VkIGJldHdlZW4gc2V0UHJvZ3JhbSBhbmQgZXhlY3V0ZVByb2dyYW0hIiksdGhpcy5kZWJ1Z1ZhbGlkYXRlKCl9Y2FsbEFuZENoZWNrJDEoYWEsKCk9PmFhLmRyYXdFbGVtZW50cyhhYS5UUklBTkdMRVMsNixhYS5VTlNJR05FRF9TSE9SVCwwKSl9YmxvY2tVbnRpbEFsbFByb2dyYW1zQ29tcGxldGVkKCl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjYWxsQW5kQ2hlY2skMSh0aGlzLmdsLCgpPT50aGlzLmdsLmZpbmlzaCgpKX1nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uKCl7cmV0dXJuIHRoaXMuZGlzam9pbnRRdWVyeVRpbWVyRXh0ZW5zaW9uPT1udWxsJiYodGhpcy5kaXNqb2ludFF1ZXJ5VGltZXJFeHRlbnNpb249Z2V0RXh0ZW5zaW9uT3JUaHJvdyQxKHRoaXMuZ2wsZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIik9PT0yPyJFWFRfZGlzam9pbnRfdGltZXJfcXVlcnlfd2ViZ2wyIjoiRVhUX2Rpc2pvaW50X3RpbWVyX3F1ZXJ5IikpLHRoaXMuZGlzam9pbnRRdWVyeVRpbWVyRXh0ZW5zaW9ufWdldFF1ZXJ5VGltZXJFeHRlbnNpb25XZWJHTDIoKXtyZXR1cm4gdGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uKCl9Z2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMSgpe3JldHVybiB0aGlzLmdldFF1ZXJ5VGltZXJFeHRlbnNpb24oKX1iZWdpblF1ZXJ5KCl7aWYoZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIik9PT0yKXtjb25zdCBiYT10aGlzLmdsLFNhPXRoaXMuZ2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMigpLFRhPWJhLmNyZWF0ZVF1ZXJ5KCk7cmV0dXJuIGJhLmJlZ2luUXVlcnkoU2EuVElNRV9FTEFQU0VEX0VYVCxUYSksVGF9Y29uc3QgYWE9dGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wxKCkseGE9YWEuY3JlYXRlUXVlcnlFWFQoKTtyZXR1cm4gYWEuYmVnaW5RdWVyeUVYVChhYS5USU1FX0VMQVBTRURfRVhULHhhKSx4YX1lbmRRdWVyeSgpe2lmKGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fVkVSU0lPTiIpPT09Mil7Y29uc3QgeGE9dGhpcy5nbCxiYT10aGlzLmdldFF1ZXJ5VGltZXJFeHRlbnNpb25XZWJHTDIoKTt4YS5lbmRRdWVyeShiYS5USU1FX0VMQVBTRURfRVhUKTtyZXR1cm59Y29uc3QgYWE9dGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wxKCk7YWEuZW5kUXVlcnlFWFQoYWEuVElNRV9FTEFQU0VEX0VYVCl9YXN5bmMgd2FpdEZvclF1ZXJ5QW5kR2V0VGltZShhYSl7cmV0dXJuIGF3YWl0IHJlcGVhdGVkVHJ5JDEoKCk9PnRoaXMuZGlzcG9zZWR8fHRoaXMuaXNRdWVyeUF2YWlsYWJsZShhYSxlbnYkMSgpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1ZFUlNJT04iKSkpLHRoaXMuZ2V0UXVlcnlUaW1lKGFhLGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fVkVSU0lPTiIpKX1nZXRRdWVyeVRpbWUoYWEseGEpe2lmKHhhPT09MClyZXR1cm4gbnVsbDtpZih4YT09PTIpe2NvbnN0IGJhPXRoaXMuZ2w7cmV0dXJuIGJhLmdldFF1ZXJ5UGFyYW1ldGVyKGFhLGJhLlFVRVJZX1JFU1VMVCkvMWU2fWVsc2V7Y29uc3QgYmE9dGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wxKCk7cmV0dXJuIGJhLmdldFF1ZXJ5T2JqZWN0RVhUKGFhLGJhLlFVRVJZX1JFU1VMVF9FWFQpLzFlNn19aXNRdWVyeUF2YWlsYWJsZShhYSx4YSl7aWYoeGE9PT0wKXJldHVybiEwO2lmKHhhPT09Mil7Y29uc3QgYmE9dGhpcy5nbCxTYT10aGlzLmdldFF1ZXJ5VGltZXJFeHRlbnNpb25XZWJHTDIoKSxUYT1iYS5nZXRRdWVyeVBhcmFtZXRlcihhYSxiYS5RVUVSWV9SRVNVTFRfQVZBSUxBQkxFKTtyZXR1cm4gdGhpcy5kaXNqb2ludD09bnVsbCYmKHRoaXMuZGlzam9pbnQ9dGhpcy5nbC5nZXRQYXJhbWV0ZXIoU2EuR1BVX0RJU0pPSU5UX0VYVCkpLFRhJiYhdGhpcy5kaXNqb2ludH1lbHNle2NvbnN0IGJhPXRoaXMuZ2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMSgpLFNhPWJhLmdldFF1ZXJ5T2JqZWN0RVhUKGFhLGJhLlFVRVJZX1JFU1VMVF9BVkFJTEFCTEVfRVhUKTtyZXR1cm4gdGhpcy5kaXNqb2ludD09bnVsbCYmKHRoaXMuZGlzam9pbnQ9dGhpcy5nbC5nZXRQYXJhbWV0ZXIoYmEuR1BVX0RJU0pPSU5UX0VYVCkpLFNhJiYhdGhpcy5kaXNqb2ludH19cG9sbEZlbmNlKGFhKXtyZXR1cm4gbmV3IFByb21pc2UoeGE9Pnt0aGlzLmFkZEl0ZW1Ub1BvbGwoKCk9PmFhLmlzRmVuY2VQYXNzZWQoKSwoKT0+eGEoKSl9KX1wb2xsSXRlbXMoKXtjb25zdCBhYT1saW5lYXJTZWFyY2hMYXN0VHJ1ZSQxKHRoaXMuaXRlbXNUb1BvbGwubWFwKHhhPT54YS5pc0RvbmVGbikpO2ZvcihsZXQgeGE9MDt4YTw9YWE7Kyt4YSl7Y29uc3R7cmVzb2x2ZUZuOmJhfT10aGlzLml0ZW1zVG9Qb2xsW3hhXTtiYSgpfXRoaXMuaXRlbXNUb1BvbGw9dGhpcy5pdGVtc1RvUG9sbC5zbGljZShhYSsxKX1hZGRJdGVtVG9Qb2xsKGFhLHhhKXtpZih0aGlzLml0ZW1zVG9Qb2xsLnB1c2goe2lzRG9uZUZuOmFhLHJlc29sdmVGbjp4YX0pLHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoPjEpcmV0dXJuO2xldCBiYTsic2V0VGltZW91dEN1c3RvbSJpbiBlbnYkMSgpLnBsYXRmb3JtJiYoYmE9ZW52JDEoKS5wbGF0Zm9ybS5zZXRUaW1lb3V0Q3VzdG9tLmJpbmQoZW52JDEoKS5wbGF0Zm9ybSkpLHJlcGVhdGVkVHJ5JDEoKCk9Pih0aGlzLnBvbGxJdGVtcygpLHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoPT09MCksKCk9PjAsbnVsbCxiYSl9YmluZFRleHR1cmVUb0ZyYW1lQnVmZmVyKGFhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpLGJpbmRDb2xvclRleHR1cmVUb0ZyYW1lYnVmZmVyJDEodGhpcy5nbCxhYSx0aGlzLmZyYW1lYnVmZmVyKSx0aGlzLmRlYnVnJiZ2YWxpZGF0ZUZyYW1lYnVmZmVyJDEodGhpcy5nbCl9dW5iaW5kVGV4dHVyZVRvRnJhbWVCdWZmZXIoKXt0aGlzLm91dHB1dFRleHR1cmUhPW51bGw/KGJpbmRDb2xvclRleHR1cmVUb0ZyYW1lYnVmZmVyJDEodGhpcy5nbCx0aGlzLm91dHB1dFRleHR1cmUsdGhpcy5mcmFtZWJ1ZmZlciksdGhpcy5kZWJ1ZyYmdmFsaWRhdGVGcmFtZWJ1ZmZlciQxKHRoaXMuZ2wpKTp1bmJpbmRDb2xvclRleHR1cmVGcm9tRnJhbWVidWZmZXIkMSh0aGlzLmdsLHRoaXMuZnJhbWVidWZmZXIpfWRvd25sb2FkTWF0cml4RHJpdmVyKGFhLHhhKXt0aGlzLmJpbmRUZXh0dXJlVG9GcmFtZUJ1ZmZlcihhYSk7Y29uc3QgYmE9eGEoKTtyZXR1cm4gdGhpcy51bmJpbmRUZXh0dXJlVG9GcmFtZUJ1ZmZlcigpLGJhfXNldE91dHB1dE1hdHJpeFRleHR1cmVEcml2ZXIoYWEseGEsYmEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCk7Y29uc3QgU2E9dGhpcy5nbDtiaW5kQ29sb3JUZXh0dXJlVG9GcmFtZWJ1ZmZlciQxKFNhLGFhLHRoaXMuZnJhbWVidWZmZXIpLHRoaXMuZGVidWcmJnZhbGlkYXRlRnJhbWVidWZmZXIkMShTYSksdGhpcy5vdXRwdXRUZXh0dXJlPWFhLGNhbGxBbmRDaGVjayQxKFNhLCgpPT5TYS52aWV3cG9ydCgwLDAseGEsYmEpKSxjYWxsQW5kQ2hlY2skMShTYSwoKT0+U2Euc2Npc3NvcigwLDAseGEsYmEpKX1zZXRPdXRwdXRNYXRyaXhXcml0ZVJlZ2lvbkRyaXZlcihhYSx4YSxiYSxTYSl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjYWxsQW5kQ2hlY2skMSh0aGlzLmdsLCgpPT50aGlzLmdsLnNjaXNzb3IoYWEseGEsYmEsU2EpKX10aHJvd0lmRGlzcG9zZWQoKXtpZih0aGlzLmRpc3Bvc2VkKXRocm93IG5ldyBFcnJvcigiQXR0ZW1wdGVkIHRvIHVzZSBkaXNwb3NlZCBHUEdQVUNvbnRleHQuIil9dGhyb3dJZk5vUHJvZ3JhbSgpe2lmKHRoaXMucHJvZ3JhbT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoIk5vIEdQVSBwcm9ncmFtIGlzIGN1cnJlbnRseSBzZXQuIil9fTtmdW5jdGlvbiBsaW5lYXJTZWFyY2hMYXN0VHJ1ZSQxKGhhKXtsZXQgYWE9MDtmb3IoO2FhPGhhLmxlbmd0aCYmaGFbYWFdKCk7KythYSk7cmV0dXJuIGFhLTF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3R7YWRkSW1wbDphZGRJbXBsQ1BVJDEsYmluY291bnRJbXBsOmJpbmNvdW50SW1wbENQVSQxLGJpbmNvdW50UmVkdWNlSW1wbDpiaW5jb3VudFJlZHVjZUltcGxDUFUkMSxiaXR3aXNlQW5kSW1wbDpiaXR3aXNlQW5kSW1wbENQVSQxLGNhc3RJbXBsOmNhc3RJbXBsQ1BVJDEsY2VpbEltcGw6Y2VpbEltcGxDUFUkMSxjb25jYXRJbXBsOmNvbmNhdEltcGxDUFUkMSxlcXVhbEltcGw6ZXF1YWxJbXBsQ1BVJDEsZXhwSW1wbDpleHBJbXBsQ1BVJDEsZXhwbTFJbXBsOmV4cG0xSW1wbENQVSQxLGZsb29ySW1wbDpmbG9vckltcGxDUFUkMSxnYXRoZXJOZEltcGw6Z2F0aGVyTmRJbXBsQ1BVJDEsZ2F0aGVyVjJJbXBsOmdhdGhlclYySW1wbENQVSQxLGdyZWF0ZXJJbXBsOmdyZWF0ZXJJbXBsQ1BVJDEsZ3JlYXRlckVxdWFsSW1wbDpncmVhdGVyRXF1YWxJbXBsQ1BVJDEsbGVzc0ltcGw6bGVzc0ltcGxDUFUkMSxsZXNzRXF1YWxJbXBsOmxlc3NFcXVhbEltcGxDUFUkMSxsaW5TcGFjZUltcGw6bGluU3BhY2VJbXBsQ1BVJDEsbG9nSW1wbDpsb2dJbXBsQ1BVJDEsbWF4SW1wbDptYXhJbXBsQ1BVJDEsbWF4aW11bUltcGw6bWF4aW11bUltcGxDUFUkMSxtaW5pbXVtSW1wbDptaW5pbXVtSW1wbENQVSQxLG11bHRpcGx5SW1wbDptdWx0aXBseUltcGxDUFUkMSxuZWdJbXBsOm5lZ0ltcGxDUFUkMSxub3RFcXVhbEltcGw6bm90RXF1YWxJbXBsQ1BVJDEscHJvZEltcGw6cHJvZEltcGxDUFUkMSxyYWdnZWRHYXRoZXJJbXBsOnJhZ2dlZEdhdGhlckltcGxDUFUkMSxyYWdnZWRSYW5nZUltcGw6cmFnZ2VkUmFuZ2VJbXBsQ1BVJDEscmFnZ2VkVGVuc29yVG9UZW5zb3JJbXBsOnJhZ2dlZFRlbnNvclRvVGVuc29ySW1wbENQVSQxLHJhbmdlSW1wbDpyYW5nZUltcGxDUFUkMSxyc3FydEltcGw6cnNxcnRJbXBsQ1BVJDEsc2NhdHRlckltcGw6c2NhdHRlckltcGxDUFUkMSxzaWdtb2lkSW1wbDpzaWdtb2lkSW1wbENQVSQxLHNpbXBsZUFic0ltcGw6c2ltcGxlQWJzSW1wbENQVSQxLHNsaWNlSW1wbDpzbGljZUltcGxDUFUkMSxzcGFyc2VGaWxsRW1wdHlSb3dzSW1wbDpzcGFyc2VGaWxsRW1wdHlSb3dzSW1wbENQVSQxLHNwYXJzZVJlc2hhcGVJbXBsOnNwYXJzZVJlc2hhcGVJbXBsQ1BVJDEsc3BhcnNlU2VnbWVudFJlZHVjdGlvbkltcGw6c3BhcnNlU2VnbWVudFJlZHVjdGlvbkltcGxDUFUkMSxzcXJ0SW1wbDpzcXJ0SW1wbENQVSQxLHN0YXRpY1JlZ2V4UmVwbGFjZUltcGw6c3RhdGljUmVnZXhSZXBsYWNlSW1wbENQVSQxLHN0cmlkZWRTbGljZUltcGw6c3RyaWRlZFNsaWNlSW1wbENQVSQxLHN0cmluZ05HcmFtc0ltcGw6c3RyaW5nTkdyYW1zSW1wbENQVSQxLHN0cmluZ1NwbGl0SW1wbDpzdHJpbmdTcGxpdEltcGxDUFUkMSxzdHJpbmdUb0hhc2hCdWNrZXRGYXN0SW1wbDpzdHJpbmdUb0hhc2hCdWNrZXRGYXN0SW1wbENQVSQxLHN1YkltcGw6c3ViSW1wbENQVSQxLHRpbGVJbXBsOnRpbGVJbXBsQ1BVJDEsdG9wS0ltcGw6dG9wS0ltcGxDUFUkMSx0cmFuc3Bvc2VJbXBsOnRyYW5zcG9zZUltcGxDUFUkMSx1bmlxdWVJbXBsOnVuaXF1ZUltcGxDUFUkMX09c2hhcmVkJDE7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0VmVjQ2hhbm5lbHMkMShoYSxhYSl7cmV0dXJuWyJ4IiwieSIsInoiLCJ3IiwidSIsInYiXS5zbGljZSgwLGFhKS5tYXAoeGE9PmAke2hhfS4ke3hhfWApfWZ1bmN0aW9uIGdldENoYW5uZWxzJDEoaGEsYWEpe3JldHVybiBhYT09PTE/W2hhXTpnZXRWZWNDaGFubmVscyQxKGhhLGFhKX1mdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMkNShoYSxhYSl7aWYoaGE9PT0xKXJldHVybiJyYyI7bGV0IHhhPSIiO2ZvcihsZXQgYmE9MDtiYTxoYTtiYSsrKXhhKz1hYVtiYV0sYmE8aGEtMSYmKHhhKz0iLCIpO3JldHVybiB4YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUGFja1Byb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7aWYodGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSExLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5yYW5rPWFhLmxlbmd0aCx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKSx0aGlzLnJhbms9PT0wKXRoaXMudXNlckNvZGU9YAogICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgIHNldE91dHB1dCh2ZWM0KGdldEEoKSwgMC4sIDAuLCAwLikpOwogICAgICAgIH0KICAgICAgYDtlbHNle2NvbnN0IHhhPWdldENoYW5uZWxzJDEoInJjIix0aGlzLnJhbmspLGJhPWdldENvb3Jkc0RhdGFUeXBlJDEodGhpcy5yYW5rKSxTYT10aGlzLmdldE91dE9mQm91bmRzQ29uZGl0aW9uKHhhKSxUYT10aGlzLmdldFNldHVwKHhhKSx3YT10aGlzLmdldE91dHB1dCh4YSk7dGhpcy51c2VyQ29kZT1gCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgJHtiYX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTsKCiAgICAgICAgICBpZigke1NhfSkgewogICAgICAgICAgICBzZXRPdXRwdXQodmVjNCgwKSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAke1RhfQoKICAgICAgICAgICAgc2V0T3V0cHV0KHZlYzQoJHt3YX0pKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIGB9fWdldFNvdXJjZUNvb3Jkc0FycihhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBiYT0wO2JhPD0xO2JhKyspZm9yKGxldCBTYT0wO1NhPD0xO1NhKyspe2xldCBUYT1gJHtiYT09PTA/InIiOiJycDEifSwgJHtTYT09PTA/ImMiOiJjcDEifWA7Zm9yKGxldCB3YT0yO3dhPHRoaXMucmFuazt3YSsrKVRhPWAke2FhW2FhLmxlbmd0aC0xLXdhXX0sYCtUYTt4YS5wdXNoKFRhKX1yZXR1cm4geGF9Z2V0T3V0T2ZCb3VuZHNDb25kaXRpb24oYWEpe2lmKHRoaXMucmFuaz09PTEpcmV0dXJuYHJjID4gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlIjp0aGlzLm91dHB1dFNoYXBlWzBdfWA7bGV0IHhhPSIiO2ZvcihsZXQgYmE9dGhpcy5yYW5rLTI7YmE8dGhpcy5yYW5rO2JhKyspeGErPWAke2FhW2JhXX0gPj0gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/YG91dFNoYXBlWyR7YmF9XWA6dGhpcy5vdXRwdXRTaGFwZVtiYV19YCxiYTx0aGlzLnJhbmstMSYmKHhhKz0ifHwiKTtyZXR1cm4geGF9Z2V0U2V0dXAoYWEpe2lmKHRoaXMucmFuaz09PTEpcmV0dXJuIiI7Y29uc3QgeGE9YWEuc2xpY2UoLTIpLGJhPXRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9gb3V0U2hhcGVbJHt0aGlzLnJhbmt9IC0gMV1gOnRoaXMub3V0cHV0U2hhcGVbdGhpcy5yYW5rLTFdLFNhPXRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9gb3V0U2hhcGVbJHt0aGlzLnJhbmt9IC0gMl1gOnRoaXMub3V0cHV0U2hhcGVbdGhpcy5yYW5rLTJdO3JldHVybmAKICAgICAgaW50IHIgPSAke3hhWzBdfTsKICAgICAgaW50IGMgPSAke3hhWzFdfTsKICAgICAgaW50IHJwMSA9IHIgKyAxOwogICAgICBpbnQgY3AxID0gYyArIDE7CgogICAgICBib29sIGNFZGdlID0gY3AxID49ICR7YmF9OwogICAgICBib29sIHJFZGdlID0gcnAxID49ICR7U2F9OwogICAgYH1nZXRPdXRwdXQoYWEpe2NvbnN0IHhhPXRoaXMuZ2V0U291cmNlQ29vcmRzQXJyKGFhKTtyZXR1cm4gdGhpcy5yYW5rPT09MT9gZ2V0QShyYyksIChyYyArIDEgPj0gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlIjp0aGlzLm91dHB1dFNoYXBlWzBdfSA/IDAuIDogZ2V0QShyYyArIDEpKSwgMCwgMGA6YGdldEEoJHt4YVswXX0pLAogICAgICAgICAgICBjRWRnZSA/IDAuIDogZ2V0QSgke3hhWzFdfSksCiAgICAgICAgICAgIHJFZGdlID8gMC4gOiBnZXRBKCR7eGFbMl19KSwKICAgICAgICAgICAgckVkZ2UgfHwgY0VkZ2UgPyAwLiA6IGdldEEoJHt4YVszXX0pYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBSZXNoYXBlUGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6ImlucHV0U2hhcGUiLHR5cGU6Iml2ZWMzIn1dLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCk7bGV0IGJhPSIiO2ZvcihsZXQgU2E9MDtTYTw0O1NhKyspe2xldCBUYT0idGhpc1JDID0gcmM7IjtTYSUyPT09MSYmKFRhKz0idGhpc1JDLnogKz0gMTsiKSxTYT4xJiYoVGErPSJ0aGlzUkMueSArPSAxOyIpLGJhKz1gCiAgICAgICAgJHtUYX0KICAgICAgICAke1NhPjA/ImlmKHRoaXNSQy55IDwgcm93cyAmJiB0aGlzUkMueiA8IGNvbHMpeyI6IiJ9CiAgICAgICAgICBpbnQgZmxhdEluZGV4ID0gZ2V0RmxhdEluZGV4KHRoaXNSQyk7CgogICAgICAgICAgaXZlYzMgaW5wdXRSQyA9IGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGZsYXRJbmRleCk7CiAgICAgICAgICB2ZWMyIGlucHV0UkNJbm5lckRpbXMgPSB2ZWMyKGZsb2F0KGlucHV0UkMueSksZmxvYXQoaW5wdXRSQy56KSk7CgogICAgICAgICAgcmVzdWx0WyR7U2F9XSA9CiAgICAgICAgICAgIGdldENoYW5uZWwoZ2V0QShpbnB1dFJDLngsIGlucHV0UkMueSwgaW5wdXRSQy56KSwgaW5wdXRSQ0lubmVyRGltcyk7CiAgICAgICAgJHtTYT4wPyJ9IjoiIn0KICAgICAgYH10aGlzLnVzZXJDb2RlPWAKICAgICAgJHtnZXRSZXNoYXBlZElucHV0Q29vcmRzJDEoeGEsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zKX0KICAgICAgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Z2V0RmxhdEluZGV4RnJvbTNET3V0cHV0JDEoKTpnZXRGbGF0SW5kZXhGcm9tM0QkMShhYSl9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzMgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKCiAgICAgICAgaXZlYzMgdGhpc1JDOwogICAgICAgIGludCByb3dzID0gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlWzFdIjphYVsxXX07CiAgICAgICAgaW50IGNvbHMgPSAke3RoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz8ib3V0U2hhcGVbMl0iOmFhWzJdfTsKCiAgICAgICAgJHtiYX0KCiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fTtmdW5jdGlvbiBnZXRSZXNoYXBlZElucHV0Q29vcmRzJDEoaGEsYWEpe3JldHVybmAKICAgIGl2ZWMzIGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGludCBpbmRleCkgewogICAgICAke2FhP2dldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXhCeVVuaWZvcm0kMShbInIiLCJjIiwiZCJdLCJpbnB1dFNoYXBlIik6Z2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleCQxKFsiciIsImMiLCJkIl0saGEpfQogICAgICByZXR1cm4gaXZlYzMociwgYywgZCk7CiAgICB9CiAgYH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgVGV4dHVyZU1hbmFnZXIkMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy5ncGdwdT1hYSx0aGlzLm51bVVzZWRUZXh0dXJlcz0wLHRoaXMubnVtRnJlZVRleHR1cmVzPTAsdGhpcy5fbnVtQnl0ZXNBbGxvY2F0ZWQ9MCx0aGlzLl9udW1CeXRlc0ZyZWU9MCx0aGlzLmZyZWVUZXh0dXJlcz17fSx0aGlzLnVzZWRUZXh0dXJlcz17fSx0aGlzLmxvZ0VuYWJsZWQ9ITF9YWNxdWlyZVRleHR1cmUoYWEseGEsYmEpe2NvbnN0IFNhPWdldFBoeXNpY2FsRnJvbUxvZ2ljYWxUZXh0dXJlVHlwZSQxKHhhLGJhKSxUYT1nZXRLZXlGcm9tVGV4dHVyZVNoYXBlJDEoYWEsU2EsYmEpO1RhIGluIHRoaXMuZnJlZVRleHR1cmVzfHwodGhpcy5mcmVlVGV4dHVyZXNbVGFdPVtdKSxUYSBpbiB0aGlzLnVzZWRUZXh0dXJlc3x8KHRoaXMudXNlZFRleHR1cmVzW1RhXT1bXSk7Y29uc3Qgd2E9Y29tcHV0ZUJ5dGVzJDEoYWEsU2EsdGhpcy5ncGdwdS5nbCx0aGlzLmdwZ3B1LnRleHR1cmVDb25maWcsYmEpO2lmKHRoaXMuZnJlZVRleHR1cmVzW1RhXS5sZW5ndGg+MCl7dGhpcy5udW1GcmVlVGV4dHVyZXMtLSx0aGlzLm51bVVzZWRUZXh0dXJlcysrLHRoaXMuX251bUJ5dGVzRnJlZS09d2EsdGhpcy5sb2coKTtjb25zdCBrYT10aGlzLmZyZWVUZXh0dXJlc1tUYV0ucG9wKCk7cmV0dXJuIHRoaXMudXNlZFRleHR1cmVzW1RhXS5wdXNoKGthKSxrYX1sZXQgRWE7cmV0dXJuIFNhPT09UGh5c2ljYWxUZXh0dXJlVHlwZSQxLlBBQ0tFRF8yWDJfRkxPQVQzMj9FYT10aGlzLmdwZ3B1LmNyZWF0ZVBhY2tlZE1hdHJpeFRleHR1cmUoYWFbMF0sYWFbMV0pOlNhPT09UGh5c2ljYWxUZXh0dXJlVHlwZSQxLlBBQ0tFRF8yWDJfRkxPQVQxNj9FYT10aGlzLmdwZ3B1LmNyZWF0ZUZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlKGFhWzBdLGFhWzFdKTpTYT09PVBoeXNpY2FsVGV4dHVyZVR5cGUkMS5VTlBBQ0tFRF9GTE9BVDMyP0VhPXRoaXMuZ3BncHUuY3JlYXRlRmxvYXQzMk1hdHJpeFRleHR1cmUoYWFbMF0sYWFbMV0pOlNhPT09UGh5c2ljYWxUZXh0dXJlVHlwZSQxLlVOUEFDS0VEX0ZMT0FUMTY/RWE9dGhpcy5ncGdwdS5jcmVhdGVGbG9hdDE2TWF0cml4VGV4dHVyZShhYVswXSxhYVsxXSk6U2E9PT1QaHlzaWNhbFRleHR1cmVUeXBlJDEuUEFDS0VEXzRYMV9VTlNJR05FRF9CWVRFJiYoRWE9dGhpcy5ncGdwdS5jcmVhdGVVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZShhYVswXSxhYVsxXSkpLHRoaXMudXNlZFRleHR1cmVzW1RhXS5wdXNoKEVhKSx0aGlzLm51bVVzZWRUZXh0dXJlcysrLHRoaXMuX251bUJ5dGVzQWxsb2NhdGVkKz13YSx0aGlzLmxvZygpLEVhfXJlbGVhc2VUZXh0dXJlKGFhLHhhLGJhLFNhKXtpZih0aGlzLmZyZWVUZXh0dXJlcz09bnVsbClyZXR1cm47Y29uc3QgVGE9Z2V0UGh5c2ljYWxGcm9tTG9naWNhbFRleHR1cmVUeXBlJDEoYmEsU2EpLHdhPWdldEtleUZyb21UZXh0dXJlU2hhcGUkMSh4YSxUYSxTYSk7d2EgaW4gdGhpcy5mcmVlVGV4dHVyZXN8fCh0aGlzLmZyZWVUZXh0dXJlc1t3YV09W10pO2NvbnN0IEVhPWNvbXB1dGVCeXRlcyQxKHhhLFRhLHRoaXMuZ3BncHUuZ2wsdGhpcy5ncGdwdS50ZXh0dXJlQ29uZmlnLFNhKSxrYT1lbnYkMSgpLmdldE51bWJlcigiV0VCR0xfREVMRVRFX1RFWFRVUkVfVEhSRVNIT0xEIik7a2EhPT0tMSYmdGhpcy5fbnVtQnl0ZXNBbGxvY2F0ZWQ+a2E/KHRoaXMuZ3BncHUuZGVsZXRlTWF0cml4VGV4dHVyZShhYS50ZXh0dXJlKSx0aGlzLl9udW1CeXRlc0FsbG9jYXRlZC09RWEpOih0aGlzLmZyZWVUZXh0dXJlc1t3YV0ucHVzaChhYSksdGhpcy5udW1GcmVlVGV4dHVyZXMrKyx0aGlzLl9udW1CeXRlc0ZyZWUrPUVhKSx0aGlzLm51bVVzZWRUZXh0dXJlcy0tO2NvbnN0IEFhPXRoaXMudXNlZFRleHR1cmVzW3dhXSxGYT1BYSYmQWEuaW5kZXhPZihhYSk7aWYoRmE9PW51bGx8fEZhPDApdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgcmVsZWFzZSBhIHRleHR1cmUgdGhhdCB3YXMgbmV2ZXIgcHJvdmlkZWQgYnkgdGhpcyB0ZXh0dXJlIG1hbmFnZXIiKTtBYVtGYV09QWFbQWEubGVuZ3RoLTFdLEFhLnBvcCgpLHRoaXMubG9nKCl9bG9nKCl7aWYoIXRoaXMubG9nRW5hYmxlZClyZXR1cm47Y29uc3QgYWE9dGhpcy5udW1GcmVlVGV4dHVyZXMrdGhpcy5udW1Vc2VkVGV4dHVyZXM7Y29uc29sZS5sb2coIkZyZWUvVXNlZCIsYCR7dGhpcy5udW1GcmVlVGV4dHVyZXN9IC8gJHt0aGlzLm51bVVzZWRUZXh0dXJlc31gLGAoJHthYX0pYCk7Y29uc3QgeGE9dGhpcy5fbnVtQnl0ZXNGcmVlL3RoaXMuX251bUJ5dGVzQWxsb2NhdGVkO2NvbnNvbGUubG9nKGBCeXRlcyBhbGxvY2F0ZWQ6ICR7dGhpcy5fbnVtQnl0ZXNBbGxvY2F0ZWR9YCksY29uc29sZS5sb2coYEJ5dGVzIHVudXNlZDogJHt0aGlzLl9udW1CeXRlc0ZyZWV9ICgke01hdGgucm91bmQoMTAwKnhhKX0lKWApfWdldCBudW1CeXRlc0FsbG9jYXRlZCgpe3JldHVybiB0aGlzLl9udW1CeXRlc0FsbG9jYXRlZH1nZXQgbnVtQnl0ZXNGcmVlKCl7cmV0dXJuIHRoaXMuX251bUJ5dGVzRnJlZX1nZXROdW1Vc2VkVGV4dHVyZXMoKXtyZXR1cm4gdGhpcy5udW1Vc2VkVGV4dHVyZXN9Z2V0TnVtRnJlZVRleHR1cmVzKCl7cmV0dXJuIHRoaXMubnVtRnJlZVRleHR1cmVzfWRpc3Bvc2UoKXtpZih0aGlzLmZyZWVUZXh0dXJlcyE9bnVsbCl7Zm9yKGNvbnN0IGFhIGluIHRoaXMuZnJlZVRleHR1cmVzKXRoaXMuZnJlZVRleHR1cmVzW2FhXS5mb3JFYWNoKHhhPT57dGhpcy5ncGdwdS5kZWxldGVNYXRyaXhUZXh0dXJlKHhhLnRleHR1cmUpfSk7Zm9yKGNvbnN0IGFhIGluIHRoaXMudXNlZFRleHR1cmVzKXRoaXMudXNlZFRleHR1cmVzW2FhXS5mb3JFYWNoKHhhPT57dGhpcy5ncGdwdS5kZWxldGVNYXRyaXhUZXh0dXJlKHhhLnRleHR1cmUpfSk7dGhpcy5mcmVlVGV4dHVyZXM9bnVsbCx0aGlzLnVzZWRUZXh0dXJlcz1udWxsLHRoaXMubnVtVXNlZFRleHR1cmVzPTAsdGhpcy5udW1GcmVlVGV4dHVyZXM9MCx0aGlzLl9udW1CeXRlc0FsbG9jYXRlZD0wLHRoaXMuX251bUJ5dGVzRnJlZT0wfX19O2Z1bmN0aW9uIG51bUJ5dGVzRm9ySW50ZXJuYWxGb3JtYXQkMShoYSxhYSl7Y29uc3QgeGE9aGE7aWYoYWE9PT14YS5SMzJGKXJldHVybiA0O2lmKGFhPT09eGEuUjE2RilyZXR1cm4gMjtpZihhYT09PXhhLlJHQkEzMkYpcmV0dXJuIDE2O2lmKGFhPT09aGEuUkdCQSlyZXR1cm4gMTY7aWYoYWE9PT14YS5SR0JBMTZGKXJldHVybiA4O2lmKGFhPT09eGEuUkdCQTgpcmV0dXJuIDQ7dGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGludGVybmFsIGZvcm1hdCAke2FhfWApfWZ1bmN0aW9uIGNvbXB1dGVCeXRlcyQxKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1pbnRlcm5hbEZvcm1hdEZvclBoeXNpY2FsVGV4VHlwZSQxKGFhLGJhKTtsZXQgd2E7aWYoU2Epe2NvbnN0W2thLEFhXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodCQxKGhhWzBdLGhhWzFdKTt3YT1rYSpBYX1lbHNle2NvbnN0W2thLEFhXT1nZXRVbnBhY2tlZE1hdHJpeFRleHR1cmVTaGFwZVdpZHRoSGVpZ2h0JDEoaGFbMF0saGFbMV0pO3dhPWthKkFhfWNvbnN0IEVhPW51bUJ5dGVzRm9ySW50ZXJuYWxGb3JtYXQkMSh4YSxUYSk7cmV0dXJuIHdhKkVhfWZ1bmN0aW9uIGludGVybmFsRm9ybWF0Rm9yUGh5c2ljYWxUZXhUeXBlJDEoaGEsYWEpe3N3aXRjaChoYSl7Y2FzZSBQaHlzaWNhbFRleHR1cmVUeXBlJDEuUEFDS0VEXzJYMl9GTE9BVDMyOnJldHVybiBnZXRJbnRlcm5hbEZvcm1hdEZvclBhY2tlZE1hdHJpeFRleHR1cmUkMShhYSk7Y2FzZSBQaHlzaWNhbFRleHR1cmVUeXBlJDEuUEFDS0VEXzJYMl9GTE9BVDE2OnJldHVybiBnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlJDEoYWEpO2Nhc2UgUGh5c2ljYWxUZXh0dXJlVHlwZSQxLlVOUEFDS0VEX0ZMT0FUMzI6cmV0dXJuIGdldEludGVybmFsRm9ybWF0Rm9yRmxvYXQzMk1hdHJpeFRleHR1cmUkMShhYSk7Y2FzZSBQaHlzaWNhbFRleHR1cmVUeXBlJDEuVU5QQUNLRURfRkxPQVQxNjpyZXR1cm4gZ2V0SW50ZXJuYWxGb3JtYXRGb3JGbG9hdDE2TWF0cml4VGV4dHVyZSQxKGFhKTtjYXNlIFBoeXNpY2FsVGV4dHVyZVR5cGUkMS5QQUNLRURfNFgxX1VOU0lHTkVEX0JZVEU6cmV0dXJuIGdldEludGVybmFsRm9ybWF0Rm9yVW5zaWduZWRCeXRlc01hdHJpeFRleHR1cmUkMShhYSk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcGh5c2ljYWwgdGV4dHVyZSB0eXBlICR7aGF9YCl9fWZ1bmN0aW9uIGdldFBoeXNpY2FsVGV4dHVyZUZvclJlbmRlcmluZyQxKGhhKXtyZXR1cm4gZW52JDEoKS5nZXRCb29sKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9FTkFCTEVEIik/aGE/UGh5c2ljYWxUZXh0dXJlVHlwZSQxLlBBQ0tFRF8yWDJfRkxPQVQzMjpQaHlzaWNhbFRleHR1cmVUeXBlJDEuVU5QQUNLRURfRkxPQVQzMjpoYT9QaHlzaWNhbFRleHR1cmVUeXBlJDEuUEFDS0VEXzJYMl9GTE9BVDE2OlBoeXNpY2FsVGV4dHVyZVR5cGUkMS5VTlBBQ0tFRF9GTE9BVDE2fWZ1bmN0aW9uIGdldFBoeXNpY2FsRnJvbUxvZ2ljYWxUZXh0dXJlVHlwZSQxKGhhLGFhKXtpZihoYT09PVRleHR1cmVVc2FnZSQxLlVQTE9BRClyZXR1cm4gUGh5c2ljYWxUZXh0dXJlVHlwZSQxLlBBQ0tFRF8yWDJfRkxPQVQzMjtpZihoYT09PVRleHR1cmVVc2FnZSQxLlJFTkRFUnx8aGE9PW51bGwpcmV0dXJuIGdldFBoeXNpY2FsVGV4dHVyZUZvclJlbmRlcmluZyQxKGFhKTtpZihoYT09PVRleHR1cmVVc2FnZSQxLkRPV05MT0FEfHxoYT09PVRleHR1cmVVc2FnZSQxLlBJWEVMUylyZXR1cm4gUGh5c2ljYWxUZXh0dXJlVHlwZSQxLlBBQ0tFRF80WDFfVU5TSUdORURfQllURTt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gbG9naWNhbCB0ZXh0dXJlIHR5cGUgJHtoYX1gKX1mdW5jdGlvbiBnZXRLZXlGcm9tVGV4dHVyZVNoYXBlJDEoaGEsYWEseGEpe3JldHVybmAke2hhWzBdfV8ke2hhWzFdfV8ke2FhfV8ke3hhfWB9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFVuYXJ5T3BQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zJDEodGhpcy5vdXRwdXRTaGFwZS5sZW5ndGgpLHRoaXMudXNlckNvZGU9YAogICAgICBmbG9hdCB1bmFyeU9wZXJhdGlvbihmbG9hdCB4KSB7CiAgICAgICAgJHt4YX0KICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IHggPSBnZXRBQXRPdXRDb29yZHMoKTsKICAgICAgICBmbG9hdCB5ID0gdW5hcnlPcGVyYXRpb24oeCk7CgogICAgICAgIHNldE91dHB1dCh5KTsKICAgICAgfQogICAgYH19O2NvbnN0IENIRUNLX05BTl9TTklQUEVUJDM9ImlmIChpc25hbih4KSkgcmV0dXJuIHg7IixMSU5FQVIkMz0icmV0dXJuIHg7IixBQlMkMz0icmV0dXJuIGFicyh4KTsiLEVMVSQ1PSJyZXR1cm4gKHggPj0gMC4wKSA/IHggOiAoZXhwKHgpIC0gMS4wKTsiLFJFTFUkNT1DSEVDS19OQU5fU05JUFBFVCQzK2AKICByZXR1cm4gKHggPCAwLjApID8gMC4wIDogeDsKYCxSRUxVNiQ1PUNIRUNLX05BTl9TTklQUEVUJDMrYAogIHJldHVybiAoeCA8IDAuMCkgPyAwLjAgOiBtaW4oNi4wLCB4KTsKYCxDTE9ORSQxPSJyZXR1cm4geDsiLFNJR01PSUQkNT0icmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLTEuMCAqIHgpKTsiOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExJTkVBUiQyPSJyZXR1cm4geDsiLEVMVSQ0PWAKICB2ZWM0IHJlc3VsdDsKCiAgcmVzdWx0LnIgPSAoeC5yID49IDAuMCkgPyB4LnIgOiAoZXhwKHgucikgLSAxLjApOwogIHJlc3VsdC5nID0gKHguZyA+PSAwLjApID8geC5nIDogKGV4cCh4LmcpIC0gMS4wKTsKICByZXN1bHQuYiA9ICh4LmIgPj0gMC4wKSA/IHguYiA6IChleHAoeC5iKSAtIDEuMCk7CiAgcmVzdWx0LmEgPSAoeC5hID49IDAuMCkgPyB4LmEgOiAoZXhwKHguYSkgLSAxLjApOwoKICByZXR1cm4gcmVzdWx0OwpgLFJFTFUkND1gCiAgdmVjNCByZXN1bHQgPSB4ICogdmVjNChncmVhdGVyVGhhbkVxdWFsKHgsIHZlYzQoMC4wKSkpOwogIGJ2ZWM0IGlzTmFOID0gaXNuYW4oeCk7CgogIHJlc3VsdC5yID0gaXNOYU4uciA/IHguciA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNOYU4uZyA/IHguZyA6IHJlc3VsdC5nOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6IHJlc3VsdC5iOwogIHJlc3VsdC5hID0gaXNOYU4uYSA/IHguYSA6IHJlc3VsdC5hOwoKICByZXR1cm4gcmVzdWx0OwpgLFJFTFU2JDQ9YAogIHZlYzQgcmVzdWx0ID0gbWluKHgsIHZlYzQoNi4pKSAqIHZlYzQoZ3JlYXRlclRoYW5FcXVhbCh4LCB2ZWM0KDAuMCkpKTsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwoKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyB4LmcgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyB4LmIgOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiByZXN1bHQuYTsKCiAgcmV0dXJuIHJlc3VsdDsKYCxTSUdNT0lEJDQ9InJldHVybiAxLjAgLyAoMS4wICsgZXhwKC0xLjAgKiB4KSk7IjtsZXQgVW5hcnlPcFBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy51c2VyQ29kZT1gCiAgICAgIHZlYzQgdW5hcnlPcGVyYXRpb24odmVjNCB4KSB7CiAgICAgICAgJHt4YX0KICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIHZlYzQgeCA9IGdldEFBdE91dENvb3JkcygpOwogICAgICAgIHZlYzQgeSA9IHVuYXJ5T3BlcmF0aW9uKHgpOwoKICAgICAgICBzZXRPdXRwdXQoeSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgVW5wYWNrUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITEsdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdCB4YT1hYS5sZW5ndGgsYmE9Z2V0Q2hhbm5lbHMkMSgicmMiLHhhKSxTYT1nZXRDb29yZHNEYXRhVHlwZSQxKHhhKSxUYT1nZXRTb3VyY2VDb29yZHMkNSh4YSxiYSksd2E9YmEuc2xpY2UoLTIpLEVhPXhhPD0xPyJyYyI6YHZlYzIoJHt3YS5qb2luKCIsIil9KWA7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke1NhfSByYyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIHZlYzQgcGFja2VkSW5wdXQgPSBnZXRBKCR7VGF9KTsKCiAgICAgICAgc2V0T3V0cHV0KGdldENoYW5uZWwocGFja2VkSW5wdXQsICR7RWF9KSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCB3aGVyZUltcGwkMj13aGVyZUltcGwkNCxFUFNJTE9OX0ZMT0FUMzIkMj0xZS03LEVQU0lMT05fRkxPQVQxNiQyPTFlLTQsYmluYXJ5Q2FjaGVzJDE9e307ZnVuY3Rpb24gZ2V0QmluYXJ5Q2FjaGUkMShoYSl7cmV0dXJuIGhhIGluIGJpbmFyeUNhY2hlcyQxfHwoYmluYXJ5Q2FjaGVzJDFbaGFdPXt9KSxiaW5hcnlDYWNoZXMkMVtoYV19Y29uc3QgQ1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQkMT1lbnYkMSgpLmdldE51bWJlcigiQ1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQiKSxCRUZPUkVfUEFHSU5HX0NPTlNUQU5UJDE9NjAwO2Z1bmN0aW9uIG51bU1CQmVmb3JlV2FybmluZyQxKCl7cmV0dXJuIGVudiQxKCkuZ2xvYmFsLnNjcmVlbj09bnVsbD8xMDI0OmVudiQxKCkuZ2xvYmFsLnNjcmVlbi5oZWlnaHQqZW52JDEoKS5nbG9iYWwuc2NyZWVuLndpZHRoKndpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKkJFRk9SRV9QQUdJTkdfQ09OU1RBTlQkMS8xMDI0LzEwMjR9bGV0IE1hdGhCYWNrZW5kV2ViR0wkMT1jbGFzcyBoYyBleHRlbmRzIEtlcm5lbEJhY2tlbmQkMXtuZXh0RGF0YUlkKCl7cmV0dXJuIGhjLm5leHREYXRhSWQrK31jb25zdHJ1Y3RvcihhYSl7aWYoc3VwZXIoKSx0aGlzLnBlbmRpbmdSZWFkPW5ldyBXZWFrTWFwLHRoaXMucGVuZGluZ0Rpc3Bvc2FsPW5ldyBXZWFrU2V0LHRoaXMuZGF0YVJlZkNvdW50PW5ldyBXZWFrTWFwLHRoaXMubnVtQnl0ZXNJbkdQVT0wLHRoaXMudXBsb2FkV2FpdE1zPTAsdGhpcy5kb3dubG9hZFdhaXRNcz0wLHRoaXMubGFzdEdsRmx1c2hUaW1lPTAsdGhpcy53YXJuZWRBYm91dE1lbW9yeT0hMSx0aGlzLnBlbmRpbmdEZWxldGVzPTAsdGhpcy5kaXNwb3NlZD0hMSwhZW52JDEoKS5nZXRCb29sKCJIQVNfV0VCR0wiKSl0aHJvdyBuZXcgRXJyb3IoIldlYkdMIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBkZXZpY2UiKTtsZXQgeGE7aWYoYWEhPW51bGwpe2lmKGFhIGluc3RhbmNlb2YgR1BHUFVDb250ZXh0JDEpeGE9YWE7ZWxzZXtjb25zdCBiYT1nZXRXZWJHTENvbnRleHQkMShlbnYkMSgpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpLGFhKTt4YT1uZXcgR1BHUFVDb250ZXh0JDEoYmEpfXRoaXMuYmluYXJ5Q2FjaGU9e30sdGhpcy5ncGdwdUNyZWF0ZWRMb2NhbGx5PSExfWVsc2V7Y29uc3QgYmE9Z2V0V2ViR0xDb250ZXh0JDEoZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKSk7eGE9bmV3IEdQR1BVQ29udGV4dCQxKGJhKSx0aGlzLmJpbmFyeUNhY2hlPWdldEJpbmFyeUNhY2hlJDEoZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKSksdGhpcy5ncGdwdUNyZWF0ZWRMb2NhbGx5PSEwfXRoaXMuZ3BncHU9eGEsdGhpcy5jYW52YXM9dGhpcy5ncGdwdS5nbC5jYW52YXMsdGhpcy50ZXh0dXJlTWFuYWdlcj1uZXcgVGV4dHVyZU1hbmFnZXIkMSh0aGlzLmdwZ3B1KSx0aGlzLm51bU1CQmVmb3JlV2FybmluZz1udW1NQkJlZm9yZVdhcm5pbmckMSgpLHRoaXMudGV4RGF0YT1uZXcgRGF0YVN0b3JhZ2UkMSh0aGlzLGVuZ2luZSQxKCkpfW51bURhdGFJZHMoKXtyZXR1cm4gdGhpcy50ZXhEYXRhLm51bURhdGFJZHMoKS10aGlzLnBlbmRpbmdEZWxldGVzfXdyaXRlVGV4dHVyZShhYSx4YSxiYSxTYSxUYSx3YSl7Y29uc3QgRWE9dGhpcy5tYWtlVGVuc29ySW5mbyh4YSxiYSksa2E9dGhpcy50ZXhEYXRhLmdldChFYS5kYXRhSWQpO2thLmlzUGFja2VkPSExLGthLnRleHR1cmU9e3RleHR1cmU6YWEsdGV4U2hhcGU6W1NhLFRhXX0sa2EudGV4U2hhcGU9W1NhLFRhXTtjb25zdCBBYT1nZXRTaGFwZUFzM0QkMSh4YSksRmE9bmV3IEVuY29kZU1hdHJpeFByb2dyYW0kMShBYSwhMSx3YSksTGE9dGhpcy5ydW5XZWJHTFByb2dyYW0oRmEsW0VhXSxiYSxbW1NhLFRhXV0pO3JldHVybiBMYS5zaGFwZT14YSxrYS50ZXh0dXJlPW51bGwsdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSksTGEuZGF0YUlkfXdyaXRlKGFhLHhhLGJhKXtpZigoZW52JDEoKS5nZXRCb29sKCJXRUJHTF9DSEVDS19OVU1FUklDQUxfUFJPQkxFTVMiKXx8ZW52JDEoKS5nZXRCb29sKCJERUJVRyIpKSYmdGhpcy5jaGVja051bWVyaWNhbFByb2JsZW1zKGFhKSxiYT09PSJjb21wbGV4NjQiJiZhYSE9bnVsbCl0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCB3cml0ZSB0byBhIGNvbXBsZXg2NCBkdHlwZS4gUGxlYXNlIHVzZSB0Zi5jb21wbGV4KHJlYWwsIGltYWcpLiIpO2NvbnN0IFNhPXtpZDp0aGlzLm5leHREYXRhSWQoKX07cmV0dXJuIHRoaXMudGV4RGF0YS5zZXQoU2Ese3NoYXBlOnhhLGR0eXBlOmJhLHZhbHVlczphYSx1c2FnZTpUZXh0dXJlVXNhZ2UkMS5VUExPQUQscmVmQ291bnQ6MX0pLFNhfXJlZkNvdW50KGFhKXtyZXR1cm4gdGhpcy50ZXhEYXRhLmhhcyhhYSk/dGhpcy50ZXhEYXRhLmdldChhYSkucmVmQ291bnQ6MH1pbmNSZWYoYWEpe2NvbnN0IHhhPXRoaXMudGV4RGF0YS5nZXQoYWEpO3hhLnJlZkNvdW50Kyt9ZGVjUmVmKGFhKXtpZih0aGlzLnRleERhdGEuaGFzKGFhKSl7Y29uc3QgeGE9dGhpcy50ZXhEYXRhLmdldChhYSk7eGEucmVmQ291bnQtLX19bW92ZShhYSx4YSxiYSxTYSxUYSl7aWYoZW52JDEoKS5nZXRCb29sKCJERUJVRyIpJiZ0aGlzLmNoZWNrTnVtZXJpY2FsUHJvYmxlbXMoeGEpLFNhPT09ImNvbXBsZXg2NCIpdGhyb3cgbmV3IEVycm9yKCJDYW5ub3Qgd3JpdGUgdG8gYSBjb21wbGV4NjQgZHR5cGUuIFBsZWFzZSB1c2UgdGYuY29tcGxleChyZWFsLCBpbWFnKS4iKTt0aGlzLnRleERhdGEuc2V0KGFhLHtzaGFwZTpiYSxkdHlwZTpTYSx2YWx1ZXM6eGEsdXNhZ2U6VGV4dHVyZVVzYWdlJDEuVVBMT0FELHJlZkNvdW50OlRhfSl9ZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWEpe3RoaXMuZGlzcG9zZURhdGEoYWEuZGF0YUlkKX1yZWFkU3luYyhhYSl7Y29uc3QgeGE9dGhpcy50ZXhEYXRhLmdldChhYSkse3ZhbHVlczpiYSxkdHlwZTpTYSxjb21wbGV4VGVuc29ySW5mb3M6VGEsc2xpY2U6d2Esc2hhcGU6RWEsaXNQYWNrZWQ6a2F9PXhhO2lmKHdhIT1udWxsKXtsZXQgZWw7a2E/ZWw9bmV3IFVuYXJ5T3BQYWNrZWRQcm9ncmFtJDEoRWEsQ0xPTkUkMSk6ZWw9bmV3IFVuYXJ5T3BQcm9ncmFtJDEoRWEsQ0xPTkUkMSk7Y29uc3QgdGw9dGhpcy5ydW5XZWJHTFByb2dyYW0oZWwsW3tkYXRhSWQ6YWEsc2hhcGU6RWEsZHR5cGU6U2F9XSxTYSksbmw9dGhpcy5yZWFkU3luYyh0bC5kYXRhSWQpO3JldHVybiB0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSxubH1pZihiYSE9bnVsbClyZXR1cm4gdGhpcy5jb252ZXJ0QW5kQ2FjaGVPbkNQVShhYSk7aWYoU2E9PT0ic3RyaW5nIilyZXR1cm4gYmE7Y29uc3QgQWE9dGhpcy5hY3RpdmVUaW1lcnMhPW51bGw7bGV0IEZhO0FhJiYoRmE9bm93JDEoKSk7bGV0IExhO2lmKFNhPT09ImNvbXBsZXg2NCIpe2NvbnN0IGVsPXRoaXMucmVhZFN5bmMoVGEucmVhbC5kYXRhSWQpLHRsPXRoaXMucmVhZFN5bmMoVGEuaW1hZy5kYXRhSWQpO0xhPW1lcmdlUmVhbEFuZEltYWdBcnJheXMkMShlbCx0bCl9ZWxzZSBMYT10aGlzLmdldFZhbHVlc0Zyb21UZXh0dXJlKGFhKTtyZXR1cm4gQWEmJih0aGlzLmRvd25sb2FkV2FpdE1zKz1ub3ckMSgpLUZhKSx0aGlzLmNvbnZlcnRBbmRDYWNoZU9uQ1BVKGFhLExhKX1hc3luYyByZWFkKGFhKXtpZih0aGlzLnBlbmRpbmdSZWFkLmhhcyhhYSkpe2NvbnN0IG5sPXRoaXMucGVuZGluZ1JlYWQuZ2V0KGFhKTtyZXR1cm4gbmV3IFByb21pc2Uoc2w9Pm5sLnB1c2goc2wpKX1jb25zdCB4YT10aGlzLnRleERhdGEuZ2V0KGFhKSx7dmFsdWVzOmJhLHNoYXBlOlNhLHNsaWNlOlRhLGR0eXBlOndhLGNvbXBsZXhUZW5zb3JJbmZvczpFYSxpc1BhY2tlZDprYX09eGE7aWYoVGEhPW51bGwpe2xldCBubDtrYT9ubD1uZXcgVW5hcnlPcFBhY2tlZFByb2dyYW0kMShTYSxDTE9ORSQxKTpubD1uZXcgVW5hcnlPcFByb2dyYW0kMShTYSxDTE9ORSQxKTtjb25zdCBzbD10aGlzLnJ1bldlYkdMUHJvZ3JhbShubCxbe2RhdGFJZDphYSxzaGFwZTpTYSxkdHlwZTp3YX1dLHdhKSxybD10aGlzLnJlYWQoc2wuZGF0YUlkKTtyZXR1cm4gdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkscmx9aWYoYmEhPW51bGwpcmV0dXJuIHRoaXMuY29udmVydEFuZENhY2hlT25DUFUoYWEpO2lmKGVudiQxKCkuZ2V0Qm9vbCgiREVCVUciKSYmIWVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfRE9XTkxPQURfRkxPQVRfRU5BQkxFRCIpJiZlbnYkMSgpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpPT09Mil0aHJvdyBuZXcgRXJyb3IoInRlbnNvci5kYXRhKCkgd2l0aCBXRUJHTF9ET1dOTE9BRF9GTE9BVF9FTkFCTEVEPWZhbHNlIGFuZCBXRUJHTF9WRVJTSU9OPTIgbm90IHlldCBzdXBwb3J0ZWQuIik7bGV0IEFhPW51bGwsRmE7aWYod2EhPT0iY29tcGxleDY0IiYmZW52JDEoKS5nZXQoIldFQkdMX0JVRkZFUl9TVVBQT1JURUQiKSl7RmE9dGhpcy5kZWNvZGUoYWEpO2NvbnN0IG5sPXRoaXMudGV4RGF0YS5nZXQoRmEuZGF0YUlkKTtBYT10aGlzLmdwZ3B1LmNyZWF0ZUJ1ZmZlckZyb21UZXh0dXJlKG5sLnRleHR1cmUudGV4dHVyZSwuLi5nZXREZW5zZVRleFNoYXBlJDEoU2EpKX10aGlzLnBlbmRpbmdSZWFkLnNldChhYSxbXSksd2EhPT0iY29tcGxleDY0IiYmYXdhaXQgdGhpcy5ncGdwdS5jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTtsZXQgTGE7aWYod2E9PT0iY29tcGxleDY0Iil7Y29uc3Qgbmw9YXdhaXQgUHJvbWlzZS5hbGwoW3RoaXMucmVhZChFYS5yZWFsLmRhdGFJZCksdGhpcy5yZWFkKEVhLmltYWcuZGF0YUlkKV0pLHNsPW5sWzBdLHJsPW5sWzFdO0xhPW1lcmdlUmVhbEFuZEltYWdBcnJheXMkMShzbCxybCl9ZWxzZSBpZihBYT09bnVsbClMYT10aGlzLmdldFZhbHVlc0Zyb21UZXh0dXJlKGFhKTtlbHNle2NvbnN0IG5sPXNpemVGcm9tU2hhcGUkMShTYSk7TGE9dGhpcy5ncGdwdS5kb3dubG9hZEZsb2F0MzJNYXRyaXhGcm9tQnVmZmVyKEFhLG5sKX1pZihGYSE9bnVsbCYmdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhGYSksQWEhPW51bGwpe2NvbnN0IG5sPXRoaXMuZ3BncHUuZ2w7Y2FsbEFuZENoZWNrJDEobmwsKCk9Pm5sLmRlbGV0ZUJ1ZmZlcihBYSkpfWNvbnN0IGVsPXRoaXMuY29udmVydEFuZENhY2hlT25DUFUoYWEsTGEpLHRsPXRoaXMucGVuZGluZ1JlYWQuZ2V0KGFhKTtyZXR1cm4gdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoYWEpLHRsLmZvckVhY2gobmw9Pm5sKGVsKSksdGhpcy5wZW5kaW5nRGlzcG9zYWwuaGFzKGFhKSYmKHRoaXMucGVuZGluZ0Rpc3Bvc2FsLmRlbGV0ZShhYSksdGhpcy5kaXNwb3NlRGF0YShhYSkmJmVuZ2luZSQxKCkucmVtb3ZlRGF0YUlkKGFhLHRoaXMpLHRoaXMucGVuZGluZ0RlbGV0ZXMtLSksZWx9cmVhZFRvR1BVKGFhLHhhPXt9KXtjb25zdCBiYT10aGlzLnRleERhdGEuZ2V0KGFhKSx7dmFsdWVzOlNhLHNoYXBlOlRhLHNsaWNlOndhLGR0eXBlOkVhLGlzUGFja2VkOmthLHRleHR1cmU6QWF9PWJhO2lmKEVhPT09ImNvbXBsZXg2NCIpdGhyb3cgbmV3IEVycm9yKCJEb2VzIG5vdCBzdXBwb3J0IHJlYWRpbmcgdGV4dHVyZSBmb3IgY29tcGxleDY0IGR0eXBlLiIpO2lmKHdhIT1udWxsKXtsZXQgdGw7a2E/dGw9bmV3IFVuYXJ5T3BQYWNrZWRQcm9ncmFtJDEoVGEsQ0xPTkUkMSk6dGw9bmV3IFVuYXJ5T3BQcm9ncmFtJDEoVGEsQ0xPTkUkMSk7Y29uc3Qgbmw9dGhpcy5ydW5XZWJHTFByb2dyYW0odGwsW3tkYXRhSWQ6YWEsc2hhcGU6VGEsZHR5cGU6RWF9XSxFYSksc2w9dGhpcy5yZWFkVG9HUFUobmwseGEpO3JldHVybiB0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSxzbH1pZihBYT09bnVsbCl0aHJvdyBTYSE9bnVsbD9uZXcgRXJyb3IoIkRhdGEgaXMgbm90IG9uIEdQVSBidXQgb24gQ1BVLiIpOm5ldyBFcnJvcigiVGhlcmUgaXMgbm8gZGF0YSBvbiBHUFUgb3IgQ1BVLiIpO2NvbnN0IEZhPXRoaXMuZGVjb2RlKGFhLHhhLmN1c3RvbVRleFNoYXBlKSxMYT1lbmdpbmUkMSgpLm1ha2VUZW5zb3JGcm9tVGVuc29ySW5mbyhGYSksZWw9dGhpcy50ZXhEYXRhLmdldChGYS5kYXRhSWQpO3JldHVybiBPYmplY3QuYXNzaWduKHt0ZW5zb3JSZWY6TGF9LGVsLnRleHR1cmUpfWJ1ZmZlclN5bmMoYWEpe2NvbnN0IHhhPXRoaXMucmVhZFN5bmMoYWEuZGF0YUlkKTtpZihhYS5kdHlwZT09PSJzdHJpbmciKXRyeXtjb25zdCBiYT14YS5tYXAoU2E9PmRlY29kZVN0cmluZyQxKFNhKSk7cmV0dXJuIGJ1ZmZlciQxKGFhLnNoYXBlLGFhLmR0eXBlLGJhKX1jYXRjaHt0aHJvdyBuZXcgRXJyb3IoIkZhaWxlZCB0byBkZWNvZGUgZW5jb2RlZCBzdHJpbmcgYnl0ZXMgaW50byB1dGYtOCIpfXJldHVybiBidWZmZXIkMShhYS5zaGFwZSxhYS5kdHlwZSx4YSl9Y2hlY2tOdW1lcmljYWxQcm9ibGVtcyhhYSl7aWYoYWEhPW51bGwpZm9yKGxldCB4YT0wO3hhPGFhLmxlbmd0aDt4YSsrKXtjb25zdCBiYT1hYVt4YV07aWYoIWNhbkJlUmVwcmVzZW50ZWQkMShiYSkpdGhyb3cgZW52JDEoKS5nZXRCb29sKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9DQVBBQkxFIik/RXJyb3IoYFRoZSB2YWx1ZSAke2JhfSBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgd2l0aCB5b3VyIGN1cnJlbnQgc2V0dGluZ3MuIENvbnNpZGVyIGVuYWJsaW5nIGZsb2F0MzIgcmVuZGVyaW5nOiAndGYuZW52KCkuc2V0KCdXRUJHTF9SRU5ERVJfRkxPQVQzMl9FTkFCTEVEJywgdHJ1ZSk7J2ApOkVycm9yKGBUaGUgdmFsdWUgJHtiYX0gY2Fubm90IGJlIHJlcHJlc2VudGVkIG9uIHRoaXMgZGV2aWNlLmApfX1nZXRWYWx1ZXNGcm9tVGV4dHVyZShhYSl7Y29uc3R7c2hhcGU6eGEsZHR5cGU6YmEsaXNQYWNrZWQ6U2F9PXRoaXMudGV4RGF0YS5nZXQoYWEpLFRhPXNpemVGcm9tU2hhcGUkMSh4YSk7aWYoZW52JDEoKS5nZXRCb29sKCJXRUJHTF9ET1dOTE9BRF9GTE9BVF9FTkFCTEVEIikpe2NvbnN0IGVsPXRoaXMuZGVjb2RlKGFhKSx0bD10aGlzLnRleERhdGEuZ2V0KGVsLmRhdGFJZCksbmw9dGhpcy5ncGdwdS5kb3dubG9hZE1hdHJpeEZyb21QYWNrZWRUZXh0dXJlKHRsLnRleHR1cmUudGV4dHVyZSwuLi5nZXREZW5zZVRleFNoYXBlJDEoeGEpKS5zdWJhcnJheSgwLFRhKTtyZXR1cm4gdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCksbmx9Y29uc3Qgd2E9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLIikmJlNhPT09ITAsRWE9d2E/Z2V0U2hhcGVBczNEJDEoeGEpOnhhLGthPXdhP25ldyBFbmNvZGVGbG9hdFBhY2tlZFByb2dyYW0kMShFYSk6bmV3IEVuY29kZUZsb2F0UHJvZ3JhbSQxKEVhKSxBYT10aGlzLnJ1bldlYkdMUHJvZ3JhbShrYSxbe3NoYXBlOkVhLGR0eXBlOmJhLGRhdGFJZDphYX1dLCJmbG9hdDMyIiksRmE9dGhpcy50ZXhEYXRhLmdldChBYS5kYXRhSWQpLExhPXRoaXMuZ3BncHUuZG93bmxvYWRCeXRlRW5jb2RlZEZsb2F0TWF0cml4RnJvbU91dHB1dFRleHR1cmUoRmEudGV4dHVyZS50ZXh0dXJlLEZhLnRleFNoYXBlWzBdLEZhLnRleFNoYXBlWzFdKS5zdWJhcnJheSgwLFRhKTtyZXR1cm4gdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhBYSksTGF9dGltZXJBdmFpbGFibGUoKXtyZXR1cm4gZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9SRUxJQUJMRSIpPjB9dGltZShhYSl7Y29uc3QgeGE9dGhpcy5hY3RpdmVUaW1lcnMsYmE9W107bGV0IFNhPSExO3RoaXMucHJvZ3JhbVRpbWVyc1N0YWNrPT1udWxsPyh0aGlzLnByb2dyYW1UaW1lcnNTdGFjaz1iYSxTYT0hMCk6dGhpcy5hY3RpdmVUaW1lcnMucHVzaChiYSksdGhpcy5hY3RpdmVUaW1lcnM9YmEsYWEoKTtjb25zdCBUYT1mbGF0dGVuJDIodGhpcy5hY3RpdmVUaW1lcnMubWFwKGthPT5rYS5xdWVyeSkpLmZpbHRlcihrYT0+a2EhPW51bGwpLHdhPWZsYXR0ZW4kMih0aGlzLmFjdGl2ZVRpbWVycy5tYXAoa2E9PmthLm5hbWUpKS5maWx0ZXIoa2E9PmthIT1udWxsKTt0aGlzLmFjdGl2ZVRpbWVycz14YSxTYSYmKHRoaXMucHJvZ3JhbVRpbWVyc1N0YWNrPW51bGwpO2NvbnN0IEVhPXt1cGxvYWRXYWl0TXM6dGhpcy51cGxvYWRXYWl0TXMsZG93bmxvYWRXYWl0TXM6dGhpcy5kb3dubG9hZFdhaXRNcyxrZXJuZWxNczpudWxsLHdhbGxNczpudWxsfTtyZXR1cm4oYXN5bmMoKT0+e2lmKGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiKT4wKXtjb25zdCBrYT1hd2FpdCBQcm9taXNlLmFsbChUYSk7RWEua2VybmVsTXM9c3VtJDYoa2EpLEVhLmdldEV4dHJhUHJvZmlsZUluZm89KCk9PmthLm1hcCgoQWEsRmEpPT4oe25hbWU6d2FbRmFdLG1zOkFhfSkpLm1hcChBYT0+YCR7QWEubmFtZX06ICR7QWEubXN9YCkuam9pbigiLCAiKX1lbHNlIEVhLmtlcm5lbE1zPXtlcnJvcjoiV2ViR0wgcXVlcnkgdGltZXJzIGFyZSBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQuIn07cmV0dXJuIHRoaXMudXBsb2FkV2FpdE1zPTAsdGhpcy5kb3dubG9hZFdhaXRNcz0wLEVhfSkoKX1tZW1vcnkoKXtyZXR1cm57dW5yZWxpYWJsZTohMSxudW1CeXRlc0luR1BVOnRoaXMubnVtQnl0ZXNJbkdQVSxudW1CeXRlc0luR1BVQWxsb2NhdGVkOnRoaXMudGV4dHVyZU1hbmFnZXIubnVtQnl0ZXNBbGxvY2F0ZWQsbnVtQnl0ZXNJbkdQVUZyZWU6dGhpcy50ZXh0dXJlTWFuYWdlci5udW1CeXRlc0ZyZWV9fXN0YXJ0VGltZXIoKXtyZXR1cm4gZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9SRUxJQUJMRSIpPjA/dGhpcy5ncGdwdS5iZWdpblF1ZXJ5KCk6e3N0YXJ0TXM6bm93JDEoKSxlbmRNczpudWxsfX1lbmRUaW1lcihhYSl7cmV0dXJuIGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiKT4wPyh0aGlzLmdwZ3B1LmVuZFF1ZXJ5KCksYWEpOihhYS5lbmRNcz1ub3ckMSgpLGFhKX1hc3luYyBnZXRRdWVyeVRpbWUoYWEpe2lmKGVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiKT4wKXJldHVybiB0aGlzLmdwZ3B1LndhaXRGb3JRdWVyeUFuZEdldFRpbWUoYWEpO2NvbnN0IHhhPWFhO3JldHVybiB4YS5lbmRNcy14YS5zdGFydE1zfWRpc3Bvc2VEYXRhKGFhLHhhPSExKXtpZih0aGlzLnBlbmRpbmdEaXNwb3NhbC5oYXMoYWEpKXJldHVybiExO2lmKCF0aGlzLnRleERhdGEuaGFzKGFhKSlyZXR1cm4hMDtpZih4YT90aGlzLnRleERhdGEuZ2V0KGFhKS5yZWZDb3VudD0wOnRoaXMudGV4RGF0YS5nZXQoYWEpLnJlZkNvdW50LS0sIXhhJiZ0aGlzLnRleERhdGEuZ2V0KGFhKS5yZWZDb3VudD4wKXJldHVybiExO2lmKHRoaXMucGVuZGluZ1JlYWQuaGFzKGFhKSlyZXR1cm4gdGhpcy5wZW5kaW5nRGlzcG9zYWwuYWRkKGFhKSx0aGlzLnBlbmRpbmdEZWxldGVzKyssITE7dGhpcy5yZWxlYXNlR1BVRGF0YShhYSk7Y29uc3R7Y29tcGxleFRlbnNvckluZm9zOmJhfT10aGlzLnRleERhdGEuZ2V0KGFhKTtyZXR1cm4gYmEhPW51bGwmJih0aGlzLmRpc3Bvc2VEYXRhKGJhLnJlYWwuZGF0YUlkLHhhKSx0aGlzLmRpc3Bvc2VEYXRhKGJhLmltYWcuZGF0YUlkLHhhKSksdGhpcy50ZXhEYXRhLmRlbGV0ZShhYSksITB9cmVsZWFzZUdQVURhdGEoYWEpe2NvbnN0e3RleHR1cmU6eGEsZHR5cGU6YmEsdGV4U2hhcGU6U2EsdXNhZ2U6VGEsaXNQYWNrZWQ6d2Esc2xpY2U6RWF9PXRoaXMudGV4RGF0YS5nZXQoYWEpLGthPUVhJiZFYS5vcmlnRGF0YUlkfHxhYSxBYT10aGlzLmRhdGFSZWZDb3VudC5nZXQoa2EpO0FhPjE/dGhpcy5kYXRhUmVmQ291bnQuc2V0KGthLEFhLTEpOih0aGlzLmRhdGFSZWZDb3VudC5kZWxldGUoa2EpLHhhIT1udWxsJiYodGhpcy5udW1CeXRlc0luR1BVLT10aGlzLmNvbXB1dGVCeXRlcyhTYSxiYSksdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh4YSxTYSxUYSx3YSkpKTtjb25zdCBGYT10aGlzLnRleERhdGEuZ2V0KGFhKTtGYS50ZXh0dXJlPW51bGwsRmEudGV4U2hhcGU9bnVsbCxGYS5pc1BhY2tlZD0hMSxGYS5zbGljZT1udWxsfWdldFRleHR1cmUoYWEpe3JldHVybiB0aGlzLnVwbG9hZFRvR1BVKGFhKSx0aGlzLnRleERhdGEuZ2V0KGFhKS50ZXh0dXJlLnRleHR1cmV9Z2V0RGF0YUluZm8oYWEpe3JldHVybiB0aGlzLnRleERhdGEuZ2V0KGFhKX1zaG91bGRFeGVjdXRlT25DUFUoYWEseGE9Q1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQkMSl7cmV0dXJuIGVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfQ1BVX0ZPUldBUkQiKSYmYWEuZXZlcnkoYmE9PnRoaXMudGV4RGF0YS5nZXQoYmEuZGF0YUlkKS50ZXh0dXJlPT1udWxsJiZzaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpPHhhKX1nZXRHUEdQVUNvbnRleHQoKXtyZXR1cm4gdGhpcy5ncGdwdX13aGVyZShhYSl7d2FybiQxKCJ0Zi53aGVyZSgpIGluIHdlYmdsIGxvY2tzIHRoZSBVSSB0aHJlYWQuIENhbGwgdGYud2hlcmVBc3luYygpIGluc3RlYWQiKTtjb25zdCB4YT1hYS5kYXRhU3luYygpO3JldHVybiB3aGVyZUltcGwkMihhYS5zaGFwZSx4YSl9cGFja2VkVW5hcnlPcChhYSx4YSxiYSl7Y29uc3QgU2E9bmV3IFVuYXJ5T3BQYWNrZWRQcm9ncmFtJDEoYWEuc2hhcGUseGEpLFRhPXRoaXMuY29tcGlsZUFuZFJ1bihTYSxbYWFdLGJhKTtyZXR1cm4gZW5naW5lJDEoKS5tYWtlVGVuc29yRnJvbVRlbnNvckluZm8oVGEpfWFicyhhYSl7aWYodGhpcy5zaG91bGRFeGVjdXRlT25DUFUoW2FhXSkmJmFhLmR0eXBlIT09ImNvbXBsZXg2NCIpe2NvbnN0IFNhPXNpbXBsZUFic0ltcGxDUFUkMSh0aGlzLnRleERhdGEuZ2V0KGFhLmRhdGFJZCkudmFsdWVzKTtyZXR1cm4gdGhpcy5tYWtlT3V0cHV0KGFhLnNoYXBlLGFhLmR0eXBlLFNhKX1pZihlbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfVU5BUllfT1BFUkFUSU9OUyIpKXJldHVybiB0aGlzLnBhY2tlZFVuYXJ5T3AoYWEsQUJTJDMsYWEuZHR5cGUpO2NvbnN0IHhhPW5ldyBVbmFyeU9wUHJvZ3JhbSQxKGFhLnNoYXBlLEFCUyQzKSxiYT10aGlzLmNvbXBpbGVBbmRSdW4oeGEsW2FhXSk7cmV0dXJuIGVuZ2luZSQxKCkubWFrZVRlbnNvckZyb21UZW5zb3JJbmZvKGJhKX1tYWtlVGVuc29ySW5mbyhhYSx4YSxiYSl7bGV0IFNhO2lmKHhhPT09InN0cmluZyImJmJhIT1udWxsJiZiYS5sZW5ndGg+MCYmaXNTdHJpbmckMShiYVswXSkpe2NvbnN0IFRhPWJhLm1hcCh3YT0+ZW5jb2RlU3RyaW5nJDEod2EpKTtTYT10aGlzLndyaXRlKFRhLGFhLHhhKX1lbHNlIFNhPXRoaXMud3JpdGUoYmEsYWEseGEpO3JldHVybiB0aGlzLnRleERhdGEuZ2V0KFNhKS51c2FnZT1udWxsLHtkYXRhSWQ6U2Esc2hhcGU6YWEsZHR5cGU6eGF9fW1ha2VPdXRwdXQoYWEseGEsYmEpe3JldHVybiBlbmdpbmUkMSgpLm1ha2VUZW5zb3JGcm9tVGVuc29ySW5mbyh0aGlzLm1ha2VUZW5zb3JJbmZvKGFhLHhhLGJhKSx0aGlzKX11bnBhY2tUZW5zb3IoYWEpe2NvbnN0IHhhPW5ldyBVbnBhY2tQcm9ncmFtJDEoYWEuc2hhcGUpO3JldHVybiB0aGlzLnJ1bldlYkdMUHJvZ3JhbSh4YSxbYWFdLGFhLmR0eXBlKX1wYWNrVGVuc29yKGFhKXtjb25zdCB4YT1uZXcgUGFja1Byb2dyYW0kMShhYS5zaGFwZSk7cmV0dXJuIHRoaXMucnVuV2ViR0xQcm9ncmFtKHhhLFthYV0sYWEuZHR5cGUsbnVsbCwhMCl9cGFja2VkUmVzaGFwZShhYSx4YSl7Y29uc3QgYmE9W2dldEJhdGNoRGltJDEoYWEuc2hhcGUpLC4uLmdldFJvd3NDb2xzJDEoYWEuc2hhcGUpXSxTYT17ZHR5cGU6YWEuZHR5cGUsc2hhcGU6YmEsZGF0YUlkOmFhLmRhdGFJZH0sVGE9W2dldEJhdGNoRGltJDEoeGEpLC4uLmdldFJvd3NDb2xzJDEoeGEpXSx3YT1uZXcgUmVzaGFwZVBhY2tlZFByb2dyYW0kMShUYSxiYSksRWE9ITAsa2E9W2JhXSxBYT10aGlzLnJ1bldlYkdMUHJvZ3JhbSh3YSxbU2FdLGFhLmR0eXBlLGthLEVhKTtyZXR1cm57ZGF0YUlkOkFhLmRhdGFJZCxzaGFwZTp4YSxkdHlwZTpBYS5kdHlwZX19ZGVjb2RlKGFhLHhhKXtjb25zdCBiYT10aGlzLnRleERhdGEuZ2V0KGFhKSx7aXNQYWNrZWQ6U2Esc2hhcGU6VGEsZHR5cGU6d2F9PWJhO2lmKHhhIT1udWxsKXtjb25zdCBlbD1zaXplRnJvbVNoYXBlJDEoVGEpLHRsPXhhWzBdKnhhWzFdKjQ7YXNzZXJ0JDIoZWw8PXRsLCgpPT4iY3VzdG9tVGV4U2hhcGUgaXMgdG9vIHNtYWxsLiBSb3cgKiBDb2x1bW4gKiA0IHNob3VsZCBiZSBlcXVhbCBvciBsYXJnZXIgdGhhbiB0aGUgc2l6ZSBvZiB0aGUgdGVuc29yIGRhdGEuIil9Y29uc3QgRWE9Z2V0U2hhcGVBczNEJDEoVGEpO2xldCBrYTtTYT9rYT1uZXcgRGVjb2RlTWF0cml4UGFja2VkUHJvZ3JhbSQxKEVhKTprYT1uZXcgRGVjb2RlTWF0cml4UHJvZ3JhbSQxKEVhKTtjb25zdCBBYT0hMCxGYT1beGE/P2dldERlbnNlVGV4U2hhcGUkMShFYSldLExhPXRoaXMucnVuV2ViR0xQcm9ncmFtKGthLFt7c2hhcGU6RWEsZHR5cGU6d2EsZGF0YUlkOmFhfV0sd2EsRmEsQWEseGEpO3JldHVybntkdHlwZTp3YSxzaGFwZTpUYSxkYXRhSWQ6TGEuZGF0YUlkfX1ydW5XZWJHTFByb2dyYW0oYWEseGEsYmEsU2EsVGE9ITEsd2Epe2NvbnN0IEVhPXRoaXMubWFrZVRlbnNvckluZm8oYWEub3V0cHV0U2hhcGUsYmEpLGthPXRoaXMudGV4RGF0YS5nZXQoRWEuZGF0YUlkKTtpZihhYS5wYWNrZWRPdXRwdXQmJihrYS5pc1BhY2tlZD0hMCksYWEub3V0UGFja2luZ1NjaGVtZT09PVBhY2tpbmdTY2hlbWUkMS5ERU5TRSl7Y29uc3Qgb2w9d2E/P2dldERlbnNlVGV4U2hhcGUkMShhYS5vdXRwdXRTaGFwZSk7a2EudGV4U2hhcGU9b2wubWFwKGFsPT5hbCoyKX1pZihhYS5vdXRUZXhVc2FnZSE9bnVsbCYmKGthLnVzYWdlPWFhLm91dFRleFVzYWdlKSxzaXplRnJvbVNoYXBlJDEoRWEuc2hhcGUpPT09MClyZXR1cm4ga2EudmFsdWVzPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMShFYS5kdHlwZSwwKSxFYTtjb25zdCBBYT1bXSxGYT14YS5tYXAob2w9PntpZihvbC5kdHlwZT09PSJjb21wbGV4NjQiKXRocm93IG5ldyBFcnJvcigiR1BHUFVQcm9ncmFtIGRvZXMgbm90IHN1cHBvcnQgY29tcGxleDY0IGlucHV0LiBGb3IgY29tcGxleDY0IGR0eXBlcywgcGxlYXNlIHNlcGFyYXRlIHRoZSBwcm9ncmFtIGludG8gcmVhbCBhbmQgaW1hZ2luYXJ5IHBhcnRzLiIpO2xldCBhbD10aGlzLnRleERhdGEuZ2V0KG9sLmRhdGFJZCk7aWYoYWwudGV4dHVyZT09bnVsbCl7aWYoIWFhLnBhY2tlZElucHV0cyYmc2l6ZUZyb21TaGFwZSQxKG9sLnNoYXBlKTw9ZW52JDEoKS5nZXROdW1iZXIoIldFQkdMX1NJWkVfVVBMT0FEX1VOSUZPUk0iKSlyZXR1cm57c2hhcGU6b2wuc2hhcGUsdGV4RGF0YTpudWxsLGlzVW5pZm9ybTohMCx1bmlmb3JtVmFsdWVzOmFsLnZhbHVlc307YWEucGFja2VkSW5wdXRzJiYoYWwuaXNQYWNrZWQ9ITAsYWwuc2hhcGU9b2wuc2hhcGUpfWlmKHRoaXMudXBsb2FkVG9HUFUob2wuZGF0YUlkKSwhIWFsLmlzUGFja2VkIT0hIWFhLnBhY2tlZElucHV0cylvbD1hbC5pc1BhY2tlZD90aGlzLnVucGFja1RlbnNvcihvbCk6dGhpcy5wYWNrVGVuc29yKG9sKSxBYS5wdXNoKG9sKSxhbD10aGlzLnRleERhdGEuZ2V0KG9sLmRhdGFJZCk7ZWxzZSBpZihhbC5pc1BhY2tlZCYmIWlzUmVzaGFwZUZyZWUkMShhbC5zaGFwZSxvbC5zaGFwZSkpe2NvbnN0IGxsPW9sLGlsPW9sLnNoYXBlO29sLnNoYXBlPWFsLnNoYXBlLG9sPXRoaXMucGFja2VkUmVzaGFwZShvbCxpbCksQWEucHVzaChvbCksYWw9dGhpcy50ZXhEYXRhLmdldChvbC5kYXRhSWQpLGxsLnNoYXBlPWlsfXJldHVybntzaGFwZTpvbC5zaGFwZSx0ZXhEYXRhOmFsLGlzVW5pZm9ybTohMX19KTt0aGlzLnVwbG9hZFRvR1BVKEVhLmRhdGFJZCk7Y29uc3QgTGE9e3NoYXBlOkVhLnNoYXBlLHRleERhdGE6a2EsaXNVbmlmb3JtOiExfSxlbD1tYWtlU2hhZGVyS2V5JDEoYWEsRmEsTGEpLHRsPXRoaXMuZ2V0QW5kU2F2ZUJpbmFyeShlbCwoKT0+Y29tcGlsZVByb2dyYW0kMSh0aGlzLmdwZ3B1LGFhLEZhLExhKSksbmw9dGhpcy5hY3RpdmVUaW1lcnMhPW51bGw7bGV0IHNsO25sJiYoc2w9dGhpcy5zdGFydFRpbWVyKCkpLGVudiQxKCkuZ2V0KCJFTkdJTkVfQ09NUElMRV9PTkxZIil8fHJ1blByb2dyYW0kMSh0aGlzLmdwZ3B1LHRsLEZhLExhLFNhKSxBYS5mb3JFYWNoKG9sPT50aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG9sKSksbmwmJihzbD10aGlzLmVuZFRpbWVyKHNsKSx0aGlzLmFjdGl2ZVRpbWVycy5wdXNoKHtuYW1lOmFhLmNvbnN0cnVjdG9yLm5hbWUscXVlcnk6dGhpcy5nZXRRdWVyeVRpbWUoc2wpfSkpO2NvbnN0IHJsPWVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9GTFVTSF9USFJFU0hPTEQiKTtpZihybD4wKXtjb25zdCBvbD1ub3ckMSgpO29sLXRoaXMubGFzdEdsRmx1c2hUaW1lPnJsJiYodGhpcy5ncGdwdS5nbC5mbHVzaCgpLHRoaXMubGFzdEdsRmx1c2hUaW1lPW9sKX1pZighZW52JDEoKS5nZXRCb29sKCJXRUJHTF9MQVpJTFlfVU5QQUNLIikmJmthLmlzUGFja2VkJiZUYT09PSExKXtjb25zdCBvbD10aGlzLnVucGFja1RlbnNvcihFYSk7cmV0dXJuIHRoaXMuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLG9sfXJldHVybiBFYX1jb21waWxlQW5kUnVuKGFhLHhhLGJhLFNhLFRhPSExKXtyZXR1cm4gYmE9YmF8fHhhWzBdLmR0eXBlLHRoaXMucnVuV2ViR0xQcm9ncmFtKGFhLHhhLGJhLFNhLFRhKX1nZXRBbmRTYXZlQmluYXJ5KGFhLHhhKXtyZXR1cm4gYWEgaW4gdGhpcy5iaW5hcnlDYWNoZXx8KHRoaXMuYmluYXJ5Q2FjaGVbYWFdPXhhKCkpLHRoaXMuYmluYXJ5Q2FjaGVbYWFdfWdldFRleHR1cmVNYW5hZ2VyKCl7cmV0dXJuIHRoaXMudGV4dHVyZU1hbmFnZXJ9ZGlzcG9zZSgpe3RoaXMuZGlzcG9zZWR8fChlbnYkMSgpLmdldEJvb2woIklTX1RFU1QiKXx8T2JqZWN0LmtleXModGhpcy5iaW5hcnlDYWNoZSkuZm9yRWFjaCh4YT0+e3RoaXMuZ3BncHUuZGVsZXRlUHJvZ3JhbSh0aGlzLmJpbmFyeUNhY2hlW3hhXS53ZWJHTFByb2dyYW0pLGRlbGV0ZSB0aGlzLmJpbmFyeUNhY2hlW3hhXX0pLHRoaXMudGV4dHVyZU1hbmFnZXIuZGlzcG9zZSgpLHRoaXMuY2FudmFzIT1udWxsJiZ0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQ8InUiJiZ0aGlzLmNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50P3RoaXMuY2FudmFzLnJlbW92ZSgpOnRoaXMuY2FudmFzPW51bGwsdGhpcy5ncGdwdUNyZWF0ZWRMb2NhbGx5JiYodGhpcy5ncGdwdS5wcm9ncmFtPW51bGwsdGhpcy5ncGdwdS5kaXNwb3NlKCkpLHRoaXMuZGlzcG9zZWQ9ITApfWZsb2F0UHJlY2lzaW9uKCl7cmV0dXJuIHRoaXMuZmxvYXRQcmVjaXNpb25WYWx1ZT09bnVsbCYmKHRoaXMuZmxvYXRQcmVjaXNpb25WYWx1ZT10aWR5JDEoKCk9PntpZighZW52JDEoKS5nZXQoIldFQkdMX1JFTkRFUl9GTE9BVDMyX0VOQUJMRUQiKSl7Y29uc3QgYWE9ZW52JDEoKS5nZXRCb29sKCJERUJVRyIpO2VudiQxKCkuc2V0KCJERUJVRyIsITEpO2NvbnN0IHhhPXRoaXMuYWJzKHNjYWxhciQxKDFlLTgpKS5kYXRhU3luYygpWzBdO2lmKGVudiQxKCkuc2V0KCJERUJVRyIsYWEpLHhhPjApcmV0dXJuIDMyfXJldHVybiAxNn0pKSx0aGlzLmZsb2F0UHJlY2lzaW9uVmFsdWV9ZXBzaWxvbigpe3JldHVybiB0aGlzLmZsb2F0UHJlY2lzaW9uKCk9PT0zMj9FUFNJTE9OX0ZMT0FUMzIkMjpFUFNJTE9OX0ZMT0FUMTYkMn11cGxvYWRUb0dQVShhYSl7Y29uc3QgeGE9dGhpcy50ZXhEYXRhLmdldChhYSkse3NoYXBlOmJhLGR0eXBlOlNhLHZhbHVlczpUYSx0ZXh0dXJlOndhLHVzYWdlOkVhLGlzUGFja2VkOmthfT14YTtpZih3YSE9bnVsbClyZXR1cm47Y29uc3QgQWE9dGhpcy5hY3RpdmVUaW1lcnMhPW51bGw7bGV0IEZhO0FhJiYoRmE9bm93JDEoKSk7bGV0IExhPXhhLnRleFNoYXBlO2lmKExhPT1udWxsJiYoTGE9Z2V0VGV4dHVyZVNoYXBlRnJvbUxvZ2ljYWxTaGFwZSQxKGJhLGthKSx4YS50ZXhTaGFwZT1MYSksVGEhPW51bGwpe2NvbnN0IGVsPWdldFNoYXBlQXMzRCQxKGJhKTtsZXQgdGwsbmw9TGFbMV0sc2w9TGFbMF07Y29uc3Qgcmw9VGEgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxUYSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5OyhrYXx8IXJsKSYmKFtubCxzbF09Z2V0UGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQkMShMYVswXSxMYVsxXSkpLGthP3RsPW5ldyBFbmNvZGVNYXRyaXhQYWNrZWRQcm9ncmFtJDEoZWwscmwpOnRsPW5ldyBFbmNvZGVNYXRyaXhQcm9ncmFtJDEoZWwscmwpO2NvbnN0IG9sPXJsP1tzbCxubF06TGEsYWw9dGhpcy5tYWtlVGVuc29ySW5mbyhvbCxTYSksbGw9dGhpcy50ZXhEYXRhLmdldChhbC5kYXRhSWQpO3JsP2xsLnVzYWdlPVRleHR1cmVVc2FnZSQxLlBJWEVMUzpsbC51c2FnZT1UZXh0dXJlVXNhZ2UkMS5VUExPQUQsbGwudGV4U2hhcGU9b2wsdGhpcy5ncGdwdS51cGxvYWREZW5zZU1hdHJpeFRvVGV4dHVyZSh0aGlzLmdldFRleHR1cmUoYWwuZGF0YUlkKSxubCxzbCxUYSk7Y29uc3QgaWw9W1tzbCxubF1dLHVsPXRoaXMucnVuV2ViR0xQcm9ncmFtKHRsLFthbF0sU2EsaWwsITApLGRsPXRoaXMudGV4RGF0YS5nZXQodWwuZGF0YUlkKTt4YS50ZXhTaGFwZT1kbC50ZXhTaGFwZSx4YS5pc1BhY2tlZD1kbC5pc1BhY2tlZCx4YS51c2FnZT1kbC51c2FnZSxlbnYkMSgpLmdldCgiRU5HSU5FX0NPTVBJTEVfT05MWSIpP3RoaXMuZGlzcG9zZURhdGEodWwuZGF0YUlkKTooeGEudGV4dHVyZT1kbC50ZXh0dXJlLHhhLnZhbHVlcz1udWxsLHRoaXMudGV4RGF0YS5kZWxldGUodWwuZGF0YUlkKSksdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhbCksQWEmJih0aGlzLnVwbG9hZFdhaXRNcys9bm93JDEoKS1GYSl9ZWxzZXtjb25zdCBlbD10aGlzLmFjcXVpcmVUZXh0dXJlKExhLEVhLFNhLGthKTt4YS50ZXh0dXJlPWVsfX1jb252ZXJ0QW5kQ2FjaGVPbkNQVShhYSx4YSl7Y29uc3QgYmE9dGhpcy50ZXhEYXRhLmdldChhYSkse2R0eXBlOlNhfT1iYTtyZXR1cm4geGEhPW51bGwmJihiYS52YWx1ZXM9ZmxvYXQzMlRvVHlwZWRBcnJheSQxKHhhLFNhKSksYmEudmFsdWVzfWFjcXVpcmVUZXh0dXJlKGFhLHhhLGJhLFNhKXtpZih0aGlzLm51bUJ5dGVzSW5HUFUrPXRoaXMuY29tcHV0ZUJ5dGVzKGFhLGJhKSwhdGhpcy53YXJuZWRBYm91dE1lbW9yeSYmdGhpcy5udW1CeXRlc0luR1BVPnRoaXMubnVtTUJCZWZvcmVXYXJuaW5nKjEwMjQqMTAyNCl7Y29uc3QgVGE9KHRoaXMubnVtQnl0ZXNJbkdQVS8xMDI0LzEwMjQpLnRvRml4ZWQoMik7dGhpcy53YXJuZWRBYm91dE1lbW9yeT0hMCxjb25zb2xlLndhcm4oYEhpZ2ggbWVtb3J5IHVzYWdlIGluIEdQVTogJHtUYX0gTUIsIG1vc3QgbGlrZWx5IGR1ZSB0byBhIG1lbW9yeSBsZWFrYCl9cmV0dXJuIHRoaXMudGV4dHVyZU1hbmFnZXIuYWNxdWlyZVRleHR1cmUoYWEseGEsU2EpfWNvbXB1dGVCeXRlcyhhYSx4YSl7cmV0dXJuIGFhWzBdKmFhWzFdKmJ5dGVzUGVyRWxlbWVudCQxKHhhKX1jaGVja0NvbXBpbGVDb21wbGV0aW9uKCl7Zm9yKGNvbnN0WyxhYV1vZiBPYmplY3QuZW50cmllcyh0aGlzLmJpbmFyeUNhY2hlKSl0aGlzLmNoZWNrQ29tcGxldGlvbl8oYWEpfWFzeW5jIGNoZWNrQ29tcGlsZUNvbXBsZXRpb25Bc3luYygpe2NvbnN0IGFhPVtdO2lmKHRoaXMuZ3BncHUucGFyYWxsZWxDb21waWxhdGlvbkV4dGVuc2lvbil7Zm9yKGNvbnN0Wyx4YV1vZiBPYmplY3QuZW50cmllcyh0aGlzLmJpbmFyeUNhY2hlKSlhYS5wdXNoKHRoaXMuY2hlY2tDb21wbGV0aW9uQXN5bmNfKHhhKSk7cmV0dXJuIFByb21pc2UuYWxsKGFhKX1lbHNle2Zvcihjb25zdFsseGFdb2YgT2JqZWN0LmVudHJpZXModGhpcy5iaW5hcnlDYWNoZSkpe2NvbnN0IGJhPW5ldyBQcm9taXNlKFNhPT57dHJ5e3RoaXMuY2hlY2tDb21wbGV0aW9uXyh4YSksU2EoITApfWNhdGNoKFRhKXt0aHJvdyBUYX19KTthYS5wdXNoKGJhKX1yZXR1cm4gUHJvbWlzZS5hbGwoYWEpfX1hc3luYyBjaGVja0NvbXBsZXRpb25Bc3luY18oYWEpe3JldHVybiB0aGlzLmdwZ3B1LmdsLmdldFByb2dyYW1QYXJhbWV0ZXIoYWEud2ViR0xQcm9ncmFtLHRoaXMuZ3BncHUucGFyYWxsZWxDb21waWxhdGlvbkV4dGVuc2lvbi5DT01QTEVUSU9OX1NUQVRVU19LSFIpP3RoaXMuY2hlY2tDb21wbGV0aW9uXyhhYSk6KGF3YWl0IG5leHRGcmFtZSQxKCksdGhpcy5jaGVja0NvbXBsZXRpb25Bc3luY18oYWEpKX1jaGVja0NvbXBsZXRpb25fKGFhKXtpZih0aGlzLmdwZ3B1LmdsLmdldFByb2dyYW1QYXJhbWV0ZXIoYWEud2ViR0xQcm9ncmFtLHRoaXMuZ3BncHUuZ2wuTElOS19TVEFUVVMpPT09ITEpdGhyb3cgY29uc29sZS5sb2codGhpcy5ncGdwdS5nbC5nZXRQcm9ncmFtSW5mb0xvZyhhYS53ZWJHTFByb2dyYW0pKSx0aGlzLmdwZ3B1LmdsLmdldFNoYWRlclBhcmFtZXRlcihhYS5mcmFnbWVudFNoYWRlcix0aGlzLmdwZ3B1LmdsLkNPTVBJTEVfU1RBVFVTKT09PSExPyhsb2dTaGFkZXJTb3VyY2VBbmRJbmZvTG9nJDEoYWEuc291cmNlLHRoaXMuZ3BncHUuZ2wuZ2V0U2hhZGVySW5mb0xvZyhhYS5mcmFnbWVudFNoYWRlcikpLG5ldyBFcnJvcigiRmFpbGVkIHRvIGNvbXBpbGUgZnJhZ21lbnQgc2hhZGVyLiIpKTpuZXcgRXJyb3IoIkZhaWxlZCB0byBsaW5rIHZlcnRleCBhbmQgZnJhZ21lbnQgc2hhZGVycy4iKTtyZXR1cm4hMH1nZXRVbmlmb3JtTG9jYXRpb25zKCl7Zm9yKGNvbnN0IGFhIG9mIE9iamVjdC52YWx1ZXModGhpcy5iaW5hcnlDYWNoZSkpe3RoaXMuZ3BncHUuYnVpbGRWYW8oYWEud2ViR0xQcm9ncmFtKTtjb25zdHt2YXJpYWJsZXNMb2NhdGlvbnM6eGEsY3VzdG9tVW5pZm9ybUxvY2F0aW9uczpiYSxpbmZMb2M6U2EsbmFuTG9jOlRhLG91dFNoYXBlTG9jYXRpb246d2Esb3V0U2hhcGVTdHJpZGVzTG9jYXRpb246RWEsb3V0VGV4U2hhcGVMb2NhdGlvbjprYX09Z2V0VW5pZm9ybUxvY2F0aW9ucyQxKHRoaXMuZ3BncHUsYWEucHJvZ3JhbSxhYS53ZWJHTFByb2dyYW0pO2FhLnZhcmlhYmxlc0xvY2F0aW9ucz14YSxhYS5jdXN0b21Vbmlmb3JtTG9jYXRpb25zPWJhLGFhLmluZkxvYz1TYSxhYS5uYW5Mb2M9VGEsYWEub3V0U2hhcGVMb2NhdGlvbj13YSxhYS5vdXRTaGFwZVN0cmlkZXNMb2NhdGlvbj1FYSxhYS5vdXRUZXhTaGFwZUxvY2F0aW9uPWthfX1jcmVhdGVUZW5zb3JGcm9tR1BVRGF0YShhYSx4YSxiYSl7YWEuY2hhbm5lbHM9YWEuY2hhbm5lbHN8fCJSR0JBIjtjb25zdHt0ZXh0dXJlOlNhLGhlaWdodDpUYSx3aWR0aDp3YSxjaGFubmVsczpFYX09YWEsa2E9ZW5naW5lJDEoKS5iYWNrZW5kO2lmKCFrYS5ncGdwdS5nbC5pc1RleHR1cmUoU2EpKXRocm93IG5ldyBFcnJvcigiVGhlIHRleHR1cmUgaXMgaW52YWxpZC4gQWxzbywgcGxlYXNlIG1ha2Ugc3VyZSB0aGUgdGV4dHVyZSBhbmQgdGhlIFRGSlMgV2ViR0wgYmFja2VuZCBhcmUgdXNpbmcgdGhlIHNhbWUgY2FudmFzLiBJZiB5b3Ugd2FudCB0byB1c2UgeW91ciBvd24gY3VzdG9tIGNhbnZhcywgeW91IGhhdmUgdG8gY3JlYXRlIGFuZCB1c2UgdGhlIGN1c3RvbSBURkpTIFdlYkdMIGJhY2tlbmQgY3JlYXRlZCBmcm9tIHRoZSBjYW52YXMgdGhyb3VnaCAnbmV3IHRmLk1hdGhCYWNrZW5kV2ViR0woY3VzdG9tQ2FudmFzKScuIik7Y29uc3QgQWE9a2Eud3JpdGVUZXh0dXJlKFNhLHhhLGJhLFRhLHdhLEVhKTtyZXR1cm4gZW5naW5lJDEoKS5tYWtlVGVuc29yRnJvbURhdGFJZChBYSx4YSxiYSxrYSl9fTtNYXRoQmFja2VuZFdlYkdMJDEubmV4dERhdGFJZD0wO2Z1bmN0aW9uIGZsb2F0MzJUb1R5cGVkQXJyYXkkMShoYSxhYSl7aWYoYWE9PT0iZmxvYXQzMiJ8fGFhPT09ImNvbXBsZXg2NCIpcmV0dXJuIGhhO2lmKGFhPT09ImludDMyInx8YWE9PT0iYm9vbCIpe2NvbnN0IHhhPWFhPT09ImludDMyIj9uZXcgSW50MzJBcnJheShoYS5sZW5ndGgpOm5ldyBVaW50OEFycmF5KGhhLmxlbmd0aCk7Zm9yKGxldCBiYT0wO2JhPHhhLmxlbmd0aDsrK2JhKXhhW2JhXT1NYXRoLnJvdW5kKGhhW2JhXSk7cmV0dXJuIHhhfWVsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGR0eXBlICR7YWF9YCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovaXNCcm93c2VyJDEoKSYmcmVnaXN0ZXJCYWNrZW5kJDEoIndlYmdsIiwoKT0+bmV3IE1hdGhCYWNrZW5kV2ViR0wkMSwyKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDSEVDS19OQU5fU05JUFBFVCQyPWAKICBpZiAoaXNuYW4oYSkpIHJldHVybiBhOwogIGlmIChpc25hbihiKSkgcmV0dXJuIGI7CmA7bGV0IEJpbmFyeU9wUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIiwiQiJdLHRoaXMub3V0cHV0U2hhcGU9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMSh4YSxiYSksdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy51c2VyQ29kZT1gCiAgICAgIGZsb2F0IGJpbmFyeU9wZXJhdGlvbihmbG9hdCBhLCBmbG9hdCBiKSB7CiAgICAgICAgJHthYX0KICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IGEgPSBnZXRBQXRPdXRDb29yZHMoKTsKICAgICAgICBmbG9hdCBiID0gZ2V0QkF0T3V0Q29vcmRzKCk7CiAgICAgICAgc2V0T3V0cHV0KGJpbmFyeU9wZXJhdGlvbihhLCBiKSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDSEVDS19OQU5fU05JUFBFVF9QQUNLRUQkMT1gCiAgcmVzdWx0LnIgPSBpc05hTi5yID8gTkFOIDogcmVzdWx0LnI7CiAgcmVzdWx0LmcgPSBpc05hTi5nID8gTkFOIDogcmVzdWx0Lmc7CiAgcmVzdWx0LmIgPSBpc05hTi5iID8gTkFOIDogcmVzdWx0LmI7CiAgcmVzdWx0LmEgPSBpc05hTi5hID8gTkFOIDogcmVzdWx0LmE7CmA7bGV0IEJpbmFyeU9wUGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhPSExKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIiwiQiJdLHRoaXMuc3VwcG9ydHNCcm9hZGNhc3Rpbmc9ITAsdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1hc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKHhhLGJhKTtjb25zdCBUYT10aGlzLm91dHB1dFNoYXBlLmxlbmd0aDt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKFRhKTtsZXQgd2E9IiI7aWYoU2EpaWYoVGE9PT0wfHxzaXplRnJvbVNoYXBlJDEodGhpcy5vdXRwdXRTaGFwZSk9PT0xKXdhPWAKICAgICAgICAgIHJlc3VsdC55ID0gMC47CiAgICAgICAgICByZXN1bHQueiA9IDAuOwogICAgICAgICAgcmVzdWx0LncgPSAwLjsKICAgICAgICBgO2Vsc2UgaWYod2E9YAogICAgICAgICAgJHtnZXRDb29yZHNEYXRhVHlwZSQxKFRhKX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgYCxUYT09PTEpdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zP3dhKz1gCiAgICAgICAgICAgIHJlc3VsdC55ID0gKGNvb3JkcyArIDEpID49IG91dFNoYXBlID8gMC4gOiByZXN1bHQueTsKICAgICAgICAgICAgcmVzdWx0LnogPSAwLjsKICAgICAgICAgICAgcmVzdWx0LncgPSAwLjsKICAgICAgICAgIGA6d2ErPWAKICAgICAgICAgICAgcmVzdWx0LnkgPSAoY29vcmRzICsgMSkgPj0gJHt0aGlzLm91dHB1dFNoYXBlWzBdfSA/IDAuIDogcmVzdWx0Lnk7CiAgICAgICAgICAgIHJlc3VsdC56ID0gMC47CiAgICAgICAgICAgIHJlc3VsdC53ID0gMC47CiAgICAgICAgICBgO2Vsc2V7Y29uc3Qga2E9Z2V0Q2hhbm5lbHMkMSgiY29vcmRzIixUYSk7dGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zP3dhKz1gCiAgICAgICAgICAgIGJvb2wgbmV4dFJvd091dE9mQm91bmRzID0KICAgICAgICAgICAgICAoJHtrYVtUYS0yXX0gKyAxKSA+PSBvdXRTaGFwZVske1RhfSAtIDJdOwogICAgICAgICAgICBib29sIG5leHRDb2xPdXRPZkJvdW5kcyA9CiAgICAgICAgICAgICAgKCR7a2FbVGEtMV19ICsgMSkgPj0gb3V0U2hhcGVbJHtUYX0gLSAxXTsKICAgICAgICAgICAgcmVzdWx0LnkgPSBuZXh0Q29sT3V0T2ZCb3VuZHMgPyAwLiA6IHJlc3VsdC55OwogICAgICAgICAgICByZXN1bHQueiA9IG5leHRSb3dPdXRPZkJvdW5kcyA/IDAuIDogcmVzdWx0Lno7CiAgICAgICAgICAgIHJlc3VsdC53ID0gbmV4dENvbE91dE9mQm91bmRzIHx8IG5leHRSb3dPdXRPZkJvdW5kcyA/IDAuIDogcmVzdWx0Lnc7CiAgICAgICAgICBgOndhKz1gCiAgICAgICAgICAgIGJvb2wgbmV4dFJvd091dE9mQm91bmRzID0KICAgICAgICAgICAgICAoJHtrYVtUYS0yXX0gKyAxKSA+PSAke3RoaXMub3V0cHV0U2hhcGVbVGEtMl19OwogICAgICAgICAgICBib29sIG5leHRDb2xPdXRPZkJvdW5kcyA9CiAgICAgICAgICAgICAgKCR7a2FbVGEtMV19ICsgMSkgPj0gJHt0aGlzLm91dHB1dFNoYXBlW1RhLTFdfTsKICAgICAgICAgICAgcmVzdWx0LnkgPSBuZXh0Q29sT3V0T2ZCb3VuZHMgPyAwLiA6IHJlc3VsdC55OwogICAgICAgICAgICByZXN1bHQueiA9IG5leHRSb3dPdXRPZkJvdW5kcyA/IDAuIDogcmVzdWx0Lno7CiAgICAgICAgICAgIHJlc3VsdC53ID0gbmV4dENvbE91dE9mQm91bmRzIHx8IG5leHRSb3dPdXRPZkJvdW5kcyA/IDAuIDogcmVzdWx0Lnc7CiAgICAgICAgICBgfXRoaXMudXNlckNvZGU9YAogICAgICB2ZWM0IGJpbmFyeU9wZXJhdGlvbih2ZWM0IGEsIHZlYzQgYikgewogICAgICAgICR7YWF9CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICB2ZWM0IGEgPSBnZXRBQXRPdXRDb29yZHMoKTsKICAgICAgICB2ZWM0IGIgPSBnZXRCQXRPdXRDb29yZHMoKTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSBiaW5hcnlPcGVyYXRpb24oYSwgYik7CiAgICAgICAgJHt3YX0KCiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpZGVudGl0eSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3g6YmF9PWFhO3JldHVybiB4YS5pbmNSZWYoYmEuZGF0YUlkKSx7ZGF0YUlkOmJhLmRhdGFJZCxzaGFwZTpiYS5zaGFwZSxkdHlwZTpiYS5kdHlwZX19Y29uc3QgaWRlbnRpdHlDb25maWckMT17a2VybmVsTmFtZTpJZGVudGl0eSQyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzppZGVudGl0eSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb21wbGV4JDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7cmVhbDpiYSxpbWFnOlNhfT1hYSxUYT14YS5tYWtlVGVuc29ySW5mbyhiYS5zaGFwZSwiY29tcGxleDY0Iiksd2E9eGEudGV4RGF0YS5nZXQoVGEuZGF0YUlkKSxFYT1pZGVudGl0eSQxKHtpbnB1dHM6e3g6YmF9LGJhY2tlbmQ6eGF9KSxrYT1pZGVudGl0eSQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtyZXR1cm4gd2EuY29tcGxleFRlbnNvckluZm9zPXtyZWFsOkVhLGltYWc6a2F9LFRhfWNvbnN0IGNvbXBsZXhDb25maWckMT17a2VybmVsTmFtZTpDb21wbGV4JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbXBsZXgkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgTEVBS1lSRUxVJDE9InJldHVybiAoYSA8IDAuKSA/IGIgKiBhIDogYTsiLExFQUtZUkVMVV9QQUNLRUQkMT1gCiAgdmVjNCBhTGVzc1RoYW5aZXJvID0gdmVjNChsZXNzVGhhbihhLCB2ZWM0KDAuKSkpOwogIHJldHVybiAoYUxlc3NUaGFuWmVybyAqIChiICogYSkpICsgKCh2ZWM0KDEuMCkgLSBhTGVzc1RoYW5aZXJvKSAqIGEpOwpgO2Z1bmN0aW9uIGxlYWt5UmVsdSQyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHthbHBoYTpUYX09YmEsd2E9eGEubWFrZVRlbnNvckluZm8oW10sImZsb2F0MzIiLGNyZWF0ZVNjYWxhclZhbHVlJDEoVGEsImZsb2F0MzIiKSksRWE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0JJTkFSWV9PUEVSQVRJT05TIik/bmV3IEJpbmFyeU9wUGFja2VkUHJvZ3JhbSQxKExFQUtZUkVMVV9QQUNLRUQkMSxTYS5zaGFwZSx3YS5zaGFwZSk6bmV3IEJpbmFyeU9wUHJvZ3JhbSQxKExFQUtZUkVMVSQxLFNhLnNoYXBlLHdhLnNoYXBlKSxrYT14YS5ydW5XZWJHTFByb2dyYW0oRWEsW1NhLHdhXSwiZmxvYXQzMiIpO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh3YSksa2F9Y29uc3QgbGVha3lSZWx1Q29uZmlnJDE9e2tlcm5lbE5hbWU6TGVha3lSZWx1JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmxlYWt5UmVsdSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBQUkVMVSQxPSJyZXR1cm4gKGEgPCAwLikgPyBiICogYSA6IGE7IixQUkVMVV9QQUNLRUQkMT1gCiAgdmVjNCBhTGVzc1RoYW5aZXJvID0gdmVjNChsZXNzVGhhbihhLCB2ZWM0KDAuKSkpOwogIHJldHVybiAoYUxlc3NUaGFuWmVybyAqIChiICogYSkpICsgKCh2ZWM0KDEuMCkgLSBhTGVzc1RoYW5aZXJvKSAqIGEpOwpgO2Z1bmN0aW9uIHByZWx1JDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYSxhbHBoYTpTYX09YWEsVGE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0JJTkFSWV9PUEVSQVRJT05TIik/bmV3IEJpbmFyeU9wUGFja2VkUHJvZ3JhbSQxKFBSRUxVX1BBQ0tFRCQxLGJhLnNoYXBlLFNhLnNoYXBlKTpuZXcgQmluYXJ5T3BQcm9ncmFtJDEoUFJFTFUkMSxiYS5zaGFwZSxTYS5zaGFwZSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShUYSxbYmEsU2FdLCJmbG9hdDMyIil9Y29uc3QgcHJlbHVDb25maWckMT17a2VybmVsTmFtZTpQcmVsdSQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpwcmVsdSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDSEVDS19OQU5fU05JUFBFVF9VTkFSWSQxPSJpZiAoaXNuYW4oeCkpIHJldHVybiB4OyI7ZnVuY3Rpb24gdW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpoYSxwYWNrZWRPcFNuaXBwZXQ6YWEsY3B1S2VybmVsSW1wbDp4YSxkdHlwZTpiYX0pe3JldHVybih7aW5wdXRzOlNhLGJhY2tlbmQ6VGF9KT0+e2NvbnN0e3g6d2F9PVNhLEVhPVRhLGthPWJhfHx3YS5kdHlwZTtpZihFYS5zaG91bGRFeGVjdXRlT25DUFUoW3dhXSkmJnhhIT1udWxsKXtjb25zdCBMYT1FYS50ZXhEYXRhLmdldCh3YS5kYXRhSWQpLGVsPXhhKExhLnZhbHVlcyxrYSk7cmV0dXJuIEVhLm1ha2VUZW5zb3JJbmZvKHdhLnNoYXBlLGthLGVsKX1jb25zdCBBYT1lbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfVU5BUllfT1BFUkFUSU9OUyIpJiZhYSE9bnVsbDtsZXQgRmE7cmV0dXJuIEFhP0ZhPW5ldyBVbmFyeU9wUGFja2VkUHJvZ3JhbSQxKHdhLnNoYXBlLGFhKTpGYT1uZXcgVW5hcnlPcFByb2dyYW0kMSh3YS5zaGFwZSxoYSksRWEucnVuV2ViR0xQcm9ncmFtKEZhLFt3YV0sa2EpfX1mdW5jdGlvbiBiaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpoYSxwYWNrZWRPcFNuaXBwZXQ6YWEsY2hlY2tPdXRPZkJvdW5kczp4YT0hMSxzdXBwb3J0c0NvbXBsZXg6YmE9ITEsY3B1S2VybmVsSW1wbDpTYSxkdHlwZTpUYX0pe3JldHVybih7aW5wdXRzOndhLGJhY2tlbmQ6RWF9KT0+e2NvbnN0e2E6a2EsYjpBYX09d2EsRmE9RWE7aWYoYmEmJmthLmR0eXBlPT09ImNvbXBsZXg2NCIpe2NvbnN0IG5sPUZhLnRleERhdGEuZ2V0KGthLmRhdGFJZCksc2w9RmEudGV4RGF0YS5nZXQoQWEuZGF0YUlkKSxbcmwsb2xdPVtbbmwuY29tcGxleFRlbnNvckluZm9zLnJlYWwsc2wuY29tcGxleFRlbnNvckluZm9zLnJlYWxdLFtubC5jb21wbGV4VGVuc29ySW5mb3MuaW1hZyxzbC5jb21wbGV4VGVuc29ySW5mb3MuaW1hZ11dLm1hcChsbD0+e2NvbnN0W2lsLGNsXT1sbCx1bD17ZGF0YUlkOmlsLmRhdGFJZCxkdHlwZTppbC5kdHlwZSxzaGFwZTprYS5zaGFwZX0sZGw9e2RhdGFJZDpjbC5kYXRhSWQsZHR5cGU6Y2wuZHR5cGUsc2hhcGU6QWEuc2hhcGV9LGhsPW5ldyBCaW5hcnlPcFByb2dyYW0kMShoYSxrYS5zaGFwZSxBYS5zaGFwZSk7cmV0dXJuIEZhLnJ1bldlYkdMUHJvZ3JhbShobCxbdWwsZGxdLHVwY2FzdFR5cGUkMShpbC5kdHlwZSxjbC5kdHlwZSkpfSksYWw9Y29tcGxleCQyKHtpbnB1dHM6e3JlYWw6cmwsaW1hZzpvbH0sYmFja2VuZDpGYX0pO3JldHVybiBGYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhybCksRmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpLGFsfWNvbnN0IExhPVRhfHx1cGNhc3RUeXBlJDEoa2EuZHR5cGUsQWEuZHR5cGUpO2lmKChrYS5kdHlwZT09PSJzdHJpbmcifHxBYS5kdHlwZT09PSJzdHJpbmcifHxGYS5zaG91bGRFeGVjdXRlT25DUFUoW2thLEFhXSkpJiZTYSE9bnVsbCl7Y29uc3Qgbmw9RmEudGV4RGF0YS5nZXQoa2EuZGF0YUlkKS52YWx1ZXMsc2w9RmEudGV4RGF0YS5nZXQoQWEuZGF0YUlkKS52YWx1ZXMscmw9a2EuZHR5cGU9PT0ic3RyaW5nIj9mcm9tVWludDhUb1N0cmluZ0FycmF5JDEobmwpOm5sLG9sPWthLmR0eXBlPT09InN0cmluZyI/ZnJvbVVpbnQ4VG9TdHJpbmdBcnJheSQxKHNsKTpzbCxbYWwsbGxdPVNhKGthLnNoYXBlLEFhLnNoYXBlLHJsLG9sLExhKSxpbD1GYS5tYWtlVGVuc29ySW5mbyhsbCxMYSksY2w9RmEudGV4RGF0YS5nZXQoaWwuZGF0YUlkKTtyZXR1cm4gY2wudmFsdWVzPWFsLGlsfWNvbnN0IGVsPWVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19CSU5BUllfT1BFUkFUSU9OUyIpJiZhYSE9bnVsbDtsZXQgdGw7cmV0dXJuIGVsP3RsPW5ldyBCaW5hcnlPcFBhY2tlZFByb2dyYW0kMShhYSxrYS5zaGFwZSxBYS5zaGFwZSx4YSk6dGw9bmV3IEJpbmFyeU9wUHJvZ3JhbSQxKGhhLGthLnNoYXBlLEFhLnNoYXBlKSxGYS5ydW5XZWJHTFByb2dyYW0odGwsW2thLEFhXSxMYSl9fWZ1bmN0aW9uIG1hcEFjdGl2YXRpb25Ub1NoYWRlclByb2dyYW0kMShoYSxhYT0hMSl7aWYoaGE9PT0ibGluZWFyIilyZXR1cm4gYWE/TElORUFSJDI6TElORUFSJDM7aWYoaGE9PT0icmVsdSIpcmV0dXJuIGFhP1JFTFUkNDpSRUxVJDU7aWYoaGE9PT0iZWx1IilyZXR1cm4gYWE/RUxVJDQ6RUxVJDU7aWYoaGE9PT0icmVsdTYiKXJldHVybiBhYT9SRUxVNiQ0OlJFTFU2JDU7aWYoaGE9PT0icHJlbHUiKXJldHVybiBhYT9QUkVMVV9QQUNLRUQkMTpQUkVMVSQxO2lmKGhhPT09ImxlYWt5cmVsdSIpcmV0dXJuIGFhP0xFQUtZUkVMVV9QQUNLRUQkMTpMRUFLWVJFTFUkMTtpZihoYT09PSJzaWdtb2lkIilyZXR1cm4gYWE/U0lHTU9JRCQ0OlNJR01PSUQkNTt0aHJvdyBuZXcgRXJyb3IoYEFjdGl2YXRpb24gJHtoYX0gaGFzIG5vdCBiZWVuIGltcGxlbWVudGVkIGZvciB0aGUgV2ViR0wgYmFja2VuZC5gKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgTWF0TXVsUGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhPSExLFRhPSExLHdhPSExLEVhPW51bGwsa2E9ITEsQWE9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIm1hdHJpeEEiLCJtYXRyaXhCIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1iYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdCBGYT1TYT9hYVsxXTphYVsyXSxMYT1NYXRoLmNlaWwoRmEvMiksZWw9U2E/ImkgKiAyLCByYy55IjoicmMueSwgaSAqIDIiLHRsPVRhPyJyYy56LCBpICogMiI6ImkgKiAyLCByYy56IixubD1TYT9bImEueHh5eSIsImEuenp3dyJdOlsiYS54eHp6IiwiYS55eXd3Il0sc2w9VGE/WyJiLnh6eHoiLCJiLnl3eXciXTpbImIueHl4eSIsImIuend6dyJdO2xldCBybD0iIixvbD0iIjtFYSYmKGthP3JsPWB2ZWM0IGFjdGl2YXRpb24odmVjNCBhKSB7CiAgICAgICAgICB2ZWM0IGIgPSBnZXRQcmVsdUFjdGl2YXRpb25XZWlnaHRzQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7RWF9CiAgICAgICAgfWA6QWE/cmw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IGEpIHsKICAgICAgICAgIHZlYzQgYiA9IGdldExlYWt5cmVsdUFscGhhQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7RWF9CiAgICAgICAgfWA6cmw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IHgpIHsKICAgICAgICAgICR7RWF9CiAgICAgICAgfWAsb2w9InJlc3VsdCA9IGFjdGl2YXRpb24ocmVzdWx0KTsiKTtjb25zdCBhbD13YT8icmVzdWx0ICs9IGdldEJpYXNBdE91dENvb3JkcygpOyI6IiI7d2EmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJiaWFzIiksa2EmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJwcmVsdUFjdGl2YXRpb25XZWlnaHRzIiksQWEmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJsZWFreXJlbHVBbHBoYSIpO2xldCBsbD0icmMueCIsaWw9InJjLngiO2FhWzBdPHhhWzBdP2xsPWBpbW9kKHJjLngsICR7YWFbMF19KWA6eGFbMF08YWFbMF0mJihpbD1gaW1vZChyYy54LCAke3hhWzBdfSlgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgJHtybH0KICAgICAgLy8gRG9uJ3QgdXNlIHVuaWZvcm0gZm9yIHNoYXJlZERpbWVuc2lvblBhY2tlZCBmb3IgcGVyZm9ybWFuY2UuCiAgICAgIGNvbnN0IGZsb2F0IHNoYXJlZERpbWVuc2lvbiA9ICR7TGF9LjA7CgogICAgICB2ZWM0IGRvdDJ4MkFSb3dCQ29sKGl2ZWMzIHJjKSB7CiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDApOwogICAgICAgIGludCBiYXRjaEEgPSAke2xsfTsKICAgICAgICBpbnQgYmF0Y2hCID0gJHtpbH07CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke0xhfTsgaSsrKSB7CiAgICAgICAgICB2ZWM0IGEgPSBnZXRNYXRyaXhBKGJhdGNoQSwgJHtlbH0pOwogICAgICAgICAgdmVjNCBiID0gZ2V0TWF0cml4QihiYXRjaEIsICR7dGx9KTsKCiAgICAgICAgICAvLyBUaGVzZSBzd2l6emxlZCBwcm9kdWN0cyBuZWVkIHRvIGJlIHNlcGFyYXRlbHkgYWRkZWQuCiAgICAgICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS90ZW5zb3JmbG93L3RmanMvaXNzdWVzLzE3MzUKICAgICAgICAgIHJlc3VsdCArPSAoJHtubFswXX0gKiAke3NsWzBdfSk7CiAgICAgICAgICByZXN1bHQgKz0gKCR7bmxbMV19ICogJHtzbFsxXX0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzMgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICB2ZWM0IHJlc3VsdCA9IGRvdDJ4MkFSb3dCQ29sKHJjKTsKCiAgICAgICAgJHthbH0KCiAgICAgICAgJHtvbH0KCiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDT01QTEVYX01VTFRJUExZJDE9e1JFQUw6InJldHVybiBhcmVhbCAqIGJyZWFsIC0gYWltYWcgKiBiaW1hZzsiLElNQUc6InJldHVybiBhcmVhbCAqIGJpbWFnICsgYWltYWcgKiBicmVhbDsifTtsZXQgQmluYXJ5T3BDb21wbGV4UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBUmVhbCIsIkFJbWFnIiwiQlJlYWwiLCJCSW1hZyJdLHRoaXMub3V0cHV0U2hhcGU9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMSh4YSxiYSksdGhpcy51c2VyQ29kZT1gCiAgICAgIGZsb2F0IGJpbmFyeU9wQ29tcGxleCgKICAgICAgICAgIGZsb2F0IGFyZWFsLCBmbG9hdCBhaW1hZywgZmxvYXQgYnJlYWwsIGZsb2F0IGJpbWFnKSB7CiAgICAgICAgJHthYX0KICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IGFyZWFsID0gZ2V0QVJlYWxBdE91dENvb3JkcygpOwogICAgICAgIGZsb2F0IGFpbWFnID0gZ2V0QUltYWdBdE91dENvb3JkcygpOwogICAgICAgIGZsb2F0IGJyZWFsID0gZ2V0QlJlYWxBdE91dENvb3JkcygpOwogICAgICAgIGZsb2F0IGJpbWFnID0gZ2V0QkltYWdBdE91dENvb3JkcygpOwogICAgICAgIHNldE91dHB1dChiaW5hcnlPcENvbXBsZXgoYXJlYWwsIGFpbWFnLCBicmVhbCwgYmltYWcpKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE1VTCQxPSJyZXR1cm4gYSAqIGI7IjtmdW5jdGlvbiBtdWx0aXBseSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2E6YmEsYjpTYX09YWEsVGE9dXBjYXN0VHlwZSQxKGJhLmR0eXBlLFNhLmR0eXBlKTtpZihiYS5kdHlwZT09PSJjb21wbGV4NjQiKXtjb25zdCBFYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpLGthPXhhLnRleERhdGEuZ2V0KFNhLmRhdGFJZCksQWE9bmV3IEJpbmFyeU9wQ29tcGxleFByb2dyYW0kMShDT01QTEVYX01VTFRJUExZJDEuUkVBTCxiYS5zaGFwZSxTYS5zaGFwZSksRmE9bmV3IEJpbmFyeU9wQ29tcGxleFByb2dyYW0kMShDT01QTEVYX01VTFRJUExZJDEuSU1BRyxiYS5zaGFwZSxTYS5zaGFwZSksTGE9W3tkYXRhSWQ6RWEuY29tcGxleFRlbnNvckluZm9zLnJlYWwuZGF0YUlkLGR0eXBlOkVhLmNvbXBsZXhUZW5zb3JJbmZvcy5yZWFsLmR0eXBlLHNoYXBlOmJhLnNoYXBlfSx7ZGF0YUlkOkVhLmNvbXBsZXhUZW5zb3JJbmZvcy5pbWFnLmRhdGFJZCxkdHlwZTpFYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZy5kdHlwZSxzaGFwZTpiYS5zaGFwZX0se2RhdGFJZDprYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbC5kYXRhSWQsZHR5cGU6a2EuY29tcGxleFRlbnNvckluZm9zLnJlYWwuZHR5cGUsc2hhcGU6U2Euc2hhcGV9LHtkYXRhSWQ6a2EuY29tcGxleFRlbnNvckluZm9zLmltYWcuZGF0YUlkLGR0eXBlOmthLmNvbXBsZXhUZW5zb3JJbmZvcy5pbWFnLmR0eXBlLHNoYXBlOlNhLnNoYXBlfV0sZWw9eGEucnVuV2ViR0xQcm9ncmFtKEFhLExhLCJmbG9hdDMyIiksdGw9eGEucnVuV2ViR0xQcm9ncmFtKEZhLExhLCJmbG9hdDMyIiksbmw9Y29tcGxleCQyKHtpbnB1dHM6e3JlYWw6ZWwsaW1hZzp0bH0sYmFja2VuZDp4YX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLG5sfWlmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbYmEsU2FdKSl7Y29uc3QgRWE9eGEudGV4RGF0YS5nZXQoYmEuZGF0YUlkKSxrYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLFtBYSxGYV09bXVsdGlwbHlJbXBsQ1BVJDEoYmEuc2hhcGUsU2Euc2hhcGUsRWEudmFsdWVzLGthLnZhbHVlcyxUYSksTGE9eGEubWFrZVRlbnNvckluZm8oRmEsVGEpLGVsPXhhLnRleERhdGEuZ2V0KExhLmRhdGFJZCk7cmV0dXJuIGVsLnZhbHVlcz1BYSxMYX1sZXQgd2E7cmV0dXJuIGVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19CSU5BUllfT1BFUkFUSU9OUyIpP3dhPW5ldyBCaW5hcnlPcFBhY2tlZFByb2dyYW0kMShNVUwkMSxiYS5zaGFwZSxTYS5zaGFwZSk6d2E9bmV3IEJpbmFyeU9wUHJvZ3JhbSQxKE1VTCQxLGJhLnNoYXBlLFNhLnNoYXBlKSx4YS5ydW5XZWJHTFByb2dyYW0od2EsW2JhLFNhXSxUYSl9Y29uc3QgbXVsdGlwbHlDb25maWckMT17a2VybmVsTmFtZTpNdWx0aXBseSQyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptdWx0aXBseSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwYWNrZWRSZXNoYXBlJDEoaGEsYWEseGEpe2NvbnN0IGJhPVtnZXRCYXRjaERpbSQxKGhhLnNoYXBlKSwuLi5nZXRSb3dzQ29scyQxKGhhLnNoYXBlKV0sU2E9e2R0eXBlOmhhLmR0eXBlLHNoYXBlOmJhLGRhdGFJZDpoYS5kYXRhSWR9LFRhPVtnZXRCYXRjaERpbSQxKGFhKSwuLi5nZXRSb3dzQ29scyQxKGFhKV0sd2E9bmV3IFJlc2hhcGVQYWNrZWRQcm9ncmFtJDEoVGEsYmEpLEVhPSEwLGthPVtiYV0sQWE9eGEucnVuV2ViR0xQcm9ncmFtKHdhLFtTYV0saGEuZHR5cGUsa2EsRWEpO3JldHVybntkYXRhSWQ6QWEuZGF0YUlkLHNoYXBlOmFhLGR0eXBlOkFhLmR0eXBlfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNoYXBlJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse3NoYXBlOlRhfT1iYSx3YT14YSxFYT1zaXplRnJvbVNoYXBlJDEoU2Euc2hhcGUpLGthPWluZmVyRnJvbUltcGxpY2l0U2hhcGUkMShUYSxFYSksQWE9c2l6ZUZyb21TaGFwZSQxKGthKTthc3NlcnQkMihFYT09PUFhLCgpPT5gVGhlIG5ldyBzaGFwZSAoJHtrYX0pIGhhcyAke0FhfSBlbGVtZW50cyBhbmQgdGhlIG9sZCBzaGFwZSAoJHtTYS5zaGFwZX0pIGhhcyAke0VhfSBlbGVtZW50cy4gVGhlIG5ldyBzaGFwZSBhbmQgb2xkIHNoYXBlIG11c3QgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZWxlbWVudHMuYCk7Y29uc3QgRmE9d2EudGV4RGF0YS5nZXQoU2EuZGF0YUlkKTtyZXR1cm4gRmEuaXNQYWNrZWQmJiFpc1Jlc2hhcGVGcmVlJDEoU2Euc2hhcGUsa2EpJiYhKEZhLnRleHR1cmUhPT1udWxsJiZpc1Jlc2hhcGVGcmVlJDEoRmEuc2hhcGUsa2EpKT9wYWNrZWRSZXNoYXBlJDEoU2Esa2Esd2EpOih3YS5pbmNSZWYoU2EuZGF0YUlkKSx7ZGF0YUlkOlNhLmRhdGFJZCxzaGFwZTprYSxkdHlwZTpTYS5kdHlwZX0pfWNvbnN0IHJlc2hhcGVDb25maWckMT17a2VybmVsTmFtZTpSZXNoYXBlJDIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlc2hhcGUkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IE1lYW5Qcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXTtjb25zdHt3aW5kb3dTaXplOmJhLGJhdGNoU2l6ZTpTYSxpblNpemU6VGEsb3V0U2l6ZTp3YX09YWE7dGhpcy5vdXRwdXRTaGFwZT1bU2Esd2FdO2NvbnN0IEVhPU1hdGguZmxvb3IoYmEvNCkqNCxrYT1iYSU0O2xldCBBYT0ic3VtVmFsdWUgKz0gZG90KHZhbHVlcywgb25lcyk7IjtpZih4YSE9bnVsbCl7Y29uc3QgTGE9MS94YTtBYT1gc3VtVmFsdWUgKz0gZG90KHZhbHVlcyAqICR7aXNJbnQkMShMYSk/TGEudG9QcmVjaXNpb24oMik6TGF9LCBvbmVzKTtgfWxldCBGYT0iIjtUYSViYT4wJiYoRmE9YAogICAgICAgIGlmIChpbklkeCA8IDAgfHwgaW5JZHggPj0gJHtUYX0pIHsKICAgICAgICAgIHJldHVybiAwLjA7CiAgICAgICAgfQogICAgICBgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgdmVjNCBvbmVzID0gdmVjNCgxLjAsIDEuMCwgMS4wLCAxLjApOwoKICAgICAgZmxvYXQgZ2V0VmFsdWUoaW50IGJhdGNoLCBpbnQgaW5JZHgpIHsKICAgICAgICAke0ZhfQogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCBpbklkeCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgaW50IG91dElkeCA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgaW5PZmZzZXQgPSBvdXRJZHggKiAke2JhfTsKCiAgICAgICAgZmxvYXQgc3VtVmFsdWUgPSAwLjA7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtFYX07IGkgKz0gNCkgewogICAgICAgICAgaW50IGluSWR4ID0gaW5PZmZzZXQgKyBpOwogICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAxKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMiksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDMpCiAgICAgICAgICApOwoKICAgICAgICAgICR7QWF9CiAgICAgICAgfQoKICAgICAgICBpbnQgaW5JZHggPSBpbk9mZnNldCArICR7RWF9OwogICAgICAgIGlmICgke2thPT09MX0pIHsKICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNChnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLCAwLjAsIDAuMCwgMC4wKTsKCiAgICAgICAgICAke0FhfQogICAgICAgIH0gZWxzZSBpZiAoJHtrYT09PTJ9KSB7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLCAwLjAsIDAuMCk7CgogICAgICAgICAgJHtBYX0KICAgICAgICB9IGVsc2UgaWYgKCR7a2E9PT0zfSkgewogICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAxKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMiksIDAuMCk7CgogICAgICAgICAgJHtBYX0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KHN1bVZhbHVlKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBSZWR1Y2VQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXTtjb25zdHt3aW5kb3dTaXplOmJhLGJhdGNoU2l6ZTpTYSxpblNpemU6VGEsb3V0U2l6ZTp3YX09YWE7dGhpcy5vdXRwdXRTaGFwZT1bU2Esd2FdO2xldCBFYT0iMC4wIixrYT0iIjt4YT09PSJwcm9kIj9FYT0iMS4wIjp4YT09PSJtaW4iPyhFYT0iMS4wIC8gMWUtMjAiLGthPSJtaW4iKTp4YT09PSJtYXgiJiYoRWE9Ii0xLjAgLyAxZS0yMCIsa2E9Im1heCIpO2xldCBBYT1gJHt4YX0oJHt4YX0oJHt4YX0obWluTWF4VmFsdWVbMF0sIG1pbk1heFZhbHVlWzFdKSwgbWluTWF4VmFsdWVbMl0pLCBtaW5NYXhWYWx1ZVszXSlgO3hhPT09InN1bSI/QWE9InN1bVZhbHVlIjp4YT09PSJwcm9kIj9BYT0icHJvZFZhbHVlIjp4YT09PSJhbGwiP0FhPSJhbGxWYWx1ZSI6eGE9PT0iYW55IiYmKEFhPSJhbnlWYWx1ZSIpO2NvbnN0IEZhPU1hdGguZmxvb3IoYmEvNCkqNCxMYT1iYSU0O2xldCBlbD1gCiAgICAgIGlmICgke3hhPT09InN1bSJ9KSB7CiAgICAgICAgc3VtVmFsdWUgKz0gZG90KHZhbHVlcywgb25lcyk7CiAgICAgIH0gZWxzZSBpZiAoJHt4YT09PSJwcm9kIn0pIHsKICAgICAgICB2ZWMyIHRtcCA9IHZlYzIodmFsdWVzWzBdLCB2YWx1ZXNbMV0pICogdmVjMih2YWx1ZXNbMl0sIHZhbHVlc1szXSk7CiAgICAgICAgcHJvZFZhbHVlICo9IHRtcFswXSAqIHRtcFsxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICBtaW5NYXhWYWx1ZSA9ICR7a2F9KHZhbHVlcywgbWluTWF4VmFsdWUpOwogICAgICAgIGlmICgke3hhPT09Im1pbiJ9IHx8ICR7eGE9PT0ibWF4In0pIHsKICAgICAgICAgIG1pbk1heFZhbHVlID0gJHtrYX0odmFsdWVzLCBtaW5NYXhWYWx1ZSk7CiAgICAgICAgICBidmVjNCBpc05hTiA9IGlzbmFuKHZhbHVlcyk7CiAgICAgICAgICBpZiAoaXNOYU4uciB8fCBpc05hTi5nIHx8IGlzTmFOLmIgfHwgaXNOYU4uYSkgewogICAgICAgICAgICBtaW5NYXhWYWx1ZSA9IHZlYzQoTkFOKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIGAsdGw9InZlYzQiO3hhPT09ImFsbCI/KEVhPSIxLjAiLGVsPWAKICAgICAgICBib29sIHJlZHVjZWRBbGxWYWx1ZSA9IGFsbCh2YWx1ZXMpOwogICAgICAgIGZsb2F0IGZsb2F0ZWRSZWR1Y2VkQWxsVmFsdWUgPSBmbG9hdChyZWR1Y2VkQWxsVmFsdWUpOwogICAgICAgIGFsbFZhbHVlID0gZmxvYXQoYWxsVmFsdWUgPj0gMS4wICYmIGZsb2F0ZWRSZWR1Y2VkQWxsVmFsdWUgPj0gMS4wKTsKICAgICAgYCx0bD0iYnZlYzQiKTp4YT09PSJhbnkiJiYoRWE9IjAuMCIsZWw9YAogICAgICAgIGJvb2wgcmVkdWNlZEFueVZhbHVlID0gYW55KHZhbHVlcyk7CiAgICAgICAgZmxvYXQgZmxvYXRlZFJlZHVjZWRBbnlWYWx1ZSA9IGZsb2F0KHJlZHVjZWRBbnlWYWx1ZSk7CiAgICAgICAgYW55VmFsdWUgPSBmbG9hdChhbnlWYWx1ZSA+PSAxLjAgfHwgZmxvYXRlZFJlZHVjZWRBbnlWYWx1ZSA+PSAxLjApOwogICAgICBgLHRsPSJidmVjNCIpO2xldCBubD0iIjtUYSViYT4wJiYobmw9YAogICAgICAgIGlmIChpbklkeCA8IDAgfHwgaW5JZHggPj0gJHtUYX0pIHsKICAgICAgICAgIHJldHVybiBpbml0aWFsaXphdGlvblZhbHVlOwogICAgICAgIH0KICAgICAgYCksdGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGZsb2F0IGluaXRpYWxpemF0aW9uVmFsdWUgPSAke0VhfTsKICAgICAgY29uc3QgdmVjNCBvbmVzID0gdmVjNCgxLjAsIDEuMCwgMS4wLCAxLjApOwoKICAgICAgZmxvYXQgZ2V0VmFsdWUoaW50IGJhdGNoLCBpbnQgaW5JZHgpIHsKICAgICAgICAke25sfQogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCBpbklkeCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgaW50IG91dElkeCA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgaW5PZmZzZXQgPSBvdXRJZHggKiAke2JhfTsKCiAgICAgICAgdmVjNCBtaW5NYXhWYWx1ZSA9IHZlYzQoJHtFYX0pOwogICAgICAgIGZsb2F0IHByb2RWYWx1ZSA9IDEuMDsKICAgICAgICBmbG9hdCBzdW1WYWx1ZSA9IDAuMDsKICAgICAgICBmbG9hdCBhbGxWYWx1ZSA9IDEuMDsKICAgICAgICBmbG9hdCBhbnlWYWx1ZSA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke0ZhfTsgaSArPSA0KSB7CiAgICAgICAgICBpbnQgaW5JZHggPSBpbk9mZnNldCArIGk7CiAgICAgICAgICAke3RsfSB2YWx1ZXMgPSAke3RsfSgKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4KSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMSksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDIpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAzKQogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0KCiAgICAgICAgaW50IGluSWR4ID0gaW5PZmZzZXQgKyAke0ZhfTsKICAgICAgICBpZiAoJHtMYT09PTF9KSB7CiAgICAgICAgICAke3RsfSB2YWx1ZXMgPSAke3RsfSgKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4KSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0gZWxzZSBpZiAoJHtMYT09PTJ9KSB7CiAgICAgICAgICAke3RsfSB2YWx1ZXMgPSAke3RsfSgKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4KSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMSksCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICk7CgogICAgICAgICAgJHtlbH0KICAgICAgICB9IGVsc2UgaWYgKCR7TGE9PT0zfSkgewogICAgICAgICAgJHt0bH0gdmFsdWVzID0gJHt0bH0oCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAyKSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoJHtBYX0pOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0UmVkdWN0aW9uU3RhZ2VzJDEoaGEpe2NvbnN0IGFhPVtdO2Zvcig7YWEubGVuZ3RoPT09MHx8YWFbYWEubGVuZ3RoLTFdLm91dFNpemUhPT0xOyl7Y29uc3QgeGE9YWEubGVuZ3RoP2FhW2FhLmxlbmd0aC0xXS5vdXRTaXplOmhhWzFdLGJhPWNvbXB1dGVPcHRpbWFsV2luZG93U2l6ZSQxKHhhKTthYS5wdXNoKHtpblNpemU6eGEsd2luZG93U2l6ZTpiYSxvdXRTaXplOk1hdGguY2VpbCh4YS9iYSl9KX1yZXR1cm4gYWF9ZnVuY3Rpb24gcmVkdWNlJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWdldFJlZHVjdGlvblN0YWdlcyQxKGhhLnNoYXBlKTtsZXQgVGE9aGE7Zm9yKGxldCB3YT0wO3dhPFNhLmxlbmd0aDt3YSsrKXtjb25zdHtpblNpemU6RWEsd2luZG93U2l6ZTprYSxvdXRTaXplOkFhfT1TYVt3YV07bGV0IEZhLExhO3hhPT09Im1lYW4iP0ZhPXdhPT09MD9uZXcgTWVhblByb2dyYW0kMSh7d2luZG93U2l6ZTprYSxpblNpemU6RWEsYmF0Y2hTaXplOmhhLnNoYXBlWzBdLG91dFNpemU6QWF9LEVhKTpuZXcgTWVhblByb2dyYW0kMSh7d2luZG93U2l6ZTprYSxpblNpemU6RWEsYmF0Y2hTaXplOmhhLnNoYXBlWzBdLG91dFNpemU6QWF9KTpGYT1uZXcgUmVkdWNlUHJvZ3JhbSQxKHt3aW5kb3dTaXplOmthLGluU2l6ZTpFYSxiYXRjaFNpemU6aGEuc2hhcGVbMF0sb3V0U2l6ZTpBYX0seGEpLExhPVRhLFRhPWJhLnJ1bldlYkdMUHJvZ3JhbShGYSxbVGFdLGFhKSxMYS5kYXRhSWQhPT1oYS5kYXRhSWQmJmJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKExhKX1yZXR1cm4gVGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFRyYW5zcG9zZVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdO2NvbnN0IGJhPW5ldyBBcnJheShhYS5sZW5ndGgpO2ZvcihsZXQgd2E9MDt3YTxiYS5sZW5ndGg7d2ErKyliYVt3YV09YWFbeGFbd2FdXTt0aGlzLm91dHB1dFNoYXBlPWJhLHRoaXMucmFuaz1iYS5sZW5ndGg7Y29uc3QgU2E9Z2V0Q29vcmRzRGF0YVR5cGUkMSh0aGlzLnJhbmspLFRhPWdldFN3aXRjaGVkQ29vcmRzJDEoeGEpO3RoaXMudXNlckNvZGU9YAogICAgdm9pZCBtYWluKCkgewogICAgICAke1NhfSByZXNSQyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICBzZXRPdXRwdXQoZ2V0QSgke1RhfSkpOwogICAgfQogICAgYH19O2Z1bmN0aW9uIGdldFN3aXRjaGVkQ29vcmRzJDEoaGEpe2NvbnN0IGFhPWhhLmxlbmd0aDtpZihhYT42KXRocm93IEVycm9yKGBUcmFuc3Bvc2UgZm9yIHJhbmsgJHthYX0gaXMgbm90IHlldCBzdXBwb3J0ZWRgKTtjb25zdCB4YT1bInJlc1JDLngiLCJyZXNSQy55IiwicmVzUkMueiIsInJlc1JDLnciLCJyZXNSQy51IiwicmVzUkMudiJdLGJhPW5ldyBBcnJheShhYSk7Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aDtTYSsrKWJhW2hhW1NhXV09eGFbU2FdO3JldHVybiBiYS5qb2luKCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFRyYW5zcG9zZVBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwO2NvbnN0IGJhPW5ldyBBcnJheShhYS5sZW5ndGgpO2ZvcihsZXQgRmE9MDtGYTxiYS5sZW5ndGg7RmErKyliYVtGYV09YWFbeGFbRmFdXTtpZih0aGlzLm91dHB1dFNoYXBlPWJhLHRoaXMucmFuaz1iYS5sZW5ndGgsdGhpcy5yYW5rPjYpdGhyb3cgRXJyb3IoYFBhY2tlZCB0cmFuc3Bvc2UgZm9yIHJhbmsgJHt0aGlzLnJhbmt9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkLmApO2NvbnN0IFNhPWdldENvb3Jkc0RhdGFUeXBlJDEodGhpcy5yYW5rKSxUYT1nZXRWZWNDaGFubmVscyQxKCJyYyIsdGhpcy5yYW5rKSx3YT1uZXcgQXJyYXkodGhpcy5yYW5rKTtmb3IobGV0IEZhPTA7RmE8eGEubGVuZ3RoO0ZhKyspd2FbeGFbRmFdXT1UYVtGYV07Y29uc3QgRWE9YHZlYzIoJHt3YS5zbGljZSgtMikuam9pbigpfSlgLGthPWArKyR7VGFbdGhpcy5yYW5rLTFdfSA8ICR7YmFbdGhpcy5yYW5rLTFdfWAsQWE9YGdldENoYW5uZWwoZ2V0QSgke3dhLmpvaW4oKX0pLCAke0VhfSlgO3RoaXMudXNlckNvZGU9YAogICAgdm9pZCBtYWluKCkgewogICAgICAke1NhfSByYyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwogICAgICByZXN1bHRbMF0gPSAke0FhfTsKICAgICAgaWYoJHtrYX0pIHsKICAgICAgICByZXN1bHRbMV0gPSAke0FhfTsKICAgICAgfQogICAgICAtLSR7VGFbdGhpcy5yYW5rLTFdfTsKICAgICAgaWYoKyske1RhW3RoaXMucmFuay0yXX0gPCAke2JhW3RoaXMucmFuay0yXX0pIHsKICAgICAgICByZXN1bHRbMl0gPSAke0FhfTsKICAgICAgICBpZigke2thfSkgewogICAgICAgICAgcmVzdWx0WzNdID0gJHtBYX07CiAgICAgICAgfQogICAgICB9CiAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRyYW5zcG9zZUltcGwkMihoYSxhYSx4YSl7Y29uc3QgYmE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0FSUkFZX09QRVJBVElPTlMiKT9uZXcgVHJhbnNwb3NlUGFja2VkUHJvZ3JhbSQxKGhhLnNoYXBlLGFhKTpuZXcgVHJhbnNwb3NlUHJvZ3JhbSQxKGhhLnNoYXBlLGFhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKGJhLFtoYV0saGEuZHR5cGUpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN1bUltcGwkMShoYSxhYSx4YSxiYSl7Y29uc3QgU2E9YWEsVGE9aGEuc2hhcGUubGVuZ3RoLHdhPXBhcnNlQXhpc1BhcmFtJDEoU2EsaGEuc2hhcGUpO2xldCBFYT13YTtjb25zdCBrYT1nZXRBeGVzUGVybXV0YXRpb24kMShFYSxUYSksQWE9a2EhPW51bGw7bGV0IEZhPWhhO0FhJiYoRmE9dHJhbnNwb3NlSW1wbCQyKGhhLGthLGJhKSxFYT1nZXRJbm5lck1vc3RBeGVzJDEoRWEubGVuZ3RoLFRhKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgic3VtIixFYSxUYSk7Y29uc3RbTGEsZWxdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMShGYS5zaGFwZSxFYSk7bGV0IHRsPUxhO3hhJiYodGw9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShMYSx3YSkpO2NvbnN0IG5sPXNpemVGcm9tU2hhcGUkMShlbCkscmw9c2l6ZUZyb21TaGFwZSQxKGhhLnNoYXBlKS9ubCxvbD1yZXNoYXBlJDIoe2lucHV0czp7eDpGYX0sYXR0cnM6e3NoYXBlOltybCxubF19LGJhY2tlbmQ6YmF9KSxhbD1zdW1PdXRUeXBlJDEoaGEuZHR5cGUpLGxsPXJlZHVjZSQxKG9sLGFsLCJzdW0iLGJhKSxpbD1yZXNoYXBlJDIoe2lucHV0czp7eDpsbH0sYXR0cnM6e3NoYXBlOnRsfSxiYWNrZW5kOmJhfSk7cmV0dXJuIGJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG9sKSxiYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhsbCksQWEmJmJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKSxpbH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdW0kMyhoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmE7cmV0dXJuIHN1bUltcGwkMShTYSxUYSx3YSx4YSl9Y29uc3Qgc3VtQ29uZmlnJDE9e2tlcm5lbE5hbWU6U3VtJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnN1bSQzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0cmFuc3Bvc2UkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7cGVybTpUYX09YmEsd2E9eGEsRWE9U2Euc2hhcGUubGVuZ3RoLGthPW5ldyBBcnJheShFYSk7Zm9yKGxldCBGYT0wO0ZhPGthLmxlbmd0aDtGYSsrKWthW0ZhXT1TYS5zaGFwZVtUYVtGYV1dO2xldCBBYTtpZih3YS5zaG91bGRFeGVjdXRlT25DUFUoW1NhXSkpe2NvbnN0IExhPXdhLnRleERhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLGVsPXRyYW5zcG9zZUltcGxDUFUkMShMYSxTYS5zaGFwZSxTYS5kdHlwZSxUYSxrYSk7QWE9d2EubWFrZVRlbnNvckluZm8oa2EsU2EuZHR5cGUpO2NvbnN0IHRsPXdhLnRleERhdGEuZ2V0KEFhLmRhdGFJZCk7dGwudmFsdWVzPWVsfWVsc2UgQWE9dHJhbnNwb3NlSW1wbCQyKFNhLFRhLHdhKTtyZXR1cm4gQWF9Y29uc3QgdHJhbnNwb3NlQ29uZmlnJDE9e2tlcm5lbE5hbWU6VHJhbnNwb3NlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRyYW5zcG9zZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBNQVRNVUxfU0hBUkVEX0RJTV9USFJFU0hPTEQkMT0xZTM7ZnVuY3Rpb24gYmF0Y2hNYXRNdWxJbXBsJDEoe2E6aGEsYjphYSx0cmFuc3Bvc2VBOnhhLHRyYW5zcG9zZUI6YmEsYmFja2VuZDpTYSxiaWFzOlRhPW51bGwscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czp3YT1udWxsLGxlYWt5cmVsdUFscGhhOkVhPTAsYWN0aXZhdGlvbjprYT1udWxsfSl7Y29uc3QgQWE9aGEuc2hhcGUubGVuZ3RoLEZhPWFhLnNoYXBlLmxlbmd0aCxMYT14YT9oYS5zaGFwZVtBYS0yXTpoYS5zaGFwZVtBYS0xXSxlbD1iYT9hYS5zaGFwZVtGYS0xXTphYS5zaGFwZVtGYS0yXSx0bD14YT9oYS5zaGFwZVtBYS0xXTpoYS5zaGFwZVtBYS0yXSxubD1iYT9hYS5zaGFwZVtGYS0yXTphYS5zaGFwZVtGYS0xXSxzbD1oYS5zaGFwZS5zbGljZSgwLC0yKSxybD1hYS5zaGFwZS5zbGljZSgwLC0yKSxvbD1zaXplRnJvbVNoYXBlJDEoc2wpLGFsPXNpemVGcm9tU2hhcGUkMShybCksaWw9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShoYS5zaGFwZS5zbGljZSgwLC0yKSxhYS5zaGFwZS5zbGljZSgwLC0yKSkuY29uY2F0KFt0bCxubF0pO2Fzc2VydCQyKExhPT09ZWwsKCk9PmBFcnJvciBpbiBtYXRNdWw6IGlubmVyIHNoYXBlcyAoJHtMYX0pIGFuZCAoJHtlbH0pIG9mIFRlbnNvcnMgd2l0aCBzaGFwZXMgJHtoYS5zaGFwZX0gYW5kICR7YWEuc2hhcGV9IGFuZCB0cmFuc3Bvc2VBPSR7eGF9IGFuZCB0cmFuc3Bvc2VCPSR7YmF9IG11c3QgbWF0Y2guYCk7Y29uc3QgY2w9eGE/W29sLExhLHRsXTpbb2wsdGwsTGFdLHVsPWJhP1thbCxubCxlbF06W2FsLGVsLG5sXSxkbD1yZXNoYXBlJDIoe2lucHV0czp7eDpoYX0sYmFja2VuZDpTYSxhdHRyczp7c2hhcGU6Y2x9fSksaGw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6YWF9LGJhY2tlbmQ6U2EsYXR0cnM6e3NoYXBlOnVsfX0pLHBsPVtkbCxobF0sZmw9TWF0aC5tYXgob2wsYWwpLG1sPXhhP2RsLnNoYXBlWzFdOmRsLnNoYXBlWzJdLGdsPVRhIT1udWxsLCRsPXdhIT1udWxsLHhsPWthPT09ImxlYWt5cmVsdSIseWw9a2EhPW51bGw/bWFwQWN0aXZhdGlvblRvU2hhZGVyUHJvZ3JhbSQxKGthLCEwKTpudWxsLGJsPWdsfHwkbHx8eGx8fHlsIT1udWxsO2xldCBTbDtpZigodGw9PT0xfHxubD09PTEpJiZtbD5NQVRNVUxfU0hBUkVEX0RJTV9USFJFU0hPTEQkMSYmYmw9PT0hMSl7bGV0IFRsPWRsLHdsPWhsO3hhJiYoVGw9dHJhbnNwb3NlJDEoe2lucHV0czp7eDpkbH0sYmFja2VuZDpTYSxhdHRyczp7cGVybTpbMCwyLDFdfX0pLHBsLnB1c2goVGwpKSxiYSYmKHdsPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6aGx9LGJhY2tlbmQ6U2EsYXR0cnM6e3Blcm06WzAsMiwxXX19KSxwbC5wdXNoKHdsKSk7Y29uc3QgSWw9bmwhPT0xLE5sPW5sPT09MTtsZXQgdmw9VGw7SWwmJih2bD1yZXNoYXBlJDIoe2lucHV0czp7eDpUbH0sYmFja2VuZDpTYSxhdHRyczp7c2hhcGU6W2ZsLG1sLDFdfX0pLHBsLnB1c2godmwpKTtjb25zdCBrbD1ubD09PTE/MjoxO2xldCBFbD13bDtObCYmKEVsPXJlc2hhcGUkMih7aW5wdXRzOnt4OndsfSxiYWNrZW5kOlNhLGF0dHJzOntzaGFwZTpbZmwsMSxtbF19fSkscGwucHVzaChFbCkpO2NvbnN0IEFsPW11bHRpcGx5JDEoe2lucHV0czp7YTp2bCxiOkVsfSxiYWNrZW5kOlNhfSk7U2w9c3VtJDMoe2lucHV0czp7eDpBbH0sYmFja2VuZDpTYSxhdHRyczp7YXhpczprbCxrZWVwRGltczohMH19KSxwbC5wdXNoKEFsKX1lbHNle2NvbnN0IFRsPXVwY2FzdFR5cGUkMShoYS5kdHlwZSxhYS5kdHlwZSksd2w9bmV3IE1hdE11bFBhY2tlZFByb2dyYW0kMShjbCx1bCxbZmwsdGwsbmxdLHhhLGJhLGdsLHlsLCRsLHhsKSxJbD1bZGwsaGxdO2lmKFRhIT1udWxsJiZJbC5wdXNoKFRhKSwkbCYmSWwucHVzaCh3YSkseGwpe2NvbnN0IE5sPVNhLm1ha2VUZW5zb3JJbmZvKFtdLCJmbG9hdDMyIixjcmVhdGVTY2FsYXJWYWx1ZSQxKEVhLCJmbG9hdDMyIikpO0lsLnB1c2goTmwpLHBsLnB1c2goTmwpfVNsPVNhLnJ1bldlYkdMUHJvZ3JhbSh3bCxJbCxUbCl9Y29uc3QgQ2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6U2x9LGJhY2tlbmQ6U2EsYXR0cnM6e3NoYXBlOmlsfX0pO3BsLnB1c2goU2wpO2Zvcihjb25zdCBUbCBvZiBwbClTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhUbCk7cmV0dXJuIENsfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gX2Z1c2VkTWF0TXVsJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7YTpTYSxiOlRhLGJpYXM6d2EscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpFYX09YWEse3RyYW5zcG9zZUE6a2EsdHJhbnNwb3NlQjpBYSxhY3RpdmF0aW9uOkZhLGxlYWt5cmVsdUFscGhhOkxhfT1iYTtyZXR1cm4gYmF0Y2hNYXRNdWxJbXBsJDEoe2E6U2EsYjpUYSx0cmFuc3Bvc2VBOmthLHRyYW5zcG9zZUI6QWEsYmFja2VuZDp4YSxiaWFzOndhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWEsbGVha3lyZWx1QWxwaGE6TGEsYWN0aXZhdGlvbjpGYX0pfWNvbnN0IF9mdXNlZE1hdE11bENvbmZpZyQxPXtrZXJuZWxOYW1lOl9GdXNlZE1hdE11bCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpfZnVzZWRNYXRNdWwkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQUJTJDI9InJldHVybiBhYnMoeCk7IjtmdW5jdGlvbiBhYnMkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYTtpZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW2JhXSkmJmJhLmR0eXBlIT09ImNvbXBsZXg2NCIpe2NvbnN0IFRhPXhhLnRleERhdGEuZ2V0KGJhLmRhdGFJZCksd2E9c2ltcGxlQWJzSW1wbENQVSQxKFRhLnZhbHVlcyk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKGJhLnNoYXBlLGJhLmR0eXBlLHdhKX1sZXQgU2E7cmV0dXJuIGVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19VTkFSWV9PUEVSQVRJT05TIik/U2E9bmV3IFVuYXJ5T3BQYWNrZWRQcm9ncmFtJDEoYmEuc2hhcGUsQUJTJDIpOlNhPW5ldyBVbmFyeU9wUHJvZ3JhbSQxKGJhLnNoYXBlLEFCUyQyKSx4YS5ydW5XZWJHTFByb2dyYW0oU2EsW2JhXSxiYS5kdHlwZSl9Y29uc3QgYWJzQ29uZmlnJDE9e2tlcm5lbE5hbWU6QWJzJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFicyQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBQ09TJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMytgCiAgaWYgKGFicyh4KSA+IDEuKSB7CiAgICByZXR1cm4gTkFOOwogIH0KICByZXR1cm4gYWNvcyh4KTsKYCxhY29zJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpBQ09TJDF9KSxhY29zQ29uZmlnJDE9e2tlcm5lbE5hbWU6QWNvcyQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphY29zJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFDT1NIJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMytgCiAgaWYgKHggPCAxLjApIHJldHVybiBOQU47CnJldHVybiBsb2coeCArIHNxcnQoeCAqIHggLSAxLjApKTtgLGFjb3NoJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpBQ09TSCQxfSksYWNvc2hDb25maWckMT17a2VybmVsTmFtZTpBY29zaCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphY29zaCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBREQkMT0icmV0dXJuIGEgKyBiOyIsYWRkS2VybmVsRnVuYyQxPWJpbmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkFERCQxLHBhY2tlZE9wU25pcHBldDpBREQkMSxzdXBwb3J0c0NvbXBsZXg6ITAsY3B1S2VybmVsSW1wbDphZGRJbXBsQ1BVJDF9KSxhZGRDb25maWckMT17a2VybmVsTmFtZTpBZGQkMixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YWRkS2VybmVsRnVuYyQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWRkTlByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudmFyaWFibGVOYW1lcz14YS5tYXAoKFRhLHdhKT0+YFQke3dhfWApO2NvbnN0IGJhPVtdO3RoaXMudmFyaWFibGVOYW1lcy5mb3JFYWNoKFRhPT57YmEucHVzaChgZmxvYXQgdiR7VGF9ID0gZ2V0JHtUYX1BdE91dENvb3JkcygpO2ApfSk7Y29uc3QgU2E9dGhpcy52YXJpYWJsZU5hbWVzLm1hcChUYT0+YHYke1RhfWApLmpvaW4oIiArICIpO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtiYS5qb2luKGAKICAgICAgICBgKX0KCiAgICAgICAgZmxvYXQgcmVzdWx0ID0gJHtTYX07CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQWRkTlBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudmFyaWFibGVOYW1lcz14YS5tYXAoKFRhLHdhKT0+YFQke3dhfWApO2NvbnN0IGJhPVtdO3RoaXMudmFyaWFibGVOYW1lcy5mb3JFYWNoKFRhPT57YmEucHVzaChgdmVjNCB2JHtUYX0gPSBnZXQke1RhfUF0T3V0Q29vcmRzKCk7YCl9KTtjb25zdCBTYT10aGlzLnZhcmlhYmxlTmFtZXMubWFwKFRhPT5gdiR7VGF9YCkuam9pbigiICsgIik7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke2JhLmpvaW4oYAogICAgICAgIGApfQoKICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7U2F9OwogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYWRkTiQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEsYmE9YWE7aWYoYmEubGVuZ3RoPT09MSlyZXR1cm4gaWRlbnRpdHkkMSh7aW5wdXRzOnt4OmJhWzBdfSxiYWNrZW5kOnhhfSk7aWYoYmEubGVuZ3RoPmVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9NQVhfVEVYVFVSRVNfSU5fU0hBREVSIikpe2NvbnN0IGthPU1hdGguZmxvb3IoYmEubGVuZ3RoLzIpLEFhPWFkZE4kMSh7aW5wdXRzOmJhLnNsaWNlKDAsa2EpLGJhY2tlbmQ6eGF9KSxGYT1hZGROJDEoe2lucHV0czpiYS5zbGljZShrYSksYmFja2VuZDp4YX0pO3JldHVybiBhZGROJDEoe2lucHV0czpbQWEsRmFdLGJhY2tlbmQ6eGF9KX1jb25zdCBTYT1iYS5tYXAoa2E9PmthLmR0eXBlKS5yZWR1Y2UoKGthLEFhKT0+dXBjYXN0VHlwZSQxKGthLEFhKSksVGE9YmEubWFwKGthPT5rYS5zaGFwZSksRWE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLIik/bmV3IEFkZE5QYWNrZWRQcm9ncmFtJDEoYmFbMF0uc2hhcGUsVGEpOm5ldyBBZGROUHJvZ3JhbSQxKGJhWzBdLnNoYXBlLFRhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEVhLGJhLFNhKX1jb25zdCBhZGROQ29uZmlnJDE9e2tlcm5lbE5hbWU6QWRkTiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphZGROJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFsbCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGtlZXBEaW1zOndhfT1iYSxFYT1TYS5zaGFwZS5sZW5ndGgsa2E9cGFyc2VBeGlzUGFyYW0kMShUYSxTYS5zaGFwZSk7bGV0IEFhPWthO2NvbnN0IEZhPWdldEF4ZXNQZXJtdXRhdGlvbiQxKEFhLEVhKTtsZXQgTGE9U2E7RmEhPW51bGwmJihMYT10cmFuc3Bvc2UkMSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkZhfX0pLEFhPWdldElubmVyTW9zdEF4ZXMkMShBYS5sZW5ndGgsRWEpKSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcyQxKCJhbGwiLEFhLEVhKTtjb25zdFtlbCx0bF09Y29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyQxKExhLnNoYXBlLEFhKSxubD1zaXplRnJvbVNoYXBlJDEodGwpLHNsPXJlc2hhcGUkMih7aW5wdXRzOnt4OkxhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbLTEsbmxdfX0pLHJsPXJlZHVjZSQxKHNsLHNsLmR0eXBlLCJhbGwiLHhhKTtsZXQgb2w7aWYod2Epe2NvbnN0IGFsPWV4cGFuZFNoYXBlVG9LZWVwRGltJDEoZWwsa2EpO29sPXJlc2hhcGUkMih7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTphbH19KX1lbHNlIG9sPXJlc2hhcGUkMih7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTplbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKSxGYSE9bnVsbCYmeGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpLG9sfWNvbnN0IGFsbENvbmZpZyQxPXtrZXJuZWxOYW1lOkFsbCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphbGwkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYW55JDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGEsa2VlcERpbXM6d2F9PWJhLEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtsZXQgQWE9a2E7Y29uc3QgRmE9Z2V0QXhlc1Blcm11dGF0aW9uJDEoQWEsRWEpO2xldCBMYT1TYTtGYSE9bnVsbCYmKExhPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06RmF9fSksQWE9Z2V0SW5uZXJNb3N0QXhlcyQxKEFhLmxlbmd0aCxFYSkpLGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zJDEoImFueSIsQWEsRWEpO2NvbnN0W2VsLHRsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoTGEuc2hhcGUsQWEpLG5sPXNpemVGcm9tU2hhcGUkMSh0bCksc2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSxubF19fSkscmw9cmVkdWNlJDEoc2wsc2wuZHR5cGUsImFueSIseGEpO2xldCBvbDtpZih3YSl7Y29uc3QgYWw9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShlbCxrYSk7b2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmFsfX0pfWVsc2Ugb2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmVsfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpLEZhIT1udWxsJiZ4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSksb2x9Y29uc3QgYW55Q29uZmlnJDE9e2tlcm5lbE5hbWU6QW55JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFueSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQXJnTWluTWF4UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl07Y29uc3R7d2luZG93U2l6ZTpTYSxiYXRjaFNpemU6VGEsb3V0U2l6ZTp3YX09YWE7YmF8fHRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJiZXN0SW5kaWNlc0EiKSx0aGlzLm91dHB1dFNoYXBlPVtUYSx3YV07Y29uc3QgRWE9eGE9PT0ibWF4Ij8iPiI6IjwiLGthPWJhPyJpbk9mZnNldCArIGk7Ijoicm91bmQoZ2V0QmVzdEluZGljZXNBKGJhdGNoLCBpbk9mZnNldCArIGkpKTsiO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgIGludCBvdXRJZHggPSBjb29yZHNbMV07CiAgICAgICAgaW50IGluT2Zmc2V0ID0gb3V0SWR4ICogJHtTYX07CgogICAgICAgIGludCBiZXN0SW5kZXggPSBpbk9mZnNldDsKICAgICAgICBmbG9hdCBiZXN0VmFsdWUgPSBnZXRBKGJhdGNoLCBiZXN0SW5kZXgpOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7U2F9OyBpKyspIHsKICAgICAgICAgIGludCBpbklkeCA9ICR7a2F9OwogICAgICAgICAgZmxvYXQgY2FuZGlkYXRlID0gZ2V0QShiYXRjaCwgaW5JZHgpOwogICAgICAgICAgaWYgKGNhbmRpZGF0ZSAke0VhfSBiZXN0VmFsdWUpIHsKICAgICAgICAgICAgYmVzdFZhbHVlID0gY2FuZGlkYXRlOwogICAgICAgICAgICBiZXN0SW5kZXggPSBpbklkeDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGZsb2F0KGJlc3RJbmRleCkpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IEFyZ01pbk1heFBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLGFzc2VydCQyKGFhLmxlbmd0aD4yLCgpPT5gUGFja2VkIGFyZyR7YmEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYmEuc2xpY2UoMSl9IHN1cHBvcnRzIG9ubHkgaW5wdXRzIHdpdGggcmFuayBhYm92ZSAyLmApO2NvbnN0IFRhPWFhW2FhLmxlbmd0aC0xXSx3YT1NYXRoLmNlaWwoVGEveGEpO3RoaXMub3V0cHV0U2hhcGU9YWEuc2xpY2UoMCwtMSksd2E+MSYmdGhpcy5vdXRwdXRTaGFwZS5wdXNoKHdhKSxTYXx8dGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJlc3RJbmRpY2VzQSIpO2NvbnN0IEVhPXRoaXMub3V0cHV0U2hhcGUsa2E9RWEubGVuZ3RoLEFhPWdldENvb3Jkc0RhdGFUeXBlJDEoa2EpLEZhPWdldENoYW5uZWxzJDEoImNvb3JkcyIsa2EpO2xldCBMYSxlbDtpZih3YT09PTEpe2VsPWthKzE7Y29uc3QgaGw9Z2V0Q29vcmRzRGF0YVR5cGUkMShlbCk7TGE9YAogICAgICAgICR7aGx9IHNvdXJjZUxvY1IgPSAke2hsfSgke0ZhLmpvaW4oKX0sIDApOwogICAgICAgICsrJHtGYVtrYS0xXX07CiAgICAgICAgJHtobH0gc291cmNlTG9jRyA9ICR7aGx9KCR7RmEuam9pbigpfSwgMCk7CiAgICAgICAgKyske0ZhW2thLTJdfTsKICAgICAgICAke2hsfSBzb3VyY2VMb2NBID0gJHtobH0oJHtGYS5qb2luKCl9LCAwKTsKICAgICAgICAtLSR7RmFba2EtMV19OwogICAgICAgICR7aGx9IHNvdXJjZUxvY0IgPSAke2hsfSgke0ZhLmpvaW4oKX0sIDApOwogICAgICAgIC0tJHtGYVtrYS0yXX07YH1lbHNlIGVsPWthLExhPWAKICAgICAgICAke0FhfSBzb3VyY2VMb2NSID0gY29vcmRzOwogICAgICAgICsrJHtGYVtrYS0xXX07CiAgICAgICAgJHtBYX0gc291cmNlTG9jRyA9IGNvb3JkczsKICAgICAgICArKyR7RmFba2EtMl19OwogICAgICAgICR7QWF9IHNvdXJjZUxvY0EgPSBjb29yZHM7CiAgICAgICAgLS0ke0ZhW2thLTFdfTsKICAgICAgICAke0FhfSBzb3VyY2VMb2NCID0gY29vcmRzOwogICAgICAgIC0tJHtGYVtrYS0yXX07YDtjb25zdCB0bD1bIngiLCJ5IiwieiIsInciLCJ1IiwidiJdLnNsaWNlKDAsZWwpLG5sPSIuIit0bFtlbC0xXSxzbD10bC5tYXAoaGw9PiJpbnQgIitobCkscmw9Z2V0Q2hhbm5lbHMkMSgic291cmNlTG9jUiIsZWwtMSkuY29uY2F0KCJpbklkeC5yIiksb2w9Z2V0Q2hhbm5lbHMkMSgic291cmNlTG9jRyIsZWwtMSkuY29uY2F0KCJpbklkeC5nIiksYWw9Z2V0Q2hhbm5lbHMkMSgic291cmNlTG9jQiIsZWwtMSkuY29uY2F0KCJpbklkeC5iIiksbGw9Z2V0Q2hhbm5lbHMkMSgic291cmNlTG9jQSIsZWwtMSkuY29uY2F0KCJpbklkeC5hIiksaWw9YmE9PT0ibWF4Ij8iZ3JlYXRlclRoYW4iOiJsZXNzVGhhbiIsY2w9U2E/IiI6YAogICAgICAgICAgaW5JZHggPSByb3VuZCh2ZWM0KGdldEJlc3RJbmRpY2VzQUNoYW5uZWwoJHtybC5qb2luKCl9KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRCZXN0SW5kaWNlc0FDaGFubmVsKCR7b2wuam9pbigpfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QmVzdEluZGljZXNBQ2hhbm5lbCgke2FsLmpvaW4oKX0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEJlc3RJbmRpY2VzQUNoYW5uZWwoJHtsbC5qb2luKCl9KSkpO2AsdWw9YHZlYzQoCiAgICAgICAgICAgIGdldEFDaGFubmVsKCR7cmwuam9pbigpfSksCiAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBQ2hhbm5lbCgke29sLmpvaW4oKX0pIDogMC4sCiAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBQ2hhbm5lbCgke2FsLmpvaW4oKX0pIDogMC4sCiAgICAgICAgICAgIGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCA/IGdldEFDaGFubmVsKCR7bGwuam9pbigpfSkgOiAwLilgLGRsPVNhPyIiOmAKICAgICAgZmxvYXQgZ2V0QmVzdEluZGljZXNBQ2hhbm5lbCgke3NsLmpvaW4oKX0pIHsKICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChnZXRCZXN0SW5kaWNlc0EoJHt0bC5qb2luKCl9KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RsLnNsaWNlKC0yKS5qb2luKCl9KSk7CiAgICAgIH1gO3RoaXMudXNlckNvZGU9YAogICAgICBmbG9hdCBnZXRBQ2hhbm5lbCgke3NsLmpvaW4oKX0pIHsKICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChnZXRBKCR7dGwuam9pbigpfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGwuc2xpY2UoLTIpLmpvaW4oKX0pKTsKICAgICAgfQogICAgICAke2RsfQogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtBYX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gJHtGYVtrYS0xXX0gPCAke0VhW2thLTFdLTF9OwogICAgICAgIGJvb2wgaGFzTmV4dFJvdyA9ICR7RmFba2EtMl19IDwgJHtFYVtrYS0yXS0xfTsKICAgICAgICAke0xhfQogICAgICAgIGl2ZWM0IHNyY0lkeCA9IGl2ZWM0KHNvdXJjZUxvY1Ike25sfSwgc291cmNlTG9jRyR7bmx9LAogICAgICAgICAgc291cmNlTG9jQiR7bmx9LCBzb3VyY2VMb2NBJHtubH0pICogJHt4YX07CiAgICAgICAgaXZlYzQgaW5JZHggPSBzcmNJZHg7CiAgICAgICAgdmVjNCBiZXN0SW5kZXggPSB2ZWM0KGluSWR4KTsKICAgICAgICB2ZWM0IGJlc3RWYWx1ZSA9ICR7dWx9OwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7eGF9OyBpKyspIHsKICAgICAgICAgIGluSWR4ID0gc3JjSWR4OwogICAgICAgICAgJHtjbH0KICAgICAgICAgIHZlYzQgY2FuZGlkYXRlID0gJHt1bH07CiAgICAgICAgICBidmVjNCBuYW4gPSBpc25hbihjYW5kaWRhdGUpOwogICAgICAgICAgYnZlYzQgcmVwbGFjZSA9IGJ2ZWM0KAogICAgICAgICAgICB2ZWM0KCR7aWx9KGNhbmRpZGF0ZSwgYmVzdFZhbHVlKSkgKiAodmVjNCgxLjApIC0gdmVjNChuYW4pKSk7CgogICAgICAgICAgYmVzdFZhbHVlID0gdmVjNChyZXBsYWNlLnggID8gY2FuZGlkYXRlLnggOiBiZXN0VmFsdWUueCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZS55ICA/IGNhbmRpZGF0ZS55IDogYmVzdFZhbHVlLnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2UueiAgPyBjYW5kaWRhdGUueiA6IGJlc3RWYWx1ZS56LAogICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlLncgID8gY2FuZGlkYXRlLncgOiBiZXN0VmFsdWUudyk7CiAgICAgICAgICBiZXN0SW5kZXggPSBtaXgoYmVzdEluZGV4LCB2ZWM0KGluSWR4KSwgdmVjNChyZXBsYWNlKSk7CiAgICAgICAgICBzcmNJZHgrKzsKICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGJlc3RJbmRleCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhcmdSZWR1Y2UkMShoYSxhYSx4YSxiYT1udWxsKXtsZXQgU2E9YWEuc2hhcGVbMF0sVGE9YWEuc2hhcGVbMV07YmEhPW51bGwmJihTYT1iYS5zaGFwZVswXSxUYT1iYS5zaGFwZVsxXSk7Y29uc3Qgd2E9Y29tcHV0ZU9wdGltYWxXaW5kb3dTaXplJDEoVGEpLEVhPXt3aW5kb3dTaXplOndhLGluU2l6ZTpUYSxiYXRjaFNpemU6U2Esb3V0U2l6ZTpNYXRoLmNlaWwoVGEvd2EpfSxrYT1uZXcgQXJnTWluTWF4UHJvZ3JhbSQxKEVhLHhhLGJhPT1udWxsKSxBYT1bYWFdO2JhIT1udWxsJiZBYS5wdXNoKGJhKTtjb25zdCBGYT1oYS5ydW5XZWJHTFByb2dyYW0oa2EsQWEsImludDMyIik7aWYoRmEuc2hhcGVbMV09PT0xKXJldHVybiBGYTtjb25zdCBMYT1hcmdSZWR1Y2UkMShoYSxhYSx4YSxGYSk7cmV0dXJuIGhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKSxMYX1mdW5jdGlvbiBhcmdSZWR1Y2VQYWNrZWQkMShoYSxhYSx4YSxiYT1udWxsKXtjb25zdCBTYT1iYSE9bnVsbD9iYS5zaGFwZTphYS5zaGFwZSxUYT1TYVtTYS5sZW5ndGgtMV0sd2E9Y29tcHV0ZU9wdGltYWxXaW5kb3dTaXplJDEoVGEpLEVhPW5ldyBBcmdNaW5NYXhQYWNrZWRQcm9ncmFtJDEoU2Esd2EseGEsYmE9PW51bGwpLGthPWJhPT1udWxsP1thYV06W2FhLGJhXSxBYT1oYS5ydW5XZWJHTFByb2dyYW0oRWEsa2EsImludDMyIik7aWYoQWEuc2hhcGUubGVuZ3RoPT09YWEuc2hhcGUubGVuZ3RoKXtjb25zdCBGYT1hcmdSZWR1Y2VQYWNrZWQkMShoYSxhYSx4YSxBYSk7cmV0dXJuIGhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEFhKSxGYX1yZXR1cm4gQWF9ZnVuY3Rpb24gYXJnTWluTWF4UmVkdWNlJDEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPVt4YV07aWYoYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgiYXJnIitiYS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKStiYS5zbGljZSgxKSxTYSxhYS5zaGFwZS5sZW5ndGgpLCFlbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfUkVEVUNFIil8fGFhLnNoYXBlLmxlbmd0aDw9Mil7Y29uc3QgVGE9W10sd2E9aGEudGV4RGF0YS5nZXQoYWEuZGF0YUlkKSxFYT13YSE9PW51bGwmJndhLmlzUGFja2VkO2xldCBrYT1hYTtFYSYmKGthPWhhLnVucGFja1RlbnNvcihhYSksVGEucHVzaChrYSkpO2NvbnN0W0FhLEZhXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoa2Euc2hhcGUsU2EpLExhPXNpemVGcm9tU2hhcGUkMShGYSksZWw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6aGEsYXR0cnM6e3NoYXBlOlstMSxMYV19fSk7VGEucHVzaChlbCk7Y29uc3QgdGw9YXJnUmVkdWNlJDEoaGEsZWwsYmEpO1RhLnB1c2godGwpO2NvbnN0IG5sPXJlc2hhcGUkMih7aW5wdXRzOnt4OnRsfSxiYWNrZW5kOmhhLGF0dHJzOntzaGFwZTpBYX19KTtyZXR1cm4gVGEuZm9yRWFjaChzbD0+aGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpKSxubH1yZXR1cm4gYXJnUmVkdWNlUGFja2VkJDEoaGEsYWEsYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFyZ01heCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhfT1iYTtsZXQgd2E9cGFyc2VBeGlzUGFyYW0kMShUYSxTYS5zaGFwZSk7Y29uc3QgRWE9Z2V0QXhlc1Blcm11dGF0aW9uJDEod2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQga2E9U2E7Y29uc3QgQWE9W107RWEhPW51bGwmJihrYT10cmFuc3Bvc2UkMSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkVhfX0pLEFhLnB1c2goa2EpLHdhPWdldElubmVyTW9zdEF4ZXMkMSh3YS5sZW5ndGgsa2Euc2hhcGUubGVuZ3RoKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgiYXJnTWF4Iixbd2FbMF1dLGthLnNoYXBlLmxlbmd0aCk7Y29uc3QgRmE9YXJnTWluTWF4UmVkdWNlJDEoeGEsa2Esd2FbMF0sIm1heCIpO3JldHVybiBBYS5mb3JFYWNoKExhPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSkpLEZhfWNvbnN0IGFyZ01heENvbmZpZyQxPXtrZXJuZWxOYW1lOkFyZ01heCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphcmdNYXgkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXJnTWluJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGF9PWJhO2xldCB3YT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtjb25zdCBFYT1nZXRBeGVzUGVybXV0YXRpb24kMSh3YSxTYS5zaGFwZS5sZW5ndGgpO2xldCBrYT1TYTtjb25zdCBBYT1bXTtFYSE9bnVsbCYmKGthPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06RWF9fSksQWEucHVzaChrYSksd2E9Z2V0SW5uZXJNb3N0QXhlcyQxKHdhLmxlbmd0aCxrYS5zaGFwZS5sZW5ndGgpKSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcyQxKCJhcmdNaW4iLFt3YVswXV0sa2Euc2hhcGUubGVuZ3RoKTtjb25zdCBGYT1hcmdNaW5NYXhSZWR1Y2UkMSh4YSxrYSx3YVswXSwibWluIik7cmV0dXJuIEFhLmZvckVhY2goTGE9PnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKExhKSksRmF9Y29uc3QgYXJnTWluQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXJnTWluJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFyZ01pbiQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBU0lOJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMytgCiAgaWYgKGFicyh4KSA+IDEuKSB7CiAgICByZXR1cm4gTkFOOwogIH0KICByZXR1cm4gYXNpbih4KTsKYCxhc2luJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpBU0lOJDF9KSxhc2luQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXNpbiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphc2luJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFTSU5IJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMysicmV0dXJuIGxvZyh4ICsgc3FydCh4ICogeCArIDEuMCkpOyIsYXNpbmgkMT11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkFTSU5IJDF9KSxhc2luaENvbmZpZyQxPXtrZXJuZWxOYW1lOkFzaW5oJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFzaW5oJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFUQU4kMT1DSEVDS19OQU5fU05JUFBFVCQzK2AKICByZXR1cm4gYXRhbih4KTsKYCxhdGFuJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpBVEFOJDF9KSxhdGFuQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXRhbiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphdGFuJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFUQU4yJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMitgCiAgcmV0dXJuIGF0YW4oYSwgYik7CmAsQVRBTjJfUEFDS0VEJDE9YAogIHZlYzQgcmVzdWx0ID0gYXRhbihhLCBiKTsKICBidmVjNCBpc05hTkEgPSBpc25hbihhKTsKICBidmVjNCBpc05hTkIgPSBpc25hbihiKTsKICBidmVjNCBpc05hTiA9IGJ2ZWM0KGlzTmFOQS54IHx8IGlzTmFOQi54LCBpc05hTkEueSB8fCBpc05hTkIueSwgaXNOYU5BLnogfHwgaXNOYU5CLnosIGlzTmFOQS53IHx8IGlzTmFOQi53KTsKICBgK0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCQxK2AKICByZXR1cm4gcmVzdWx0OwpgLGF0YW4yJDE9YmluYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6QVRBTjIkMSxwYWNrZWRPcFNuaXBwZXQ6QVRBTjJfUEFDS0VEJDF9KSxhdGFuMkNvbmZpZyQxPXtrZXJuZWxOYW1lOkF0YW4yJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmF0YW4yJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFUQU5IJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMytgCiAgaWYgKCh4IDwgLTEuMCkgfHwgKHggPiAxLjApKSByZXR1cm4gTkFOOwpyZXR1cm4gKGxvZygxLjAgKyB4KSAtIGxvZygxLjAgLSB4KSkgLyAyLjA7YCxhdGFuaCQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6QVRBTkgkMX0pLGF0YW5oQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXRhbmgkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YXRhbmgkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFBvb2wyRFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYT0hMSxUYT0hMSl7aWYodGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHhhPT09ImF2ZyImJmJhKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IGNvbXB1dGUgcG9zaXRpb25zIGZvciBhdmVyYWdlIHBvb2wuIik7Y29uc3Qgd2E9YWEuZmlsdGVyV2lkdGgsRWE9YWEuc3RyaWRlSGVpZ2h0LGthPWFhLnN0cmlkZVdpZHRoLEFhPWFhLmRpbGF0aW9uSGVpZ2h0LEZhPWFhLmRpbGF0aW9uV2lkdGgsTGE9YWEuZWZmZWN0aXZlRmlsdGVySGVpZ2h0LGVsPWFhLmVmZmVjdGl2ZUZpbHRlcldpZHRoLHRsPWFhLnBhZEluZm8udG9wLG5sPWFhLnBhZEluZm8ubGVmdDt0aGlzLm91dHB1dFNoYXBlPWFhLm91dFNoYXBlO2NvbnN0IHNsPXhhPT09ImF2ZyIscmw9YCgoYmF0Y2ggICogJHthYS5pbkhlaWdodH0gKyB4UikgKiAke2FhLmluV2lkdGh9ICsgeEMpICogJHthYS5pbkNoYW5uZWxzfSArIGRgLG9sPWAoeFIgKiAke2FhLmluV2lkdGh9ICsgeEMpICogJHthYS5pbkNoYW5uZWxzfSArIGRgO2xldCBhbD0iMC4wIjtpZihzbHx8KGFsPSItMS4wIC8gMWUtMjAiKSxiYSl7Y29uc3QgaGw9Ij49Ijt0aGlzLnVzZXJDb2RlPWAKICAgICAgICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHtFYX0sICR7a2F9KTsKICAgICAgICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHt0bH0sICR7bmx9KTsKCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKCiAgICAgICAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMueXogKiBzdHJpZGVzIC0gcGFkczsKICAgICAgICAgIGludCB4UkNvcm5lciA9IHhSQ0Nvcm5lci54OwogICAgICAgICAgaW50IHhDQ29ybmVyID0geFJDQ29ybmVyLnk7CgogICAgICAgICAgLy8gbWF4L21pbiB4KD8sID8sIGQpIHRvIGdldCB5KHlSLCB5QywgZCkuCiAgICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZAogICAgICAgICAgZmxvYXQgbWluTWF4VmFsdWUgPSAwLjA7CiAgICAgICAgICBmbG9hdCBtaW5NYXhWYWx1ZUZvdW5kID0gMC4wOwogICAgICAgICAgaW50IG1pbk1heFBvc2l0aW9uID0gMDsKICAgICAgICAgIGZsb2F0IGF2Z1ZhbHVlID0gMC4wOwoKICAgICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke0xhfTsKICAgICAgICAgICAgICB3UiArPSAke0FhfSkgewogICAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSOwoKICAgICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtlbH07CiAgICAgICAgICAgICAgICB3QyArPSAke0ZhfSkgewogICAgICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgd0M7CgogICAgICAgICAgICAgIGlmICh4QyA8IDAgfHwgeEMgPj0gJHthYS5pbldpZHRofSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldFgoYmF0Y2gsIHhSLCB4QywgZCk7CgogICAgICAgICAgICAgIC8vIElmIGEgbWluIC8gbWF4IHZhbHVlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHVzZSBpdC4gSWYgbm90LAogICAgICAgICAgICAgIC8vIHVzZSB0aGUgY3VycmVudCB2YWx1ZS4KICAgICAgICAgICAgICBmbG9hdCBjdXJyTWluTWF4VmFsdWUgPSBtaXgoCiAgICAgICAgICAgICAgICAgIHZhbHVlLCBtaW5NYXhWYWx1ZSwgbWluTWF4VmFsdWVGb3VuZCk7CiAgICAgICAgICAgICAgaWYgKHZhbHVlICR7aGx9IGN1cnJNaW5NYXhWYWx1ZSkgewogICAgICAgICAgICAgICAgbWluTWF4VmFsdWUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIG1pbk1heFZhbHVlRm91bmQgPSAxLjA7CiAgICAgICAgICAgICAgICBtaW5NYXhQb3NpdGlvbiA9ICR7U2E/VGE/cmw6b2w6YHdSICogJHtlbH0gKyB3Q2B9OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KGZsb2F0KG1pbk1heFBvc2l0aW9uKSk7CiAgICAgICAgfQogICAgICBgO3JldHVybn1jb25zdCBsbD0ibWF4IjtsZXQgaWw9YCR7eGF9KCR7eGF9KCR7eGF9KG1pbk1heFZhbHVlWzBdLCBtaW5NYXhWYWx1ZVsxXSksIG1pbk1heFZhbHVlWzJdKSwgbWluTWF4VmFsdWVbM10pYDt4YT09PSJhdmciJiYoaWw9ImF2Z1ZhbHVlIC8gbWF4KGNvdW50LCAxLjApIik7Y29uc3QgY2w9TWF0aC5mbG9vcih3YS80KSo0LHVsPXdhJTQsZGw9YAogICAgICBpZiAoJHtzbH0pIHsKICAgICAgICBhdmdWYWx1ZSArPSBkb3QodmFsdWVzLCBvbmVzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBtaW5NYXhWYWx1ZSA9ICR7bGx9KHZhbHVlcywgbWluTWF4VmFsdWUpOwogICAgICB9CiAgICBgO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHtFYX0sICR7a2F9KTsKICAgICAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7dGx9LCAke25sfSk7CiAgICAgIGNvbnN0IGZsb2F0IGluaXRpYWxpemF0aW9uVmFsdWUgPSAke2FsfTsKICAgICAgY29uc3QgdmVjNCBvbmVzID0gdmVjNCgxLjAsIDEuMCwgMS4wLCAxLjApOwoKICAgICAgZmxvYXQgY291bnQgPSAwLjA7CgogICAgICBmbG9hdCBnZXRWYWx1ZShpbnQgYmF0Y2gsIGludCB4UiwgaW50IHhDLCBpbnQgZCkgewogICAgICAgIGlmICh4QyA8IDAgfHwgeEMgPj0gJHthYS5pbldpZHRofSkgewogICAgICAgICAgcmV0dXJuIGluaXRpYWxpemF0aW9uVmFsdWU7CiAgICAgICAgfQogICAgICAgIGNvdW50ICs9IDEuMDsKICAgICAgICByZXR1cm4gZ2V0WChiYXRjaCwgeFIsIHhDLCBkKTsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKCiAgICAgICAgaXZlYzIgeFJDQ29ybmVyID0gY29vcmRzLnl6ICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IHhSQ29ybmVyID0geFJDQ29ybmVyLng7CiAgICAgICAgaW50IHhDQ29ybmVyID0geFJDQ29ybmVyLnk7CgogICAgICAgIC8vIG1heC9taW4geCg/LCA/LCBkKSB0byBnZXQgeSh5UiwgeUMsIGQpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkCiAgICAgICAgdmVjNCBtaW5NYXhWYWx1ZSA9IHZlYzQoJHthbH0pOwogICAgICAgIGZsb2F0IGF2Z1ZhbHVlID0gMC4wOwogICAgICAgIGNvdW50ID0gMC4wOwoKICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHtMYX07CiAgICAgICAgICAgIHdSICs9ICR7QWF9KSB7CiAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSOwoKICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gJHthYS5pbkhlaWdodH0pIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CgogICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7Y2x9OyB3QyArPSA0KSB7CiAgICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgd0MgKiAke0ZhfTsKCiAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDLCBkKSwKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDICsgJHtGYX0sIGQpLAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMgKyAyICogJHtGYX0sIGQpLAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMgKyAzICogJHtGYX0sIGQpCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAke2RsfQogICAgICAgICAgfQoKICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgJHtjbH07CiAgICAgICAgICBpZiAoJHt1bD09PTF9KSB7CiAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDLCBkKSwKICAgICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlLAogICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgICApOwoKICAgICAgICAgICAgJHtkbH0KICAgICAgICAgIH0gZWxzZSBpZiAoJHt1bD09PTJ9KSB7CiAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDLCBkKSwKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDICsgJHtGYX0sIGQpLAogICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgICApOwoKICAgICAgICAgICAgJHtkbH0KICAgICAgICAgIH0gZWxzZSBpZiAoJHt1bD09PTN9KSB7CiAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDLCBkKSwKICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeFIsIHhDICsgJHtGYX0sIGQpLAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMgKyAyICogJHtGYX0sIGQpLAogICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICR7ZGx9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dCgke2lsfSk7CiAgICAgIH0KICAgIGB9fSxQb29sM0RQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEsU2E9ITEsVGE9ITEpe2lmKHRoaXMudmFyaWFibGVOYW1lcz1bIngiXSx4YT09PSJhdmciJiZiYSl0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBjb21wdXRlIHBvc2l0aW9ucyBmb3IgYXZlcmFnZSBwb29sLiIpO2NvbnN0IHdhPWFhLmZpbHRlcldpZHRoLEVhPWFhLnN0cmlkZURlcHRoLGthPWFhLnN0cmlkZUhlaWdodCxBYT1hYS5zdHJpZGVXaWR0aCxGYT1hYS5kaWxhdGlvbkRlcHRoLExhPWFhLmRpbGF0aW9uSGVpZ2h0LGVsPWFhLmRpbGF0aW9uV2lkdGgsdGw9YWEuZWZmZWN0aXZlRmlsdGVyRGVwdGgsbmw9YWEuZWZmZWN0aXZlRmlsdGVySGVpZ2h0LHNsPWFhLmVmZmVjdGl2ZUZpbHRlcldpZHRoLHJsPWFhLnBhZEluZm8uZnJvbnQsb2w9YWEucGFkSW5mby50b3AsYWw9YWEucGFkSW5mby5sZWZ0O3RoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGU7Y29uc3QgbGw9eGE9PT0iYXZnIjtsZXQgaWw9IjAuMCI7aWYobGx8fChpbD0iLTEuMCAvIDFlLTIwIiksYmEpe2NvbnN0IGZsPSI+PSI7dGhpcy51c2VyQ29kZT1gCiAgICAgICAgY29uc3QgaXZlYzMgc3RyaWRlcyA9CiAgICAgICAgICAgIGl2ZWMzKCR7RWF9LCAke2thfSwgJHtBYX0pOwogICAgICAgIGNvbnN0IGl2ZWMzIHBhZHMgPSBpdmVjMygke3JsfSwgJHtvbH0sICR7YWx9KTsKCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzUgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDsKICAgICAgICAgIGludCBjaCA9IGNvb3Jkcy51OwoKICAgICAgICAgIGl2ZWMzIHhDb3JuZXIgPSBpdmVjMyhjb29yZHMueSwgY29vcmRzLnosIGNvb3Jkcy53KSAqIHN0cmlkZXMgLSBwYWRzOwogICAgICAgICAgaW50IHhEQ29ybmVyID0geENvcm5lci54OwogICAgICAgICAgaW50IHhSQ29ybmVyID0geENvcm5lci55OwogICAgICAgICAgaW50IHhDQ29ybmVyID0geENvcm5lci56OwoKICAgICAgICAgIC8vIG1heC9taW4geCg/LCA/LCA/LCBjaCkgdG8gZ2V0IHkoeUQsIHlSLCB5QywgY2gpLgogICAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQKICAgICAgICAgIGZsb2F0IG1pbk1heFZhbHVlID0gMC4wOwogICAgICAgICAgZmxvYXQgbWluTWF4VmFsdWVGb3VuZCA9IDAuMDsKICAgICAgICAgIGludCBtaW5NYXhQb3NpdGlvbiA9IDA7CgogICAgICAgICAgZm9yIChpbnQgd0QgPSAwOyB3RCA8ICR7dGx9OwogICAgICAgICAgICAgIHdEICs9ICR7RmF9KSB7CiAgICAgICAgICAgIGludCB4RCA9IHhEQ29ybmVyICsgd0Q7CgogICAgICAgICAgICBpZiAoeEQgPCAwIHx8IHhEID49ICR7YWEuaW5EZXB0aH0pIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7bmx9OwogICAgICAgICAgICAgICAgd1IgKz0gJHtMYX0pIHsKICAgICAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSOwoKICAgICAgICAgICAgICBpZiAoeFIgPCAwIHx8IHhSID49ICR7YWEuaW5IZWlnaHR9KSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke3NsfTsKICAgICAgICAgICAgICAgICAgd0MgKz0gJHtlbH0pIHsKICAgICAgICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgd0M7CgogICAgICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0WChiYXRjaCwgeEQsIHhSLCB4QywgY2gpOwoKICAgICAgICAgICAgICAgIC8vIElmIGEgbWluIC8gbWF4IHZhbHVlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHVzZSBpdC4gSWYgbm90LAogICAgICAgICAgICAgICAgLy8gdXNlIHRoZSBjdXJyZW50IHZhbHVlLgogICAgICAgICAgICAgICAgZmxvYXQgY3Vyck1pbk1heFZhbHVlID0gbWl4KAogICAgICAgICAgICAgICAgICAgIHZhbHVlLCBtaW5NYXhWYWx1ZSwgbWluTWF4VmFsdWVGb3VuZCk7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUgJHtmbH0gY3Vyck1pbk1heFZhbHVlKSB7CiAgICAgICAgICAgICAgICAgIG1pbk1heFZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgIG1pbk1heFZhbHVlRm91bmQgPSAxLjA7CiAgICAgICAgICAgICAgICAgIG1pbk1heFBvc2l0aW9uID0gJHtTYT9UYT9gKCgoYmF0Y2ggKiAke2FhLmluRGVwdGh9ICsgeEQpICogJHthYS5pbkhlaWdodH0gKyB4UikgKiAke2FhLmluV2lkdGh9ICsgeEMpICogJHthYS5pbkNoYW5uZWxzfSArIGNoYDpgKCh4RCAqICR7YWEuaW5IZWlnaHR9ICsgeFIpICogJHthYS5pbldpZHRofSArIHhDKSAqICR7YWEuaW5DaGFubmVsc30gKyBjaGA6YHdEICogJHtubH0gKiAke3NsfSArCiAgICAgICAgICAgICAgICAgICAgICB3UiAqICR7c2x9ICsgd0NgfTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHNldE91dHB1dChmbG9hdChtaW5NYXhQb3NpdGlvbikpOwogICAgICAgIH0KICAgICAgYDtyZXR1cm59Y29uc3QgY2w9Im1heCI7bGV0IHVsPWAke3hhfSgke3hhfSgke3hhfShtaW5NYXhWYWx1ZVswXSwgbWluTWF4VmFsdWVbMV0pLCBtaW5NYXhWYWx1ZVsyXSksIG1pbk1heFZhbHVlWzNdKWA7eGE9PT0iYXZnIiYmKHVsPSJhdmdWYWx1ZSAvIG1heChjb3VudCwgMS4wKSIpO2NvbnN0IGRsPU1hdGguZmxvb3Iod2EvNCkqNCxobD13YSU0LHBsPWAKICAgICAgaWYgKCR7bGx9KSB7CiAgICAgICAgYXZnVmFsdWUgKz0gZG90KHZhbHVlcywgb25lcyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbWluTWF4VmFsdWUgPSAke2NsfSh2YWx1ZXMsIG1pbk1heFZhbHVlKTsKICAgICAgfQogICAgYDt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzMgc3RyaWRlcyA9CiAgICAgICAgaXZlYzMoJHtFYX0sICR7a2F9LCAke0FhfSk7CiAgICAgIGNvbnN0IGl2ZWMzIHBhZHMgPSBpdmVjMygke3JsfSwgJHtvbH0sICR7YWx9KTsKICAgICAgY29uc3QgZmxvYXQgaW5pdGlhbGl6YXRpb25WYWx1ZSA9ICR7aWx9OwogICAgICBjb25zdCB2ZWM0IG9uZXMgPSB2ZWM0KDEuMCwgMS4wLCAxLjAsIDEuMCk7CgogICAgICBmbG9hdCBjb3VudCA9IDAuMDsKCiAgICAgIGZsb2F0IGdldFZhbHVlKGludCBiYXRjaCwgaW50IHhELCBpbnQgeFIsIGludCB4QywgaW50IGNoKSB7CiAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICByZXR1cm4gaW5pdGlhbGl6YXRpb25WYWx1ZTsKICAgICAgICB9CiAgICAgICAgY291bnQgKz0gMS4wOwogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCB4RCwgeFIsIHhDLCBjaCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDsKICAgICAgICBpbnQgY2ggPSBjb29yZHMudTsKCiAgICAgICAgaXZlYzMgeENvcm5lciA9IGl2ZWMzKGNvb3Jkcy55LCBjb29yZHMueiwgY29vcmRzLncpICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IHhEQ29ybmVyID0geENvcm5lci54OwogICAgICAgIGludCB4UkNvcm5lciA9IHhDb3JuZXIueTsKICAgICAgICBpbnQgeENDb3JuZXIgPSB4Q29ybmVyLno7CgogICAgICAgIC8vIG1heC9taW4geCg/LCA/LCA/LCBkKSB0byBnZXQgeSh5RCwgeVIsIHlDLCBjaCkuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQKICAgICAgICB2ZWM0IG1pbk1heFZhbHVlID0gdmVjNCgke2lsfSk7CiAgICAgICAgZmxvYXQgYXZnVmFsdWUgPSAwLjA7CiAgICAgICAgY291bnQgPSAwLjA7CgogICAgICAgIGZvciAoaW50IHdEID0gMDsgd0QgPCAke3RsfTsKICAgICAgICAgICAgd0QgKz0gJHtGYX0pIHsKICAgICAgICAgIGludCB4RCA9IHhEQ29ybmVyICsgd0Q7CgogICAgICAgICAgaWYgKHhEIDwgMCB8fCB4RCA+PSAke2FhLmluRGVwdGh9KSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke25sfTsKICAgICAgICAgICAgd1IgKz0gJHtMYX0pIHsKICAgICAgICAgICAgaW50IHhSID0geFJDb3JuZXIgKyB3UjsKCiAgICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gJHthYS5pbkhlaWdodH0pIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7ZGx9OyB3QyArPSA0KSB7CiAgICAgICAgICAgICAgaW50IHhDID0geENDb3JuZXIgKyB3QyAqICR7ZWx9OwoKICAgICAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QywgY2gpLAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMgKyAke2VsfSwgY2gpLAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMgKyAyICogJHtlbH0sIGNoKSwKICAgICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4RCwgeFIsIHhDICsgMyAqICR7ZWx9LCBjaCkKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAke3BsfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnQgeEMgPSB4Q0Nvcm5lciArICR7ZGx9OwogICAgICAgICAgICBpZiAoJHtobD09PTF9KSB7CiAgICAgICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMsIGNoKSwKICAgICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlLAogICAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICR7cGx9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoJHtobD09PTJ9KSB7CiAgICAgICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMsIGNoKSwKICAgICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4RCwgeFIsIHhDICsgJHtlbH0sIGNoKSwKICAgICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlCiAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgJHtwbH0KICAgICAgICAgICAgfSBlbHNlIGlmICgke2hsPT09M30pIHsKICAgICAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QywgY2gpLAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMgKyAke2VsfSwgY2gpLAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMgKyAyICogJHtlbH0sIGNoKSwKICAgICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAke3BsfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dCgke3VsfSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBhdmdQb29sJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWE7YXNzZXJ0Tm90Q29tcGxleCQxKFNhLCJhdmdQb29sIik7Y29uc3R7ZmlsdGVyU2l6ZTpUYSxzdHJpZGVzOndhLHBhZDpFYSxkaW1Sb3VuZGluZ01vZGU6a2F9PWJhLEFhPTE7YXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEod2EsQWEpLCgpPT5gRXJyb3IgaW4gYXZnUG9vbDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt3YX0gYW5kIGRpbGF0aW9ucyAnJHtBYX0nYCk7Y29uc3QgRmE9Y29tcHV0ZVBvb2wyREluZm8kMShTYS5zaGFwZSxUYSx3YSxBYSxFYSxrYSk7aWYoRmEuZmlsdGVyV2lkdGg9PT0xJiZGYS5maWx0ZXJIZWlnaHQ9PT0xJiZhcnJheXNFcXVhbCQxKEZhLmluU2hhcGUsRmEub3V0U2hhcGUpKXJldHVybiBpZGVudGl0eSQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtjb25zdCBMYT1uZXcgUG9vbDJEUHJvZ3JhbSQxKEZhLCJhdmciLCExKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sImZsb2F0MzIiKX1jb25zdCBhdmdQb29sQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXZnUG9vbCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphdmdQb29sJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2wzRCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtmaWx0ZXJTaXplOlRhLHN0cmlkZXM6d2EscGFkOkVhLGRpbVJvdW5kaW5nTW9kZTprYSxkYXRhRm9ybWF0OkFhfT1iYSxGYT1bMSwxLDFdLExhPWNvbXB1dGVQb29sM0RJbmZvJDEoU2Euc2hhcGUsVGEsd2EsRmEsRWEsa2EsQWEpLGVsPW5ldyBQb29sM0RQcm9ncmFtJDEoTGEsImF2ZyIsITEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oZWwsW1NhXSwiZmxvYXQzMiIpfWNvbnN0IGF2Z1Bvb2wzRENvbmZpZyQxPXtrZXJuZWxOYW1lOkF2Z1Bvb2wzRCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphdmdQb29sM0QkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IEF2Z1Bvb2wyREJhY2twcm9wUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSJdLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZTtjb25zdCB4YT1hYS5maWx0ZXJIZWlnaHQsYmE9YWEuZmlsdGVyV2lkdGgsU2E9YWEuc3RyaWRlSGVpZ2h0LFRhPWFhLnN0cmlkZVdpZHRoLHdhPWFhLmRpbGF0aW9uSGVpZ2h0LEVhPWFhLmRpbGF0aW9uV2lkdGgsa2E9YWEuZWZmZWN0aXZlRmlsdGVySGVpZ2h0LEFhPWFhLmVmZmVjdGl2ZUZpbHRlcldpZHRoLEZhPWthLTEtYWEucGFkSW5mby50b3AsTGE9QWEtMS1hYS5wYWRJbmZvLmxlZnQsZWw9MS8oeGEqYmEpO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHtGYX0sICR7TGF9KTsKICAgICAgY29uc3QgZmxvYXQgYXZnTXVsdGlwbGllciA9IGZsb2F0KCR7ZWx9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKCiAgICAgICAgaXZlYzIgZHlSQ0Nvcm5lciA9IGNvb3Jkcy55eiAtIHBhZHM7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5UkNDb3JuZXIueDsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlSQ0Nvcm5lci55OwoKICAgICAgICAvLyBDb252b2x2ZSBkeSg/LCA/LCBkKSB3aXRoIHBvcyBtYXNrKDosIDosIGQpIHRvIGdldCBkeCh4UiwgeEMsIGQpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7a2F9OwogICAgICAgICAgICB3UiArPSAke3dhfSkgewogICAgICAgICAgZmxvYXQgZHlSID0gZmxvYXQoZHlSQ29ybmVyICsgd1IpIC8gJHtTYX0uMDsKCiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtBYX07CiAgICAgICAgICAgIHdDKz0gJHtFYX0pIHsKICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gJHtUYX0uMDsKCiAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgIGZyYWN0KGR5QykgPiAwLjApIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWR5QyA9IGludChkeUMpOwoKICAgICAgICAgICAgZmxvYXQgZHlWYWx1ZSA9IGdldER5KGIsIGlkeVIsIGlkeUMsIGQpOwoKICAgICAgICAgICAgZG90UHJvZCArPSBkeVZhbHVlICogYXZnTXVsdGlwbGllcjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX0sQXZnUG9vbDNEQmFja3Byb3BQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5Il0sdGhpcy5vdXRwdXRTaGFwZT1hYS5pblNoYXBlO2NvbnN0IHhhPWFhLmZpbHRlckRlcHRoLGJhPWFhLmZpbHRlckhlaWdodCxTYT1hYS5maWx0ZXJXaWR0aCxUYT1hYS5zdHJpZGVEZXB0aCx3YT1hYS5zdHJpZGVIZWlnaHQsRWE9YWEuc3RyaWRlV2lkdGgsa2E9YWEuZGlsYXRpb25EZXB0aCxBYT1hYS5kaWxhdGlvbkhlaWdodCxGYT1hYS5kaWxhdGlvbldpZHRoLExhPWFhLmVmZmVjdGl2ZUZpbHRlckRlcHRoLGVsPWFhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCx0bD1hYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxubD1MYS0xLWFhLnBhZEluZm8uZnJvbnQsc2w9ZWwtMS1hYS5wYWRJbmZvLnRvcCxybD10bC0xLWFhLnBhZEluZm8ubGVmdCxvbD0xLyh4YSpiYSpTYSk7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMzIHBhZHMgPSBpdmVjMygke25sfSwgJHtzbH0sICR7cmx9KTsKICAgICAgY29uc3QgZmxvYXQgYXZnTXVsdGlwbGllciA9IGZsb2F0KCR7b2x9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDsKICAgICAgICBpbnQgY2ggPSBjb29yZHMudTsKCiAgICAgICAgaXZlYzMgZHlDb3JuZXIgPSBpdmVjMyhjb29yZHMueSwgY29vcmRzLnosIGNvb3Jkcy53KSAtIHBhZHM7CiAgICAgICAgaW50IGR5RENvcm5lciA9IGR5Q29ybmVyLng7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5Q29ybmVyLnk7CiAgICAgICAgaW50IGR5Q0Nvcm5lciA9IGR5Q29ybmVyLno7CgogICAgICAgIC8vIENvbnZvbHZlIGR5KD8sID8sID8sIGQpIHdpdGggcG9zIG1hc2soOiwgOiwgOiwgY2gpIHRvIGdldAogICAgICAgIC8vIGR4KHhELCB4UiwgeEMsIGNoKS4KICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZC4gOiA9IGFjcm9zcyBhbGwgdmFsdWVzIGluIHRoYXQgYXhpcy4KICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwoKICAgICAgICBmb3IgKGludCB3RCA9IDA7IHdEIDwgJHtMYX07CiAgICAgICAgICAgIHdEICs9ICR7a2F9KSB7CiAgICAgICAgICBmbG9hdCBkeUQgPSBmbG9hdChkeURDb3JuZXIgKyB3RCkgLyAke1RhfS4wOwoKICAgICAgICAgIGlmIChkeUQgPCAwLjAgfHwgZHlEID49ICR7YWEub3V0RGVwdGh9LjAgfHwgZnJhY3QoZHlEKSA+IDAuMCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBpZHlEID0gaW50KGR5RCk7CgogICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7ZWx9OwogICAgICAgICAgICAgIHdSICs9ICR7QWF9KSB7CiAgICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvICR7d2F9LjA7CgogICAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fAogICAgICAgICAgICAgICAgZnJhY3QoZHlSKSA+IDAuMCkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBpZHlSID0gaW50KGR5Uik7CgogICAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHt0bH07CiAgICAgICAgICAgICAgICB3QyArPSAke0ZhfSkgewogICAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7RWF9LjA7CgogICAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgICAgZnJhY3QoZHlDKSA+IDAuMCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICAgIGZsb2F0IGR5VmFsdWUgPSBnZXREeShiYXRjaCwgaWR5RCwgaWR5UiwgaWR5QywgY2gpOwoKICAgICAgICAgICAgICBkb3RQcm9kICs9IGR5VmFsdWUgKiBhdmdNdWx0aXBsaWVyOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2wzREdyYWQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxpbnB1dDpUYX09YWEsd2E9VGEse2ZpbHRlclNpemU6RWEsc3RyaWRlczprYSxwYWQ6QWEsZGltUm91bmRpbmdNb2RlOkZhfT1iYSxMYT1bMSwxLDFdLGVsPWNvbXB1dGVQb29sM0RJbmZvJDEod2Euc2hhcGUsRWEsa2EsTGEsQWEsRmEpLHRsPW5ldyBBdmdQb29sM0RCYWNrcHJvcFByb2dyYW0kMShlbCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbSh0bCxbU2FdLHdhLmR0eXBlKX1jb25zdCBhdmdQb29sM0RHcmFkQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXZnUG9vbDNER3JhZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphdmdQb29sM0RHcmFkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2xHcmFkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsaW5wdXQ6VGF9PWFhLHdhPVRhO2Fzc2VydE5vdENvbXBsZXgkMShbU2EsVGFdLCJhdmdQb29sR3JhZCIpO2NvbnN0e2ZpbHRlclNpemU6RWEsc3RyaWRlczprYSxwYWQ6QWF9PWJhLEZhPWNvbXB1dGVQb29sMkRJbmZvJDEod2Euc2hhcGUsRWEsa2EsMSxBYSksTGE9bmV3IEF2Z1Bvb2wyREJhY2twcm9wUHJvZ3JhbSQxKEZhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sd2EuZHR5cGUpfWNvbnN0IGF2Z1Bvb2xHcmFkQ29uZmlnJDE9e2tlcm5lbE5hbWU6QXZnUG9vbEdyYWQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YXZnUG9vbEdyYWQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYmF0Y2hNYXRNdWwkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHthOlNhLGI6VGF9PWFhLHt0cmFuc3Bvc2VBOndhLHRyYW5zcG9zZUI6RWF9PWJhO3JldHVybiBiYXRjaE1hdE11bEltcGwkMSh7YTpTYSxiOlRhLHRyYW5zcG9zZUE6d2EsdHJhbnNwb3NlQjpFYSxiYWNrZW5kOnhhfSl9Y29uc3QgYmF0Y2hNYXRNdWxDb25maWckMT17a2VybmVsTmFtZTpCYXRjaE1hdE11bCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpiYXRjaE1hdE11bCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQmF0Y2hOb3JtUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhKXt0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMudmFyaWFibGVOYW1lcz1bIngiLCJtZWFuIiwidmFyaWFuY2UiXSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKGFhLHhhKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKGFhLGJhKTtsZXQgRWE9IjAuMCI7U2EhPW51bGwmJihhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKGFhLFNhKSx0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgib2Zmc2V0IiksRWE9ImdldE9mZnNldEF0T3V0Q29vcmRzKCkiKTtsZXQga2E9IjEuMCI7VGEhPW51bGwmJihhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSQxKGFhLFRhKSx0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgic2NhbGUiKSxrYT0iZ2V0U2NhbGVBdE91dENvb3JkcygpIiksdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IHggPSBnZXRYQXRPdXRDb29yZHMoKTsKICAgICAgICBmbG9hdCBtZWFuID0gZ2V0TWVhbkF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgdmFyaWFuY2UgPSBnZXRWYXJpYW5jZUF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgb2Zmc2V0ID0gJHtFYX07CiAgICAgICAgZmxvYXQgc2NhbGUgPSAke2thfTsKICAgICAgICBmbG9hdCBpbnYgPSBzY2FsZSAqIGludmVyc2VzcXJ0KHZhcmlhbmNlICsgZmxvYXQoJHt3YX0pKTsKICAgICAgICBzZXRPdXRwdXQoZG90KHZlYzMoeCwgLW1lYW4sIG9mZnNldCksIHZlYzMoaW52LCBpbnYsIDEpKSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQmF0Y2hOb3JtUGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhKXt0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwibWVhbiIsInZhcmlhbmNlIl0sYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShhYSx4YSksYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShhYSxiYSk7bGV0IEVhPSJ2ZWM0KDAuMCkiO1NhIT1udWxsJiYoYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShhYSxTYSksdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goIm9mZnNldCIpLEVhPSJnZXRPZmZzZXRBdE91dENvb3JkcygpIik7bGV0IGthPSJ2ZWM0KDEuMCkiO1RhIT1udWxsJiYoYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUkMShhYSxUYSksdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInNjYWxlIiksa2E9ImdldFNjYWxlQXRPdXRDb29yZHMoKSIpLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICB2ZWM0IG9mZnNldCA9ICR7RWF9OwogICAgICAgIHZlYzQgc2NhbGUgPSAke2thfTsKCiAgICAgICAgdmVjNCB4ID0gZ2V0WEF0T3V0Q29vcmRzKCk7CiAgICAgICAgdmVjNCBtZWFuID0gZ2V0TWVhbkF0T3V0Q29vcmRzKCk7CiAgICAgICAgdmVjNCB2YXJpYW5jZSA9IGdldFZhcmlhbmNlQXRPdXRDb29yZHMoKTsKCiAgICAgICAgdmVjNCBpbnYgPSBzY2FsZSAqIGludmVyc2VzcXJ0KHZhcmlhbmNlICsgdmVjNCgke3dhfSkpOwoKICAgICAgICBzZXRPdXRwdXQoKHggLSBtZWFuKSAqIGludiArIG9mZnNldCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBiYXRjaE5vcm0kMT0oe2lucHV0czpoYSxiYWNrZW5kOmFhLGF0dHJzOnhhfSk9Pntjb25zdHt4OmJhLG1lYW46U2EsdmFyaWFuY2U6VGEsb2Zmc2V0OndhLHNjYWxlOkVhfT1oYTthc3NlcnQkMihTYS5zaGFwZS5sZW5ndGg9PT1UYS5zaGFwZS5sZW5ndGgsKCk9PiJCYXRjaCBub3JtYWxpemF0aW9uIGdyYWRpZW50IHJlcXVpcmVzIG1lYW4gYW5kIHZhcmlhbmNlIHRvIGhhdmUgZXF1YWwgcmFua3MuIiksYXNzZXJ0JDIod2E9PW51bGx8fFNhLnNoYXBlLmxlbmd0aD09PXdhLnNoYXBlLmxlbmd0aCwoKT0+IkJhdGNoIG5vcm1hbGl6YXRpb24gZ3JhZGllbnQgcmVxdWlyZXMgbWVhbiBhbmQgb2Zmc2V0IHRvIGhhdmUgZXF1YWwgcmFua3MuIiksYXNzZXJ0JDIoRWE9PW51bGx8fFNhLnNoYXBlLmxlbmd0aD09PUVhLnNoYXBlLmxlbmd0aCwoKT0+IkJhdGNoIG5vcm1hbGl6YXRpb24gZ3JhZGllbnQgcmVxdWlyZXMgbWVhbiBhbmQgc2NhbGUgdG8gaGF2ZSBlcXVhbCByYW5rcy4iKTtsZXR7dmFyaWFuY2VFcHNpbG9uOmthfT14YTtrYT09bnVsbCYmKGthPS4wMDEpO2NvbnN0IEFhPVtiYSxTYSxUYV07bGV0IEZhPW51bGw7d2EhPW51bGwmJihGYT13YS5zaGFwZSxBYS5wdXNoKHdhKSk7bGV0IExhPW51bGw7RWEhPW51bGwmJihMYT1FYS5zaGFwZSxBYS5wdXNoKEVhKSk7Y29uc3QgZWw9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX05PUk1BTElaQVRJT04iKT9uZXcgQmF0Y2hOb3JtUGFja2VkUHJvZ3JhbSQxKGJhLnNoYXBlLFNhLnNoYXBlLFRhLnNoYXBlLEZhLExhLGthKTpuZXcgQmF0Y2hOb3JtUHJvZ3JhbSQxKGJhLnNoYXBlLFNhLnNoYXBlLFRhLnNoYXBlLEZhLExhLGthKTtyZXR1cm4gYWEucnVuV2ViR0xQcm9ncmFtKGVsLEFhLEFhWzBdLmR0eXBlKX0sYmF0Y2hOb3JtQ29uZmlnJDE9e2tlcm5lbE5hbWU6RnVzZWRCYXRjaE5vcm0kMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YmF0Y2hOb3JtJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBTbGljZVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsic291cmNlIl0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnJhbms9YWEubGVuZ3RoO2NvbnN0IHhhPWdldENvb3Jkc0RhdGFUeXBlJDEodGhpcy5yYW5rKTt0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToic3RhcnQiLGFycmF5SW5kZXg6dGhpcy5yYW5rLHR5cGU6ImludCJ9XTtjb25zdCBiYT1nZXRDb29yZHMkMyh0aGlzLnJhbmspO2xldCBTYTtjb25zdCBUYT1hYS5tYXAoKHdhLEVhKT0+YHNvdXJjZUxvYy4ke2Nvb3JkcyQxW0VhXX0gPSBzdGFydFske0VhfV0gKyBjb29yZHMuJHtjb29yZHMkMVtFYV19O2ApO1NhPWAKICAgICAgICAke3hhfSBzb3VyY2VMb2M7CiAgICAgICAgJHt4YX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgJHtUYS5qb2luKGAKYCl9CiAgICAgIGAsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke1NhfQogICAgICAgIHNldE91dHB1dChnZXRTb3VyY2UoJHtiYX0pKTsKICAgICAgfQogICAgYH19O2NvbnN0IGNvb3JkcyQxPVsieCIsInkiLCJ6IiwidyIsInUiLCJ2Il07ZnVuY3Rpb24gZ2V0Q29vcmRzJDMoaGEpe2lmKGhhPT09MSlyZXR1cm4ic291cmNlTG9jIjtpZihoYTw9NilyZXR1cm4gY29vcmRzJDEuc2xpY2UoMCxoYSkubWFwKGFhPT4ic291cmNlTG9jLiIrYWEpLmpvaW4oIiwiKTt0aHJvdyBFcnJvcihgU2xpY2luZyBmb3IgcmFuayAke2hhfSBpcyBub3QgeWV0IHN1cHBvcnRlZGApfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBTbGljZVBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsic291cmNlIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnJhbms9YWEubGVuZ3RoLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJzdGFydCIsYXJyYXlJbmRleDp0aGlzLnJhbmssdHlwZToiaW50In1dO2NvbnN0IHhhPWdldENvb3Jkc0RhdGFUeXBlJDEodGhpcy5yYW5rKSxiYT1nZXRDaGFubmVscyQxKCJjb29yZHMiLHRoaXMucmFuayksU2E9Z2V0Q2hhbm5lbHMkMSgic291cmNlTG9jIix0aGlzLnJhbmspLFRhPXRoaXMucmFuaz09PTE/InNvdXJjZUxvYyI6YHZlYzIoJHtTYS5zbGljZSgtMikuam9pbigpfSlgLHdhPWBnZXRDaGFubmVsKGdldFNvdXJjZSgke1NhLmpvaW4oKX0pLCAke1RhfSlgLEVhPWAKICAgICAgcmVzdWx0LnggPSAke3dhfTsKICAgICAgaWYgKCsrJHtiYVt0aGlzLnJhbmstMV19IDwgJHthYVt0aGlzLnJhbmstMV19KSB7CiAgICAgICAgKyske1NhW3RoaXMucmFuay0xXX07CiAgICAgICAgcmVzdWx0LnkgPSAke3dhfTsKICAgICAgICAtLSR7U2FbdGhpcy5yYW5rLTFdfTsKICAgICAgfQogICAgYCxrYT10aGlzLnJhbms9PT0xPyIiOmAKICAgICAgLS0ke2JhW3RoaXMucmFuay0xXX07CiAgICAgIGlmICgrKyR7YmFbdGhpcy5yYW5rLTJdfSA8ICR7YWFbdGhpcy5yYW5rLTJdfSkgewogICAgICAgICsrJHtTYVt0aGlzLnJhbmstMl19OwogICAgICAgIHJlc3VsdC56ID0gJHt3YX07CiAgICAgICAgaWYgKCsrJHtiYVt0aGlzLnJhbmstMV19IDwgJHthYVt0aGlzLnJhbmstMV19KSB7CiAgICAgICAgICArKyR7U2FbdGhpcy5yYW5rLTFdfTsKICAgICAgICAgIHJlc3VsdC53ID0gJHt3YX07CiAgICAgICAgfQogICAgICB9CiAgICBgLEFhPXRoaXMucmFuazw9ND9gc291cmNlTG9jID0gY29vcmRzICsKICAgICAgICAgICAgJHt4YX0oJHthYS5tYXAoKEZhLExhKT0+YHN0YXJ0WyR7TGF9XWApLmpvaW4oKX0pO2A6YWEubWFwKChGYSxMYSk9PmAke1NhW0xhXX0gPSAke2JhW0xhXX0gKyBzdGFydFske0xhfV07YCkuam9pbihgCmApO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHt4YX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgJHt4YX0gc291cmNlTG9jOwogICAgICAgICR7QWF9CiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICAke0VhfQogICAgICAgICR7a2F9CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzaGFsbG93U2xpY2UkMShoYSxhYSx4YSxiYSl7Y29uc3QgU2E9YmEudGV4RGF0YS5nZXQoaGEuZGF0YUlkKSxUYT1iYS5tYWtlVGVuc29ySW5mbyh4YSxoYS5kdHlwZSksd2E9YmEudGV4RGF0YS5nZXQoVGEuZGF0YUlkKTtPYmplY3QuYXNzaWduKHdhLFNhKSx3YS5yZWZDb3VudD0xLHdhLnNoYXBlPXhhLHdhLmR0eXBlPWhhLmR0eXBlO2xldCBFYT1jb21wdXRlRmxhdE9mZnNldCQxKGFhLGNvbXB1dGVTdHJpZGVzJDEoaGEuc2hhcGUpKTtTYS5zbGljZSYmKEVhKz1TYS5zbGljZS5mbGF0T2Zmc2V0KSx3YS5zbGljZT17ZmxhdE9mZnNldDpFYSxvcmlnRGF0YUlkOlNhLnNsaWNlJiZTYS5zbGljZS5vcmlnRGF0YUlkfHxoYS5kYXRhSWR9O2NvbnN0IGthPWJhLmRhdGFSZWZDb3VudC5nZXQod2Euc2xpY2Uub3JpZ0RhdGFJZCl8fDE7cmV0dXJuIGJhLmRhdGFSZWZDb3VudC5zZXQod2Euc2xpY2Uub3JpZ0RhdGFJZCxrYSsxKSxUYX1mdW5jdGlvbiBzbGljZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtiZWdpbjpUYSxzaXplOndhfT1iYSxbRWEsa2FdPXBhcnNlU2xpY2VQYXJhbXMkMShTYSxUYSx3YSk7aWYoYXNzZXJ0UGFyYW1zVmFsaWQkMShTYSxFYSxrYSksc2l6ZUZyb21TaGFwZSQxKGthKT09PTApcmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKGthLFNhLmR0eXBlLFtdKTtpZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW1NhXSl8fFNhLmR0eXBlPT09InN0cmluZyIpe2NvbnN0IExhPXhhLnRleERhdGEuZ2V0KFNhLmRhdGFJZCksZWw9c2xpY2VJbXBsQ1BVJDEoTGEudmFsdWVzLEVhLGthLFNhLnNoYXBlLFNhLmR0eXBlKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oa2EsU2EuZHR5cGUsZWwpfWNvbnN0e2lzUGFja2VkOkFhfT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLEZhPWlzU2xpY2VDb250aW5vdXMkMShTYS5zaGFwZSxFYSxrYSk7aWYoQWF8fCFGYSl7Y29uc3QgTGE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0FSUkFZX09QRVJBVElPTlMiKT9uZXcgU2xpY2VQYWNrZWRQcm9ncmFtJDEoa2EpOm5ldyBTbGljZVByb2dyYW0kMShrYSksZWw9W0VhXTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sU2EuZHR5cGUsZWwpfXJldHVybiB4YS51cGxvYWRUb0dQVShTYS5kYXRhSWQpLHNoYWxsb3dTbGljZSQxKFNhLEVhLGthLHhhKX1jb25zdCBzbGljZUNvbmZpZyQxPXtrZXJuZWxOYW1lOlNsaWNlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNsaWNlJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGJhdGNoVG9TcGFjZU5EJDE9aGE9Pntjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtibG9ja1NoYXBlOlRhLGNyb3BzOndhfT1iYTthc3NlcnQkMihTYS5zaGFwZS5sZW5ndGg8PTQsKCk9PiJiYXRjaFRvU3BhY2VORCBmb3IgcmFuayA+IDQgd2l0aCBhIFdlYkdMIGJhY2tlbmQgbm90IGltcGxlbWVudGVkIHlldCIpO2NvbnN0IEVhPVRhLnJlZHVjZSgoYWwsbGwpPT5hbCpsbCksa2E9Z2V0UmVzaGFwZWQkMShTYS5zaGFwZSxUYSxFYSksQWE9Z2V0UGVybXV0ZWQkMShrYS5sZW5ndGgsVGEubGVuZ3RoKSxGYT1nZXRSZXNoYXBlZFBlcm11dGVkJDEoU2Euc2hhcGUsVGEsRWEpLExhPWdldFNsaWNlQmVnaW5Db29yZHMkMSh3YSxUYS5sZW5ndGgpLGVsPWdldFNsaWNlU2l6ZSQxKEZhLHdhLFRhLmxlbmd0aCksdGw9W10sbmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmthfX0pLHNsPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6bmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06QWF9fSkscmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkZhfX0pLG9sPXNsaWNlJDEoe2lucHV0czp7eDpybH0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46TGEsc2l6ZTplbH19KTtyZXR1cm4gdGwucHVzaChubCksdGwucHVzaChzbCksdGwucHVzaChybCksdGwuZm9yRWFjaChhbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpKSxvbH0sYmF0Y2hUb1NwYWNlTkRDb25maWckMT17a2VybmVsTmFtZTpCYXRjaFRvU3BhY2VORCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpiYXRjaFRvU3BhY2VORCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiaW5jb3VudCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2Esd2VpZ2h0czpUYX09YWEse3NpemU6d2F9PWJhLEVhPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksa2E9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxBYT1iaW5jb3VudEltcGxDUFUkMShFYSxrYSxUYS5kdHlwZSxUYS5zaGFwZSx3YSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFt3YV0sVGEuZHR5cGUsQWEpfWNvbnN0IGJpbmNvdW50Q29uZmlnJDE9e2tlcm5lbE5hbWU6QmluY291bnQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YmluY291bnQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQklUV0lTRUFORCQxPWAKICBpbnQgciA9IGludChhLnIpICYgaW50KGIucik7CiAgaW50IGcgPSBpbnQoYS5nKSAmIGludChiLmcpOwogIGludCByYiA9IGludChhLmIpICYgaW50KGIuYik7CiAgaW50IHJhID0gaW50KGEuYSkgJiBpbnQoYi5hKTsKICByZXR1cm4gdmVjNChyLCBnLCByYiwgcmEpOwpgLEJJVFdJU0VBTkRfVU5QQUNLRUQkMT1gCiAgcmV0dXJuIGZsb2F0KGludChhLnIpICYgaW50KGIucikpOwpgO2Z1bmN0aW9uIGJpdHdpc2VBbmQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHthOmJhLGI6U2F9PWFhLFRhPWVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19CSU5BUllfT1BFUkFUSU9OUyIpLHdhPWVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik7aWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtiYSxTYV0pfHx3YT09PTEpe2NvbnN0IGthPXhhLnRleERhdGEuZ2V0KGJhLmRhdGFJZCkudmFsdWVzLEFhPXhhLnRleERhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLFtGYSxMYV09Yml0d2lzZUFuZEltcGxDUFUkMShiYS5zaGFwZSxTYS5zaGFwZSxrYSxBYSxiYS5kdHlwZSksZWw9eGEubWFrZVRlbnNvckluZm8oTGEsYmEuZHR5cGUpLHRsPXhhLnRleERhdGEuZ2V0KGVsLmRhdGFJZCk7cmV0dXJuIHRsLnZhbHVlcz1GYSxlbH1sZXQgRWE7cmV0dXJuIFRhP0VhPW5ldyBCaW5hcnlPcFBhY2tlZFByb2dyYW0kMShCSVRXSVNFQU5EJDEsYmEuc2hhcGUsU2Euc2hhcGUsITEpOkVhPW5ldyBCaW5hcnlPcFByb2dyYW0kMShCSVRXSVNFQU5EX1VOUEFDS0VEJDEsYmEuc2hhcGUsU2Euc2hhcGUpLHhhLnJ1bldlYkdMUHJvZ3JhbShFYSxbYmEsU2FdLGJhLmR0eXBlKX1jb25zdCBiaXR3aXNlQW5kQ29uZmlnJDE9e2tlcm5lbE5hbWU6Qml0d2lzZUFuZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpiaXR3aXNlQW5kJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJyb2FkY2FzdEFyZ3MkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtzMDpiYSxzMTpTYX09YWEsVGE9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSx3YT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLEVhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlJDEoQXJyYXkuZnJvbShUYSksQXJyYXkuZnJvbSh3YSkpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhbRWEubGVuZ3RoXSwiaW50MzIiLEludDMyQXJyYXkuZnJvbShFYSkpfWNvbnN0IGJyb2FkY2FzdEFyZ3NDb25maWckMT17a2VybmVsTmFtZTpCcm9hZGNhc3RBcmdzJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmJyb2FkY2FzdEFyZ3MkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgTk9UX0VRVUFMJDE9InJldHVybiBmbG9hdChhICE9IGIpOyIsbm90RXF1YWwkMT1iaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpOT1RfRVFVQUwkMSxjcHVLZXJuZWxJbXBsOm5vdEVxdWFsSW1wbENQVSQxLGR0eXBlOiJib29sIn0pLG5vdEVxdWFsQ29uZmlnJDE9e2tlcm5lbE5hbWU6Tm90RXF1YWwkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bm90RXF1YWwkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVhbCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2lucHV0OmJhfT1hYSxTYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpO3JldHVybiBpZGVudGl0eSQxKHtpbnB1dHM6e3g6U2EuY29tcGxleFRlbnNvckluZm9zLnJlYWx9LGJhY2tlbmQ6eGF9KX1jb25zdCByZWFsQ29uZmlnJDE9e2tlcm5lbE5hbWU6UmVhbCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyZWFsJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFRPX0lOVCQxPSJyZXR1cm4gZmxvYXQoaW50KHgpKTsiO2Z1bmN0aW9uIGludCQxKGhhLGFhKXtjb25zdCB4YT1uZXcgVW5hcnlPcFByb2dyYW0kMShoYS5zaGFwZSxUT19JTlQkMSksYmE9YWEucnVuV2ViR0xQcm9ncmFtKHhhLFtoYV0sImludDMyIik7cmV0dXJue2RhdGFJZDpiYS5kYXRhSWQsc2hhcGU6YmEuc2hhcGUsZHR5cGU6YmEuZHR5cGV9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNhc3QkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7ZHR5cGU6VGF9PWJhO2lmKFRhPT09ImNvbXBsZXg2NCIpe2lmKFNhLmR0eXBlPT09ImNvbXBsZXg2NCIpcmV0dXJuIGlkZW50aXR5JDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2NvbnN0IHdhPXplcm9zJDIoU2Euc2hhcGUpLEVhPWNhc3QkMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntkdHlwZToiZmxvYXQzMiJ9fSksa2E9Y29tcGxleCQyKHtpbnB1dHM6e3JlYWw6RWEsaW1hZzp3YX0sYmFja2VuZDp4YX0pO3JldHVybiB3YS5kaXNwb3NlKCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLGthfWlmKFNhLmR0eXBlPT09ImNvbXBsZXg2NCIpe2NvbnN0IHdhPXJlYWwkMSh7aW5wdXRzOntpbnB1dDpTYX0sYmFja2VuZDp4YX0pLEVhPWNhc3QkMih7aW5wdXRzOnt4OndhfSxiYWNrZW5kOnhhLGF0dHJzOntkdHlwZTpUYX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLEVhfWlmKCFoYXNFbmNvZGluZ0xvc3MkMShTYS5kdHlwZSxUYSkpe2NvbnN0IHdhPWlkZW50aXR5JDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO3JldHVybntkYXRhSWQ6d2EuZGF0YUlkLHNoYXBlOndhLnNoYXBlLGR0eXBlOlRhfX1pZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW1NhXSkpe2NvbnN0IHdhPXhhLnRleERhdGEuZ2V0KFNhLmRhdGFJZCkudmFsdWVzLFtFYSxrYSxBYV09Y2FzdEltcGxDUFUkMSh3YSxTYS5zaGFwZSxTYS5kdHlwZSxUYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKEVhLGthLEFhKX1pZihUYT09PSJpbnQzMiIpcmV0dXJuIGludCQxKFNhLHhhKTtpZihUYT09PSJib29sIil7Y29uc3Qgd2E9eGEubWFrZVRlbnNvckluZm8oW10sImJvb2wiLGdldFR5cGVkQXJyYXlGcm9tRFR5cGUkMSgiYm9vbCIsMSkpLGthPW5vdEVxdWFsJDEoe2lucHV0czp7YTpTYSxiOndhfSxiYWNrZW5kOnhhfSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHdhKSxrYX10aHJvdyBuZXcgRXJyb3IoYEVycm9yIGluIENhc3Q6IGZhaWxlZCB0byBjYXN0ICR7U2EuZHR5cGV9IHRvICR7VGF9YCl9Y29uc3QgY2FzdENvbmZpZyQxPXtrZXJuZWxOYW1lOkNhc3QkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y2FzdCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDRUlMJDE9InJldHVybiBjZWlsKHgpOyIsY2VpbCQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6Q0VJTCQxLHBhY2tlZE9wU25pcHBldDpDRUlMJDEsY3B1S2VybmVsSW1wbDpjZWlsSW1wbENQVSQxfSksY2VpbENvbmZpZyQxPXtrZXJuZWxOYW1lOkNlaWwkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y2VpbCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQ2xpcFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJtaW5WYWwiLHR5cGU6ImZsb2F0In0se25hbWU6Im1heFZhbCIsdHlwZToiZmxvYXQifV0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldEFBdE91dENvb3JkcygpOwogICAgICAgIGlmIChpc25hbih2YWx1ZSkpIHsKICAgICAgICAgIHNldE91dHB1dCh2YWx1ZSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzZXRPdXRwdXQoY2xhbXAodmFsdWUsIG1pblZhbCwgbWF4VmFsKSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQ2xpcFBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJtaW5WYWwiLHR5cGU6ImZsb2F0In0se25hbWU6Im1heFZhbCIsdHlwZToiZmxvYXQifV0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIHZlYzQgdmFsdWUgPSBnZXRBQXRPdXRDb29yZHMoKTsKCiAgICAgICAgaWYgKGFueShpc25hbih2YWx1ZSkpKSB7CiAgICAgICAgICBzZXRPdXRwdXQodmFsdWUpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgc2V0T3V0cHV0KGNsYW1wKHZhbHVlLCB2ZWM0KG1pblZhbCksIHZlYzQobWF4VmFsKSkpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2xpcEJ5VmFsdWUkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7Y2xpcFZhbHVlTWluOlRhLGNsaXBWYWx1ZU1heDp3YX09YmE7bGV0IEVhO2VudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19DTElQIik/RWE9bmV3IENsaXBQYWNrZWRQcm9ncmFtJDEoU2Euc2hhcGUpOkVhPW5ldyBDbGlwUHJvZ3JhbSQxKFNhLnNoYXBlKTtjb25zdCBrYT1bW1RhXSxbd2FdXTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEVhLFtTYV0sU2EuZHR5cGUsa2EpfWNvbnN0IGNsaXBCeVZhbHVlQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q2xpcEJ5VmFsdWUkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y2xpcEJ5VmFsdWUkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IENvbXBsZXhBYnNQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bInJlYWwiLCJpbWFnIl0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IHJlID0gYWJzKGdldFJlYWxBdE91dENvb3JkcygpKTsKICAgICAgICBmbG9hdCBpbSA9IGFicyhnZXRJbWFnQXRPdXRDb29yZHMoKSk7CiAgICAgICAgZmxvYXQgbXggPSBtYXgocmUsIGltKTsKCiAgICAgICAgLy8gc2FkbHkgdGhlIGxlbmd0aCBmdW5jdGlvbiBpbiBnbHNsIGlzIG5vdCB1bmRlcmZsb3ctc2FmZQogICAgICAgIC8vIChhdCBsZWFzdCBub3Qgb24gSW50ZWwgR1BVcykuIFNvIHRoZSBzYWZlIHNvbHV0aW9uIGlzCiAgICAgICAgLy8gdG8gZW5zdXJlIHVuZGVyZmxvdy1zYWZldHkgaW4gYWxsIGNhc2VzLgogICAgICAgIHNldE91dHB1dCgKICAgICAgICAgIG14ID09IDAuMCA/IDAuMCA6IG14ICogbGVuZ3RoKHZlYzIoMSwgbWluKHJlLCBpbSkvbXgpKQogICAgICAgICk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYWtlQ29tcGxleENvbXBvbmVudFRlbnNvckluZm8kMShoYSxhYSl7cmV0dXJue2RhdGFJZDphYS5kYXRhSWQsZHR5cGU6YWEuZHR5cGUsc2hhcGU6aGEuc2hhcGV9fWZ1bmN0aW9uIGNvbXBsZXhBYnMkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYSxTYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpLFRhPW5ldyBDb21wbGV4QWJzUHJvZ3JhbSQxKGJhLnNoYXBlKSx3YT1bbWFrZUNvbXBsZXhDb21wb25lbnRUZW5zb3JJbmZvJDEoYmEsU2EuY29tcGxleFRlbnNvckluZm9zLnJlYWwpLG1ha2VDb21wbGV4Q29tcG9uZW50VGVuc29ySW5mbyQxKGJhLFNhLmNvbXBsZXhUZW5zb3JJbmZvcy5pbWFnKV07cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShUYSx3YSx3YVswXS5kdHlwZSl9Y29uc3QgY29tcGxleEFic0NvbmZpZyQxPXtrZXJuZWxOYW1lOkNvbXBsZXhBYnMkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29tcGxleEFicyQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQ29uY2F0UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMub3V0cHV0U2hhcGU9Y29tcHV0ZU91dFNoYXBlJDQoYWEsMSksdGhpcy52YXJpYWJsZU5hbWVzPWFhLm1hcCgod2EsRWEpPT5gVCR7RWF9YCk7Y29uc3QgeGE9bmV3IEFycmF5KGFhLmxlbmd0aC0xKTt4YVswXT1hYVswXVsxXTtmb3IobGV0IHdhPTE7d2E8eGEubGVuZ3RoO3dhKyspeGFbd2FdPXhhW3dhLTFdK2FhW3dhXVsxXTtjb25zdCBiYT1bYGlmICh5QyA8ICR7eGFbMF19KSBzZXRPdXRwdXQoZ2V0VDAoeVIsIHlDKSk7YF07Zm9yKGxldCB3YT0xO3dhPHhhLmxlbmd0aDt3YSsrKXtjb25zdCBFYT14YVt3YS0xXTtiYS5wdXNoKGBlbHNlIGlmICh5QyA8ICR7eGFbd2FdfSkgc2V0T3V0cHV0KGdldFQke3dhfSh5UiwgeUMtJHtFYX0pKTtgKX1jb25zdCBTYT14YS5sZW5ndGgsVGE9eGFbeGEubGVuZ3RoLTFdO2JhLnB1c2goYGVsc2Ugc2V0T3V0cHV0KGdldFQke1NhfSh5UiwgeUMtJHtUYX0pKTtgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMyIGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCB5UiA9IGNvb3Jkcy54OwogICAgICAgIGludCB5QyA9IGNvb3Jkcy55OwoKICAgICAgICAke2JhLmpvaW4oYAogICAgICAgIGApfQogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IENvbmNhdFBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLm91dHB1dFNoYXBlPWNvbXB1dGVPdXRTaGFwZSQ0KGFhLHhhKTtjb25zdCBiYT10aGlzLm91dHB1dFNoYXBlLFNhPWJhLmxlbmd0aCxUYT1nZXRDb29yZHNEYXRhVHlwZSQxKFNhKSx3YT1nZXRDaGFubmVscyQxKCJjb29yZHMiLFNhKSxFYT1bIngiLCJ5IiwieiIsInciLCJ1IiwidiJdLnNsaWNlKDAsU2EpO3RoaXMudmFyaWFibGVOYW1lcz1hYS5tYXAoKHNsLHJsKT0+YFQke3JsfWApO2NvbnN0IGthPW5ldyBBcnJheShhYS5sZW5ndGgtMSk7a2FbMF09YWFbMF1beGFdO2ZvcihsZXQgc2w9MTtzbDxrYS5sZW5ndGg7c2wrKylrYVtzbF09a2Fbc2wtMV0rYWFbc2xdW3hhXTtjb25zdCBBYT1FYVt4YV0sRmE9RWEuc2xpY2UoLTIpLExhPUVhLmpvaW4oKTtsZXQgZWw9YGlmICgke0FhfSA8ICR7a2FbMF19KSB7CiAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoCiAgICAgICAgICAgIGdldFQwKCR7TGF9KSwgdmVjMigke0ZhLmpvaW4oKX0pKTsKICAgICAgICB9YDtmb3IobGV0IHNsPTE7c2w8a2EubGVuZ3RoO3NsKyspe2NvbnN0IHJsPWthW3NsLTFdO2VsKz1gCiAgICAgICAgaWYgKCR7QWF9IDwgJHtrYVtzbF19ICAmJiAke0FhfSA+PSAke2thW3NsLTFdfSkgewogICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoCiAgICAgICAgICAgIGdldFQke3NsfSgke3NoaWZ0ZWRDaGFubmVscyQxKEVhLEFhLHJsKX0pLAogICAgICAgICAgICB2ZWMyKCR7c2hpZnRlZENoYW5uZWxzJDEoRmEsQWEscmwpfSkpOwogICAgICAgIH1gfWNvbnN0IHRsPWthLmxlbmd0aCxubD1rYVtrYS5sZW5ndGgtMV07ZWwrPWAKICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbCgKICAgICAgICAgIGdldFQke3RsfSgke3NoaWZ0ZWRDaGFubmVscyQxKEVhLEFhLG5sKX0pLAogICAgICAgICAgdmVjMigke3NoaWZ0ZWRDaGFubmVscyQxKEZhLEFhLG5sKX0pKTtgLHRoaXMudXNlckNvZGU9YAogICAgICBmbG9hdCBnZXRWYWx1ZSgke0VhLm1hcChzbD0+ImludCAiK3NsKX0pIHsKICAgICAgICAke2VsfQogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtUYX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KGdldFZhbHVlKCR7d2F9KSwgMC4sIDAuLCAwLik7CgogICAgICAgICR7d2FbU2EtMV19ID0gJHt3YVtTYS0xXX0gKyAxOwogICAgICAgIGlmICgke3dhW1NhLTFdfSA8ICR7YmFbU2EtMV19KSB7CiAgICAgICAgICByZXN1bHQuZyA9IGdldFZhbHVlKCR7d2F9KTsKICAgICAgICB9CgogICAgICAgICR7d2FbU2EtMl19ID0gJHt3YVtTYS0yXX0gKyAxOwogICAgICAgIGlmICgke3dhW1NhLTJdfSA8ICR7YmFbU2EtMl19KSB7CiAgICAgICAgICByZXN1bHQuYSA9IGdldFZhbHVlKCR7d2F9KTsKICAgICAgICB9CgogICAgICAgICR7d2FbU2EtMV19ID0gJHt3YVtTYS0xXX0gLSAxOwogICAgICAgIGlmICgke3dhW1NhLTJdfSA8ICR7YmFbU2EtMl19ICYmCiAgICAgICAgICAgICR7d2FbU2EtMV19IDwgJHtiYVtTYS0xXX0pIHsKICAgICAgICAgIHJlc3VsdC5iID0gZ2V0VmFsdWUoJHt3YX0pOwogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgICAgfQogICAgYH19O2Z1bmN0aW9uIHNoaWZ0ZWRDaGFubmVscyQxKGhhLGFhLHhhKXtjb25zdCBiYT1oYS5pbmRleE9mKGFhKTtyZXR1cm4gaGEubWFwKChUYSx3YSk9PndhPT09YmE/YCR7VGF9IC0gJHt4YX1gOlRhKS5qb2luKCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaW1hZyQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2lucHV0OmJhfT1hYSxTYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpO3JldHVybiBpZGVudGl0eSQxKHtpbnB1dHM6e3g6U2EuY29tcGxleFRlbnNvckluZm9zLmltYWd9LGJhY2tlbmQ6eGF9KX1jb25zdCBpbWFnQ29uZmlnJDE9e2tlcm5lbE5hbWU6SW1hZyQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzppbWFnJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbmNhdEltcGwkMihoYSxhYSx4YSl7Y29uc3QgYmE9aGFbMF0uZHR5cGU7aWYoYmE9PT0iY29tcGxleDY0Iil7Y29uc3QgdGw9aGEubWFwKGFsPT5yZWFsJDEoe2lucHV0czp7aW5wdXQ6YWx9LGJhY2tlbmQ6eGF9KSksbmw9aGEubWFwKGFsPT5pbWFnJDEoe2lucHV0czp7aW5wdXQ6YWx9LGJhY2tlbmQ6eGF9KSksc2w9Y29uY2F0SW1wbCQyKHRsLGFhLHhhKSxybD1jb25jYXRJbXBsJDIobmwsYWEseGEpLG9sPWNvbXBsZXgkMih7aW5wdXRzOntyZWFsOnNsLGltYWc6cmx9LGJhY2tlbmQ6eGF9KTtyZXR1cm4gdGwuZm9yRWFjaChhbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpKSxubC5mb3JFYWNoKGFsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhbCkpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhybCksb2x9bGV0IFNhPXhhLnNob3VsZEV4ZWN1dGVPbkNQVShoYSk7aWYoYmE9PT0ic3RyaW5nIiYmKFNhPSEwKSxTYSl7Y29uc3QgdGw9aGEubWFwKGlsPT57Y29uc3QgdWw9Wy0xLHNpemVGcm9tU2hhcGUkMShpbC5zaGFwZS5zbGljZShhYSkpXTtyZXR1cm4gcmVzaGFwZSQyKHtpbnB1dHM6e3g6aWx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOnVsfX0pfSksbmw9dGwubWFwKGlsPT4oe3ZhbHM6eGEucmVhZFN5bmMoaWwuZGF0YUlkKSxzaGFwZTppbC5zaGFwZX0pKSxzbD1jb21wdXRlT3V0U2hhcGUkNCh0bC5tYXAoaWw9PmlsLnNoYXBlKSwxKSxybD10bFswXS5zaGFwZVswXT09PTEsb2w9Y29uY2F0SW1wbENQVSQxKG5sLHNsLGJhLHJsKSxhbD1jb21wdXRlT3V0U2hhcGUkNChoYS5tYXAoaWw9PmlsLnNoYXBlKSxhYSksbGw9eGEubWFrZVRlbnNvckluZm8oYWwsYmEsb2wpO3JldHVybiB0bC5mb3JFYWNoKGlsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhpbCkpLGxsfWNvbnN0IFRhPWhhLmZpbHRlcih0bD0+c2l6ZUZyb21TaGFwZSQxKHRsLnNoYXBlKT4wKSx3YT1lbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfQVJSQVlfT1BFUkFUSU9OUyIpJiZUYVswXS5zaGFwZS5sZW5ndGg+MTtpZihUYS5sZW5ndGg9PT0xKXtjb25zdCB0bD13YT9uZXcgVW5hcnlPcFByb2dyYW0kMShoYVswXS5zaGFwZSxDTE9ORSQxKTpuZXcgVW5hcnlPcFBhY2tlZFByb2dyYW0kMShoYVswXS5zaGFwZSxDTE9ORSQxKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKHRsLGhhLGJhKX1jb25zdCBFYT1lbnYkMSgpLmdldE51bWJlcigiV0VCR0xfTUFYX1RFWFRVUkVTX0lOX1NIQURFUiIpO2lmKFRhLmxlbmd0aD5FYSl7Y29uc3QgdGw9W107Zm9yKGxldCBzbD0wO3NsPFRhLmxlbmd0aDtzbCs9RWEpe2NvbnN0IHJsPVRhLnNsaWNlKHNsLHNsK0VhKTt0bC5wdXNoKGNvbmNhdEltcGwkMihybCxhYSx4YSkpfWNvbnN0IG5sPWNvbmNhdEltcGwkMih0bCxhYSx4YSk7Zm9yKGNvbnN0IHNsIG9mIHRsKXhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKTtyZXR1cm4gbmx9aWYod2Epe2NvbnN0IHRsPW5ldyBDb25jYXRQYWNrZWRQcm9ncmFtJDEoVGEubWFwKG5sPT5ubC5zaGFwZSksYWEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0odGwsVGEsYmEpfWNvbnN0e3RlbnNvcnMyRDprYSxvdXRTaGFwZTpBYX09Y29tcHV0ZVRlbnNvcnMyRCQxKFRhLGFhLHhhKSxGYT1uZXcgQ29uY2F0UHJvZ3JhbSQxKGthLm1hcCh0bD0+dGwuc2hhcGUpKSxMYT14YS5ydW5XZWJHTFByb2dyYW0oRmEsa2EsYmEpO2thLmZvckVhY2godGw9PnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSk7Y29uc3QgZWw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6TGF9LGF0dHJzOntzaGFwZTpBYX0sYmFja2VuZDp4YX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSksZWx9ZnVuY3Rpb24gY29tcHV0ZVRlbnNvcnMyRCQxKGhhLGFhLHhhKXtjb25zdCBiYT1jb21wdXRlT3V0U2hhcGUkNChoYS5tYXAoVGE9PlRhLnNoYXBlKSxhYSk7cmV0dXJue3RlbnNvcnMyRDpoYS5tYXAoVGE9PnJlc2hhcGUkMih7aW5wdXRzOnt4OlRhfSxhdHRyczp7c2hhcGU6Wy0xLHNpemVGcm9tU2hhcGUkMShUYS5zaGFwZS5zbGljZShhYSkpXX0sYmFja2VuZDp4YX0pKSxvdXRTaGFwZTpiYX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29uY2F0JDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7YXhpczpTYX09YmEsVGE9cGFyc2VBeGlzUGFyYW0kMShTYSxhYVswXS5zaGFwZSlbMF0sd2E9YWEubWFwKEFhPT5BYS5zaGFwZSk7YXNzZXJ0UGFyYW1zQ29uc2lzdGVudCQxKHdhLFRhKTtjb25zdCBFYT1jb21wdXRlT3V0U2hhcGUkNChhYS5tYXAoQWE9PkFhLnNoYXBlKSxUYSk7aWYoc2l6ZUZyb21TaGFwZSQxKEVhKT09PTApcmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKEVhLGFhWzBdLmR0eXBlLFtdKTtjb25zdCBrYT1hYS5maWx0ZXIoQWE9PnNpemVGcm9tU2hhcGUkMShBYS5zaGFwZSk+MCk7cmV0dXJuIGthLmxlbmd0aD09PTE/aWRlbnRpdHkkMSh7aW5wdXRzOnt4OmthWzBdfSxiYWNrZW5kOnhhfSk6Y29uY2F0SW1wbCQyKGthLFRhLHhhKX1jb25zdCBjb25jYXRDb25maWckMT17a2VybmVsTmFtZTpDb25jYXQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29uY2F0JDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBDb252MkRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGE9ITEsYmE9bnVsbCxTYT0hMSxUYT0hMSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsIlciXSx0aGlzLm91dHB1dFNoYXBlPWFhLm91dFNoYXBlO2NvbnN0IHdhPWFhLnBhZEluZm8udG9wLEVhPWFhLnBhZEluZm8ubGVmdCxrYT1hYS5zdHJpZGVIZWlnaHQsQWE9YWEuc3RyaWRlV2lkdGgsRmE9YWEuZGlsYXRpb25IZWlnaHQsTGE9YWEuZGlsYXRpb25XaWR0aCxlbD1hYS5maWx0ZXJIZWlnaHQsdGw9YWEuZmlsdGVyV2lkdGgsbmw9TWF0aC5mbG9vcihhYS5pbkNoYW5uZWxzLzQpKjQsc2w9YWEuaW5DaGFubmVscyU0LHJsPWFhLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNMYXN0IixvbD1ybD8xOjIsYWw9cmw/MjozLGxsPXJsPzM6MTtsZXQgaWw9IiIsY2w9IiI7YmEmJihTYT9pbD1gZmxvYXQgYWN0aXZhdGlvbihmbG9hdCBhKSB7CiAgICAgICAgICBmbG9hdCBiID0gZ2V0UHJlbHVBY3RpdmF0aW9uV2VpZ2h0c0F0T3V0Q29vcmRzKCk7CiAgICAgICAgICAke2JhfQogICAgICAgIH1gOlRhP2lsPWBmbG9hdCBhY3RpdmF0aW9uKGZsb2F0IGEpIHsKICAgICAgICAgIGZsb2F0IGIgPSBnZXRMZWFreXJlbHVBbHBoYUF0T3V0Q29vcmRzKCk7CiAgICAgICAgICAke2JhfQogICAgICAgIH1gOmlsPWAKICAgICAgICAgIGZsb2F0IGFjdGl2YXRpb24oZmxvYXQgeCkgewogICAgICAgICAgICAke2JhfQogICAgICAgICAgfQogICAgICAgIGAsY2w9InJlc3VsdCA9IGFjdGl2YXRpb24ocmVzdWx0KTsiKTtjb25zdCB1bD14YT8icmVzdWx0ICs9IGdldEJpYXNBdE91dENvb3JkcygpOyI6IiI7eGEmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJiaWFzIiksU2EmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJwcmVsdUFjdGl2YXRpb25XZWlnaHRzIiksVGEmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJsZWFreXJlbHVBbHBoYSIpLHRoaXMudXNlckNvZGU9YAogICAgICAke2lsfQoKICAgICAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7a2F9LCAke0FhfSk7CiAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke3dhfSwgJHtFYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZDIgPSBjb29yZHNbJHtsbH1dOwoKICAgICAgICBpdmVjMiB4UkNDb3JuZXIgPQogICAgICAgICAgICBpdmVjMihjb29yZHNbJHtvbH1dLCBjb29yZHNbJHthbH1dKSAqIHN0cmlkZXMgLSBwYWRzOwogICAgICAgIGludCB4UkNvcm5lciA9IHhSQ0Nvcm5lci54OwogICAgICAgIGludCB4Q0Nvcm5lciA9IHhSQ0Nvcm5lci55OwoKICAgICAgICAvLyBDb252b2x2ZSB4KD8sID8sIGQxKSB3aXRoIHcoOiwgOiwgZDEsIGQyKSB0byBnZXQgeSh5UiwgeUMsIGQyKS4KICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZC4gOiA9IGFjcm9zcyBhbGwgdmFsdWVzIGluIHRoYXQgYXhpcy4KICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwogICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke2VsfTsgd1IrKykgewogICAgICAgICAgaW50IHhSID0geFJDb3JuZXIgKyB3UiAqICR7RmF9OwoKICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gJHthYS5pbkhlaWdodH0pIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CgogICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7dGx9OyB3QysrKSB7CiAgICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgd0MgKiAke0xhfTsKCiAgICAgICAgICAgIGlmICh4QyA8IDAgfHwgeEMgPj0gJHthYS5pbldpZHRofSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCBkMSA9IDA7IGQxIDwgJHtubH07IGQxICs9IDQpIHsKICAgICAgICAgICAgICB2ZWM0IHdWYWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgICAgZ2V0Vyh3Uiwgd0MsIGQxLCBkMiksCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgZDEgKyAxLCBkMiksCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgZDEgKyAyLCBkMiksCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgZDEgKyAzLCBkMikKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBpZiAoJHtybH0pIHsKICAgICAgICAgICAgICAgIHZlYzQgeFZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgZDEpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4UiwgeEMsIGQxICsgMSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgZDEgKyAyKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSArIDMpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZlYzQgeFZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGQxLCB4UiwgeEMpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBkMSArIDEsIHhSLCB4QyksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGQxICsgMiwgeFIsIHhDKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgZDEgKyAzLCB4UiwgeEMpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoJHtzbD09PTF9KSB7CgogICAgICAgICAgICAgIGlmICgke3JsfSkgewogICAgICAgICAgICAgICAgZG90UHJvZCArPQogICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgJHtubH0pICoKICAgICAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgJHtubH0sIGQyKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZG90UHJvZCArPQogICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsICR7bmx9LCB4UiwgeEMpICoKICAgICAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgJHtubH0sIGQyKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9IGVsc2UgaWYgKCR7c2w9PT0yfSkgewogICAgICAgICAgICAgIHZlYzIgd1ZhbHVlcyA9IHZlYzIoCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgJHtubH0sIGQyKSwKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCAke25sfSArIDEsIGQyKQogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGlmICgke3JsfSkgewogICAgICAgICAgICAgICAgdmVjMiB4VmFsdWVzID0gdmVjMigKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCAke25sfSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgJHtubH0gKyAxKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGRvdFByb2QgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2ZWMyIHhWYWx1ZXMgPSB2ZWMyKAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCAke25sfSwgeFIsIHhDKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgJHtubH0gKyAxLCB4UiwgeEMpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfSBlbHNlIGlmICgke3NsPT09M30pIHsKICAgICAgICAgICAgICB2ZWMzIHdWYWx1ZXMgPSB2ZWMzKAogICAgICAgICAgICAgICAgZ2V0Vyh3Uiwgd0MsICR7bmx9LCBkMiksCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgJHtubH0gKyAxLCBkMiksCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgJHtubH0gKyAyLCBkMikKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBpZiAoJHtybH0pIHsKICAgICAgICAgICAgICAgIHZlYzMgeFZhbHVlcyA9IHZlYzMoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgJHtubH0pLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4UiwgeEMsICR7bmx9ICsgMSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgJHtubH0gKyAyKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGRvdFByb2QgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2ZWMzIHhWYWx1ZXMgPSB2ZWMzKAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCAke25sfSwgeFIsIHhDKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgJHtubH0gKyAxLCB4UiwgeEMpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCAke25sfSArIDIsIHhSLCB4QykKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmbG9hdCByZXN1bHQgPSBkb3RQcm9kOwogICAgICAgICR7dWx9CiAgICAgICAgJHtjbH0KICAgICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgICAgfQogICAgYH19LENvbnYzRFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsIlciXSx0aGlzLm91dHB1dFNoYXBlPWFhLm91dFNoYXBlO2NvbnN0IHhhPWFhLnBhZEluZm8uZnJvbnQsYmE9YWEucGFkSW5mby50b3AsU2E9YWEucGFkSW5mby5sZWZ0LFRhPWFhLnN0cmlkZURlcHRoLHdhPWFhLnN0cmlkZUhlaWdodCxFYT1hYS5zdHJpZGVXaWR0aCxrYT1hYS5kaWxhdGlvbkRlcHRoLEFhPWFhLmRpbGF0aW9uSGVpZ2h0LEZhPWFhLmRpbGF0aW9uV2lkdGgsTGE9YWEuZmlsdGVyRGVwdGgsZWw9YWEuZmlsdGVySGVpZ2h0LHRsPWFhLmZpbHRlcldpZHRoLG5sPU1hdGguZmxvb3IoYWEuaW5DaGFubmVscy80KSo0LHNsPWFhLmluQ2hhbm5lbHMlNDt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzMgc3RyaWRlcyA9IGl2ZWMzKCR7VGF9LCAke3dhfSwgJHtFYX0pOwogICAgICBjb25zdCBpdmVjMyBwYWRzID0gaXZlYzMoJHt4YX0sICR7YmF9LCAke1NhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzUgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaW50IGQyID0gY29vcmRzLnU7CgogICAgICAgIGl2ZWMzIHhGUkNDb3JuZXIgPSBpdmVjMyhjb29yZHMueSwgY29vcmRzLnosIGNvb3Jkcy53KSAqIHN0cmlkZXMgLSBwYWRzOwogICAgICAgIGludCB4RkNvcm5lciA9IHhGUkNDb3JuZXIueDsKICAgICAgICBpbnQgeFJDb3JuZXIgPSB4RlJDQ29ybmVyLnk7CiAgICAgICAgaW50IHhDQ29ybmVyID0geEZSQ0Nvcm5lci56OwoKICAgICAgICAvLyBDb252b2x2ZSB4KD8sID8sID8sIGQxKSB3aXRoIHcoOiwgOiwgOiwgZDEsIGQyKSB0byBnZXQKICAgICAgICAvLyB5KHlGLCB5UiwgeUMsIGQyKS4gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsCiAgICAgICAgLy8gdmFsdWVzIGluIHRoYXQgYXhpcy4KICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwogICAgICAgIGZvciAoaW50IHdGID0gMDsgd0YgPCAke0xhfTsgd0YrKykgewogICAgICAgICAgaW50IHhGID0geEZDb3JuZXIgKyB3RiAqICR7a2F9OwoKICAgICAgICAgIGlmICh4RiA8IDAgfHwgeEYgPj0gJHthYS5pbkRlcHRofSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHtlbH07IHdSKyspIHsKICAgICAgICAgICAgaW50IHhSID0geFJDb3JuZXIgKyB3UiAqICR7QWF9OwoKICAgICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHt0bH07IHdDKyspIHsKICAgICAgICAgICAgICBpbnQgeEMgPSB4Q0Nvcm5lciArIHdDICogJHtGYX07CgogICAgICAgICAgICAgIGlmICh4QyA8IDAgfHwgeEMgPj0gJHthYS5pbldpZHRofSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBmb3IgKGludCBkMSA9IDA7IGQxIDwgJHtubH07IGQxICs9IDQpIHsKICAgICAgICAgICAgICAgIHZlYzQgeFZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGQxKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEgKyAxKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEgKyAyKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEgKyAzKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHZlYzQgd1ZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICAgIGdldFcod0YsIHdSLCB3QywgZDEsIGQyKSwKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCBkMSArIDEsIGQyKSwKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCBkMSArIDIsIGQyKSwKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCBkMSArIDMsIGQyKQogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGlmICgke3NsPT09MX0pIHsKICAgICAgICAgICAgICAgIGRvdFByb2QgKz0KICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgJHtubH0pICoKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCAke25sfSwgZDIpOwogICAgICAgICAgICAgIH0gZWxzZSBpZiAoJHtzbD09PTJ9KSB7CiAgICAgICAgICAgICAgICB2ZWMyIHhWYWx1ZXMgPSB2ZWMyKAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCAke25sfSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsICR7bmx9ICsgMSkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB2ZWMyIHdWYWx1ZXMgPSB2ZWMyKAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsICR7bmx9LCBkMiksCiAgICAgICAgICAgICAgICAgIGdldFcod0YsIHdSLCB3QywgJHtubH0gKyAxLCBkMikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9IGVsc2UgaWYgKCR7c2w9PT0zfSkgewogICAgICAgICAgICAgICAgdmVjMyB4VmFsdWVzID0gdmVjMygKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgJHtubH0pLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCAke25sfSArIDEpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCAke25sfSArIDIpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgdmVjMyB3VmFsdWVzID0gdmVjMygKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCAke25sfSwgZDIpLAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsICR7bmx9ICsgMSwgZDIpLAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsICR7bmx9ICsgMiwgZDIpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBDb252MkRQYWNrZWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGE9ITEsYmE9bnVsbCxTYT0hMSxUYT0hMSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsIlciXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToicGFkcyIsdHlwZToiaXZlYzIifSx7bmFtZToic3RyaWRlcyIsdHlwZToiaXZlYzIifSx7bmFtZToiZGlsYXRpb25zIix0eXBlOiJpdmVjMiJ9LHtuYW1lOiJpbkRpbXMiLHR5cGU6Iml2ZWMyIn1dLHRoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGUsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCk7Y29uc3Qgd2E9YWEucGFkSW5mby5sZWZ0LEVhPWFhLnN0cmlkZVdpZHRoLGthPWFhLmRpbGF0aW9uV2lkdGgsQWE9YWEuZmlsdGVySGVpZ2h0LEZhPWFhLmZpbHRlcldpZHRoLExhPUZhO2xldCBlbD1gCiAgICAgICBpbnQgeFI7IGludCB4QzsgaW50IHhDT2Zmc2V0OwogICAgICAgdmVjNCB3VGV4ZWw7IHZlYzQgcHJldmlvdXM7IHZlYzQgZmluYWw7YDtmb3IobGV0IHJsPTA7cmw8RmE7cmwrKyllbCs9YAogICAgICAgICAgIHZlYzQgeFRleGVsQyR7cmwqMn07CiAgICAgICAgICAgaW50IHhUZXhlbEMke3JsKjJ9UmVhZHk7CiAgICAgICAgICAgdmVjNCB4VGV4ZWxDJHtybCoyKzF9OwogICAgICAgICAgIGludCB4VGV4ZWxDJHtybCoyKzF9UmVhZHk7CiAgICAgICAgICAgdmVjNCB4QyR7cmx9O2A7ZWwrPWAKICAgICBmb3IgKGludCByID0gMDsgciA8ICR7QWF9OyByKyspIHsKICAgICAgZm9yIChpbnQgZDEgPSAwOyBkMSA8ICR7YWEuaW5DaGFubmVsc307IGQxICs9IDIpIHsKICAgICAgIGA7Zm9yKGxldCBybD0wO3JsPEZhO3JsKyspZWwrPWAKICAgICAgICAgICB4VGV4ZWxDJHtybCoyfSA9IHZlYzQoMC4wKTsKICAgICAgICAgICB4VGV4ZWxDJHtybCoyfVJlYWR5ID0gMDsKICAgICAgICAgICB4VGV4ZWxDJHtybCoyKzF9ID0gdmVjNCgwLjApOwogICAgICAgICAgIHhUZXhlbEMke3JsKjIrMX1SZWFkeSA9IDA7CiAgICAgICAgICAgeEMke3JsfSA9IHZlYzQoMC4wKTtgO2VsKz1gCiAgICAgICAgIHhSID0geFJDb3JuZXIgKyByICogZGlsYXRpb25zWzBdOwogICAgICAgICBpZiAoeFIgPj0wICYmIHhSIDwgaW5EaW1zWzBdKSB7CiAgICAgICBgO2ZvcihsZXQgcmw9MDtybDwoTGErMSkvMjtybCsrKXtjb25zdCBvbD1ybCoyO2lmKGVsKz1gCiAgICAgICAgICAgeEMgPSB4Q0Nvcm5lciArICR7b2wqa2F9OwogICAgICAgICAgIGAsRWE9PT0xKXtpZihvbDxGYSYmKHdhJTI9PT0xPyhlbCs9YAogICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAxOwogICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCA+PSAwICYmIHhDT2Zmc2V0IDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke29sfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gbWFudWFsbHkgY2xlYXIgdW51c2VkIGNoYW5uZWxzIGluIGNhc2UKICAgICAgICAgICAgICAgICAgIC8vIHdlJ3JlIHJlYWRpbmcgZnJvbSByZWN5Y2xlZCB0ZXh0dXJlLgogICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgYCxrYT09PTEmJm9sPjA/ZWwrPWAKICAgICAgICAgICAgICAgICB4QyR7b2x9ID0gdmVjNCh4VGV4ZWxDJHtvbC0yfS56dywgeFRleGVsQyR7b2x9Lnh5KTsKICAgICAgICAgICAgICAgICBgOmVsKz1gCiAgICAgICAgICAgICAgICAgICB4Q09mZnNldCA9IHhDICsgMSAtIDI7CgogICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXMgPSBnZXRYKGJhdGNoLCB4UiwgeENPZmZzZXQsIGQxKTsKCiAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gbWFudWFsbHkgY2xlYXIgdW51c2VkIGNoYW5uZWxzIGluIGNhc2UKICAgICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXMuencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgIHhDJHtvbH0gPSB2ZWM0KHByZXZpb3VzLnp3LCB4VGV4ZWxDJHtvbH0ueHkpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgeEMke29sfSA9IHZlYzQoMC4wLCAwLjAsIHhUZXhlbEMke29sfS54eSk7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBgKTplbCs9YAogICAgICAgICAgICAgICAgIGlmICh4QyA+PSAwICYmIHhDIDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke29sfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfSA9IGdldFgoYmF0Y2gsIHhSLCB4QywgZDEpOwogICAgICAgICAgICAgICAgICAgaWYgKHhDICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgeEMke29sfSA9IHhUZXhlbEMke29sfTsKICAgICAgICAgICAgICAgICBgLG9sKzE8RmEpKXtjb25zdCBhbD13YSUyPT09MD9uZWFyZXN0TGFyZ2VyRXZlbiQxKGthKTprYTtrYSUyPT09MCYmd2ElMj09PTF8fGthJTIhPT0wJiZ3YSUyIT09MT8oZWwrPWAKICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyBpbW9kKHBhZHNbMV0sIDIpICsgJHthbH07CgogICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2wrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CgogICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAgIC8vIHdlJ3JlIHJlYWRpbmcgZnJvbSByZWN5Y2xlZCB0ZXh0dXJlLgogICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgYCxrYT4xP2VsKz1gCiAgICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0IC09IDI7CiAgICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCA+PSAwICYmIHhDT2Zmc2V0IDwgaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgICAgeEMke29sKzF9ID0gdmVjNChwcmV2aW91cy56dywgeFRleGVsQyR7b2wrMX0ueHkpOwogICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgeEMke29sKzF9ID0gdmVjNCgwLjAsIDAuMCwgeFRleGVsQyR7b2wrMX0ueHkpOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGA6ZWwrPWAKICAgICAgICAgICAgICAgICAgICAgeEMke29sKzF9ID0gdmVjNCh4VGV4ZWxDJHtvbH0uencsIHhUZXhlbEMke29sKzF9Lnh5KTsKICAgICAgICAgICAgICAgICAgICAgYCk6YWw9PT0xP2VsKz1gCiAgICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHhUZXhlbEMke29sfTsKICAgICAgICAgICAgICAgICAgICAgYDplbCs9YAogICAgICAgICAgICAgICAgICAgICB4Q09mZnNldCA9IHhDICsgJHthbH07CgogICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHtvbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2wrMX1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHhUZXhlbEMke29sKzF9OwogICAgICAgICAgICAgICAgICAgICBgfX1lbHNlIG9sPEZhJiYod2ElMj09PTE/KGVsKz1gCiAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDEgLSBzdHJpZGVzWzFdOwogICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2x9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CiAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIGlmKHhDICsgMSA+PSAwICYmIHhDICsgMSA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHtvbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9ID0gZ2V0WChiYXRjaCwgeFIsIHhDICsgMSwgZDEpOwogICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICBpZiAoeEMgKyAyID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgeEMke29sfSA9IHZlYzQoeFRleGVsQyR7b2x9Lnp3LCB4VGV4ZWxDJHtvbCsxfS56dyk7CiAgICAgICAgICAgICAgIGAsb2wrMTxGYSYmKGVsKz1gCiAgICAgICAgICAgICAgICAgICBmaW5hbCA9IHZlYzQoMC4wKTsKICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAxICsgc3RyaWRlc1sxXTsKICAgICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgZmluYWwgPSBnZXRYKGJhdGNoLCB4UiwgeENPZmZzZXQsIGQxKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHZlYzQoeFRleGVsQyR7b2wrMX0ueHksIGZpbmFsLnh5KTsKICAgICAgICAgICAgICAgICBgKSk6KGVsKz1gCiAgICAgICAgICAgICAgICAgaWYoeEMgPj0gMCAmJiB4QyA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHtvbH1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH0gPSBnZXRYKGJhdGNoLCB4UiwgeEMsIGQxKTsKICAgICAgICAgICAgICAgICAgIGlmICh4QyArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyBzdHJpZGVzWzFdOwogICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2wrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2wrMX0uencgPSB2ZWMyKDAuKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgeEMke29sfSA9IHZlYzQoCiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH0ueHksIHhUZXhlbEMke29sKzF9Lnh5KTsKICAgICAgICAgICAgICAgYCxvbCsxPEZhJiYoZWwrPWAKICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHZlYzQoeFRleGVsQyR7b2x9Lnp3LCB4VGV4ZWxDJHtvbCsxfS56dyk7CiAgICAgICAgICAgICAgICAgYCkpKTtvbDxGYSYmKGVsKz1gCiAgICAgICAgICAgICB3VGV4ZWwgPSBnZXRXKHIsICR7b2x9LCBkMSwgZDIpOwogICAgICAgICAgICAgZG90UHJvZCArPSB4QyR7b2x9Lnh4enogKiB2ZWM0KHdUZXhlbC54eSwgd1RleGVsLnh5KTsKICAgICAgICAgICAgIGlmKGQxICsgMSA8ICR7YWEuaW5DaGFubmVsc30pIHsKICAgICAgICAgICAgICAgZG90UHJvZCArPSB4QyR7b2x9Lnl5d3cgKiB2ZWM0KHdUZXhlbC56dywgd1RleGVsLnp3KTsKICAgICAgICAgICAgIH0KICAgICAgICAgICBgLG9sKzE8RmEmJihlbCs9YAogICAgICAgICAgICAgICB3VGV4ZWwgPSBnZXRXKHIsICR7b2wrMX0sIGQxLCBkMik7CiAgICAgICAgICAgICAgIGRvdFByb2QgKz0geEMke29sKzF9Lnh4enogKiB2ZWM0KHdUZXhlbC54eSwgd1RleGVsLnh5KTsKICAgICAgICAgICAgICAgaWYoZDEgKyAxIDwgJHthYS5pbkNoYW5uZWxzfSkgewogICAgICAgICAgICAgICAgIGRvdFByb2QgKz0geEMke29sKzF9Lnl5d3cgKiB2ZWM0KHdUZXhlbC56dywgd1RleGVsLnp3KTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgYCkpfWVsKz1gCiAgICAgfQogICBgLGVsKz1gCiAgICAgfQogICBgLGVsKz1gCiAgICAgfQogICBgO2xldCB0bD0iIixubD0iIjtiYSYmKFNhP3RsPWB2ZWM0IGFjdGl2YXRpb24odmVjNCBhKSB7CiAgICAgICAgICAgdmVjNCBiID0gZ2V0UHJlbHVBY3RpdmF0aW9uV2VpZ2h0c0F0T3V0Q29vcmRzKCk7CiAgICAgICAgICAgJHtiYX0KICAgICAgICAgfWA6VGE/dGw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IGEpIHsKICAgICAgICAgICB2ZWM0IGIgPSBnZXRMZWFreXJlbHVBbHBoYUF0T3V0Q29vcmRzKCk7CiAgICAgICAgICAgJHtiYX0KICAgICAgICAgfWA6dGw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IHgpIHsKICAgICAgICAgICAke2JhfQogICAgICAgICB9YCxubD0icmVzdWx0ID0gYWN0aXZhdGlvbihyZXN1bHQpOyIpO2NvbnN0IHNsPXhhPyJyZXN1bHQgKz0gZ2V0Qmlhc0F0T3V0Q29vcmRzKCk7IjoiIjt4YSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJpYXMiKSxTYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInByZWx1QWN0aXZhdGlvbldlaWdodHMiKSxUYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImxlYWt5cmVsdUFscGhhIiksdGhpcy51c2VyQ29kZT1gCiAgICAgICAke3RsfQoKICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMueXogKiBzdHJpZGVzIC0gcGFkczsKICAgICAgICAgaW50IGQyID0gY29vcmRzLnc7CiAgICAgICAgIGludCB4UkNvcm5lciA9IHhSQ0Nvcm5lci54OwogICAgICAgICBpbnQgeENDb3JuZXIgPSB4UkNDb3JuZXIueTsKCiAgICAgICAgIC8vaW50aWFsaXplIGRvdFByb2Qgd2l0aCBhIHNtYWxsIGVwc2lsb24gc2VlbXMgdG8gcmVkdWNlIEdQVSBhY2N1cmFjeSBsb3NzLgogICAgICAgICB2ZWM0IGRvdFByb2QgPSB2ZWM0KDAuMDAwMDAwMDAwMDAwMDAxKTsKCiAgICAgICAgICR7ZWx9CgogICAgICAgICB2ZWM0IHJlc3VsdCA9IGRvdFByb2QgLSB2ZWM0KDAuMDAwMDAwMDAwMDAwMDAxKTsKICAgICAgICAgJHtzbH0KICAgICAgICAgJHtubH0KICAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgICB9CiAgICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBJbTJDb2xQYWNrZWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToiaW5wdXRTaGFwZSIsdHlwZToiaXZlYzQifSx7bmFtZToicGFkIix0eXBlOiJpdmVjMiJ9LHtuYW1lOiJzdHJpZGUiLHR5cGU6Iml2ZWMyIn0se25hbWU6ImRpbGF0aW9uIix0eXBlOiJpdmVjMiJ9LHtuYW1lOiJpbkNoYW5uZWxzIix0eXBlOiJpbnQifSx7bmFtZToiaXRlbXNQZXJCbG9ja1JvdyIsdHlwZToiaW50In0se25hbWU6Im91dFdpZHRoIix0eXBlOiJpbnQifV0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdHtkYXRhRm9ybWF0OmJhfT14YSxTYT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpLFRhPWJhPT09ImNoYW5uZWxzTGFzdCIsd2E9VGE/MToyLEVhPVRhPzI6MyxrYT10aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/ImlmKGJsb2NrSW5kZXggPCBvdXRTaGFwZVsyXSAmJiBwb3MgPCBvdXRTaGFwZVsxXSkgeyI6YGlmKGJsb2NrSW5kZXggPCAke2FhWzJdfSAmJiBwb3MgPCAke2FhWzFdfSkge2A7bGV0IEFhPSIiO2ZvcihsZXQgRmE9MDtGYTw9MTtGYSsrKWZvcihsZXQgTGE9MDtMYTw9MTtMYSsrKUFhKz1gCiAgICAgICAgICBibG9ja0luZGV4ID0gcmMueiArICR7TGF9OwogICAgICAgICAgcG9zID0gcmMueSArICR7RmF9OwoKICAgICAgICAgICR7a2F9CiAgICAgICAgICAgIG9mZnNldFkgPSBpbnQoYmxvY2tJbmRleCAvIG91dFdpZHRoKSAqIHN0cmlkZVswXSAtIHBhZFswXTsKICAgICAgICAgICAgZDAgPSBvZmZzZXRZICsgZGlsYXRpb25bMF0gKiAocG9zIC8gaXRlbXNQZXJCbG9ja1Jvdyk7CgogICAgICAgICAgICBpZihkMCA8IGlucHV0U2hhcGVbJHt3YX1dICYmIGQwID49IDApIHsKICAgICAgICAgICAgICAvLyBVc2UgY3VzdG9tIGltb2QgaW5zdGVhZCBtb2QuIE9uIEludGVsIEdQVSwgbW9kIG1heSBnZW5lcmF0ZQogICAgICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdmFsdWUuCiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvdGZqcy9pc3N1ZXMvNTQ0NwogICAgICAgICAgICAgIG9mZnNldFggPSBpbW9kKGJsb2NrSW5kZXgsIG91dFdpZHRoKSAqIHN0cmlkZVsxXSAtIHBhZFsxXTsKICAgICAgICAgICAgICBkMSA9IG9mZnNldFggKyBkaWxhdGlvblsxXSAqIChpbW9kKHBvcywgaXRlbXNQZXJCbG9ja1JvdykgLwogICAgICAgICAgICAgICAgICBpbkNoYW5uZWxzKTsKCiAgICAgICAgICAgICAgaWYoZDEgPCBpbnB1dFNoYXBlWyR7RWF9XSAmJiBkMSA+PSAwKSB7CgogICAgICAgICAgICAgICAgY2ggPSBpbW9kKHBvcywgaW5DaGFubmVscyk7CgogICAgICAgICAgICAgICAgaWYgKCR7VGF9KSB7CiAgICAgICAgICAgICAgICAgIGlubmVyRGltcyA9IHZlYzIoZDEsIGNoKTsKICAgICAgICAgICAgICAgICAgcmVzdWx0WyR7RmEqMitMYX1dID0gZ2V0Q2hhbm5lbCgKICAgICAgICAgICAgICAgICAgICBnZXRBKHJjLngsIGQwLCBpbnQoaW5uZXJEaW1zLngpLAogICAgICAgICAgICAgICAgICAgIGludChpbm5lckRpbXMueSkpLCBpbm5lckRpbXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW5uZXJEaW1zID0gdmVjMihkMCwgZDEpOwogICAgICAgICAgICAgICAgICByZXN1bHRbJHtGYSoyK0xhfV0gPSBnZXRDaGFubmVsKAogICAgICAgICAgICAgICAgICAgIGdldEEocmMueCwgY2gsIGludChpbm5lckRpbXMueCksCiAgICAgICAgICAgICAgICAgICAgaW50KGlubmVyRGltcy55KSksIGlubmVyRGltcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgYDt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMzIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7CgogICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwKTsKCiAgICAgICAgaW50IGJsb2NrSW5kZXgsIHBvcywgb2Zmc2V0WSwgZDAsIG9mZnNldFgsIGQxLCBjaDsKICAgICAgICB2ZWMyIGlubmVyRGltczsKCiAgICAgICAgJHtBYX0KCiAgICAgICAgJHtTYS5vdXRwdXR9ID0gcmVzdWx0OwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0U2hhcGVGb3JCYXRjaE1hdE11bCQxKGhhLGFhKXtjb25zdCB4YT1oYS5sZW5ndGg7cmV0dXJuIHhhPj0zP2FhP1suLi5oYS5zbGljZSgwLC0zKSxoYVt4YS0zXSpoYVt4YS0yXSxoYVt4YS0xXV06Wy4uLmhhLnNsaWNlKDAsLTMpLGhhW3hhLTNdLGhhW3hhLTJdKmhhW3hhLTFdXTohYWEmJnhhPT09MSYmaGFbMF0+MT9baGFbMF0sMV06bnVsbH1mdW5jdGlvbiBjb252MmRCeU1hdE11bCQxKHt4OmhhLGZpbHRlcjphYSxjb252SW5mbzp4YSxiYWNrZW5kOmJhLGJpYXM6U2E9bnVsbCxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOlRhPW51bGwsbGVha3lyZWx1QWxwaGE6d2E9MCxhY3RpdmF0aW9uOkVhPW51bGx9KXtjb25zdCBrYT1oYS5zaGFwZSxBYT1iYS50ZXhEYXRhLmdldChoYS5kYXRhSWQpLEZhPXhhLmluQ2hhbm5lbHMsTGE9a2FbMF0qa2FbMV0qa2FbMl0sZWw9eGEub3V0Q2hhbm5lbHMsdGw9eGEuZGF0YUZvcm1hdD09PSJjaGFubmVsc0xhc3QiLG5sPSExLHNsPSExO2xldCBybDtjb25zdCBvbD1bXTtpZihUYSE9bnVsbCl7Y29uc3QgaWw9Z2V0U2hhcGVGb3JCYXRjaE1hdE11bCQxKFRhLnNoYXBlLHRsKTtpbCE9bnVsbCYmKFRhPXJlc2hhcGUkMih7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTppbH19KSxvbC5wdXNoKFRhKSl9aWYoU2EhPW51bGwpe2NvbnN0IGlsPWdldFNoYXBlRm9yQmF0Y2hNYXRNdWwkMShTYS5zaGFwZSx0bCk7aWwhPW51bGwmJihTYT1yZXNoYXBlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6aWx9fSksb2wucHVzaChTYSkpfWlmKCEoKExhPT09MXx8ZWw9PT0xKSYmRmE+TUFUTVVMX1NIQVJFRF9ESU1fVEhSRVNIT0xEJDEpJiZBYS5pc1BhY2tlZCYmdGwmJkFhLnRleHR1cmUhPW51bGwmJmthWzJdJTIhPT0wJiZhcnJheXNFcXVhbCQxKEFhLnNoYXBlLnNsaWNlKC0zKSxrYS5zbGljZSgtMykpKXtjb25zdCBpbD1rYVswXSprYVsxXSooa2FbMl0rMSksY2w9e2RhdGFJZDpoYS5kYXRhSWQsc2hhcGU6WzEsaWwseGEuaW5DaGFubmVsc10sZHR5cGU6aGEuZHR5cGV9LHVsPUFhLnNoYXBlO0FhLnNoYXBlPUFhLnNoYXBlLnNsaWNlKCksQWEuc2hhcGVbQWEuc2hhcGUubGVuZ3RoLTJdKyssYXNzZXJ0JDIoaXNSZXNoYXBlRnJlZSQxKEFhLnNoYXBlLGNsLnNoYXBlKSwoKT0+YHBhY2tlZCByZXNoYXBlICR7QWEuc2hhcGV9IHRvICR7Y2wuc2hhcGV9IGlzbid0IGZyZWVgKTtjb25zdCBkbD1yZXNoYXBlJDIoe2lucHV0czp7eDphYX0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6WzEseGEuaW5DaGFubmVscyx4YS5vdXRDaGFubmVsc119fSk7b2wucHVzaChkbCk7Y29uc3QgaGw9YmF0Y2hNYXRNdWxJbXBsJDEoe2E6Y2wsYjpkbCxiYWNrZW5kOmJhLHRyYW5zcG9zZUE6bmwsdHJhbnNwb3NlQjpzbCxiaWFzOlNhLGFjdGl2YXRpb246RWEscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpUYSxsZWFreXJlbHVBbHBoYTp3YX0pLHBsPWJhLnRleERhdGEuZ2V0KGhsLmRhdGFJZCk7YXNzZXJ0JDIocGwuaXNQYWNrZWQsKCk9PiJiYXRjaE1hdE11bCByZXN1bHQgaXMgZXhwZWN0ZWQgdG8gYmUgcGFja2VkIiksQWEuc2hhcGU9dWwscGwuc2hhcGU9eGEub3V0U2hhcGUscmw9aWRlbnRpdHkkMSh7aW5wdXRzOnt4OmhsfSxiYWNrZW5kOmJhfSkscmwuc2hhcGU9eGEub3V0U2hhcGUsb2wucHVzaChobCl9ZWxzZXtjb25zdCBpbD14YS5vdXRIZWlnaHQqeGEub3V0V2lkdGgsY2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6aGF9LGJhY2tlbmQ6YmEsYXR0cnM6e3NoYXBlOnRsP1t4YS5iYXRjaFNpemUsaWwseGEuaW5DaGFubmVsc106W3hhLmJhdGNoU2l6ZSx4YS5pbkNoYW5uZWxzLGlsXX19KSx1bD1yZXNoYXBlJDIoe2lucHV0czp7eDphYX0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6WzEseGEuaW5DaGFubmVscyx4YS5vdXRDaGFubmVsc119fSksZGw9YmF0Y2hNYXRNdWxJbXBsJDEoe2E6dGw/Y2w6dWwsYjp0bD91bDpjbCx0cmFuc3Bvc2VBOiF0bCx0cmFuc3Bvc2VCOnNsLGJhY2tlbmQ6YmEsYmlhczpTYSxhY3RpdmF0aW9uOkVhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6VGEsbGVha3lyZWx1QWxwaGE6d2F9KTtybD1yZXNoYXBlJDIoe2lucHV0czp7eDpkbH0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6eGEub3V0U2hhcGV9fSksb2wucHVzaChjbCksb2wucHVzaCh1bCksb2wucHVzaChkbCl9Zm9yKGNvbnN0IGlsIG9mIG9sKWJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGlsKTtyZXR1cm4gcmx9ZnVuY3Rpb24gY29udjJkV2l0aEltMlJvdyQxKHt4OmhhLGZpbHRlcjphYSxjb252SW5mbzp4YSxiYWNrZW5kOmJhLGJpYXM6U2E9bnVsbCxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOlRhPW51bGwsbGVha3lyZWx1QWxwaGE6d2E9MCxhY3RpdmF0aW9uOkVhPW51bGx9KXtjb25zdHtmaWx0ZXJXaWR0aDprYSxmaWx0ZXJIZWlnaHQ6QWEsaW5DaGFubmVsczpGYSxvdXRXaWR0aDpMYSxvdXRIZWlnaHQ6ZWwsZGF0YUZvcm1hdDp0bH09eGEsbmw9dGw9PT0iY2hhbm5lbHNMYXN0IixzbD1rYSpBYSpGYSxybD1lbCpMYSxvbD1beGEuYmF0Y2hTaXplLHNsLHJsXSxhbD0hMCxsbD0hMSxpbD1bXTtpZihUYSE9bnVsbCl7Y29uc3QgQ2w9Z2V0U2hhcGVGb3JCYXRjaE1hdE11bCQxKFRhLnNoYXBlLG5sKTtDbCE9bnVsbCYmKFRhPXJlc2hhcGUkMih7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpDbH19KSxpbC5wdXNoKFRhKSl9aWYoU2EhPW51bGwpe2NvbnN0IENsPWdldFNoYXBlRm9yQmF0Y2hNYXRNdWwkMShTYS5zaGFwZSxubCk7Q2whPW51bGwmJihTYT1yZXNoYXBlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6Q2x9fSksaWwucHVzaChTYSkpfWNvbnN0IGNsPXJlc2hhcGUkMih7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpbMSxzbCxzaXplRnJvbVNoYXBlJDEoYWEuc2hhcGUpL3NsXX19KTtpbC5wdXNoKGNsKTtjb25zdCB1bD1uZXcgSW0yQ29sUGFja2VkUHJvZ3JhbSQxKG9sLHhhKSxkbD1baGEuc2hhcGUsW3hhLnBhZEluZm8udG9wLHhhLnBhZEluZm8ubGVmdF0sW3hhLnN0cmlkZUhlaWdodCx4YS5zdHJpZGVXaWR0aF0sW3hhLmRpbGF0aW9uSGVpZ2h0LHhhLmRpbGF0aW9uV2lkdGhdLFt4YS5pbkNoYW5uZWxzXSxbeGEuZmlsdGVyV2lkdGgqeGEuaW5DaGFubmVsc10sW3hhLm91dFdpZHRoXV0saGw9YmEucnVuV2ViR0xQcm9ncmFtKHVsLFtoYV0sImZsb2F0MzIiLGRsKSxwbD1yZXNoYXBlJDIoe2lucHV0czp7eDpobH0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6b2x9fSk7aWwucHVzaChobCksaWwucHVzaChwbCk7Y29uc3QgZmw9U2EhPW51bGwsbWw9VGEhPW51bGwsZ2w9RWE9PT0ibGVha3lyZWx1IiwkbD1FYT9tYXBBY3RpdmF0aW9uVG9TaGFkZXJQcm9ncmFtJDEoRWEsITApOm51bGwseGw9bmV3IE1hdE11bFBhY2tlZFByb2dyYW0kMShubD9wbC5zaGFwZTpjbC5zaGFwZSxubD9jbC5zaGFwZTpwbC5zaGFwZSxubD9beGEuYmF0Y2hTaXplLHJsLHhhLm91dENoYW5uZWxzXTpbeGEuYmF0Y2hTaXplLHhhLm91dENoYW5uZWxzLHJsXSxhbCxsbCxmbCwkbCxtbCxnbCkseWw9bmw/W3BsLGNsXTpbY2wscGxdO2lmKFNhJiZ5bC5wdXNoKFNhKSxtbCYmeWwucHVzaChUYSksZ2wpe2NvbnN0IENsPWJhLm1ha2VUZW5zb3JJbmZvKFtdLCJmbG9hdDMyIixjcmVhdGVTY2FsYXJWYWx1ZSQxKHdhLCJmbG9hdDMyIikpO3lsLnB1c2goQ2wpLGlsLnB1c2goQ2wpfWNvbnN0IGJsPWJhLnJ1bldlYkdMUHJvZ3JhbSh4bCx5bCwiZmxvYXQzMiIpLFNsPXJlc2hhcGUkMih7aW5wdXRzOnt4OmJsfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTp4YS5vdXRTaGFwZX19KTtpbC5wdXNoKGJsKTtmb3IoY29uc3QgQ2wgb2YgaWwpYmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oQ2wpO3JldHVybiBTbH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252MmQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGZpbHRlcjpUYX09YWEse3N0cmlkZXM6d2EscGFkOkVhLGRhdGFGb3JtYXQ6a2EsZGlsYXRpb25zOkFhLGRpbVJvdW5kaW5nTW9kZTpGYX09YmEsTGE9Y29udmVydENvbnYyRERhdGFGb3JtYXQkMShrYSksZWw9Y29tcHV0ZUNvbnYyREluZm8kMShTYS5zaGFwZSxUYS5zaGFwZSx3YSxBYSxFYSxGYSwhMSxMYSk7bGV0IHRsO2lmKGVsLmZpbHRlckhlaWdodD09PTEmJmVsLmZpbHRlcldpZHRoPT09MSYmZWwuZGlsYXRpb25IZWlnaHQ9PT0xJiZlbC5kaWxhdGlvbldpZHRoPT09MSYmZWwuc3RyaWRlSGVpZ2h0PT09MSYmZWwuc3RyaWRlV2lkdGg9PT0xJiYoZWwucGFkSW5mby50eXBlPT09IlNBTUUifHxlbC5wYWRJbmZvLnR5cGU9PT0iVkFMSUQiKSl0bD1jb252MmRCeU1hdE11bCQxKHt4OlNhLGZpbHRlcjpUYSxjb252SW5mbzplbCxiYWNrZW5kOnhhfSk7ZWxzZSBpZihlbC5zdHJpZGVXaWR0aDw9MiYmTGE9PT0iY2hhbm5lbHNMYXN0IiYmZW52JDEoKS5nZXRCb29sKCJXRUJHTF9FWFBfQ09OViIpKXtjb25zdCBzbD1uZXcgQ29udjJEUGFja2VkUHJvZ3JhbSQxKGVsKSxybD1bW2VsLnBhZEluZm8udG9wLGVsLnBhZEluZm8ubGVmdF0sW2VsLnN0cmlkZUhlaWdodCxlbC5zdHJpZGVXaWR0aF0sW2VsLmRpbGF0aW9uSGVpZ2h0LGVsLmRpbGF0aW9uV2lkdGhdLFtlbC5pbkhlaWdodCxlbC5pbldpZHRoXV07dGw9eGEucnVuV2ViR0xQcm9ncmFtKHNsLFtTYSxUYV0sImZsb2F0MzIiLHJsKX1lbHNlIGlmKGVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfQ09OVl9JTTJDT0wiKSl0bD1jb252MmRXaXRoSW0yUm93JDEoe3g6U2EsZmlsdGVyOlRhLGNvbnZJbmZvOmVsLGJhY2tlbmQ6eGF9KTtlbHNle2NvbnN0IHNsPW5ldyBDb252MkRQcm9ncmFtJDEoZWwpO3RsPXhhLnJ1bldlYkdMUHJvZ3JhbShzbCxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3Qgbmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6dGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmVsLm91dFNoYXBlfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh0bCksbmx9Y29uc3QgY29udjJEQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q29udjJEJDIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbnYyZCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgQ29udjJERGVyRmlsdGVyUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiZHkiXSx0aGlzLm91dHB1dFNoYXBlPWFhLmZpbHRlclNoYXBlO2NvbnN0IHhhPWFhLnN0cmlkZUhlaWdodCxiYT1hYS5zdHJpZGVXaWR0aCxTYT1hYS5wYWRJbmZvLnRvcCxUYT1hYS5wYWRJbmZvLmxlZnQsd2E9YWEuZGF0YUZvcm1hdD09PSJjaGFubmVsc0xhc3QiO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IHdSID0gY29vcmRzLng7CiAgICAgICAgaW50IHdDID0gY29vcmRzLnk7CiAgICAgICAgaW50IGQxID0gY29vcmRzLno7CiAgICAgICAgaW50IGQyID0gY29vcmRzLnc7CgogICAgICAgIC8vIENvbnZvbHZlIHgoPywgPywgZDEpIHdpdGggZHkoOiwgOiwgZDIpIHRvIGdldCBkdyh3Uiwgd0MsIGQxLCBkMikuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsIHZhbHVlcyBpbiB0aGF0IGF4aXMuCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCAke2FhLmJhdGNoU2l6ZX07IGIrKykgewogICAgICAgICAgZm9yIChpbnQgeVIgPSAwOyB5UiA8ICR7YWEub3V0SGVpZ2h0fTsgeVIrKykgewogICAgICAgICAgICBpbnQgeFIgPSB3UiArIHlSICogJHt4YX0gLSAke1NhfTsKCiAgICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gJHthYS5pbkhlaWdodH0pIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChpbnQgeUMgPSAwOyB5QyA8ICR7YWEub3V0V2lkdGh9OyB5QysrKSB7CiAgICAgICAgICAgICAgaW50IHhDID0gd0MgKyB5QyAqICR7YmF9IC0gJHtUYX07CgogICAgICAgICAgICAgIGlmICh4QyA8IDAgfHwgeEMgPj0gJHthYS5pbldpZHRofSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAke3dhP2BmbG9hdCBkeVZhbHVlID0gZ2V0RHkoYiwgeVIsIHlDLCBkMik7CiAgICAgICAgICAgICAgZmxvYXQgeFZhbHVlID0gZ2V0WChiLCB4UiwgeEMsIGQxKTsKICAgICAgICAgICAgICBkb3RQcm9kICs9ICh4VmFsdWUgKiBkeVZhbHVlKTtgOmBmbG9hdCBkeVZhbHVlID0gZ2V0RHkoYiwgZDIsIHlSLCB5Qyk7CiAgICAgICAgICAgICAgZmxvYXQgeFZhbHVlID0gZ2V0WChiLCBkMSwgeFIsIHhDKTsKICAgICAgICAgICAgICBkb3RQcm9kICs9ICh4VmFsdWUgKiBkeVZhbHVlKTtgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19LENvbnYyRERlcklucHV0UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSIsIlciXSx0aGlzLm91dHB1dFNoYXBlPWFhLmluU2hhcGU7Y29uc3QgeGE9YWEuZmlsdGVySGVpZ2h0LGJhPWFhLmZpbHRlcldpZHRoLFNhPWFhLnN0cmlkZUhlaWdodCxUYT1hYS5zdHJpZGVXaWR0aCx3YT1hYS5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCIsRWE9eGEtMS1hYS5wYWRJbmZvLnRvcCxrYT1iYS0xLWFhLnBhZEluZm8ubGVmdCxBYT13YT8xOjIsRmE9d2E/MjozLExhPXdhPzM6MTt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7RWF9LCAke2thfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgIGludCBkMSA9IGNvb3Jkc1ske0xhfV07CgogICAgICAgIGl2ZWMyIGR5Q29ybmVyID0gaXZlYzIoY29vcmRzWyR7QWF9XSwgY29vcmRzWyR7RmF9XSkgLSBwYWRzOwogICAgICAgIGludCBkeVJDb3JuZXIgPSBkeUNvcm5lci54OwogICAgICAgIGludCBkeUNDb3JuZXIgPSBkeUNvcm5lci55OwoKICAgICAgICAvLyBDb252b2x2ZSBkeSg/LCA/LCBkMikgd2l0aCB3KDosIDosIGQxLCBkMikgdG8gY29tcHV0ZSBkeCh4UiwgeEMsIGQxKS4KICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZC4gOiA9IGFjcm9zcyBhbGwgdmFsdWVzIGluIHRoYXQgYXhpcy4KICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwogICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke3hhfTsgd1IrKykgewogICAgICAgICAgZmxvYXQgZHlSID0gZmxvYXQoZHlSQ29ybmVyICsgd1IpIC8gJHtTYX0uMDsKCiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKCiAgICAgICAgICBpbnQgd1JQZXJtID0gJHt4YX0gLSAxIC0gd1I7CgogICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7YmF9OyB3QysrKSB7CiAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7VGF9LjA7CgogICAgICAgICAgICBpZiAoZHlDIDwgMC4wIHx8IGR5QyA+PSAke2FhLm91dFdpZHRofS4wIHx8CiAgICAgICAgICAgICAgICBmcmFjdChkeUMpID4gMC4wKSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGlkeUMgPSBpbnQoZHlDKTsKCiAgICAgICAgICAgIGludCB3Q1Blcm0gPSAke2JhfSAtIDEgLSB3QzsKCiAgICAgICAgICAgIGZvciAoaW50IGQyID0gMDsgZDIgPCAke2FhLm91dENoYW5uZWxzfTsgZDIrKykgewoKICAgICAgICAgICAgICBpZiAoJHt3YX0pIHsKICAgICAgICAgICAgICAgIGZsb2F0IHhWYWx1ZSA9IGdldER5KGJhdGNoLCBpZHlSLCBpZHlDLCBkMik7CiAgICAgICAgICAgICAgICBmbG9hdCB3VmFsdWUgPSBnZXRXKHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSB4VmFsdWUgKiB3VmFsdWU7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZsb2F0IHhWYWx1ZSA9IGdldER5KGJhdGNoLCBkMiwgaWR5UiwgaWR5Qyk7CiAgICAgICAgICAgICAgICBmbG9hdCB3VmFsdWUgPSBnZXRXKHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSB4VmFsdWUgKiB3VmFsdWU7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoZG90UHJvZCk7CiAgICAgIH0KICAgIGB9fSxDb252M0REZXJGaWx0ZXJQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJkeSJdLHRoaXMub3V0cHV0U2hhcGU9YWEuZmlsdGVyU2hhcGU7Y29uc3QgeGE9YWEuc3RyaWRlRGVwdGgsYmE9YWEuc3RyaWRlSGVpZ2h0LFNhPWFhLnN0cmlkZVdpZHRoLFRhPWFhLnBhZEluZm8uZnJvbnQsd2E9YWEucGFkSW5mby50b3AsRWE9YWEucGFkSW5mby5sZWZ0O3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzUgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IHdGID0gY29vcmRzLng7CiAgICAgICAgaW50IHdSID0gY29vcmRzLnk7CiAgICAgICAgaW50IHdDID0gY29vcmRzLno7CiAgICAgICAgaW50IGQxID0gY29vcmRzLnc7CiAgICAgICAgaW50IGQyID0gY29vcmRzLnU7CgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CgogICAgICAgIGZvciAoaW50IGIgPSAwOyBiIDwgJHthYS5iYXRjaFNpemV9OyBiKyspIHsKICAgICAgICAgIGZvciAoaW50IHlGID0gMDsgeUYgPCAke2FhLm91dERlcHRofTsgeUYrKykgewogICAgICAgICAgICBpbnQgeEYgPSB3RiArIHlGICogJHt4YX0gLSAke1RhfTsKCiAgICAgICAgICAgIGlmICh4RiA8IDAgfHwgeEYgPj0gJHthYS5pbkRlcHRofSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB5UiA9IDA7IHlSIDwgJHthYS5vdXRIZWlnaHR9OyB5UisrKSB7CiAgICAgICAgICAgICAgaW50IHhSID0gd1IgKyB5UiAqICR7YmF9IC0gJHt3YX07CgogICAgICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gJHthYS5pbkhlaWdodH0pIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgZm9yIChpbnQgeUMgPSAwOyB5QyA8ICR7YWEub3V0V2lkdGh9OyB5QysrKSB7CiAgICAgICAgICAgICAgICBpbnQgeEMgPSB3QyArIHlDICogJHtTYX0gLSAke0VhfTsKCiAgICAgICAgICAgICAgICBpZiAoeEMgPCAwIHx8IHhDID49ICR7YWEuaW5XaWR0aH0pIHsKICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZmxvYXQgZHlWYWx1ZSA9IGdldER5KGIsIHlGLCB5UiwgeUMsIGQyKTsKICAgICAgICAgICAgICAgIGZsb2F0IHhWYWx1ZSA9IGdldFgoYiwgeEYsIHhSLCB4QywgZDEpOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSAoeFZhbHVlICogZHlWYWx1ZSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19LENvbnYzRERlcklucHV0UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSIsIlciXSx0aGlzLm91dHB1dFNoYXBlPWFhLmluU2hhcGU7Y29uc3QgeGE9YWEuZmlsdGVyRGVwdGgsYmE9YWEuZmlsdGVySGVpZ2h0LFNhPWFhLmZpbHRlcldpZHRoLFRhPWFhLnN0cmlkZURlcHRoLHdhPWFhLnN0cmlkZUhlaWdodCxFYT1hYS5zdHJpZGVXaWR0aCxrYT14YS0xLWFhLnBhZEluZm8uZnJvbnQsQWE9YmEtMS1hYS5wYWRJbmZvLnRvcCxGYT1TYS0xLWFhLnBhZEluZm8ubGVmdDt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzMgcGFkcyA9IGl2ZWMzKCR7a2F9LCAke0FhfSwgJHtGYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM1IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgIGludCBkMSA9IGNvb3Jkcy51OwoKCiAgICAgICAgaXZlYzMgZHlDb3JuZXIgPSBpdmVjMyhjb29yZHMueSwgY29vcmRzLnosIGNvb3Jkcy53KSAtIHBhZHM7CiAgICAgICAgaW50IGR5RkNvcm5lciA9IGR5Q29ybmVyLng7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5Q29ybmVyLnk7CiAgICAgICAgaW50IGR5Q0Nvcm5lciA9IGR5Q29ybmVyLno7CgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd0YgPSAwOyB3RiA8ICR7eGF9OyB3RisrKSB7CiAgICAgICAgICBmbG9hdCBkeUYgPSBmbG9hdChkeUZDb3JuZXIgKyB3RikgLyAke1RhfS4wOwoKICAgICAgICAgIGlmIChkeUYgPCAwLjAgfHwgZHlGID49ICR7YWEub3V0RGVwdGh9LjAgfHwgZnJhY3QoZHlGKSA+IDAuMCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBpZHlGID0gaW50KGR5Rik7CgogICAgICAgICAgaW50IHdGUGVybSA9ICR7eGF9IC0gMSAtIHdGOwoKICAgICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke2JhfTsgd1IrKykgewogICAgICAgICAgICBmbG9hdCBkeVIgPSBmbG9hdChkeVJDb3JuZXIgKyB3UikgLyAke3dhfS4wOwoKICAgICAgICAgICAgaWYgKGR5UiA8IDAuMCB8fCBkeVIgPj0gJHthYS5vdXRIZWlnaHR9LjAgfHwKICAgICAgICAgICAgICBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKCiAgICAgICAgICAgIGludCB3UlBlcm0gPSAke2JhfSAtIDEgLSB3UjsKCiAgICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke1NhfTsgd0MrKykgewogICAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7RWF9LjA7CgogICAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgICAgZnJhY3QoZHlDKSA+IDAuMCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICAgIGludCB3Q1Blcm0gPSAke1NhfSAtIDEgLSB3QzsKCiAgICAgICAgICAgICAgZm9yIChpbnQgZDIgPSAwOyBkMiA8ICR7YWEub3V0Q2hhbm5lbHN9OyBkMisrKSB7CiAgICAgICAgICAgICAgICBmbG9hdCB4VmFsdWUgPSBnZXREeShiYXRjaCwgaWR5RiwgaWR5UiwgaWR5QywgZDIpOwogICAgICAgICAgICAgICAgZmxvYXQgd1ZhbHVlID0gZ2V0Vyh3RlBlcm0sIHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSB4VmFsdWUgKiB3VmFsdWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYyREJhY2twcm9wRmlsdGVyJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxkeTpUYX09YWEse3N0cmlkZXM6d2EscGFkOkVhLGRhdGFGb3JtYXQ6a2EsZGltUm91bmRpbmdNb2RlOkFhLGZpbHRlclNoYXBlOkZhfT1iYSxMYT1jb252ZXJ0Q29udjJERGF0YUZvcm1hdCQxKGthKSxlbD1jb21wdXRlQ29udjJESW5mbyQxKFNhLnNoYXBlLEZhLHdhLDEsRWEsQWEsITEsTGEpLHRsPW5ldyBDb252MkREZXJGaWx0ZXJQcm9ncmFtJDEoZWwpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0odGwsW1NhLFRhXSwiZmxvYXQzMiIpfWNvbnN0IGNvbnYyREJhY2twcm9wRmlsdGVyQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q29udjJEQmFja3Byb3BGaWx0ZXIkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29udjJEQmFja3Byb3BGaWx0ZXIkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IENvbnYyRERlcklucHV0UGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSIsIlciXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToic3RyaWRlcyIsdHlwZToidmVjMiJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLmluU2hhcGUsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXMkMSh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCk7Y29uc3QgeGE9YWEuZmlsdGVySGVpZ2h0LGJhPWFhLmZpbHRlcldpZHRoLFNhPXhhLTEtYWEucGFkSW5mby50b3AsVGE9YmEtMS1hYS5wYWRJbmZvLmxlZnQ7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke1NhfSwgJHtUYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZDEgPSBjb29yZHNbM107CgogICAgICAgIGl2ZWMyIGR5Q29ybmVyID0gaXZlYzIoY29vcmRzWzFdLCBjb29yZHNbMl0pIC0gcGFkczsKICAgICAgICBpbnQgZHlSQ29ybmVyID0gZHlDb3JuZXIueDsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlDb3JuZXIueTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHt4YX07IHdSKyspIHsKICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvIHN0cmlkZXNbMF07CiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKICAgICAgICAgIGludCB3UlBlcm0gPSAke3hhfSAtIDEgLSB3UjsKCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtiYX07IHdDKyspIHsKICAgICAgICAgICAgaW50IHdDUGVybSA9ICR7YmF9IC0gMSAtIHdDOwoKICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gc3RyaWRlc1sxXTsKICAgICAgICAgICAgYm9vbCBpZHlDVmFsID0gKGR5QyA+PSAwLjApICYmIChkeUMgPCAke2FhLm91dFdpZHRofS4wKQogICAgICAgICAgICAgICYmIChmcmFjdChkeUMpID09IDAuMCk7CiAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICBmbG9hdCBkeUMyID0gZmxvYXQoZHlDQ29ybmVyICsgd0MgKyAxKSAvIHN0cmlkZXNbMV07CiAgICAgICAgICAgIGJvb2wgaWR5Q1ZhbDIgPSAoZHlDMiA+PSAwLjApICYmIChkeUMyIDwgJHthYS5vdXRXaWR0aH0uMCkKICAgICAgICAgICAgICAmJiAoZnJhY3QoZHlDMikgPT0gMC4wKTsKICAgICAgICAgICAgaW50IGlkeUMyID0gaW50KGR5QzIpOwoKICAgICAgICAgICAgaWYgKGlkeUNWYWwgJiYgaWR5Q1ZhbDIpIHsKICAgICAgICAgICAgICBmb3IgKGludCBkMiA9IDA7IGQyIDwgJHthYS5vdXRDaGFubmVsc307IGQyICs9IDIpIHsKICAgICAgICAgICAgICAgIHZlYzQgd1ZhbHVlID0gZ2V0Vyh3UlBlcm0sIHdDUGVybSwgZDEsIGQyKTsKICAgICAgICAgICAgICAgIHZlYzQgZHlTYW1wbGUgPSBnZXREeShiYXRjaCwgaWR5UiwgaWR5QywgZDIpOwogICAgICAgICAgICAgICAgdmVjNCBkeVNhbXBsZTIgPSAoaWR5QyAvIDIgPT0gaWR5QzIgLyAyKSA/CiAgICAgICAgICAgICAgICAgIGR5U2FtcGxlIDogZ2V0RHkoYmF0Y2gsIGlkeVIsIGlkeUMyLCBkMik7CgogICAgICAgICAgICAgICAgdmVjMiBkeVZhbHVlID0gbW9kKGZsb2F0KGlkeUMpLCAyLikgPT0gMC4gPwogICAgICAgICAgICAgICAgICBkeVNhbXBsZS54eSA6IGR5U2FtcGxlLnp3OwogICAgICAgICAgICAgICAgcmVzdWx0Lnh5ICs9IHZlYzIoZG90KGR5VmFsdWUsIHdWYWx1ZS54eSksCiAgICAgICAgICAgICAgICAgIGRvdChkeVZhbHVlLCB3VmFsdWUuencpKTsKCiAgICAgICAgICAgICAgICBkeVZhbHVlID0gbW9kKGZsb2F0KGlkeUMyKSwgMi4pID09IDAuID8KICAgICAgICAgICAgICAgICAgZHlTYW1wbGUyLnh5IDogZHlTYW1wbGUyLnp3OwogICAgICAgICAgICAgICAgcmVzdWx0Lnp3ICs9IHZlYzIoZG90KGR5VmFsdWUsIHdWYWx1ZS54eSksCiAgICAgICAgICAgICAgICAgIGRvdChkeVZhbHVlLCB3VmFsdWUuencpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaWR5Q1ZhbCkgewogICAgICAgICAgICAgIGZvciAoaW50IGQyID0gMDsgZDIgPCAke2FhLm91dENoYW5uZWxzfTsgZDIgKz0gMikgewogICAgICAgICAgICAgICAgdmVjNCB3VmFsdWUgPSBnZXRXKHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgdmVjNCBkeVNhbXBsZSA9IGdldER5KGJhdGNoLCBpZHlSLCBpZHlDLCBkMik7CiAgICAgICAgICAgICAgICB2ZWMyIGR5VmFsdWUgPSBtb2QoZmxvYXQoaWR5QyksIDIuKSA9PSAwLiA/CiAgICAgICAgICAgICAgICAgIGR5U2FtcGxlLnh5IDogZHlTYW1wbGUuenc7CiAgICAgICAgICAgICAgICByZXN1bHQueHkgKz0gdmVjMihkb3QoZHlWYWx1ZSwgd1ZhbHVlLnh5KSwKICAgICAgICAgICAgICAgICAgZG90KGR5VmFsdWUsIHdWYWx1ZS56dykpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChpZHlDVmFsMikgewogICAgICAgICAgICAgIGZvciAoaW50IGQyID0gMDsgZDIgPCAke2FhLm91dENoYW5uZWxzfTsgZDIgKz0gMikgewogICAgICAgICAgICAgICAgdmVjNCB3VmFsdWUgPSBnZXRXKHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgdmVjNCBkeVNhbXBsZSA9IGdldER5KGJhdGNoLCBpZHlSLCBpZHlDMiwgZDIpOwogICAgICAgICAgICAgICAgdmVjMiBkeVZhbHVlID0gbW9kKGZsb2F0KGlkeUMyKSwgMi4pID09IDAuID8KICAgICAgICAgICAgICAgICAgZHlTYW1wbGUueHkgOiBkeVNhbXBsZS56dzsKICAgICAgICAgICAgICAgIHJlc3VsdC56dyArPSB2ZWMyKGRvdChkeVZhbHVlLCB3VmFsdWUueHkpLAogICAgICAgICAgICAgICAgICBkb3QoZHlWYWx1ZSwgd1ZhbHVlLnp3KSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjJEQmFja3Byb3BJbnB1dCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2R5OlNhLGZpbHRlcjpUYX09YWEse2lucHV0U2hhcGU6d2Esc3RyaWRlczpFYSxwYWQ6a2EsZGF0YUZvcm1hdDpBYSxkaW1Sb3VuZGluZ01vZGU6RmF9PWJhLExhPWNvbnZlcnRDb252MkREYXRhRm9ybWF0JDEoQWEpLGVsPWNvbXB1dGVDb252MkRJbmZvJDEod2EsVGEuc2hhcGUsRWEsMSxrYSxGYSwhMSxMYSk7aWYoZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0NPTlYyRFRSQU5TUE9TRSIpJiZMYT09PSJjaGFubmVsc0xhc3QiKXtjb25zdCB0bD1bW2VsLnN0cmlkZUhlaWdodCxlbC5zdHJpZGVXaWR0aF1dLG5sPW5ldyBDb252MkREZXJJbnB1dFBhY2tlZFByb2dyYW0kMShlbCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShubCxbU2EsVGFdLCJmbG9hdDMyIix0bCl9ZWxzZXtjb25zdCB0bD1uZXcgQ29udjJERGVySW5wdXRQcm9ncmFtJDEoZWwpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0odGwsW1NhLFRhXSwiZmxvYXQzMiIpfX1jb25zdCBjb252MkRCYWNrcHJvcElucHV0Q29uZmlnJDE9e2tlcm5lbE5hbWU6Q29udjJEQmFja3Byb3BJbnB1dCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpjb252MkRCYWNrcHJvcElucHV0JDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYzRCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGlsYXRpb25zOmthfT1iYSxBYT1jb21wdXRlQ29udjNESW5mbyQxKFNhLnNoYXBlLFRhLnNoYXBlLHdhLGthLEVhKSxGYT1uZXcgQ29udjNEUHJvZ3JhbSQxKEFhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEZhLFtTYSxUYV0sImZsb2F0MzIiKX1jb25zdCBjb252M0RDb25maWckMT17a2VybmVsTmFtZTpDb252M0QkMixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29udjNEJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYzREJhY2twcm9wRmlsdGVyVjIkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZmlsdGVyU2hhcGU6a2F9PWJhLEFhPWNvbXB1dGVDb252M0RJbmZvJDEoU2Euc2hhcGUsa2Esd2EsMSxFYSksRmE9bmV3IENvbnYzRERlckZpbHRlclByb2dyYW0kMShBYSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShGYSxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgY29udjNEQmFja3Byb3BGaWx0ZXJWMkNvbmZpZyQxPXtrZXJuZWxOYW1lOkNvbnYzREJhY2twcm9wRmlsdGVyVjIkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29udjNEQmFja3Byb3BGaWx0ZXJWMiQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252M0RCYWNrcHJvcElucHV0JDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsZmlsdGVyOlRhfT1hYSx7cGFkOndhLHN0cmlkZXM6RWEsaW5wdXRTaGFwZTprYX09YmEsQWE9Y29tcHV0ZUNvbnYzREluZm8kMShrYSxUYS5zaGFwZSxFYSwxLHdhKSxGYT1uZXcgQ29udjNERGVySW5wdXRQcm9ncmFtJDEoQWEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRmEsW1NhLFRhXSwiZmxvYXQzMiIpfWNvbnN0IGNvbnYzREJhY2twcm9wSW5wdXRDb25maWckMT17a2VybmVsTmFtZTpDb252M0RCYWNrcHJvcElucHV0VjIkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29udjNEQmFja3Byb3BJbnB1dCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDT1MkMT1DSEVDS19OQU5fU05JUFBFVF9VTkFSWSQxK2AKICByZXR1cm4gY29zKHgpOwpgLENPU19QQUNLRUQkMT1gCiAgdmVjNCByZXN1bHQgPSBjb3MoeCk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKICAke0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCQxfQogIHJldHVybiByZXN1bHQ7CmAsY29zJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpDT1MkMSxwYWNrZWRPcFNuaXBwZXQ6Q09TX1BBQ0tFRCQxfSksY29zQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q29zJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvcyQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDT1NIJDE9YAogIGZsb2F0IGUyeCA9IGV4cCgteCk7CiAgcmV0dXJuIChlMnggKyAxLjAgLyBlMngpIC8gMi4wOwpgLGNvc2gkMT11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkNPU0gkMX0pLGNvc2hDb25maWckMT17a2VybmVsTmFtZTpDb3NoJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvc2gkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IENyb3BBbmRSZXNpemVQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkltYWdlIiwiQm94ZXMiLCJCb3hJbmQiXSx0aGlzLm91dHB1dFNoYXBlPVtdO2NvbnN0W3dhLEVhLGthLEFhXT1hYSxbRmFdPXhhLFtMYSxlbF09YmE7dGhpcy5vdXRwdXRTaGFwZT1bRmEsTGEsZWwsQWFdO2NvbnN0IHRsPVNhPT09ImJpbGluZWFyIj8xOjAsW25sLHNsXT1bYCR7RWEtMX0uMGAsYCR7a2EtMX0uMGBdLFtybCxvbCxhbF09TGE+MT9bYCR7KEVhLTEpLyhMYS0xKX1gLCIoeTIteTEpICogaGVpZ2h0X3JhdGlvIixgeTEqJHtubH0gKyBmbG9hdCh5KSooaGVpZ2h0X3NjYWxlKWBdOlsiMC4wIiwiMC4wIixgMC41ICogKHkxK3kyKSAqICR7bmx9YF0sW2xsLGlsLGNsXT1lbD4xP1tgJHsoa2EtMSkvKGVsLTEpfWAsIih4Mi14MSkgKiB3aWR0aF9yYXRpbyIsYHgxKiR7c2x9ICsgZmxvYXQoeCkqKHdpZHRoX3NjYWxlKWBdOlsiMC4wIiwiMC4wIixgMC41ICogKHgxK3gyKSAqICR7c2x9YF07dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGZsb2F0IGhlaWdodF9yYXRpbyA9IGZsb2F0KCR7cmx9KTsKICAgICAgY29uc3QgZmxvYXQgd2lkdGhfcmF0aW8gPSBmbG9hdCgke2xsfSk7CiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgeSA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgeCA9IGNvb3Jkc1syXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKCiAgICAgICAgLy8gZ2V0IGJveCB2YWxzCiAgICAgICAgZmxvYXQgeTEgPSBnZXRCb3hlcyhiLDApOwogICAgICAgIGZsb2F0IHgxID0gZ2V0Qm94ZXMoYiwxKTsKICAgICAgICBmbG9hdCB5MiA9IGdldEJveGVzKGIsMik7CiAgICAgICAgZmxvYXQgeDIgPSBnZXRCb3hlcyhiLDMpOwoKICAgICAgICAvLyBnZXQgaW1hZ2UgaW4gYmF0Y2ggaW5kZXgKICAgICAgICBpbnQgYkluZCA9IHJvdW5kKGdldEJveEluZChiKSk7CiAgICAgICAgaWYoYkluZCA8IDAgfHwgYkluZCA+PSAke3dhfSkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZmxvYXQgaGVpZ2h0X3NjYWxlID0gJHtvbH07CiAgICAgICAgZmxvYXQgd2lkdGhfc2NhbGUgPSAke2lsfTsKCiAgICAgICAgZmxvYXQgaW5feSA9ICR7YWx9OwogICAgICAgIGlmKCBpbl95IDwgMC4wIHx8IGluX3kgPiAke25sfSApIHsKICAgICAgICAgIHNldE91dHB1dChmbG9hdCgke1RhfSkpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBmbG9hdCBpbl94ID0gJHtjbH07CiAgICAgICAgaWYoIGluX3ggPCAwLjAgfHwgaW5feCA+ICR7c2x9ICkgewogICAgICAgICAgc2V0T3V0cHV0KGZsb2F0KCR7VGF9KSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB2ZWMyIHNvdXJjZUZyYWNJbmRleENSID0gdmVjMihpbl94LGluX3kpOwogICAgICAgIGlmKCR7dGx9ID09IDEpIHsKICAgICAgICAgIC8vIENvbXB1dGUgdGhlIGZvdXIgaW50ZWdlciBpbmRpY2VzLgogICAgICAgICAgaXZlYzIgc291cmNlRmxvb3JDUiA9IGl2ZWMyKHNvdXJjZUZyYWNJbmRleENSKTsKICAgICAgICAgIGl2ZWMyIHNvdXJjZUNlaWxDUiA9IGl2ZWMyKGNlaWwoc291cmNlRnJhY0luZGV4Q1IpKTsKCiAgICAgICAgICBmbG9hdCB0b3BMZWZ0ID0gZ2V0SW1hZ2UoYiwgc291cmNlRmxvb3JDUi55LCBzb3VyY2VGbG9vckNSLngsIGQpOwogICAgICAgICAgZmxvYXQgYm90dG9tTGVmdCA9IGdldEltYWdlKGIsIHNvdXJjZUNlaWxDUi55LCBzb3VyY2VGbG9vckNSLngsIGQpOwogICAgICAgICAgZmxvYXQgdG9wUmlnaHQgPSBnZXRJbWFnZShiLCBzb3VyY2VGbG9vckNSLnksIHNvdXJjZUNlaWxDUi54LCBkKTsKICAgICAgICAgIGZsb2F0IGJvdHRvbVJpZ2h0ID0gZ2V0SW1hZ2UoYiwgc291cmNlQ2VpbENSLnksIHNvdXJjZUNlaWxDUi54LCBkKTsKCiAgICAgICAgICB2ZWMyIGZyYWNDUiA9IHNvdXJjZUZyYWNJbmRleENSIC0gdmVjMihzb3VyY2VGbG9vckNSKTsKCiAgICAgICAgICBmbG9hdCB0b3AgPSB0b3BMZWZ0ICsgKHRvcFJpZ2h0IC0gdG9wTGVmdCkgKiBmcmFjQ1IueDsKICAgICAgICAgIGZsb2F0IGJvdHRvbSA9IGJvdHRvbUxlZnQgKyAoYm90dG9tUmlnaHQgLSBib3R0b21MZWZ0KSAqIGZyYWNDUi54OwogICAgICAgICAgZmxvYXQgbmV3VmFsdWUgPSB0b3AgKyAoYm90dG9tIC0gdG9wKSAqIGZyYWNDUi55OwogICAgICAgICAgc2V0T3V0cHV0KG5ld1ZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gQ29tcHV0ZSB0aGUgY29vcmRpbmF0b3JzIG9mIG5lYXJlc3QgbmVpZ2hib3IgcG9pbnQuCiAgICAgICAgICBpdmVjMiBzb3VyY2VOZWFyZXN0Q1IgPSBpdmVjMihmbG9vcigKICAgICAgICAgICAgc291cmNlRnJhY0luZGV4Q1IgKyB2ZWMyKDAuNSwwLjUpKSk7CiAgICAgICAgICBmbG9hdCBuZXdWYWx1ZSA9IGdldEltYWdlKGIsIHNvdXJjZU5lYXJlc3RDUi55LCBzb3VyY2VOZWFyZXN0Q1IueCwgZCk7CiAgICAgICAgICBzZXRPdXRwdXQobmV3VmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGNyb3BBbmRSZXNpemUkMT1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2U6U2EsYm94ZXM6VGEsYm94SW5kOndhfT1hYSx7Y3JvcFNpemU6RWEsbWV0aG9kOmthLGV4dHJhcG9sYXRpb25WYWx1ZTpBYX09YmEsRmE9bmV3IENyb3BBbmRSZXNpemVQcm9ncmFtJDEoU2Euc2hhcGUsVGEuc2hhcGUsRWEsa2EsQWEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRmEsW1NhLFRhLHdhXSwiZmxvYXQzMiIpfSxjcm9wQW5kUmVzaXplQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q3JvcEFuZFJlc2l6ZSQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpjcm9wQW5kUmVzaXplJDF9O3ZhciBDdW1PcFR5cGUkMTsoZnVuY3Rpb24oaGEpe2hhLlByb2Q9IioiLGhhLlN1bT0iKyJ9KShDdW1PcFR5cGUkMXx8KEN1bU9wVHlwZSQxPXt9KSk7bGV0IEN1bVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy5vcD1hYSx0aGlzLm91dHB1dFNoYXBlPXhhLHRoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToiaW5kZXgiLHR5cGU6ImZsb2F0In1dO2NvbnN0IFRhPXRoaXMub3V0cHV0U2hhcGUubGVuZ3RoLHdhPXRoaXMub3A9PT1DdW1PcFR5cGUkMS5Qcm9kPyIxLjAiOiIwLjAiLEVhPWJhP3dhOmBnZXRYKCR7Z2V0Q29vcmRzJDIoVGEsImNvb3JkcyIsdGhpcy5vcCl9KWAsa2E9dGhpcy5vdXRwdXRTaGFwZVt0aGlzLm91dHB1dFNoYXBlLmxlbmd0aC0xXTtsZXQgQWE9IiIsRmE9IiI7YmE/KEFhPVNhP2BlbmQgIT0gJHtrYS0xfWA6ImVuZCAhPSAwIixGYT1TYT8iZW5kICsgMSI6ImVuZCAtIDEiKTooQWE9U2E/YGVuZCArIHBvdzIgPCAke2thfWA6ImVuZCA+PSBwb3cyIixGYT1TYT8iZW5kICsgcG93MiI6ImVuZCAtIHBvdzIiKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7Z2V0Q29vcmRzRGF0YVR5cGUkMShUYSl9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBlbmQgPSAke2dldEZpbmFsQ29vcmQkMShUYSwiY29vcmRzIix0aGlzLm9wKX07CiAgICAgICAgZmxvYXQgdmFsID0gJHtFYX07CiAgICAgICAgaW50IHBvdzIgPSBpbnQocG93KDIuMCwgaW5kZXgpKTsKICAgICAgICBpZiAoJHtBYX0pIHsKICAgICAgICAgIGludCBpZHggPSAke0ZhfTsKICAgICAgICAgICR7Z2V0RmluYWxDb29yZCQxKFRhLCJjb29yZHMiLHRoaXMub3ApfSA9IGlkeDsKICAgICAgICAgIHZhbCAke3RoaXMub3B9PSBnZXRYKCR7Z2V0Q29vcmRzJDIoVGEsImNvb3JkcyIsdGhpcy5vcCl9KTsKICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KHZhbCk7CiAgICAgIH0KICAgIGB9fTtmdW5jdGlvbiBnZXRDb29yZHMkMihoYSxhYSx4YSl7aWYoaGE9PT0xKXJldHVybmAke2FhfWA7aWYoaGE9PT0yKXJldHVybmAke2FhfS54LCAke2FhfS55YDtpZihoYT09PTMpcmV0dXJuYCR7YWF9LngsICR7YWF9LnksICR7YWF9LnpgO2lmKGhhPT09NClyZXR1cm5gJHthYX0ueCwgJHthYX0ueSwgJHthYX0ueiwgJHthYX0ud2A7dGhyb3cgbmV3IEVycm9yKGBDdW11bGF0aXZlICR7eGF9IGZvciByYW5rICR7aGF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCl9ZnVuY3Rpb24gZ2V0RmluYWxDb29yZCQxKGhhLGFhLHhhKXtpZihoYT09PTEpcmV0dXJuYCR7YWF9YDtpZihoYT09PTIpcmV0dXJuYCR7YWF9LnlgO2lmKGhhPT09MylyZXR1cm5gJHthYX0uemA7aWYoaGE9PT00KXJldHVybmAke2FhfS53YDt0aHJvdyBuZXcgRXJyb3IoYEN1bXVsYXRpdmUgJHt4YX0gZm9yIHJhbmsgJHtoYX0gaXMgbm90IHlldCBzdXBwb3J0ZWRgKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjdW1JbXBsJDEoaGEsYWEseGEsYmEsU2EsVGEpe2NvbnN0IHdhPWFhLnNoYXBlLmxlbmd0aCxFYT1nZXRBeGVzUGVybXV0YXRpb24kMShbYmFdLHdhKTtsZXQga2E9YWE7RWEhPW51bGwmJihrYT10cmFuc3Bvc2UkMSh7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkVhfX0pKTtjb25zdCBBYT1nZXRJbm5lck1vc3RBeGVzJDEoMSx3YSlbMF07aWYoQWEhPT13YS0xKXRocm93IG5ldyBFcnJvcihgV2ViR0wgY3VtcHJvZCBzaGFkZXIgZXhwZWN0cyBhbiBpbm5lci1tb3N0IGF4aXM9JHthYS5zaGFwZS5sZW5ndGgtMX0gYnV0IGdvdCBheGlzPSR7YmF9YCk7Y29uc3QgRmE9a2Euc2hhcGVbQWFdO2xldCBMYT1pZGVudGl0eSQxKHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6eGF9KTtmb3IobGV0IGVsPTA7ZWw8PU1hdGguY2VpbChNYXRoLmxvZzIoRmEpKS0xO2VsKyspe2NvbnN0IHRsPW5ldyBDdW1Qcm9ncmFtJDEoaGEsa2Euc2hhcGUsITEsVGEpLG5sPVtbZWxdXSxzbD1MYTtMYT14YS5ydW5XZWJHTFByb2dyYW0odGwsW0xhXSxMYS5kdHlwZSxubCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpfWlmKFNhKXtjb25zdCBlbD1uZXcgQ3VtUHJvZ3JhbSQxKGhhLGthLnNoYXBlLFNhLFRhKSx0bD1MYTtMYT14YS5ydW5XZWJHTFByb2dyYW0oZWwsW0xhXSxMYS5kdHlwZSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpfWlmKEVhIT1udWxsKXtjb25zdCBlbD1nZXRVbmRvQXhlc1Blcm11dGF0aW9uJDEoRWEpLHRsPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06ZWx9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKExhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhrYSksdGx9cmV0dXJuIExhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGN1bXByb2QkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxleGNsdXNpdmU6d2EscmV2ZXJzZTpFYX09YmE7cmV0dXJuIGN1bUltcGwkMShDdW1PcFR5cGUkMS5Qcm9kLFNhLHhhLFRhLHdhLEVhKX1jb25zdCBjdW1wcm9kQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q3VtcHJvZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpjdW1wcm9kJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGN1bXN1bSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGV4Y2x1c2l2ZTp3YSxyZXZlcnNlOkVhfT1iYTtyZXR1cm4gY3VtSW1wbCQxKEN1bU9wVHlwZSQxLlN1bSxTYSx4YSxUYSx3YSxFYSl9Y29uc3QgY3Vtc3VtQ29uZmlnJDE9e2tlcm5lbE5hbWU6Q3Vtc3VtJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmN1bXN1bSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZW5zZUJpbmNvdW50JDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSx3ZWlnaHRzOlRhfT1hYSx7c2l6ZTp3YSxiaW5hcnlPdXRwdXQ6RWF9PWJhO2lmKFNhLnNoYXBlLmxlbmd0aD09PTEpe2NvbnN0IGthPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksQWE9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxGYT1iaW5jb3VudEltcGxDUFUkMShrYSxBYSxUYS5kdHlwZSxUYS5zaGFwZSx3YSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFt3YV0sVGEuZHR5cGUsRmEpfWVsc2UgaWYoU2Euc2hhcGUubGVuZ3RoPT09Mil7Y29uc3Qga2E9eGEuYnVmZmVyU3luYyhTYSksQWE9eGEuYnVmZmVyU3luYyhUYSksRmE9YmluY291bnRSZWR1Y2VJbXBsQ1BVJDEoa2EsQWEsd2EsRWEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhGYS5zaGFwZSxUYS5kdHlwZSxGYS52YWx1ZXMpfXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gZGVuc2VCaW5jb3VudDogaW5wdXQgbXVzdCBiZSBhdCBtb3N0IHJhbmsgMiwgYnV0IGdvdCByYW5rJHtTYS5zaGFwZS5sZW5ndGh9LmApfWNvbnN0IGRlbnNlQmluY291bnRDb25maWckMT17a2VybmVsTmFtZTpEZW5zZUJpbmNvdW50JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRlbnNlQmluY291bnQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IERlcHRoVG9TcGFjZVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMub3V0cHV0U2hhcGU9W10sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmJsb2NrU2l6ZT14YSx0aGlzLmRhdGFGb3JtYXQ9YmEsdGhpcy51c2VyQ29kZT1gCiAgICB2b2lkIG1haW4oKSB7CiAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgaW50IGggPSAke3RoaXMuZ2V0SGVpZ2h0Q29vcmRTdHJpbmcoKX07CiAgICAgIGludCB3ID0gJHt0aGlzLmdldFdpZHRoQ29vcmRTdHJpbmcoKX07CiAgICAgIGludCBkID0gJHt0aGlzLmdldERlcHRoQ29vcmRTdHJpbmcoKX07CgogICAgICBpbnQgaW5faCA9IGggLyAke3hhfTsKICAgICAgaW50IG9mZnNldF9oID0gaW1vZChoLCAke3hhfSk7CiAgICAgIGludCBpbl93ID0gdyAvICR7eGF9OwogICAgICBpbnQgb2Zmc2V0X3cgPSBpbW9kKHcsICR7eGF9KTsKICAgICAgaW50IG9mZnNldF9kID0gKG9mZnNldF9oICogJHt4YX0gKyBvZmZzZXRfdykgKgogICAgICAgICR7dGhpcy5nZXRPdXRwdXREZXB0aFNpemUoKX07CiAgICAgIGludCBpbl9kID0gZCArIG9mZnNldF9kOwoKICAgICAgZmxvYXQgcmVzdWx0ID0gJHt0aGlzLmdldElucHV0U2FtcGxpbmdTdHJpbmcoKX07CiAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgfQogIGB9Z2V0SGVpZ2h0Q29vcmRTdHJpbmcoKXtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09Ik5IV0MiPyJjb29yZHNbMV0iOiJjb29yZHNbMl0ifWdldFdpZHRoQ29vcmRTdHJpbmcoKXtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09Ik5IV0MiPyJjb29yZHNbMl0iOiJjb29yZHNbM10ifWdldERlcHRoQ29vcmRTdHJpbmcoKXtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09Ik5IV0MiPyJjb29yZHNbM10iOiJjb29yZHNbMV0ifWdldE91dHB1dERlcHRoU2l6ZSgpe3JldHVybiB0aGlzLmRhdGFGb3JtYXQ9PT0iTkhXQyI/dGhpcy5vdXRwdXRTaGFwZVszXTp0aGlzLm91dHB1dFNoYXBlWzFdfWdldElucHV0U2FtcGxpbmdTdHJpbmcoKXtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09Ik5IV0MiPyJnZXRYKGIsIGluX2gsIGluX3csIGluX2QpIjoiZ2V0WChiLCBpbl9kLCBpbl9oLCBpbl93KSJ9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZXB0aFRvU3BhY2UkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YmxvY2tTaXplOlRhLGRhdGFGb3JtYXQ6d2F9PWJhLEVhPVNhLnNoYXBlWzBdLGthPXdhPT09Ik5IV0MiP1NhLnNoYXBlWzFdOlNhLnNoYXBlWzJdLEFhPXdhPT09Ik5IV0MiP1NhLnNoYXBlWzJdOlNhLnNoYXBlWzNdLEZhPXdhPT09Ik5IV0MiP1NhLnNoYXBlWzNdOlNhLnNoYXBlWzFdLExhPWthKlRhLGVsPUFhKlRhLHRsPUZhLyhUYSpUYSksbmw9d2E9PT0iTkhXQyI/W0VhLExhLGVsLHRsXTpbRWEsdGwsTGEsZWxdLHNsPW5ldyBEZXB0aFRvU3BhY2VQcm9ncmFtJDEobmwsVGEsd2EpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oc2wsW1NhXSxTYS5kdHlwZSl9Y29uc3QgZGVwdGhUb1NwYWNlQ29uZmlnJDE9e2tlcm5lbE5hbWU6RGVwdGhUb1NwYWNlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRlcHRoVG9TcGFjZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRGVwdGh3aXNlQ29udjJEUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhPSExLGJhPW51bGwsU2E9ITEsVGE9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJXIl0sdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InBhZHMiLHR5cGU6Iml2ZWMyIn0se25hbWU6InN0cmlkZXMiLHR5cGU6Iml2ZWMyIn0se25hbWU6ImRpbGF0aW9ucyIsdHlwZToiaXZlYzIifSx7bmFtZToiaW5EaW1zIix0eXBlOiJpdmVjMiJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLm91dFNoYXBlLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zJDEodGhpcy5vdXRwdXRTaGFwZS5sZW5ndGgpO2NvbnN0IHdhPWFhLmZpbHRlckhlaWdodCxFYT1hYS5maWx0ZXJXaWR0aCxrYT1hYS5vdXRDaGFubmVscy9hYS5pbkNoYW5uZWxzO2xldCBBYT0iIixGYT0iIjtiYSYmKFNhP0FhPWBmbG9hdCBhY3RpdmF0aW9uKGZsb2F0IGEpIHsKICAgICAgICAgIGZsb2F0IGIgPSBnZXRQcmVsdUFjdGl2YXRpb25XZWlnaHRzQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6VGE/QWE9YGZsb2F0IGFjdGl2YXRpb24oZmxvYXQgYSkgewogICAgICAgICAgZmxvYXQgYiA9IGdldExlYWt5cmVsdUFscGhhQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6QWE9YAogICAgICAgICAgZmxvYXQgYWN0aXZhdGlvbihmbG9hdCB4KSB7CiAgICAgICAgICAgICR7YmF9CiAgICAgICAgICB9CiAgICAgICAgYCxGYT0icmVzdWx0ID0gYWN0aXZhdGlvbihyZXN1bHQpOyIpO2NvbnN0IExhPXhhPyJyZXN1bHQgKz0gZ2V0Qmlhc0F0T3V0Q29vcmRzKCk7IjoiIjt4YSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJpYXMiKSxTYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInByZWx1QWN0aXZhdGlvbldlaWdodHMiKSxUYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImxlYWt5cmVsdUFscGhhIiksdGhpcy51c2VyQ29kZT1gCiAgICAgICR7QWF9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaXZlYzIgeFJDQ29ybmVyID0gY29vcmRzLnl6ICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IGQyID0gY29vcmRzLnc7CiAgICAgICAgaW50IGQxID0gZDIgLyAke2thfTsKICAgICAgICBpbnQgcSA9IGQyIC0gZDEgKiAke2thfTsKCiAgICAgICAgaW50IHhSQ29ybmVyID0geFJDQ29ybmVyLng7CiAgICAgICAgaW50IHhDQ29ybmVyID0geFJDQ29ybmVyLnk7CgogICAgICAgIC8vIENvbnZvbHZlIHgoPywgPywgZDEpIHdpdGggdyg6LCA6LCBkMSwgcSkgdG8gZ2V0IHkoeVIsIHlDLCBkMikuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsIHZhbHVlcyBpbiB0aGF0IGF4aXMuCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKICAgICAgICAvLyBUTyBETyhkc21pbGtvdik6IEZsYXR0ZW4gdGhlIHR3byBmb3IgbG9vcHMgYW5kIHZlYzQgdGhlIG9wZXJhdGlvbnMuCiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7d2F9OyB3UisrKSB7CiAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSICogZGlsYXRpb25zWzBdOwoKICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gaW5EaW1zWzBdKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke0VhfTsgd0MrKykgewogICAgICAgICAgICBpbnQgeEMgPSB4Q0Nvcm5lciArIHdDICogZGlsYXRpb25zWzFdOwoKICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIHhSLCB4QywgZDEpOwogICAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0Vyh3Uiwgd0MsIGQxLCBxKTsKICAgICAgICAgICAgZG90UHJvZCArPSB4VmFsICogd1ZhbDsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZsb2F0IHJlc3VsdCA9IGRvdFByb2Q7CiAgICAgICAgJHtMYX0KICAgICAgICAke0ZhfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IERlcHRod2lzZUNvbnZQYWNrZWQyRFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YT0hMSxiYT1udWxsLFNhPSExLFRhPSExKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiVyJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJwYWRzIix0eXBlOiJpdmVjMiJ9LHtuYW1lOiJzdHJpZGVzIix0eXBlOiJpdmVjMiJ9LHtuYW1lOiJkaWxhdGlvbnMiLHR5cGU6Iml2ZWMyIn0se25hbWU6ImluRGltcyIsdHlwZToiaXZlYzIifV0sdGhpcy5vdXRwdXRTaGFwZT1hYS5vdXRTaGFwZSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyQxKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdCB3YT1hYS5vdXRDaGFubmVscy9hYS5pbkNoYW5uZWxzLEVhPWFhLnBhZEluZm8ubGVmdCxrYT1hYS5zdHJpZGVXaWR0aCxBYT1hYS5kaWxhdGlvbldpZHRoLEZhPWFhLmZpbHRlckhlaWdodCxMYT1hYS5maWx0ZXJXaWR0aCxlbD1MYTtsZXQgdGw9YAogICAgICBpbnQgeFI7IGludCB4QzsgaW50IHhDT2Zmc2V0OwogICAgICB2ZWM0IHdUZXhlbDsgdmVjNCBwcmV2aW91czsgdmVjNCBmaW5hbDtgO2ZvcihsZXQgb2w9MDtvbDxMYTtvbCsrKXRsKz1gCiAgICAgICAgICB2ZWM0IHhUZXhlbEMke29sKjJ9OwogICAgICAgICAgaW50IHhUZXhlbEMke29sKjJ9UmVhZHk7CiAgICAgICAgICB2ZWM0IHhUZXhlbEMke29sKjIrMX07CiAgICAgICAgICBpbnQgeFRleGVsQyR7b2wqMisxfVJlYWR5OwogICAgICAgICAgdmVjNCB4QyR7b2x9O2A7dGwrPWAKICAgIGZvciAoaW50IHIgPSAwOyByIDwgJHtGYX07IHIrKykgewogICAgICBgO2ZvcihsZXQgb2w9MDtvbDxMYTtvbCsrKXRsKz1gCiAgICAgICAgICB4VGV4ZWxDJHtvbCoyfSA9IHZlYzQoMC4wKTsKICAgICAgICAgIHhUZXhlbEMke29sKjJ9UmVhZHkgPSAwOwogICAgICAgICAgeFRleGVsQyR7b2wqMisxfSA9IHZlYzQoMC4wKTsKICAgICAgICAgIHhUZXhlbEMke29sKjIrMX1SZWFkeSA9IDA7CiAgICAgICAgICB4QyR7b2x9ID0gdmVjNCgwLjApO2A7dGwrPWAKICAgICAgICB4UiA9IHhSQ29ybmVyICsgciAqIGRpbGF0aW9uc1swXTsKICAgICAgICBpZiAoeFIgPj0wICYmIHhSIDwgaW5EaW1zWzBdKSB7CiAgICAgIGA7Zm9yKGxldCBvbD0wO29sPChlbCsxKS8yO29sKyspe2NvbnN0IGFsPW9sKjI7aWYodGwrPWAKICAgICAgICAgIHhDID0geENDb3JuZXIgKyAke2FsKkFhfTsKICAgICAgICAgIGAsa2E9PT0xKXtpZihhbDxMYSYmKEVhJTI9PT0xPyh0bCs9YAogICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDE7CiAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbH1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbH0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGAsQWE9PT0xJiZhbD4wP3RsKz1gCiAgICAgICAgICAgICAgICB4QyR7YWx9ID0gdmVjNCh4VGV4ZWxDJHthbC0yfS56dywgeFRleGVsQyR7YWx9Lnh5KTsKICAgICAgICAgICAgICAgIGA6dGwrPWAKICAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDEgLSAyOwoKICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzLnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeEMke2FsfSA9IHZlYzQocHJldmlvdXMuencsIHhUZXhlbEMke2FsfS54eSk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgeEMke2FsfSA9IHZlYzQoMC4wLCAwLjAsIHhUZXhlbEMke2FsfS54eSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYCk6dGwrPWAKICAgICAgICAgICAgICAgIGlmICh4QyA+PSAwICYmIHhDIDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke2FsfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9ID0gZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSk7CiAgICAgICAgICAgICAgICAgIGlmICh4QyArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB4QyR7YWx9ID0geFRleGVsQyR7YWx9OwogICAgICAgICAgICAgICAgYCxhbCsxPExhKSl7Y29uc3QgbGw9RWElMj09PTA/bmVhcmVzdExhcmdlckV2ZW4kMShBYSk6QWE7QWElMj09PTAmJkVhJTI9PT0xfHxBYSUyIT09MCYmRWElMiE9PTE/KHRsKz1gCiAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyBpbW9kKHBhZHNbMV0sIDIpICsgJHtsbH07CgogICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsKzF9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBgLEFhPjE/dGwrPWAKICAgICAgICAgICAgICAgICAgICB4Q09mZnNldCAtPSAyOwogICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCA+PSAwICYmIHhDT2Zmc2V0IDwgaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CiAgICAgICAgICAgICAgICAgICAgIHhDJHthbCsxfSA9IHZlYzQocHJldmlvdXMuencsIHhUZXhlbEMke2FsKzF9Lnh5KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICB4QyR7YWwrMX0gPSB2ZWM0KDAuMCwgMC4wLCB4VGV4ZWxDJHthbCsxfS54eSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGA6dGwrPWAKICAgICAgICAgICAgICAgICAgICB4QyR7YWwrMX0gPSB2ZWM0KHhUZXhlbEMke2FsfS56dywgeFRleGVsQyR7YWwrMX0ueHkpOwogICAgICAgICAgICAgICAgICAgIGApOmxsPT09MT90bCs9YAogICAgICAgICAgICAgICAgICAgIHhDJHthbCsxfSA9IHhUZXhlbEMke2FsfTsKICAgICAgICAgICAgICAgICAgICBgOnRsKz1gCiAgICAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArICR7bGx9OwoKICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsKzF9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeEMke2FsKzF9ID0geFRleGVsQyR7YWwrMX07CiAgICAgICAgICAgICAgICAgICAgYH19ZWxzZSBhbDxMYSYmKEVhJTI9PT0xPyh0bCs9YAogICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDEgLSBzdHJpZGVzWzFdOwogICAgICAgICAgICAgICAgaWYoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbH1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgIC8vIHdlJ3JlIHJlYWRpbmcgZnJvbSByZWN5Y2xlZCB0ZXh0dXJlLgogICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbH1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYoeEMgKyAxID49IDAgJiYgeEMgKyAxIDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke2FsKzF9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4QyArIDEsIGQxKTsKICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgaWYgKHhDICsgMiA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB4QyR7YWx9ID0gdmVjNCh4VGV4ZWxDJHthbH0uencsIHhUZXhlbEMke2FsKzF9Lnp3KTsKICAgICAgICAgICAgICBgLGFsKzE8TGEmJih0bCs9YAogICAgICAgICAgICAgICAgICBmaW5hbCA9IHZlYzQoMC4wKTsKICAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDEgKyBzdHJpZGVzWzFdOwogICAgICAgICAgICAgICAgICBpZih4Q09mZnNldCA+PSAwICYmIHhDT2Zmc2V0IDwgaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgPSBnZXRYKGJhdGNoLCB4UiwgeENPZmZzZXQsIGQxKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB4QyR7YWwrMX0gPSB2ZWM0KHhUZXhlbEMke2FsKzF9Lnh5LCBmaW5hbC54eSk7CiAgICAgICAgICAgICAgICBgKSk6KHRsKz1gCiAgICAgICAgICAgICAgICBpZih4QyA+PSAwICYmIHhDIDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke2FsfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9ID0gZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSk7CiAgICAgICAgICAgICAgICAgIGlmICh4QyArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB4Q09mZnNldCA9IHhDICsgc3RyaWRlc1sxXTsKICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7YWwrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsKzF9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CiAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX0uencgPSB2ZWMyKDAuKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB4QyR7YWx9ID0gdmVjNCgKICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9Lnh5LCB4VGV4ZWxDJHthbCsxfS54eSk7CiAgICAgICAgICAgICAgYCxhbCsxPExhJiYodGwrPWAKICAgICAgICAgICAgICAgICAgeEMke2FsKzF9ID0gdmVjNCh4VGV4ZWxDJHthbH0uencsIHhUZXhlbEMke2FsKzF9Lnp3KTsKICAgICAgICAgICAgICAgIGApKSk7YWw8TGEmJih0bCs9YAogICAgICAgICAgICB3VGV4ZWwgPSBnZXRXKHIsICR7YWx9LCBkMSwgcSk7CiAgICAgICAgICAgIGRvdFByb2QgKz0geEMke2FsfSAqIHZlYzQod1RleGVsLnh6LCB3VGV4ZWwueHopOwogICAgICAgICAgYCxhbCsxPExhJiYodGwrPWAKICAgICAgICAgICAgICB3VGV4ZWwgPSBnZXRXKHIsICR7YWwrMX0sIGQxLCBxKTsKICAgICAgICAgICAgICBkb3RQcm9kICs9IHhDJHthbCsxfSAqIHZlYzQod1RleGVsLnh6LCB3VGV4ZWwueHopOwogICAgICAgICAgICBgKSl9dGwrPWAKICAgIH0KICBgLHRsKz1gCiAgICAgIH0KICAgIGA7bGV0IG5sPSIiLHNsPSIiO2JhJiYoU2E/bmw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IGEpIHsKICAgICAgICAgIHZlYzQgYiA9IGdldFByZWx1QWN0aXZhdGlvbldlaWdodHNBdE91dENvb3JkcygpOwogICAgICAgICAgJHtiYX0KICAgICAgICB9YDpUYT9ubD1gdmVjNCBhY3RpdmF0aW9uKHZlYzQgYSkgewogICAgICAgICAgdmVjNCBiID0gZ2V0TGVha3lyZWx1QWxwaGFBdE91dENvb3JkcygpOwogICAgICAgICAgJHtiYX0KICAgICAgICB9YDpubD1gdmVjNCBhY3RpdmF0aW9uKHZlYzQgeCkgewogICAgICAgICAgJHtiYX0KICAgICAgICB9YCxzbD0icmVzdWx0ID0gYWN0aXZhdGlvbihyZXN1bHQpOyIpO2NvbnN0IHJsPXhhPyJyZXN1bHQgKz0gZ2V0Qmlhc0F0T3V0Q29vcmRzKCk7IjoiIjt4YSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJpYXMiKSxTYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInByZWx1QWN0aXZhdGlvbldlaWdodHMiKSxUYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImxlYWt5cmVsdUFscGhhIiksdGhpcy51c2VyQ29kZT1gCiAgICAgICR7bmx9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaXZlYzIgeFJDQ29ybmVyID0gY29vcmRzLnl6ICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IGQyID0gY29vcmRzLnc7CiAgICAgICAgaW50IGQxID0gZDIgLyAke3dhfTsKICAgICAgICBpbnQgcSA9IGQyIC0gZDEgKiAke3dhfTsKICAgICAgICBpbnQgeFJDb3JuZXIgPSB4UkNDb3JuZXIueDsKICAgICAgICBpbnQgeENDb3JuZXIgPSB4UkNDb3JuZXIueTsKCiAgICAgICAgLy9pbnRpYWxpemUgZG90UHJvZCB3aXRoIGEgc21hbGwgZXBzaWxvbiBzZWVtcyB0byByZWR1Y2UgR1BVIGFjY3VyYWN5IGxvc3MuCiAgICAgICAgdmVjNCBkb3RQcm9kID0gdmVjNCgwLjAwMDAwMDAwMDAwMDAwMSk7CgogICAgICAgICR7dGx9CgogICAgICAgIHZlYzQgcmVzdWx0ID0gZG90UHJvZCAtIHZlYzQoMC4wMDAwMDAwMDAwMDAwMDEpOwogICAgICAgICR7cmx9CiAgICAgICAgJHtzbH0KICAgICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZE5hdGl2ZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGlsYXRpb25zOmthLGRpbVJvdW5kaW5nTW9kZTpBYX09YmE7bGV0IEZhPWthO0ZhPT1udWxsJiYoRmE9WzEsMV0pLGFzc2VydCQyKGVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZSQxKHdhLEZhKSwoKT0+YEVycm9yIGluIGRlcHRod2lzZUNvbnYyZDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt3YX0gYW5kIGRpbGF0aW9ucyAnJHtGYX0nYCk7Y29uc3QgTGE9Y29tcHV0ZUNvbnYyREluZm8kMShTYS5zaGFwZSxUYS5zaGFwZSx3YSxGYSxFYSxBYSwhMCk7bGV0IGVsO2VudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19ERVBUSFdJU0VDT05WIikmJkxhLnN0cmlkZVdpZHRoPD0yJiZMYS5vdXRDaGFubmVscy9MYS5pbkNoYW5uZWxzPT09MT9lbD1uZXcgRGVwdGh3aXNlQ29udlBhY2tlZDJEUHJvZ3JhbSQxKExhKTplbD1uZXcgRGVwdGh3aXNlQ29udjJEUHJvZ3JhbSQxKExhKTtjb25zdCB0bD1bW0xhLnBhZEluZm8udG9wLExhLnBhZEluZm8ubGVmdF0sW0xhLnN0cmlkZUhlaWdodCxMYS5zdHJpZGVXaWR0aF0sW0xhLmRpbGF0aW9uSGVpZ2h0LExhLmRpbGF0aW9uV2lkdGhdLFtMYS5pbkhlaWdodCxMYS5pbldpZHRoXV07cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShlbCxbU2EsVGFdLCJmbG9hdDMyIix0bCl9Y29uc3QgZGVwdGh3aXNlQ29udjJkTmF0aXZlQ29uZmlnJDE9e2tlcm5lbE5hbWU6RGVwdGh3aXNlQ29udjJkTmF0aXZlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRlcHRod2lzZUNvbnYyZE5hdGl2ZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRGVwdGh3aXNlQ29udjJERGVyRmlsdGVyUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiZHkiXSx0aGlzLm91dHB1dFNoYXBlPWFhLmZpbHRlclNoYXBlO2NvbnN0IHhhPWFhLnN0cmlkZUhlaWdodCxiYT1hYS5zdHJpZGVXaWR0aCxTYT1hYS5wYWRJbmZvLnRvcCxUYT1hYS5wYWRJbmZvLmxlZnQsd2E9YWEub3V0Q2hhbm5lbHMvYWEuaW5DaGFubmVsczt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCB3UiA9IGNvb3Jkcy54OwogICAgICAgIGludCB3QyA9IGNvb3Jkcy55OwogICAgICAgIGludCBkMSA9IGNvb3Jkcy56OwogICAgICAgIGludCBkbSA9IGNvb3Jkcy53OwogICAgICAgIGludCBkMiA9IGQxICogJHt3YX0gKyBkbTsKCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKCiAgICAgICAgLy8gVE8gRE86IFZlYzQgb3ZlciB0aGUgYmF0Y2ggc2l6ZQogICAgICAgIGZvciAoaW50IGIgPSAwOyBiIDwgJHthYS5iYXRjaFNpemV9OyBiKyspIHsKICAgICAgICAgIGZvciAoaW50IHlSID0gMDsgeVIgPCAke2FhLm91dEhlaWdodH07IHlSKyspIHsKICAgICAgICAgICAgaW50IHhSID0gd1IgKyB5UiAqICR7eGF9IC0gJHtTYX07CgogICAgICAgICAgICBpZiAoeFIgPCAwIHx8IHhSID49ICR7YWEuaW5IZWlnaHR9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaW50IHlDID0gMDsgeUMgPCAke2FhLm91dFdpZHRofTsgeUMrKykgewogICAgICAgICAgICAgIGludCB4QyA9IHdDICsgeUMgKiAke2JhfSAtICR7VGF9OwoKICAgICAgICAgICAgICBpZiAoeEMgPCAwIHx8IHhDID49ICR7YWEuaW5XaWR0aH0pIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgZmxvYXQgZHlWYWx1ZSA9IGdldER5KGIsIHlSLCB5QywgZDIpOwogICAgICAgICAgICAgIGZsb2F0IHhWYWx1ZSA9IGdldFgoYiwgeFIsIHhDLCBkMSk7CiAgICAgICAgICAgICAgZG90UHJvZCArPSAoeFZhbHVlICogZHlWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX0sRGVwdGh3aXNlQ29udjJERGVySW5wdXRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5IiwiVyJdLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZTtjb25zdCB4YT1hYS5maWx0ZXJIZWlnaHQsYmE9YWEuZmlsdGVyV2lkdGgsU2E9YWEuc3RyaWRlSGVpZ2h0LFRhPWFhLnN0cmlkZVdpZHRoLHdhPXhhLTEtYWEucGFkSW5mby50b3AsRWE9YmEtMS1hYS5wYWRJbmZvLmxlZnQsa2E9YWEub3V0Q2hhbm5lbHMvYWEuaW5DaGFubmVsczt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7d2F9LCAke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgIGludCBkMSA9IGNvb3Jkc1szXTsKICAgICAgICBpdmVjMiBkeUNvcm5lciA9IGNvb3Jkcy55eiAtIHBhZHM7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5Q29ybmVyLng7CiAgICAgICAgaW50IGR5Q0Nvcm5lciA9IGR5Q29ybmVyLnk7CgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CgogICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke3hhfTsgd1IrKykgewogICAgICAgICAgZmxvYXQgZHlSID0gZmxvYXQoZHlSQ29ybmVyICsgd1IpIC8gJHtTYX0uMDsKCiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKCiAgICAgICAgICBpbnQgd1JQZXJtID0gJHt4YX0gLSAxIC0gd1I7CgogICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7YmF9OyB3QysrKSB7CiAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7VGF9LjA7CgogICAgICAgICAgICBpZiAoZHlDIDwgMC4wIHx8IGR5QyA+PSAke2FhLm91dFdpZHRofS4wIHx8CiAgICAgICAgICAgICAgICBmcmFjdChkeUMpID4gMC4wKSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGlkeUMgPSBpbnQoZHlDKTsKCiAgICAgICAgICAgIGludCB3Q1Blcm0gPSAke2JhfSAtIDEgLSB3QzsKCiAgICAgICAgICAgIC8vIFRPIERPOiBWZWM0IG92ZXIgdGhlIGNoYW5uZWxNdWwKICAgICAgICAgICAgZm9yIChpbnQgZG0gPSAwOyBkbSA8ICR7a2F9OyBkbSsrKSB7CiAgICAgICAgICAgICAgaW50IGQyID0gZDEgKiAke2thfSArIGRtOwogICAgICAgICAgICAgIGZsb2F0IHhWYWx1ZSA9IGdldER5KGJhdGNoLCBpZHlSLCBpZHlDLCBkMik7CiAgICAgICAgICAgICAgZmxvYXQgd1ZhbHVlID0gZ2V0Vyh3UlBlcm0sIHdDUGVybSwgZDEsIGRtKTsKICAgICAgICAgICAgICBkb3RQcm9kICs9IHhWYWx1ZSAqIHdWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoZG90UHJvZCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlciQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZHk6VGF9PWFhLHtzdHJpZGVzOndhLGRpbGF0aW9uczpFYSxwYWQ6a2EsZGltUm91bmRpbmdNb2RlOkFhLGZpbHRlclNoYXBlOkZhfT1iYSxMYT1jb21wdXRlQ29udjJESW5mbyQxKFNhLnNoYXBlLEZhLHdhLEVhLGthLEFhLCEwKSxlbD1uZXcgRGVwdGh3aXNlQ29udjJERGVyRmlsdGVyUHJvZ3JhbSQxKExhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKGVsLFtTYSxUYV0sImZsb2F0MzIiKX1jb25zdCBkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlckNvbmZpZyQxPXtrZXJuZWxOYW1lOkRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxmaWx0ZXI6VGF9PWFhLHtzdHJpZGVzOndhLGRpbGF0aW9uczpFYSxwYWQ6a2EsZGltUm91bmRpbmdNb2RlOkFhLGlucHV0U2hhcGU6RmF9PWJhLExhPWNvbXB1dGVDb252MkRJbmZvJDEoRmEsVGEuc2hhcGUsd2EsRWEsa2EsQWEsITApLGVsPW5ldyBEZXB0aHdpc2VDb252MkREZXJJbnB1dFByb2dyYW0kMShMYSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShlbCxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dENvbmZpZyQxPXtrZXJuZWxOYW1lOkRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRGlhZ1Byb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiWCJdLHRoaXMub3V0cHV0U2hhcGU9W2FhLGFhXSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBmbG9hdCB2YWwgPSBjb29yZHNbMF0gPT0gY29vcmRzWzFdID8gZ2V0WChjb29yZHNbMF0pIDogMC4wOwogICAgICAgICAgc2V0T3V0cHV0KHZhbCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkaWFnJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWEsU2E9Wy4uLmJhLnNoYXBlLC4uLmJhLnNoYXBlXSxUYT1zaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpLHdhPXJlc2hhcGUkMih7aW5wdXRzOnt4OmJhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbVGFdfX0pLEVhPW5ldyBEaWFnUHJvZ3JhbSQxKFRhKSxrYT14YS5ydW5XZWJHTFByb2dyYW0oRWEsW3dhXSx3YS5kdHlwZSksQWE9cmVzaGFwZSQyKHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlNhfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh3YSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oa2EpLEFhfWNvbnN0IGRpYWdDb25maWckMT17a2VybmVsTmFtZTpEaWFnJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRpYWckMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IERpbGF0aW9uMkRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJXIl0sdGhpcy5vdXRwdXRTaGFwZT1hYS5vdXRTaGFwZTtjb25zdHtpbkhlaWdodDp4YSxpbldpZHRoOmJhLHBhZEluZm86U2Esc3RyaWRlSGVpZ2h0OlRhLHN0cmlkZVdpZHRoOndhLGZpbHRlckhlaWdodDpFYSxmaWx0ZXJXaWR0aDprYSxkaWxhdGlvbkhlaWdodDpBYSxkaWxhdGlvbldpZHRoOkZhfT1hYSx7dG9wOkxhLGxlZnQ6ZWx9PVNhO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHtUYX0sICR7d2F9KTsKICAgICAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7TGF9LCAke2VsfSk7CiAgICAgIGNvbnN0IGZsb2F0IG5lZ19pbmZpbml0eSA9IC0zLjRlMzg7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaW50IGQxID0gY29vcmRzLnc7CiAgICAgICAgaXZlYzIgb3V0VG9wTGVmdENvcm5lciA9CiAgICAgICAgICAgIGNvb3Jkcy55eiAqIHN0cmlkZXMgLSBwYWRzOwogICAgICAgIGludCBoQmVnID0gb3V0VG9wTGVmdENvcm5lci54OwogICAgICAgIGludCB3QmVnID0gb3V0VG9wTGVmdENvcm5lci55OwoKICAgICAgICBmbG9hdCBjdXJWYWwgPSBuZWdfaW5maW5pdHk7CiAgICAgICAgZm9yIChpbnQgaCA9IDA7IGggPCAke0VhfTsgaCsrKSB7CiAgICAgICAgICBpbnQgaEluID0gaEJlZyArIGggKiAke0FhfTsKCiAgICAgICAgICBpZiAoaEluID49IDAgJiYgaEluIDwgJHt4YX0pIHsKICAgICAgICAgICAgZm9yIChpbnQgdyA9IDA7IHcgPCAke2thfTsgdysrKSB7CiAgICAgICAgICAgICAgaW50IHdJbiA9IHdCZWcgKyB3ICogJHtGYX07CgogICAgICAgICAgICAgIGlmICh3SW4gPj0gMCAmJiB3SW4gPCAke2JhfSkgewogICAgICAgICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIGhJbiwgd0luLCBkMSk7CiAgICAgICAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhoLCB3LCBkMSk7CgogICAgICAgICAgICAgICAgZmxvYXQgdmFsID0geFZhbCArIHdWYWw7CiAgICAgICAgICAgICAgICBpZiAodmFsID4gY3VyVmFsKSB7CiAgICAgICAgICAgICAgICAgIGN1clZhbCA9IHZhbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZsb2F0IHJlc3VsdCA9IGN1clZhbDsKICAgICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRpbGF0aW9uMkQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGZpbHRlcjpUYX09YWEse3N0cmlkZXM6d2EscGFkOkVhLGRpbGF0aW9uczprYX09YmEsQWE9Y29tcHV0ZURpbGF0aW9uMkRJbmZvJDEoU2Euc2hhcGUsVGEuc2hhcGUsd2EsRWEsIk5IV0MiLGthKTtsZXQgRmE7Y29uc3QgTGE9bmV3IERpbGF0aW9uMkRQcm9ncmFtJDEoQWEpO0ZhPXhhLnJ1bldlYkdMUHJvZ3JhbShMYSxbU2EsVGFdLCJmbG9hdDMyIik7Y29uc3QgZWw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6RmF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkFhLm91dFNoYXBlfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhGYSksZWx9Y29uc3QgZGlsYXRpb24yRENvbmZpZyQxPXtrZXJuZWxOYW1lOkRpbGF0aW9uMkQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZGlsYXRpb24yRCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBlaW5zdW0kMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtlcXVhdGlvbjpTYX09YmEsVGE9YWEse2FsbERpbXM6d2Esc3VtbWVkRGltczpFYSxpZERpbXM6a2F9PWRlY29kZUVpbnN1bUVxdWF0aW9uJDEoU2EsVGEubGVuZ3RoKTtjaGVja0VpbnN1bURpbVNpemVzJDEod2EubGVuZ3RoLGthLFRhKTtjb25zdHtwYXRoOkFhLHN0ZXBzOkZhfT1nZXRFaW5zdW1Db21wdXRlUGF0aCQxKEVhLGthKSxMYT1GYS5sZW5ndGg7bGV0IGVsPW51bGwsdGw9d2EubGVuZ3RoO2NvbnN0IG5sPVtdO2ZvcihsZXQgc2w9MDtzbDxMYTsrK3NsKXtmb3IoY29uc3Qgcmwgb2YgRmFbc2xdKXtjb25zdHtwZXJtdXRhdGlvbkluZGljZXM6b2wsZXhwYW5kRGltczphbH09Z2V0RWluc3VtUGVybXV0YXRpb24kMSh0bCxrYVtybF0pO2xldCBsbDtpc0lkZW50aXR5UGVybXV0YXRpb24kMShvbCk/bGw9VGFbcmxdOihsbD10cmFuc3Bvc2UkMSh7aW5wdXRzOnt4OlRhW3JsXX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpvbH19KSxubC5wdXNoKGxsKSk7Y29uc3QgaWw9bGwuc2hhcGUuc2xpY2UoKTtmb3IobGV0IGNsPTA7Y2w8YWwubGVuZ3RoOysrY2wpaWwuc3BsaWNlKGFsW2NsXSwwLDEpO2FycmF5c0VxdWFsJDEobGwuc2hhcGUsaWwpfHwobGw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6bGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmlsfX0pLG5sLnB1c2gobGwpKSxlbD09PW51bGw/ZWw9bGw6KGVsPW11bHRpcGx5JDEoe2lucHV0czp7YTpsbCxiOmVsfSxiYWNrZW5kOnhhfSksbmwucHVzaChlbCkpfXNsPExhLTEmJihBYVtzbF0+PTAmJihlbD1zdW0kMyh7aW5wdXRzOnt4OmVsfSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOkFhW3NsXS0od2EubGVuZ3RoLXRsKSxrZWVwRGltczohMX19KSxubC5wdXNoKGVsKSksdGwtLSl9Zm9yKGNvbnN0IHNsIG9mIG5sKXNsIT09ZWwmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKTtyZXR1cm4gZWx9Y29uc3QgZWluc3VtQ29uZmlnJDE9e2tlcm5lbE5hbWU6RWluc3VtJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmVpbnN1bSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBFTFUkMz0icmV0dXJuICh4ID49IDAuMCkgPyB4IDogKGV4cCh4KSAtIDEuMCk7IixFTFVfUEFDS0VEJDE9YAogIHZlYzQgcmVzdWx0OwoKICByZXN1bHQuciA9ICh4LnIgPj0gMC4wKSA/IHguciA6IChleHAoeC5yKSAtIDEuMCk7CiAgcmVzdWx0LmcgPSAoeC5nID49IDAuMCkgPyB4LmcgOiAoZXhwKHguZykgLSAxLjApOwogIHJlc3VsdC5iID0gKHguYiA+PSAwLjApID8geC5iIDogKGV4cCh4LmIpIC0gMS4wKTsKICByZXN1bHQuYSA9ICh4LmEgPj0gMC4wKSA/IHguYSA6IChleHAoeC5hKSAtIDEuMCk7CgogIHJldHVybiByZXN1bHQ7CmAsZWx1JDI9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpFTFUkMyxwYWNrZWRPcFNuaXBwZXQ6RUxVX1BBQ0tFRCQxfSksZWx1Q29uZmlnJDE9e2tlcm5lbE5hbWU6RWx1JDIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmVsdSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBFTFVfREVSJDE9InJldHVybiAoYiA+PSAwLjApID8gYSA6IGEgKiAoYiArIDEuMCk7IixFTFVfREVSX1BBQ0tFRCQxPWAKICB2ZWM0IGJHVEVaZXJvID0gdmVjNChncmVhdGVyVGhhbkVxdWFsKGIsIHZlYzQoMC4pKSk7CiAgcmV0dXJuIChiR1RFWmVybyAqIGEpICsgKCh2ZWM0KDEuMCkgLSBiR1RFWmVybykgKiAoYSAqIChiICsgdmVjNCgxLjApKSkpOwpgLGVsdUdyYWQkMT1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7ZHk6YmEseTpTYX09YWEsVGE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0JJTkFSWV9PUEVSQVRJT05TIik/bmV3IEJpbmFyeU9wUGFja2VkUHJvZ3JhbSQxKEVMVV9ERVJfUEFDS0VEJDEsYmEuc2hhcGUsU2Euc2hhcGUpOm5ldyBCaW5hcnlPcFByb2dyYW0kMShFTFVfREVSJDEsYmEuc2hhcGUsU2Euc2hhcGUpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oVGEsW2JhLFNhXSxiYS5kdHlwZSl9LGVsdUdyYWRDb25maWckMT17a2VybmVsTmFtZTpFbHVHcmFkJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmVsdUdyYWQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgUEFDS0VEX0VRVUFMJDE9YAogIHJldHVybiB2ZWM0KGVxdWFsKGEsIGIpKTsKYCxFUVVBTCQxPSJyZXR1cm4gZmxvYXQoYSA9PSBiKTsiLGVxdWFsJDE9YmluYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6RVFVQUwkMSxwYWNrZWRPcFNuaXBwZXQ6UEFDS0VEX0VRVUFMJDEsZHR5cGU6ImJvb2wiLGNwdUtlcm5lbEltcGw6ZXF1YWxJbXBsQ1BVJDF9KSxlcXVhbENvbmZpZyQxPXtrZXJuZWxOYW1lOkVxdWFsJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmVxdWFsJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVSRiQxPWAKICAvLyBFcnJvciBmdW5jdGlvbiBpcyBjYWxjdWxhdGVkIGFwcHJveGltYXRlbHkgd2l0aCBlbGVtZW50YXJ5IGZ1bmN0aW9uLgogIC8vIFNlZSAiSGFuZGJvb2sgb2YgTWF0aGVtYXRpY2FsIEZ1bmN0aW9ucyB3aXRoIEZvcm11bGFzLAogIC8vIEdyYXBocywgYW5kIE1hdGhlbWF0aWNhbCBUYWJsZXMiLCBBYnJhbW93aXR6IGFuZCBTdGVndW4uCiAgZmxvYXQgcCA9ICR7RVJGX1AkMX07CiAgZmxvYXQgYTEgPSAke0VSRl9BMSQxfTsKICBmbG9hdCBhMiA9ICR7RVJGX0EyJDF9OwogIGZsb2F0IGEzID0gJHtFUkZfQTMkMX07CiAgZmxvYXQgYTQgPSAke0VSRl9BNCQxfTsKICBmbG9hdCBhNSA9ICR7RVJGX0E1JDF9OwoKICBmbG9hdCBzaWduID0gc2lnbih4KTsKICB4ID0gYWJzKHgpOwogIGZsb2F0IHQgPSAxLjAgLyAoMS4wICsgcCAqIHgpOwogIHJldHVybiBzaWduICogKDEuMCAtICgoKCgoYTUqdCArIGE0KSp0KSArIGEzKSp0ICsgYTIpKnQgKyBhMSkqdCpleHAoLXgqeCkpOwpgLGVyZiQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6RVJGJDF9KSxlcmZDb25maWckMT17a2VybmVsTmFtZTpFcmYkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZXJmJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVYUCQxPUNIRUNLX05BTl9TTklQUEVUX1VOQVJZJDErYAogIHJldHVybiBleHAoeCk7CmAsRVhQX1BBQ0tFRCQxPWAKICB2ZWM0IHJlc3VsdCA9IGV4cCh4KTsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwogIHJlc3VsdC5yID0gaXNOYU4uciA/IHguciA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNOYU4uZyA/IHguZyA6IHJlc3VsdC5nOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6IHJlc3VsdC5iOwogIHJlc3VsdC5hID0gaXNOYU4uYSA/IHguYSA6IHJlc3VsdC5hOwoKICByZXR1cm4gcmVzdWx0OwpgLGV4cCQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6RVhQJDEscGFja2VkT3BTbmlwcGV0OkVYUF9QQUNLRUQkMSxjcHVLZXJuZWxJbXBsOmV4cEltcGxDUFUkMSxkdHlwZToiZmxvYXQzMiJ9KSxleHBDb25maWckMT17a2VybmVsTmFtZTpFeHAkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZXhwJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZXhwYW5kRGltcyQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYXR0cnM6eGEsYmFja2VuZDpiYX09aGEse2RpbTpTYX09eGEse2lucHV0OlRhfT1hYSx3YT1UYS5zaGFwZS5sZW5ndGgsRWE9VGEuc2hhcGUuc2xpY2UoKTtsZXQga2E9U2E7cmV0dXJuIFNhPDAmJihhc3NlcnQkMigtKHdhKzEpPD1TYSwoKT0+YEF4aXMgbXVzdCBiZSBpbiB0aGUgaW50ZXJ2YWwgWyR7LSh3YSsxKX0sICR7d2F9XWApLGthPXdhK1NhKzEpLEVhLnNwbGljZShrYSwwLDEpLHJlc2hhcGUkMih7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpFYX19KX1jb25zdCBleHBhbmREaW1zQ29uZmlnJDE9e2tlcm5lbE5hbWU6RXhwYW5kRGltcyQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpleHBhbmREaW1zJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVYUE0xJDE9InJldHVybiBleHAoeCkgLSAxLjA7IixleHBtMSQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6RVhQTTEkMSxwYWNrZWRPcFNuaXBwZXQ6RVhQTTEkMSxjcHVLZXJuZWxJbXBsOmV4cG0xSW1wbENQVSQxfSksZXhwbTFDb25maWckMT17a2VybmVsTmFtZTpFeHBtMSQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpleHBtMSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRkZUUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJyZWFsIiwiaW1hZyJdO2NvbnN0IFNhPXhhWzFdO3RoaXMub3V0cHV0U2hhcGU9eGE7Y29uc3QgVGE9YmE/YDIuMCAqICR7TWF0aC5QSX1gOmAtMi4wICogJHtNYXRoLlBJfWAsd2E9YmE/YCR7U2F9LjBgOiIxLjAiO2xldCBFYTtpZihhYT09PSJyZWFsIilFYT0icmV0dXJuIHJlYWwgKiBleHBSIC0gaW1hZyAqIGV4cEk7IjtlbHNlIGlmKGFhPT09ImltYWciKUVhPSJyZXR1cm4gcmVhbCAqIGV4cEkgKyBpbWFnICogZXhwUjsiO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBGRlQgY29tcG9uZW50IG11c3QgYmUgZWl0aGVyICJyZWFsIiBvciAiaW1hZyIsIGdvdCAke2FhfS5gKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgZmxvYXQgZXhwb25lbnRNdWx0aXBsaWVyID0gJHtUYX07CgogICAgICBmbG9hdCB1bmFyeU9wQ29tcGxleChmbG9hdCByZWFsLCBmbG9hdCBleHBSLCBmbG9hdCBpbWFnLCBmbG9hdCBleHBJKSB7CiAgICAgICAgJHtFYX0KICAgICAgfQoKICAgICAgZmxvYXQgbXVsTWF0REZUKGludCBiYXRjaCwgaW50IGluZGV4KSB7CiAgICAgICAgZmxvYXQgaW5kZXhSYXRpbyA9IGZsb2F0KGluZGV4KSAvIGZsb2F0KCR7U2F9KTsKICAgICAgICBmbG9hdCBleHBvbmVudE11bHRpcGxpZXJUaW1lc0luZGV4UmF0aW8gPQogICAgICAgICAgICBleHBvbmVudE11bHRpcGxpZXIgKiBpbmRleFJhdGlvOwoKICAgICAgICBmbG9hdCByZXN1bHQgPSAwLjA7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtTYX07IGkrKykgewogICAgICAgICAgLy8geCA9ICgtMnwyICogUEkgLyBOKSAqIGluZGV4ICogaTsKICAgICAgICAgIGZsb2F0IHggPSBleHBvbmVudE11bHRpcGxpZXJUaW1lc0luZGV4UmF0aW8gKiBmbG9hdChpKTsKICAgICAgICAgIGZsb2F0IGV4cFIgPSBjb3MoeCk7CiAgICAgICAgICBmbG9hdCBleHBJID0gc2luKHgpOwogICAgICAgICAgZmxvYXQgcmVhbCA9IGdldFJlYWwoYmF0Y2gsIGkpOwogICAgICAgICAgZmxvYXQgaW1hZyA9IGdldEltYWcoYmF0Y2gsIGkpOwoKICAgICAgICAgIHJlc3VsdCArPQogICAgICAgICAgICAgIHVuYXJ5T3BDb21wbGV4KHJlYWwsIGV4cFIsIGltYWcsIGV4cEkpIC8gJHt3YX07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgc2V0T3V0cHV0KG11bE1hdERGVChjb29yZHNbMF0sIGNvb3Jkc1sxXSkpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZmZ0SW1wbCQxKGhhLGFhLHhhKXtjb25zdCBiYT14YS50ZXhEYXRhLmdldChoYS5kYXRhSWQpLFNhPXNpemVGcm9tU2hhcGUkMShoYS5zaGFwZSksVGE9aGEuc2hhcGVbaGEuc2hhcGUubGVuZ3RoLTFdLHdhPVNhL1RhLEVhPXJlc2hhcGUkMih7aW5wdXRzOnt4OmhhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbd2EsVGFdfX0pLGthPUVhLnNoYXBlLEFhPW5ldyBGRlRQcm9ncmFtJDEoInJlYWwiLGthLGFhKSxGYT1uZXcgRkZUUHJvZ3JhbSQxKCJpbWFnIixrYSxhYSksTGE9W3tkYXRhSWQ6YmEuY29tcGxleFRlbnNvckluZm9zLnJlYWwuZGF0YUlkLGR0eXBlOmJhLmNvbXBsZXhUZW5zb3JJbmZvcy5yZWFsLmR0eXBlLHNoYXBlOmthfSx7ZGF0YUlkOmJhLmNvbXBsZXhUZW5zb3JJbmZvcy5pbWFnLmRhdGFJZCxkdHlwZTpiYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZy5kdHlwZSxzaGFwZTprYX1dLGVsPXhhLnJ1bldlYkdMUHJvZ3JhbShBYSxMYSwiZmxvYXQzMiIpLHRsPXhhLnJ1bldlYkdMUHJvZ3JhbShGYSxMYSwiZmxvYXQzMiIpLG5sPWNvbXBsZXgkMih7aW5wdXRzOntyZWFsOmVsLGltYWc6dGx9LGJhY2tlbmQ6eGF9KTt4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpO2NvbnN0IHNsPXJlc2hhcGUkMih7aW5wdXRzOnt4Om5sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpoYS5zaGFwZX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSxzbH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmZnQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtpbnB1dDpiYX09YWE7cmV0dXJuIGZmdEltcGwkMShiYSwhMSx4YSl9Y29uc3QgZmZ0Q29uZmlnJDE9e2tlcm5lbE5hbWU6RkZUJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmZmdCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRmlsbFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToidmFsdWUiLHR5cGU6ImZsb2F0In1dLHRoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgLy8gSW5wdXQgY2FuIGJlIG9idGFpbmVkIGZyb20gdW5pZm9ybSB2YWx1ZS4KICAgICAgICBzZXRPdXRwdXQodmFsdWUpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZmlsbCQyKGhhKXtjb25zdHtiYWNrZW5kOmFhLGF0dHJzOnhhfT1oYSx7c2hhcGU6YmEsdmFsdWU6U2F9PXhhO2xldHtkdHlwZTpUYX09eGE7aWYoVGE9VGF8fGluZmVyRHR5cGUkMShTYSksVGE9PT0ic3RyaW5nIil7Y29uc3Qgd2E9Z2V0QXJyYXlGcm9tRFR5cGUkMShUYSxzaXplRnJvbVNoYXBlJDEoYmEpKTtyZXR1cm4gd2EuZmlsbChTYSksYWEubWFrZVRlbnNvckluZm8oYmEsVGEsd2EpfWVsc2V7Y29uc3Qgd2E9bmV3IEZpbGxQcm9ncmFtJDEoYmEsU2EpLEVhPVtbU2FdXTtyZXR1cm4gYWEucnVuV2ViR0xQcm9ncmFtKHdhLFtdLFRhLEVhKX19Y29uc3QgZmlsbENvbmZpZyQxPXtrZXJuZWxOYW1lOkZpbGwkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZmlsbCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRmxpcExlZnRSaWdodFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiSW1hZ2UiXSx0aGlzLm91dHB1dFNoYXBlPVtdO2NvbnN0IHhhPWFhWzJdO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBpbnQgeCA9IGNvb3Jkc1syXTsKCiAgICAgICAgICBpbnQgY29vcmRYID0gJHt4YX0gLSB4IC0gMTsKICAgICAgICAgIGZsb2F0IG91dHB1dFZhbHVlOwogICAgICAgICAgaWYoY29vcmRYID49IDAgJiYgY29vcmRYIDwgJHt4YX0pIHsKICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSBnZXRJbWFnZShjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRYLCBjb29yZHNbM10pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSBnZXRJbWFnZShjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10pOwogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KG91dHB1dFZhbHVlKTsKICAgICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZmxpcExlZnRSaWdodENvbmZpZyQxPXtrZXJuZWxOYW1lOkZsaXBMZWZ0UmlnaHQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6KHtpbnB1dHM6aGEsYmFja2VuZDphYX0pPT57Y29uc3R7aW1hZ2U6eGF9PWhhLGJhPWFhLFNhPW5ldyBGbGlwTGVmdFJpZ2h0UHJvZ3JhbSQxKHhhLnNoYXBlKTtyZXR1cm4gYmEucnVuV2ViR0xQcm9ncmFtKFNhLFt4YV0seGEuZHR5cGUpfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRkxPT1IkMT0icmV0dXJuIGZsb29yKHgpOyIsZmxvb3IkMT11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkZMT09SJDEscGFja2VkT3BTbmlwcGV0OkZMT09SJDEsY3B1S2VybmVsSW1wbDpmbG9vckltcGxDUFUkMX0pLGZsb29yQ29uZmlnJDE9e2tlcm5lbE5hbWU6Rmxvb3IkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Zmxvb3IkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSU5UX0RJViQxPWAKICBmbG9hdCBzID0gc2lnbihhKSAqIHNpZ24oYik7CiAgaW50IGlhID0gcm91bmQoYSk7CiAgaW50IGliID0gcm91bmQoYik7CiAgaWYgKGliICE9IDApIHsKICAgIC8vIFdpbmRvd3MgKEQzRCkgd2FudHMgZ3VhcmFudGVlZCBub24temVybyBpbnQgZGl2aXNpb24gYXQgY29tcGlsZS10aW1lLgogICAgcmV0dXJuIGZsb2F0KGlkaXYoaWEsIGliLCBzKSk7CiAgfSBlbHNlIHsKICAgIHJldHVybiBOQU47CiAgfQpgLElOVF9ESVZfUEFDS0VEJDE9YAogIGl2ZWM0IGlhID0gcm91bmQoYSk7CiAgaXZlYzQgaWIgPSByb3VuZChiKTsKICBidmVjNCBjb25kID0gbm90RXF1YWwoaWIsIGl2ZWM0KDApKTsKICBpdmVjNCByZXN1bHQgPSBpdmVjNCgwKTsKICB2ZWM0IHMgPSBzaWduKGEpICogc2lnbihiKTsKCiAgLy8gV2luZG93cyAoRDNEKSB3YW50cyBndWFyYW50ZWVkIG5vbi16ZXJvIGludCBkaXZpc2lvbiBhdCBjb21waWxlLXRpbWUuCiAgaWYgKGNvbmRbMF0pIHsKICAgIHJlc3VsdFswXSA9IGlkaXYoaWFbMF0sIGliWzBdLCBzWzBdKTsKICB9CiAgaWYgKGNvbmRbMV0pIHsKICAgIHJlc3VsdFsxXSA9IGlkaXYoaWFbMV0sIGliWzFdLCBzWzFdKTsKICB9CiAgaWYgKGNvbmRbMl0pIHsKICAgIHJlc3VsdFsyXSA9IGlkaXYoaWFbMl0sIGliWzJdLCBzWzJdKTsKICB9CiAgaWYgKGNvbmRbM10pIHsKICAgIHJlc3VsdFszXSA9IGlkaXYoaWFbM10sIGliWzNdLCBzWzNdKTsKICB9CiAgcmV0dXJuIHZlYzQocmVzdWx0KTsKYCxmbG9vckRpdiQyPWJpbmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OklOVF9ESVYkMSxwYWNrZWRPcFNuaXBwZXQ6SU5UX0RJVl9QQUNLRUQkMSxkdHlwZToiaW50MzIifSksZmxvb3JEaXZDb25maWckMT17a2VybmVsTmFtZTpGbG9vckRpdiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpmbG9vckRpdiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgRnJvbVBpeGVsc1Byb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdO2NvbnN0IHhhPWdldEdsc2xEaWZmZXJlbmNlcyQxKCksW2JhLFNhXT1hYTt0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzMgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IHRleFIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IHRleEMgPSBjb29yZHNbMV07CiAgICAgICAgaW50IGRlcHRoID0gY29vcmRzWzJdOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKCR7U2F9LjAsICR7YmF9LjApOwoKICAgICAgICB2ZWM0IHZhbHVlcyA9ICR7eGEudGV4dHVyZTJEfShBLCB1dik7CiAgICAgICAgZmxvYXQgdmFsdWU7CiAgICAgICAgaWYgKGRlcHRoID09IDApIHsKICAgICAgICAgIHZhbHVlID0gdmFsdWVzLnI7CiAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAxKSB7CiAgICAgICAgICB2YWx1ZSA9IHZhbHVlcy5nOwogICAgICAgIH0gZWxzZSBpZiAoZGVwdGggPT0gMikgewogICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuYjsKICAgICAgICB9IGVsc2UgaWYgKGRlcHRoID09IDMpIHsKICAgICAgICAgIHZhbHVlID0gdmFsdWVzLmE7CiAgICAgICAgfQoKICAgICAgICBzZXRPdXRwdXQoZmxvb3IodmFsdWUgKiAyNTUuMCArIDAuNSkpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IEZyb21QaXhlbHNQYWNrZWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMSx0aGlzLnBhY2tlZE91dHB1dD0hMDtjb25zdCB4YT1nZXRHbHNsRGlmZmVyZW5jZXMkMSgpLFtiYSxTYV09YWE7dGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMzIGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCB0ZXhSID0gY29vcmRzWzBdOwogICAgICAgIGludCB0ZXhDID0gY29vcmRzWzFdOwogICAgICAgIGludCBkZXB0aCA9IGNvb3Jkc1syXTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKCiAgICAgICAgZm9yKGludCByb3c9MDsgcm93PD0xOyByb3crKykgewogICAgICAgICAgZm9yKGludCBjb2w9MDsgY29sPD0xOyBjb2wrKykgewogICAgICAgICAgICB0ZXhDID0gY29vcmRzWzFdICsgcm93OwogICAgICAgICAgICBkZXB0aCA9IGNvb3Jkc1syXSArIGNvbDsKCiAgICAgICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtTYX0uMCwgJHtiYX0uMCk7CiAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gJHt4YS50ZXh0dXJlMkR9KEEsIHV2KTsKICAgICAgICAgICAgZmxvYXQgdmFsdWU7CiAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMucjsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAxKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuZzsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAyKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuYjsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAzKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuYTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVzdWx0W3JvdyAqIDIgKyBjb2xdID0gZmxvb3IodmFsdWUgKiAyNTUuMCArIDAuNSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAke3hhLm91dHB1dH0gPSByZXN1bHQ7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBmcm9tUGl4ZWxzQ29uZmlnJDE9e2tlcm5lbE5hbWU6RnJvbVBpeGVscyQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpmcm9tUGl4ZWxzJDF9O2xldCBmcm9tUGl4ZWxzMkRDb250ZXh0JDEsd2lsbFJlYWRGcmVxdWVudGx5JDE9ZW52JDEoKS5nZXRCb29sKCJDQU5WQVMyRF9XSUxMX1JFQURfRlJFUVVFTlRMWV9GT1JfR1BVIik7ZnVuY3Rpb24gZnJvbVBpeGVscyQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGE7bGV0e3BpeGVsczpTYX09YWE7Y29uc3R7bnVtQ2hhbm5lbHM6VGF9PWJhLHdhPXR5cGVvZiBIVE1MVmlkZW9FbGVtZW50PCJ1IiYmU2EgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50LEVhPXR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50PCJ1IiYmU2EgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50LFtrYSxBYV09d2E/W1NhLnZpZGVvV2lkdGgsU2EudmlkZW9IZWlnaHRdOltTYS53aWR0aCxTYS5oZWlnaHRdLEZhPVtBYSxrYV0sTGE9W0FhLGthLFRhXTtpZihFYXx8d2Epe2NvbnN0IHNsPWVudiQxKCkuZ2V0Qm9vbCgiQ0FOVkFTMkRfV0lMTF9SRUFEX0ZSRVFVRU5UTFlfRk9SX0dQVSIpOyhmcm9tUGl4ZWxzMkRDb250ZXh0JDE9PW51bGx8fHNsIT09d2lsbFJlYWRGcmVxdWVudGx5JDEpJiYod2lsbFJlYWRGcmVxdWVudGx5JDE9c2wsZnJvbVBpeGVsczJEQ29udGV4dCQxPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNhbnZhcyIpLmdldENvbnRleHQoIjJkIix7d2lsbFJlYWRGcmVxdWVudGx5OndpbGxSZWFkRnJlcXVlbnRseSQxfSkpLGZyb21QaXhlbHMyRENvbnRleHQkMS5jYW52YXMud2lkdGg9a2EsZnJvbVBpeGVsczJEQ29udGV4dCQxLmNhbnZhcy5oZWlnaHQ9QWEsZnJvbVBpeGVsczJEQ29udGV4dCQxLmRyYXdJbWFnZShTYSwwLDAsa2EsQWEpLFNhPWZyb21QaXhlbHMyRENvbnRleHQkMS5jYW52YXN9Y29uc3QgZWw9eGEubWFrZVRlbnNvckluZm8oRmEsImludDMyIik7eGEudGV4RGF0YS5nZXQoZWwuZGF0YUlkKS51c2FnZT1UZXh0dXJlVXNhZ2UkMS5QSVhFTFMseGEuZ3BncHUudXBsb2FkUGl4ZWxEYXRhVG9UZXh0dXJlKHhhLmdldFRleHR1cmUoZWwuZGF0YUlkKSxTYSk7Y29uc3QgdGw9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLIik/bmV3IEZyb21QaXhlbHNQYWNrZWRQcm9ncmFtJDEoTGEpOm5ldyBGcm9tUGl4ZWxzUHJvZ3JhbSQxKExhKSxubD14YS5ydW5XZWJHTFByb2dyYW0odGwsW2VsXSwiaW50MzIiKTtyZXR1cm4geGEuZGlzcG9zZURhdGEoZWwuZGF0YUlkKSxubH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmdXNlZENvbnYyZCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhLGJpYXM6d2EscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpFYX09YWEse3N0cmlkZXM6a2EscGFkOkFhLGRhdGFGb3JtYXQ6RmEsZGlsYXRpb25zOkxhLGRpbVJvdW5kaW5nTW9kZTplbCxhY3RpdmF0aW9uOnRsLGxlYWt5cmVsdUFscGhhOm5sfT1iYSxzbD1jb252ZXJ0Q29udjJERGF0YUZvcm1hdCQxKEZhKSxybD1jb21wdXRlQ29udjJESW5mbyQxKFNhLnNoYXBlLFRhLnNoYXBlLGthLExhLEFhLGVsLCExLHNsKTtsZXQgb2w7Y29uc3QgYWw9W10sbGw9d2EhPW51bGwsaWw9RWEhPW51bGwsY2w9dGw9PT0ibGVha3lyZWx1Iix1bD0oKT0+e2NvbnN0IGhsPVtTYSxUYV0scGw9KGZsLG1sKT0+e2lmKG1sPT09Ik5DSFciJiZmbC5zaGFwZS5sZW5ndGg9PT0xJiZmbC5zaGFwZVswXSE9PTEpe2NvbnN0IGdsPXJlc2hhcGUkMih7aW5wdXRzOnt4OmZsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbZmwuc2hhcGVbMF0sMSwxXX19KTtyZXR1cm4gYWwucHVzaChnbCksZ2x9cmV0dXJuIGZsfTtpZihsbCYmaGwucHVzaChwbCh3YSxGYSkpLGlsJiZobC5wdXNoKHBsKEVhLEZhKSksY2wpe2NvbnN0IGZsPXhhLm1ha2VUZW5zb3JJbmZvKFtdLCJmbG9hdDMyIixjcmVhdGVTY2FsYXJWYWx1ZSQxKG5sLCJmbG9hdDMyIikpO2hsLnB1c2goZmwpLGFsLnB1c2goZmwpfXJldHVybiBobH07aWYocmwuZmlsdGVySGVpZ2h0PT09MSYmcmwuZmlsdGVyV2lkdGg9PT0xJiZybC5kaWxhdGlvbkhlaWdodD09PTEmJnJsLmRpbGF0aW9uV2lkdGg9PT0xJiZybC5zdHJpZGVIZWlnaHQ9PT0xJiZybC5zdHJpZGVXaWR0aD09PTEmJihybC5wYWRJbmZvLnR5cGU9PT0iU0FNRSJ8fHJsLnBhZEluZm8udHlwZT09PSJWQUxJRCIpKW9sPWNvbnYyZEJ5TWF0TXVsJDEoe3g6U2EsZmlsdGVyOlRhLGNvbnZJbmZvOnJsLGJhY2tlbmQ6eGEsYmlhczp3YSxhY3RpdmF0aW9uOnRsLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWEsbGVha3lyZWx1QWxwaGE6bmx9KTtlbHNlIGlmKHJsLnN0cmlkZVdpZHRoPD0yJiZzbD09PSJjaGFubmVsc0xhc3QiJiZlbnYkMSgpLmdldEJvb2woIldFQkdMX0VYUF9DT05WIikpe2NvbnN0IGhsPXRsP21hcEFjdGl2YXRpb25Ub1NoYWRlclByb2dyYW0kMSh0bCwhMCk6bnVsbCxwbD1uZXcgQ29udjJEUGFja2VkUHJvZ3JhbSQxKHJsLGxsLGhsLGlsLGNsKSxmbD1bW3JsLnBhZEluZm8udG9wLHJsLnBhZEluZm8ubGVmdF0sW3JsLnN0cmlkZUhlaWdodCxybC5zdHJpZGVXaWR0aF0sW3JsLmRpbGF0aW9uSGVpZ2h0LHJsLmRpbGF0aW9uV2lkdGhdLFtybC5pbkhlaWdodCxybC5pbldpZHRoXV0sbWw9dWwoKTtvbD14YS5ydW5XZWJHTFByb2dyYW0ocGwsbWwsImZsb2F0MzIiLGZsKX1lbHNlIGlmKGVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfQ09OVl9JTTJDT0wiKSlvbD1jb252MmRXaXRoSW0yUm93JDEoe3g6U2EsZmlsdGVyOlRhLGNvbnZJbmZvOnJsLGJhY2tlbmQ6eGEsYmlhczp3YSxhY3RpdmF0aW9uOnRsLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWEsbGVha3lyZWx1QWxwaGE6bmx9KTtlbHNle2NvbnN0IGhsPXRsP21hcEFjdGl2YXRpb25Ub1NoYWRlclByb2dyYW0kMSh0bCwhMSk6bnVsbCxwbD1uZXcgQ29udjJEUHJvZ3JhbSQxKHJsLGxsLGhsLGlsLGNsKSxmbD11bCgpO29sPXhhLnJ1bldlYkdMUHJvZ3JhbShwbCxmbCwiZmxvYXQzMiIpfWNvbnN0IGRsPXJlc2hhcGUkMih7aW5wdXRzOnt4Om9sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpybC5vdXRTaGFwZX19KTtyZXR1cm4gYWwucHVzaChvbCksYWwuZm9yRWFjaChobD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oaGwpKSxkbH1jb25zdCBmdXNlZENvbnYyRENvbmZpZyQxPXtrZXJuZWxOYW1lOkZ1c2VkQ29udjJEJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmZ1c2VkQ29udjJkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZ1c2VkRGVwdGh3aXNlQ29udjJEJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxmaWx0ZXI6VGEsYmlhczp3YSxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOkVhfT1hYSx7c3RyaWRlczprYSxwYWQ6QWEsZGlsYXRpb25zOkZhLGRpbVJvdW5kaW5nTW9kZTpMYSxhY3RpdmF0aW9uOmVsLGxlYWt5cmVsdUFscGhhOnRsfT1iYSxubD1bXTtsZXQgc2w9RmE7c2w9PW51bGwmJihzbD1bMSwxXSksYXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEoa2Esc2wpLCgpPT5gRXJyb3IgaW4gZGVwdGh3aXNlQ29udjJkOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke2thfSBhbmQgZGlsYXRpb25zICcke3NsfSdgKTtjb25zdCBybD1jb21wdXRlQ29udjJESW5mbyQxKFNhLnNoYXBlLFRhLnNoYXBlLGthLHNsLEFhLExhLCEwKSxvbD1lbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfREVQVEhXSVNFQ09OViIpJiZybC5zdHJpZGVXaWR0aDw9MiYmcmwub3V0Q2hhbm5lbHMvcmwuaW5DaGFubmVscz09PTEsYWw9ZWw/bWFwQWN0aXZhdGlvblRvU2hhZGVyUHJvZ3JhbSQxKGVsLG9sKTpudWxsLGxsPVtTYSxUYV0saWw9d2EhPW51bGwsY2w9RWEhPW51bGwsdWw9ZWw9PT0ibGVha3lyZWx1IjtpZihpbCYmbGwucHVzaCh3YSksY2wmJmxsLnB1c2goRWEpLHVsKXtjb25zdCBmbD14YS5tYWtlVGVuc29ySW5mbyhbXSwiZmxvYXQzMiIsY3JlYXRlU2NhbGFyVmFsdWUkMSh0bCwiZmxvYXQzMiIpKTtsbC5wdXNoKGZsKSxubC5wdXNoKGZsKX1sZXQgZGw7b2w/ZGw9bmV3IERlcHRod2lzZUNvbnZQYWNrZWQyRFByb2dyYW0kMShybCxpbCxhbCxjbCx1bCk6ZGw9bmV3IERlcHRod2lzZUNvbnYyRFByb2dyYW0kMShybCxpbCxhbCxjbCx1bCk7Y29uc3QgaGw9W1tybC5wYWRJbmZvLnRvcCxybC5wYWRJbmZvLmxlZnRdLFtybC5zdHJpZGVIZWlnaHQscmwuc3RyaWRlV2lkdGhdLFtybC5kaWxhdGlvbkhlaWdodCxybC5kaWxhdGlvbldpZHRoXSxbcmwuaW5IZWlnaHQscmwuaW5XaWR0aF1dLHBsPXhhLnJ1bldlYkdMUHJvZ3JhbShkbCxsbCwiZmxvYXQzMiIsaGwpO3JldHVybiBubC5mb3JFYWNoKGZsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhmbCkpLHBsfWNvbnN0IGZ1c2VkRGVwdGh3aXNlQ29udjJEQ29uZmlnJDE9e2tlcm5lbE5hbWU6RnVzZWREZXB0aHdpc2VDb252MkQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZnVzZWREZXB0aHdpc2VDb252MkQkMX07bGV0IEdhdGhlck5EUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhKXt0aGlzLnNsaWNlRGltPWFhLHRoaXMuc3RyaWRlcz14YSx0aGlzLnBhcmFtc1NoYXBlPVNhLHRoaXMudmFyaWFibGVOYW1lcz1bIngiLCJpbmRpY2VzIl0sdGhpcy5vdXRwdXRTaGFwZT1iYTtjb25zdCBUYT1nZXRDb29yZHNEYXRhVHlwZSQxKGJhLmxlbmd0aCk7bGV0IHdhPWAKICAgIGludCBpbmRleDtgO2ZvcihsZXQgRWE9MDtFYTx0aGlzLnNsaWNlRGltO0VhKyspd2ErPWAKICAgICAgICAgIGluZGV4ID0gcm91bmQoZ2V0SW5kaWNlcyhjb29yZHNbMF0sICR7RWF9KSk7CiAgICAgICAgICBvdXRfb2ZfYm91bmRzID0gb3V0X29mX2JvdW5kcyB8fCBpbmRleCA8IDA7CiAgICAgICAgICBvdXRfb2ZfYm91bmRzID0gb3V0X29mX2JvdW5kcyB8fCBpbmRleCA+PSAke3RoaXMucGFyYW1zU2hhcGVbRWFdfTsKICAgICAgICAgIGZsYXR0ZW5JbmRleCArPSBpbmRleCAqICR7dGhpcy5zdHJpZGVzW0VhXX07YDt0aGlzLnVzZXJDb2RlPWAKICAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgJHtUYX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBpbnQgZmxhdHRlbkluZGV4ID0gMDsKICAgICAgICAgIGJvb2wgb3V0X29mX2JvdW5kcyA9IGZhbHNlOwoKICAgICAgICAgICR7d2F9CgogICAgICAgICAgc2V0T3V0cHV0KG91dF9vZl9ib3VuZHMgPyAwLjAgOiBnZXRYKGZsYXR0ZW5JbmRleCwgY29vcmRzWzFdKSk7CiAgICAgICAgfQogICAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2F0aGVyTmQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtwYXJhbXM6YmEsaW5kaWNlczpTYX09YWEsVGE9U2Euc2hhcGUsd2E9VGFbVGEubGVuZ3RoLTFdLEVhPXNpemVGcm9tU2hhcGUkMShiYS5zaGFwZSksW2thLEFhLEZhLExhXT1wcmVwYXJlQW5kVmFsaWRhdGUkMShiYSxTYSksZWw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltBYSx3YV19fSksdGw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6YmF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltzaXplRnJvbVNoYXBlJDEoYmEuc2hhcGUpL0ZhLEZhXX19KTtpZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW2JhLFNhXSl8fGJhLmR0eXBlPT09InN0cmluZyIpe2NvbnN0IG9sPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksYWw9eGEuYnVmZmVyU3luYyhiYSksbGw9Z2F0aGVyTmRJbXBsQ1BVJDEob2wsYWwsYmEuZHR5cGUsQWEsd2EsRmEsTGEsYmEuc2hhcGUsRWEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSxiYS5kdHlwZSxsbC52YWx1ZXMpfWNvbnN0IG5sPW5ldyBHYXRoZXJORFByb2dyYW0kMSh3YSxMYSxbQWEsRmFdLGJhLnNoYXBlKSxzbD14YS5ydW5XZWJHTFByb2dyYW0obmwsW3RsLGVsXSx0bC5kdHlwZSkscmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmthfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSxybH1jb25zdCBnYXRoZXJOZENvbmZpZyQxPXtrZXJuZWxOYW1lOkdhdGhlck5kJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmdhdGhlck5kJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBHYXRoZXJQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiLCJpbmRpY2VzIl0sdGhpcy5vdXRwdXRTaGFwZT14YSx0aGlzLnJhbms9eGEubGVuZ3RoO2NvbnN0IGJhPWdldENvb3Jkc0RhdGFUeXBlJDEodGhpcy5yYW5rKSxTYT1nZXRTb3VyY2VDb29yZHMkNChhYSk7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke2JhfSByZXNSQyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBpbmRleCA9IGludChnZXRJbmRpY2VzKHJlc1JDLngsIHJlc1JDLnopKTsKICAgICAgICBmbG9hdCBpbkJvdW5kcyA9IChpbmRleCA+PSAwKSAmJiAoaW5kZXggPCAke2FhWzJdfSkgPyAxLjAgOiAwLjA7CiAgICAgICAgc2V0T3V0cHV0KGluQm91bmRzICogZ2V0QSgke1NhfSkpOwogICAgICB9CiAgICBgfX07ZnVuY3Rpb24gZ2V0U291cmNlQ29vcmRzJDQoaGEsYWEpe2NvbnN0IHhhPVsicmVzUkMueCIsInJlc1JDLnkiLCJyZXNSQy56IiwicmVzUkMudyJdLGJhPVtdO2ZvcihsZXQgU2E9MDtTYTxoYS5sZW5ndGg7U2ErKylTYT09PTI/YmEucHVzaCgiaW5kZXgiKTpiYS5wdXNoKGAke3hhW1NhXX1gKTtyZXR1cm4gYmEuam9pbigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdhdGhlclYyJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxpbmRpY2VzOlRhfT1hYSx7YXhpczp3YSxiYXRjaERpbXM6RWF9PWJhLGthPXBhcnNlQXhpc1BhcmFtJDEod2EsU2Euc2hhcGUpWzBdO2lmKGVudiQxKCkuZ2V0KCJERUJVRyIpKXtjb25zdCBhbD14YS5yZWFkU3luYyhUYS5kYXRhSWQpLGxsPVNhLnNoYXBlW2thXTtmb3IobGV0IGlsPTA7aWw8YWwubGVuZ3RoOysraWwpe2NvbnN0IGNsPWFsW2lsXTthc3NlcnQkMihjbDw9bGwtMSYmY2w+PTAsKCk9PmBHYXRoZXJWMjogdGhlIGluZGV4IHZhbHVlICR7Y2x9IGlzIG5vdCBpbiBbMCwgJHtsbC0xfV1gKX19Y29uc3QgQWE9Y29sbGVjdEdhdGhlck9wU2hhcGVJbmZvJDEoU2EsVGEsa2EsRWEpLEZhPXNpemVGcm9tU2hhcGUkMShUYS5zaGFwZSksTGE9W10sZWw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltBYS5iYXRjaFNpemUsQWEub3V0ZXJTaXplLEFhLmRpbVNpemUsQWEuc2xpY2VTaXplXX19KSx0bD1yZXNoYXBlJDIoe2lucHV0czp7eDpUYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W0FhLmJhdGNoU2l6ZSxGYS9BYS5iYXRjaFNpemVdfX0pO0xhLnB1c2goZWwpLExhLnB1c2godGwpO2NvbnN0IG5sPVtBYS5iYXRjaFNpemUsQWEub3V0ZXJTaXplLEZhL0FhLmJhdGNoU2l6ZSxBYS5zbGljZVNpemVdO2lmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbU2EsVGFdKXx8U2EuZHR5cGU9PT0ic3RyaW5nIil7Y29uc3QgYWw9eGEuYnVmZmVyU3luYyh0bCksbGw9eGEuYnVmZmVyU3luYyhlbCksaWw9Z2F0aGVyVjJJbXBsQ1BVJDEobGwsYWwsbmwpO3JldHVybiBMYS5mb3JFYWNoKGNsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhjbCkpLHhhLm1ha2VUZW5zb3JJbmZvKEFhLm91dHB1dFNoYXBlLGlsLmR0eXBlLGlsLnZhbHVlcyl9Y29uc3Qgc2w9bmV3IEdhdGhlclByb2dyYW0kMShlbC5zaGFwZSxubCkscmw9eGEucnVuV2ViR0xQcm9ncmFtKHNsLFtlbCx0bF0sZWwuZHR5cGUpO0xhLnB1c2gocmwpO2NvbnN0IG9sPXJlc2hhcGUkMih7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpBYS5vdXRwdXRTaGFwZX19KTtyZXR1cm4gTGEuZm9yRWFjaChhbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpKSxvbH1jb25zdCBnYXRoZXJWMkNvbmZpZyQxPXtrZXJuZWxOYW1lOkdhdGhlclYyJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmdhdGhlclYyJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEdSRUFURVIkMT0icmV0dXJuIGZsb2F0KGEgPiBiKTsiLEdSRUFURVJfUEFDS0VEJDE9YAogIHJldHVybiB2ZWM0KGdyZWF0ZXJUaGFuKGEsIGIpKTsKYCxncmVhdGVyJDE9YmluYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6R1JFQVRFUiQxLHBhY2tlZE9wU25pcHBldDpHUkVBVEVSX1BBQ0tFRCQxLGNwdUtlcm5lbEltcGw6Z3JlYXRlckltcGxDUFUkMSxkdHlwZToiYm9vbCJ9KSxncmVhdGVyQ29uZmlnJDE9e2tlcm5lbE5hbWU6R3JlYXRlciQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpncmVhdGVyJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEdSRUFURVJfRVFVQUwkMT0icmV0dXJuIGZsb2F0KGEgPj0gYik7IixHUkVBVEVSX0VRVUFMX1BBQ0tFRCQxPWAKICByZXR1cm4gdmVjNChncmVhdGVyVGhhbkVxdWFsKGEsIGIpKTsKYCxncmVhdGVyRXF1YWwkMT1iaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpHUkVBVEVSX0VRVUFMJDEscGFja2VkT3BTbmlwcGV0OkdSRUFURVJfRVFVQUxfUEFDS0VEJDEsZHR5cGU6ImJvb2wiLGNwdUtlcm5lbEltcGw6Z3JlYXRlckVxdWFsSW1wbENQVSQxfSksZ3JlYXRlckVxdWFsQ29uZmlnJDE9e2tlcm5lbE5hbWU6R3JlYXRlckVxdWFsJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmdyZWF0ZXJFcXVhbCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpZmZ0JDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7aW5wdXQ6YmF9PWFhO3JldHVybiBmZnRJbXBsJDEoYmEsITAseGEpfWNvbnN0IGlmZnRDb25maWckMT17a2VybmVsTmFtZTpJRkZUJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmlmZnQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSVNfRklOSVRFJDE9InJldHVybiBmbG9hdCghaXNuYW4oeCkgJiYgIWlzaW5mKHgpKTsiLGlzRmluaXRlJDI9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpJU19GSU5JVEUkMSxkdHlwZToiYm9vbCJ9KSxpc0Zpbml0ZUNvbmZpZyQxPXtrZXJuZWxOYW1lOklzRmluaXRlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmlzRmluaXRlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IElTX0lORiQxPSJyZXR1cm4gZmxvYXQoaXNpbmYoeCkpOyIsaXNJbmYkMT11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OklTX0lORiQxLGR0eXBlOiJib29sIn0pLGlzSW5mQ29uZmlnJDE9e2tlcm5lbE5hbWU6SXNJbmYkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6aXNJbmYkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSVNfTkFOJDE9InJldHVybiBmbG9hdChpc25hbih4KSk7Iixpc05hTiQyPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6SVNfTkFOJDEsZHR5cGU6ImJvb2wifSksaXNOYU5Db25maWckMT17a2VybmVsTmFtZTpJc05hbiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzppc05hTiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMRVNTJDE9InJldHVybiBmbG9hdChhIDwgYik7IixMRVNTX1BBQ0tFRCQxPWAKICByZXR1cm4gdmVjNChsZXNzVGhhbihhLCBiKSk7CmAsbGVzcyQxPWJpbmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkxFU1MkMSxwYWNrZWRPcFNuaXBwZXQ6TEVTU19QQUNLRUQkMSxjcHVLZXJuZWxJbXBsOmxlc3NJbXBsQ1BVJDEsZHR5cGU6ImJvb2wifSksbGVzc0NvbmZpZyQxPXtrZXJuZWxOYW1lOkxlc3MkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bGVzcyQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMRVNTX0VRVUFMJDE9InJldHVybiBmbG9hdChhIDw9IGIpOyIsTEVTU19FUVVBTF9QQUNLRUQkMT1gCiAgcmV0dXJuIHZlYzQobGVzc1RoYW5FcXVhbChhLCBiKSk7CmAsbGVzc0VxdWFsJDE9YmluYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6TEVTU19FUVVBTCQxLHBhY2tlZE9wU25pcHBldDpMRVNTX0VRVUFMX1BBQ0tFRCQxLGNwdUtlcm5lbEltcGw6bGVzc0VxdWFsSW1wbENQVSQxLGR0eXBlOiJib29sIn0pLGxlc3NFcXVhbENvbmZpZyQxPXtrZXJuZWxOYW1lOkxlc3NFcXVhbCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsZXNzRXF1YWwkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbGluU3BhY2UkMShoYSl7Y29uc3R7YmFja2VuZDphYSxhdHRyczp4YX09aGEse3N0YXJ0OmJhLHN0b3A6U2EsbnVtOlRhfT14YSx3YT1saW5TcGFjZUltcGxDUFUkMShiYSxTYSxUYSk7cmV0dXJuIGFhLm1ha2VUZW5zb3JJbmZvKFt3YS5sZW5ndGhdLCJmbG9hdDMyIix3YSl9Y29uc3QgbGluU3BhY2VDb25maWckMT17a2VybmVsTmFtZTpMaW5TcGFjZSQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsaW5TcGFjZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMT0ckMT1DSEVDS19OQU5fU05JUFBFVF9VTkFSWSQxK2AKICByZXR1cm4geCA8IDAuMCA/IDAuLzAuIDogbG9nKHgpOwpgLExPR19QQUNLRUQkMT1gCiAgdmVjNCByZXN1bHQgPSBsb2coeCk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiAoeC5yIDwgMC4wID8gMC4vMC4gOiByZXN1bHQucik7CiAgcmVzdWx0LmcgPSBpc05hTi5nID8geC5nIDogKHguZyA8IDAuMCA/IDAuLzAuIDogcmVzdWx0LmcpOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6ICh4LmIgPCAwLjAgPyAwLi8wLiA6IHJlc3VsdC5iKTsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiAoeC5hIDwgMC4wID8gMC4vMC4gOiByZXN1bHQuYSk7CiAgcmV0dXJuIHJlc3VsdDsKYCxsb2ckMj11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkxPRyQxLHBhY2tlZE9wU25pcHBldDpMT0dfUEFDS0VEJDEsY3B1S2VybmVsSW1wbDpsb2dJbXBsQ1BVJDF9KSxsb2dDb25maWckMT17a2VybmVsTmFtZTpMb2ckMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bG9nJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExPRzFQJDE9Q0hFQ0tfTkFOX1NOSVBQRVRfVU5BUlkkMStgCiAgcmV0dXJuIGxvZygxLjAgKyB4KTsKYCxsb2cxcCQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6TE9HMVAkMX0pLGxvZzFwQ29uZmlnJDE9e2tlcm5lbE5hbWU6TG9nMXAkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bG9nMXAkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgTE9HSUNBTF9BTkQkMT0icmV0dXJuIGZsb2F0KGEgPj0gMS4wICYmIGIgPj0gMS4wKTsiLExPR0lDQUxfQU5EX1BBQ0tFRCQxPWAKICByZXR1cm4gdmVjNCgKICAgIHZlYzQoZ3JlYXRlclRoYW5FcXVhbChhLCB2ZWM0KDEuMCkpKSAqCiAgICB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoYiwgdmVjNCgxLjApKSkpOwpgLGxvZ2ljYWxBbmQkMT1iaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpMT0dJQ0FMX0FORCQxLHBhY2tlZE9wU25pcHBldDpMT0dJQ0FMX0FORF9QQUNLRUQkMSxkdHlwZToiYm9vbCJ9KSxsb2dpY2FsQW5kQ29uZmlnJDE9e2tlcm5lbE5hbWU6TG9naWNhbEFuZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsb2dpY2FsQW5kJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExPR0lDQUxfTk9UJDE9InJldHVybiBmbG9hdCghKHggPj0gMS4wKSk7Iixsb2dpY2FsTm90JDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpMT0dJQ0FMX05PVCQxfSksbG9naWNhbE5vdENvbmZpZyQxPXtrZXJuZWxOYW1lOkxvZ2ljYWxOb3QkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bG9naWNhbE5vdCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMT0dJQ0FMX09SJDE9InJldHVybiBmbG9hdChhID49IDEuMCB8fCBiID49IDEuMCk7IixMT0dJQ0FMX09SX1BBQ0tFRCQxPWAKICByZXR1cm4gbWluKAogICAgdmVjNChncmVhdGVyVGhhbkVxdWFsKGEsIHZlYzQoMS4wKSkpICsKICAgIHZlYzQoZ3JlYXRlclRoYW5FcXVhbChiLCB2ZWM0KDEuMCkpKSwKICAgIHZlYzQoMS4wKSk7CmAsbG9naWNhbE9yJDE9YmluYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6TE9HSUNBTF9PUiQxLHBhY2tlZE9wU25pcHBldDpMT0dJQ0FMX09SX1BBQ0tFRCQxLGR0eXBlOiJib29sIn0pLGxvZ2ljYWxPckNvbmZpZyQxPXtrZXJuZWxOYW1lOkxvZ2ljYWxPciQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsb2dpY2FsT3IkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IExSTlByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMub3V0cHV0U2hhcGU9W107Y29uc3Qgd2E9eGEsRWE9YWFbM10tMTt0aGlzLm91dHB1dFNoYXBlPWFhO2xldCBrYTtjb25zdCBBYT1gZmxvYXQoJHtiYX0pICsgZmxvYXQoJHtTYX0pICogc3VtYDtUYT09PS41P2thPWBpbnZlcnNlc3FydCgke0FhfSlgOlRhPT09MT9rYT1gMS4wLygke0FhfSlgOmthPWBleHAobG9nKCR7QWF9KSAqIGZsb2F0KC0ke1RhfSkpO2AsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgciA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgYyA9IGNvb3Jkc1syXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKICAgICAgICBmbG9hdCB4ID0gZ2V0WChiLCByLCBjLCBkKTsKICAgICAgICBmbG9hdCBzdW0gPSAwLjA7CiAgICAgICAgZm9yIChpbnQgaiA9IC0ke3dhfTsgaiA8PSAke3dhfTsgaisrKSB7CiAgICAgICAgICBpbnQgaWR4ID0gZCArIGo7CiAgICAgICAgICBpZiAoaWR4ID49IDAgJiYgaWR4IDw9ICAke0VhfSkgewogICAgICAgICAgICBmbG9hdCB6ID0gZ2V0WChiLCByLCBjLCBpZHgpOwogICAgICAgICAgICBzdW0gKz0geiAqIHo7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZsb2F0IHZhbCA9IHggKiAke2thfTsKICAgICAgICBzZXRPdXRwdXQodmFsKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBMUk5QYWNrZWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwO2NvbnN0IHdhPXhhLEVhPWFhWzNdLTE7dGhpcy5vdXRwdXRTaGFwZT1hYTtsZXQga2E7Y29uc3QgQWE9YGZsb2F0KCR7YmF9KSArIGZsb2F0KCR7U2F9KSAqIHN1bWA7VGE9PT0uNT9rYT1gaW52ZXJzZXNxcnQoJHtBYX0pYDpUYT09PTE/a2E9YDEuMC8oJHtBYX0pYDprYT1gZXhwKGxvZygke0FhfSkgKiBmbG9hdCgtJHtUYX0pKTtgLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHMueDsKICAgICAgICBpbnQgciA9IGNvb3Jkcy55OwogICAgICAgIGludCBjID0gY29vcmRzLno7CiAgICAgICAgaW50IGQgPSBjb29yZHMudzsKCiAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gZCA8ICR7dGhpcy5vdXRwdXRTaGFwZVszXX07CiAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gYyA8ICR7dGhpcy5vdXRwdXRTaGFwZVsyXX07CgogICAgICAgIHZlYzQgc3VtID0gdmVjNCgwLik7CiAgICAgICAgdmVjNCB4RnJhZ0F0T3V0cHV0Q29vcmRzID0gZ2V0WChiLCByLCBjLCBkKTsKCiAgICAgICAgdmVjNCB4QXRPdXRwdXRDb29yZHMgPSB2ZWM0KAogICAgICAgICAgZ2V0Q2hhbm5lbCh4RnJhZ0F0T3V0cHV0Q29vcmRzLCB2ZWMyKGMsIGQpKSwKICAgICAgICAgIGhhc05leHRDb2wgPwogICAgICAgICAgICBnZXRDaGFubmVsKHhGcmFnQXRPdXRwdXRDb29yZHMsIHZlYzIoYywgZCArIDEpKSA6IDAuMCwKICAgICAgICAgIGhhc05leHRSb3cgPwogICAgICAgICAgICBnZXRDaGFubmVsKHhGcmFnQXRPdXRwdXRDb29yZHMgLCB2ZWMyKGMgKyAxLCBkKSkgOiAwLjAsCiAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/CiAgICAgICAgICAgIGdldENoYW5uZWwoeEZyYWdBdE91dHB1dENvb3JkcywgdmVjMihjICsgMSwgZCArIDEpKSA6IDAuMAogICAgICAgICk7CgogICAgICAgIGludCBmaXJzdENoYW5uZWwgPSBkIC0gJHt3YX07CiAgICAgICAgdmVjMiBjYWNoZSA9IHZlYzIoMC4pOwogICAgICAgIGlmKGZpcnN0Q2hhbm5lbCA+PSAwKXsKICAgICAgICAgIHZlYzQgZmlyc3RDaGFubmVsRnJhZyA9IGdldFgoYiwgciwgYywgZmlyc3RDaGFubmVsKTsKICAgICAgICAgIGNhY2hlLnggPSBnZXRDaGFubmVsKGZpcnN0Q2hhbm5lbEZyYWcsIHZlYzIoYywgZmlyc3RDaGFubmVsKSk7CiAgICAgICAgICAgIGlmKGhhc05leHRSb3cpewogICAgICAgICAgICAgIGNhY2hlLnkgPSBnZXRDaGFubmVsKGZpcnN0Q2hhbm5lbEZyYWcsIHZlYzIoYyArIDEsIGZpcnN0Q2hhbm5lbCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpdmVjMiBkZXB0aCA9IGl2ZWMyKGQsIGQgKyAxKTsKICAgICAgICBmb3IgKGludCBqID0gLSAke3dhfTsgaiA8PSAke3dhfTsgaisrKSB7CiAgICAgICAgICBpdmVjMiBpZHggPSBkZXB0aCArIGo7CiAgICAgICAgICBidmVjMiBhYm92ZUxvd2VyQm91bmQgPSBncmVhdGVyVGhhbkVxdWFsKGlkeCwgaXZlYzIoMCkpOwogICAgICAgICAgYnZlYzIgYmVsb3dVcHBlckJvdW5kID0gbGVzc1RoYW5FcXVhbChpZHgsIGl2ZWMyKCR7RWF9KSk7CgogICAgICAgICAgYm9vbCBkZXB0aEluUmFuZ2UgPSBhYm92ZUxvd2VyQm91bmQueCAmJiBiZWxvd1VwcGVyQm91bmQueDsKICAgICAgICAgIGJvb2wgZGVwdGhQbHVzT25lSW5SYW5nZSA9IGFib3ZlTG93ZXJCb3VuZC55ICYmIGJlbG93VXBwZXJCb3VuZC55OwoKICAgICAgICAgIGlmKGRlcHRoSW5SYW5nZSB8fCBkZXB0aFBsdXNPbmVJblJhbmdlKXsKICAgICAgICAgICAgdmVjNCB6ID0gdmVjNCgwLik7CiAgICAgICAgICAgIHZlYzQgeEZyYWdBdEN1cnJlbnREZXB0aDsKICAgICAgICAgICAgei54eiA9IGNhY2hlLnh5OwogICAgICAgICAgICBpZihkZXB0aFBsdXNPbmVJblJhbmdlICYmIGhhc05leHRDb2wpewogICAgICAgICAgICAgIHhGcmFnQXRDdXJyZW50RGVwdGggPSBpZHgueSAhPSBkID8KICAgICAgICAgICAgICAgIGdldFgoYiwgciwgYywgaWR4LnkpIDogeEZyYWdBdE91dHB1dENvb3JkczsKICAgICAgICAgICAgICB6LnkgPSBnZXRDaGFubmVsKHhGcmFnQXRDdXJyZW50RGVwdGgsIHZlYzIoYywgaWR4LnkpKTsKICAgICAgICAgICAgICBpZihoYXNOZXh0Um93KXsKICAgICAgICAgICAgICAgIHoudyA9IGdldENoYW5uZWwoeEZyYWdBdEN1cnJlbnREZXB0aCwgdmVjMihjICsgMSwgaWR4LnkpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FjaGUueHkgPSB6Lnl3OwogICAgICAgICAgICBzdW0gKz0geiAqIHo7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHZlYzQgcmVzdWx0ID0geEF0T3V0cHV0Q29vcmRzICogJHtrYX07CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBscm4kMT1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2RlcHRoUmFkaXVzOlRhLGJpYXM6d2EsYWxwaGE6RWEsYmV0YTprYX09YmEsQWE9ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLX05PUk1BTElaQVRJT04iKT9uZXcgTFJOUGFja2VkUHJvZ3JhbSQxKFNhLnNoYXBlLFRhLHdhLEVhLGthKTpuZXcgTFJOUHJvZ3JhbSQxKFNhLnNoYXBlLFRhLHdhLEVhLGthKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEFhLFtTYV0sU2EuZHR5cGUpfSxMUk5Db25maWckMT17a2VybmVsTmFtZTpMUk4kMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bHJuJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBMUk5HcmFkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJpbnB1dEltYWdlIiwib3V0cHV0SW1hZ2UiLCJkeSJdLHRoaXMub3V0cHV0U2hhcGU9W10sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmRlcHRoPWFhWzNdLHRoaXMuZGVwdGhSYWRpdXM9eGEsdGhpcy5iaWFzPWJhLHRoaXMuYWxwaGE9U2EsdGhpcy5iZXRhPVRhLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IHIgPSBjb29yZHNbMV07CiAgICAgICAgaW50IGMgPSBjb29yZHNbMl07CgogICAgICAgIGZsb2F0IHJlc3VsdCA9IDAuMDsKICAgICAgICBmb3IgKGludCBkID0gMDsgZCA8ICR7dGhpcy5kZXB0aH07ICsrZCkgewogICAgICAgICAgaW50IGRlcHRoQmVnaW4gPSBpbnQobWF4KDAuMCwgZmxvYXQoZCAtICR7eGF9KSkpOwogICAgICAgICAgaW50IGRlcHRoRW5kID0gaW50KG1pbihmbG9hdCgke3RoaXMuZGVwdGh9KSwKICAgICAgICAgICAgICBmbG9hdChkICsgJHt4YX0gKyAxKSkpOwoKICAgICAgICAgIGNvbnN0IGludCBNSU5fREVQVEhfQkVHSU4gPSAwOwogICAgICAgICAgY29uc3QgaW50IE1BWF9ERVBUSF9FTkQgPSAke3RoaXMuZGVwdGh9OwoKICAgICAgICAgIGZsb2F0IG5vcm0gPSAwLjA7CiAgICAgICAgICBmb3IgKGludCBrID0gTUlOX0RFUFRIX0JFR0lOOyBrIDwgTUFYX0RFUFRIX0VORDsgKytrKSB7CiAgICAgICAgICAgIGlmIChrIDwgZGVwdGhCZWdpbil7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoayA+PSBkZXB0aEJlZ2luICYmIGsgPCBkZXB0aEVuZCkgewogICAgICAgICAgICAgIG5vcm0gKz0gZ2V0SW5wdXRJbWFnZShiLCByLCBjLCBrKSAqIGdldElucHV0SW1hZ2UoYiwgciwgYywgayk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBub3JtID0gZmxvYXQoJHtTYX0pICogbm9ybSArIGZsb2F0KCR7YmF9KTsKCiAgICAgICAgICBmb3IoaW50IGsgPSBNSU5fREVQVEhfQkVHSU47IGsgPCBNQVhfREVQVEhfRU5EOyArK2spewogICAgICAgICAgICBpZiAoayA8IGRlcHRoQmVnaW4pewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGsgPj0gZGVwdGhCZWdpbiAmJiBrIDwgZGVwdGhFbmQpewogICAgICAgICAgICAgIGZsb2F0IGR5aSA9IC0yLjAgKiBmbG9hdCgke1NhfSkKICAgICAgICAgICAgICAgICogZmxvYXQoJHtUYX0pCiAgICAgICAgICAgICAgICAqIGdldElucHV0SW1hZ2UoYiwgciwgYywgaykgKiBnZXRPdXRwdXRJbWFnZShiLCByLCBjLCBkKQogICAgICAgICAgICAgICAgLyBub3JtOwogICAgICAgICAgICAgIGlmIChrID09IGQpIHsKICAgICAgICAgICAgICAgIGR5aSArPSBwb3cobm9ybSwgLTEuMCAqICR7VGF9KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGsgPT0gY29vcmRzWzNdKSB7CiAgICAgICAgICAgICAgICBkeWkgKj0gZ2V0RHkoYiwgciwgYywgZCk7CiAgICAgICAgICAgICAgICByZXN1bHQgKz0gZHlpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CiAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbHJuR3JhZCQxPWhhPT57Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLHk6VGEsZHk6d2F9PWFhLHtkZXB0aFJhZGl1czpFYSxiaWFzOmthLGFscGhhOkFhLGJldGE6RmF9PWJhLExhPW5ldyBMUk5HcmFkUHJvZ3JhbSQxKFNhLnNoYXBlLEVhLGthLEFhLEZhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYSxUYSx3YV0sU2EuZHR5cGUpfSxMUk5HcmFkQ29uZmlnJDE9e2tlcm5lbE5hbWU6TFJOR3JhZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpscm5HcmFkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heEltcGwkMihoYSxhYSx4YSxiYSl7Y29uc3QgU2E9c2l6ZUZyb21TaGFwZSQxKGFhKSx3YT1zaXplRnJvbVNoYXBlJDEoaGEuc2hhcGUpL1NhLEVhPXJlc2hhcGUkMih7aW5wdXRzOnt4OmhhfSxhdHRyczp7c2hhcGU6W3dhLFNhXX0sYmFja2VuZDpiYX0pLGthPXJlZHVjZSQxKEVhLGhhLmR0eXBlLCJtYXgiLGJhKSxBYT1yZXNoYXBlJDIoe2lucHV0czp7eDprYX0sYXR0cnM6e3NoYXBlOnhhfSxiYWNrZW5kOmJhfSk7cmV0dXJuIGJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEVhKSxiYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhrYSksQWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4JDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse3JlZHVjdGlvbkluZGljZXM6VGEsa2VlcERpbXM6d2F9PWJhLEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtsZXQgQWE9a2E7Y29uc3QgRmE9Z2V0QXhlc1Blcm11dGF0aW9uJDEoQWEsRWEpLExhPUZhIT1udWxsLGVsPXhhLnNob3VsZEV4ZWN1dGVPbkNQVShbU2FdKTtsZXQgdGw9U2E7aWYoTGEpe2lmKGVsKXtjb25zdCBsbD14YS50ZXhEYXRhLmdldCh0bC5kYXRhSWQpLnZhbHVlcyxpbD1uZXcgQXJyYXkoRWEpO2ZvcihsZXQgZGw9MDtkbDxpbC5sZW5ndGg7ZGwrKylpbFtkbF09U2Euc2hhcGVbRmFbZGxdXTtjb25zdCBjbD10cmFuc3Bvc2VJbXBsQ1BVJDEobGwsU2Euc2hhcGUsU2EuZHR5cGUsRmEsaWwpO3RsPXhhLm1ha2VUZW5zb3JJbmZvKGlsLFNhLmR0eXBlKTtjb25zdCB1bD14YS50ZXhEYXRhLmdldCh0bC5kYXRhSWQpO3VsLnZhbHVlcz1jbH1lbHNlIHRsPXRyYW5zcG9zZUltcGwkMihTYSxGYSx4YSk7QWE9Z2V0SW5uZXJNb3N0QXhlcyQxKEFhLmxlbmd0aCxFYSl9YXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgibWF4IixBYSxFYSk7Y29uc3Rbbmwsc2xdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMkMSh0bC5zaGFwZSxBYSk7bGV0IHJsPW5sO3dhJiYocmw9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShubCxrYSkpO2xldCBvbDtpZihlbCl7Y29uc3QgbGw9eGEudGV4RGF0YS5nZXQodGwuZGF0YUlkKS52YWx1ZXMsaWw9bWF4SW1wbENQVSQxKGxsLHNpemVGcm9tU2hhcGUkMShzbCkscmwsU2EuZHR5cGUpO29sPXhhLm1ha2VUZW5zb3JJbmZvKHJsLFNhLmR0eXBlKTtjb25zdCBjbD14YS50ZXhEYXRhLmdldChvbC5kYXRhSWQpO2NsLnZhbHVlcz1pbH1lbHNlIG9sPW1heEltcGwkMih0bCxzbCxybCx4YSk7cmV0dXJuIExhJiZ4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh0bCksb2x9Y29uc3QgbWF4Q29uZmlnJDE9e2tlcm5lbE5hbWU6TWF4JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1heCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBNQVhJTVVNJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMitgCiAgcmV0dXJuIG1heChhLCBiKTsKYCxNQVhJTVVNX1BBQ0tFRCQxPWAKICB2ZWM0IHJlc3VsdCA9IHZlYzQobWF4KGEsIGIpKTsKICBidmVjNCBpc05hTkEgPSBpc25hbihhKTsKICBidmVjNCBpc05hTkIgPSBpc25hbihiKTsKICBidmVjNCBpc05hTiA9IGJ2ZWM0KGlzTmFOQS54IHx8IGlzTmFOQi54LCBpc05hTkEueSB8fCBpc05hTkIueSwgaXNOYU5BLnogfHwgaXNOYU5CLnosIGlzTmFOQS53IHx8IGlzTmFOQi53KTsKICBgK0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCQxK2AKICByZXR1cm4gcmVzdWx0OwpgLG1heGltdW0kMj1iaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpNQVhJTVVNJDEscGFja2VkT3BTbmlwcGV0Ok1BWElNVU1fUEFDS0VEJDEsY3B1S2VybmVsSW1wbDptYXhpbXVtSW1wbENQVSQxfSksbWF4aW11bUNvbmZpZyQxPXtrZXJuZWxOYW1lOk1heGltdW0kMixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bWF4aW11bSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhQb29sJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWE7YXNzZXJ0Tm90Q29tcGxleCQxKFNhLCJtYXhQb29sIik7Y29uc3R7ZmlsdGVyU2l6ZTpUYSxzdHJpZGVzOndhLHBhZDpFYSxkaW1Sb3VuZGluZ01vZGU6a2F9PWJhLEFhPTE7YXNzZXJ0JDIoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lJDEod2EsQWEpLCgpPT5gRXJyb3IgaW4gbWF4UG9vbDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt3YX0gYW5kIGRpbGF0aW9ucyAnJHtBYX0nYCk7Y29uc3QgRmE9Y29tcHV0ZVBvb2wyREluZm8kMShTYS5zaGFwZSxUYSx3YSxBYSxFYSxrYSk7aWYoRmEuZmlsdGVyV2lkdGg9PT0xJiZGYS5maWx0ZXJIZWlnaHQ9PT0xJiZhcnJheXNFcXVhbCQxKEZhLmluU2hhcGUsRmEub3V0U2hhcGUpKXJldHVybiBpZGVudGl0eSQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtjb25zdCBMYT1uZXcgUG9vbDJEUHJvZ3JhbSQxKEZhLCJtYXgiLCExKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sU2EuZHR5cGUpfWNvbnN0IG1heFBvb2xDb25maWckMT17a2VybmVsTmFtZTpNYXhQb29sJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1heFBvb2wkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4UG9vbDNkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2ZpbHRlclNpemU6VGEsc3RyaWRlczp3YSxwYWQ6RWEsZGF0YUZvcm1hdDprYSxkaW1Sb3VuZGluZ01vZGU6QWF9PWJhLEZhPVsxLDEsMV0sTGE9Y29tcHV0ZVBvb2wzREluZm8kMShTYS5zaGFwZSxUYSx3YSxGYSxFYSxBYSxrYSksZWw9bmV3IFBvb2wzRFByb2dyYW0kMShMYSwibWF4IiwhMSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShlbCxbU2FdLFNhLmR0eXBlKX1jb25zdCBtYXhQb29sM0RDb25maWckMT17a2VybmVsTmFtZTpNYXhQb29sM0QkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bWF4UG9vbDNkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBNYXhQb29sMkRCYWNrcHJvcFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiZHkiLCJtYXhQb3MiXSx0aGlzLm91dHB1dFNoYXBlPWFhLmluU2hhcGU7Y29uc3QgeGE9YWEuc3RyaWRlSGVpZ2h0LGJhPWFhLnN0cmlkZVdpZHRoLFNhPWFhLmRpbGF0aW9uSGVpZ2h0LFRhPWFhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCx3YT1hYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxFYT1UYS0xLWFhLnBhZEluZm8udG9wLGthPXdhLTEtYWEucGFkSW5mby5sZWZ0LEFhPVRhKndhLTE7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke0VhfSwgJHtrYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwoKICAgICAgICBpdmVjMiBkeVJDQ29ybmVyID0gY29vcmRzLnl6IC0gcGFkczsKICAgICAgICBpbnQgZHlSQ29ybmVyID0gZHlSQ0Nvcm5lci54OwogICAgICAgIGludCBkeUNDb3JuZXIgPSBkeVJDQ29ybmVyLnk7CgogICAgICAgIC8vIENvbnZvbHZlIGR5KD8sID8sIGQpIHdpdGggcG9zIG1hc2soOiwgOiwgZCkgdG8gZ2V0IGR4KHhSLCB4QywgZCkuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsIHZhbHVlcyBpbiB0aGF0IGF4aXMuCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHtUYX07CiAgICAgICAgICB3UiArPSAke1NhfSkgewogICAgICAgICAgZmxvYXQgZHlSID0gZmxvYXQoZHlSQ29ybmVyICsgd1IpIC8gJHt4YX0uMDsKCiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHt3YX07IHdDKyspIHsKICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gJHtiYX0uMDsKCiAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgIGZyYWN0KGR5QykgPiAwLjApIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWR5QyA9IGludChkeUMpOwoKICAgICAgICAgICAgZmxvYXQgZHlWYWx1ZSA9IGdldER5KGIsIGlkeVIsIGlkeUMsIGQpOwogICAgICAgICAgICBpbnQgbWF4UG9zVmFsdWUgPSAke0FhfSAtIGludChnZXRNYXhQb3MoYiwgaWR5UiwgaWR5QywgZCkpOwoKICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IHZhbHVlLCBjaGVjayBpdCBhZ2FpbnN0IHRoZSB2YWx1ZSBmcm9tIHRoZQogICAgICAgICAgICAvLyBwb3NpdGlvbiBtYXRyaXguCiAgICAgICAgICAgIGludCBjdXJQb3NWYWx1ZSA9IHdSICogJHt3YX0gKyB3QzsKICAgICAgICAgICAgZmxvYXQgbWFzayA9IGZsb2F0KG1heFBvc1ZhbHVlID09IGN1clBvc1ZhbHVlID8gMS4wIDogMC4wKTsKCiAgICAgICAgICAgIGRvdFByb2QgKz0gZHlWYWx1ZSAqIG1hc2s7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19LE1heFBvb2wzREJhY2twcm9wUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSIsIm1heFBvcyJdLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZTtjb25zdCB4YT1hYS5zdHJpZGVEZXB0aCxiYT1hYS5zdHJpZGVIZWlnaHQsU2E9YWEuc3RyaWRlV2lkdGgsVGE9YWEuZGlsYXRpb25EZXB0aCx3YT1hYS5kaWxhdGlvbkhlaWdodCxFYT1hYS5kaWxhdGlvbldpZHRoLGthPWFhLmVmZmVjdGl2ZUZpbHRlckRlcHRoLEFhPWFhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCxGYT1hYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxMYT1rYS0xLWFhLnBhZEluZm8uZnJvbnQsZWw9QWEtMS1hYS5wYWRJbmZvLnRvcCx0bD1GYS0xLWFhLnBhZEluZm8ubGVmdCxubD1rYSpBYSpGYS0xO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMyBwYWRzID0gaXZlYzMoJHtMYX0sICR7ZWx9LCAke3RsfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzUgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaW50IGNoID0gY29vcmRzLnU7CgogICAgICAgIGl2ZWMzIGR5Q29ybmVyID0gaXZlYzMoY29vcmRzLnksIGNvb3Jkcy56LCBjb29yZHMudykgLSBwYWRzOwogICAgICAgIGludCBkeURDb3JuZXIgPSBkeUNvcm5lci54OwogICAgICAgIGludCBkeVJDb3JuZXIgPSBkeUNvcm5lci55OwogICAgICAgIGludCBkeUNDb3JuZXIgPSBkeUNvcm5lci56OwoKICAgICAgICAvLyBDb252b2x2ZSBkeSg/LCA/LCA/LCBjaCkgd2l0aCBwb3MgbWFzayg6LCA6LCA6LCBkKSB0byBnZXQKICAgICAgICAvLyBkeCh4RCwgeFIsIHhDLCBjaCkuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsIHZhbHVlcyBpbiB0aGF0IGF4aXMuCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgd0QgPSAwOyB3RCA8ICR7a2F9OwogICAgICAgICAgIHdEICs9ICR7VGF9KSB7CiAgICAgICAgICBmbG9hdCBkeUQgPSBmbG9hdChkeURDb3JuZXIgKyB3RCkgLyAke3hhfS4wOwoKICAgICAgICAgIGlmIChkeUQgPCAwLjAgfHwgZHlEID49ICR7YWEub3V0RGVwdGh9LjAgfHwgZnJhY3QoZHlEKSA+IDAuMCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBpZHlEID0gaW50KGR5RCk7CgogICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7QWF9OwogICAgICAgICAgICAgIHdSICs9ICR7d2F9KSB7CiAgICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvICR7YmF9LjA7CgogICAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fAogICAgICAgICAgICAgICAgZnJhY3QoZHlSKSA+IDAuMCkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBpZHlSID0gaW50KGR5Uik7CgogICAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtGYX07CiAgICAgICAgICAgICAgICB3QyArPSAke0VhfSkgewogICAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7U2F9LjA7CgogICAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgICAgZnJhY3QoZHlDKSA+IDAuMCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICAgIGZsb2F0IGR5VmFsdWUgPSBnZXREeShiYXRjaCwgaWR5RCwgaWR5UiwgaWR5QywgY2gpOwogICAgICAgICAgICAgIGludCBtYXhQb3NWYWx1ZSA9ICR7bmx9IC0KICAgICAgICAgICAgICAgICAgaW50KGdldE1heFBvcyhiYXRjaCwgaWR5RCwgaWR5UiwgaWR5QywgY2gpKTsKCiAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IHZhbHVlLCBjaGVjayBpdCBhZ2FpbnN0IHRoZSB2YWx1ZSBmcm9tIHRoZQogICAgICAgICAgICAgIC8vIHBvc2l0aW9uIG1hdHJpeC4KICAgICAgICAgICAgICBpbnQgY3VyUG9zVmFsdWUgPQogICAgICAgICAgICAgICAgICB3RCAqICR7QWF9ICogJHtGYX0gKwogICAgICAgICAgICAgICAgICB3UiAqICR7RmF9ICsgd0M7CiAgICAgICAgICAgICAgZmxvYXQgbWFzayA9IGZsb2F0KG1heFBvc1ZhbHVlID09IGN1clBvc1ZhbHVlID8gMS4wIDogMC4wKTsKCiAgICAgICAgICAgICAgZG90UHJvZCArPSBkeVZhbHVlICogbWFzazsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoZG90UHJvZCk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhQb29sM0RHcmFkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsaW5wdXQ6VGF9PWFhLHdhPVRhLHtmaWx0ZXJTaXplOkVhLHN0cmlkZXM6a2EscGFkOkFhLGRpbVJvdW5kaW5nTW9kZTpGYX09YmEsTGE9WzEsMSwxXSxlbD1jb21wdXRlUG9vbDNESW5mbyQxKHdhLnNoYXBlLEVhLGthLExhLEFhLEZhKSx0bD1uZXcgUG9vbDNEUHJvZ3JhbSQxKGVsLCJtYXgiLCEwKSxubD14YS5ydW5XZWJHTFByb2dyYW0odGwsW3dhXSx3YS5kdHlwZSksc2w9bmV3IE1heFBvb2wzREJhY2twcm9wUHJvZ3JhbSQxKGVsKSxybD14YS5ydW5XZWJHTFByb2dyYW0oc2wsW1NhLG5sXSx3YS5kdHlwZSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSxybH1jb25zdCBtYXhQb29sM0RHcmFkQ29uZmlnJDE9e2tlcm5lbE5hbWU6TWF4UG9vbDNER3JhZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptYXhQb29sM0RHcmFkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2xHcmFkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsaW5wdXQ6VGEsb3V0cHV0OndhfT1hYSxFYT1UYTthc3NlcnROb3RDb21wbGV4JDEoW1RhLHdhXSwibWF4UG9vbEdyYWQiKTtjb25zdHtmaWx0ZXJTaXplOmthLHN0cmlkZXM6QWEscGFkOkZhLGRpbVJvdW5kaW5nTW9kZTpMYX09YmEsZWw9Y29tcHV0ZVBvb2wyREluZm8kMShFYS5zaGFwZSxrYSxBYSwxLEZhLExhKSx0bD0hMCxubD1uZXcgUG9vbDJEUHJvZ3JhbSQxKGVsLCJtYXgiLHRsKSxzbD14YS5ydW5XZWJHTFByb2dyYW0obmwsW0VhXSxFYS5kdHlwZSkscmw9bmV3IE1heFBvb2wyREJhY2twcm9wUHJvZ3JhbSQxKGVsKSxvbD14YS5ydW5XZWJHTFByb2dyYW0ocmwsW1NhLHNsXSxFYS5kdHlwZSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSxvbH1jb25zdCBtYXhQb29sR3JhZENvbmZpZyQxPXtrZXJuZWxOYW1lOk1heFBvb2xHcmFkJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1heFBvb2xHcmFkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2xXaXRoQXJnbWF4SW1wbCQxKGhhLGFhLHhhLGJhKXtsZXQgU2E9bmV3IFBvb2wyRFByb2dyYW0kMSh4YSwibWF4IiwhMSk7Y29uc3QgVGE9YmEucnVuV2ViR0xQcm9ncmFtKFNhLFtoYV0sImZsb2F0MzIiKTtTYT1uZXcgUG9vbDJEUHJvZ3JhbSQxKHhhLCJtYXgiLCEwLCEwLGFhKTtjb25zdCB3YT1iYS5ydW5XZWJHTFByb2dyYW0oU2EsW2hhXSwiZmxvYXQzMiIpO3JldHVybltUYSx3YV19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWF4UG9vbFdpdGhBcmdtYXhDb25maWckMT17a2VybmVsTmFtZTpNYXhQb29sV2l0aEFyZ21heCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzooe2lucHV0czpoYSxhdHRyczphYSxiYWNrZW5kOnhhfSk9Pntjb25zdHt4OmJhfT1oYSx7ZmlsdGVyU2l6ZTpTYSxzdHJpZGVzOlRhLHBhZDp3YSxpbmNsdWRlQmF0Y2hJbkluZGV4OkVhfT1hYSxrYT14YTthc3NlcnQkMihiYS5zaGFwZS5sZW5ndGg9PT00LCgpPT5gRXJyb3IgaW4gbWF4UG9vbDogaW5wdXQgbXVzdCBiZSByYW5rIDQgYnV0IGdvdCByYW5rICR7YmEuc2hhcGUubGVuZ3RofS5gKTtjb25zdCBBYT1bMSwxXTthc3NlcnQkMihlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUkMShUYSxBYSksKCk9PmBFcnJvciBpbiBtYXhQb29sOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke1RhfSBhbmQgZGlsYXRpb25zICcke0FhfSdgKTtjb25zdCBGYT1jb21wdXRlUG9vbDJESW5mbyQxKGJhLnNoYXBlLFNhLFRhLEFhLHdhKSxbTGEsZWxdPW1heFBvb2xXaXRoQXJnbWF4SW1wbCQxKGJhLEVhLEZhLGthKTtyZXR1cm5bTGEsZWxdfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWVhbkltcGwkMShoYSxhYSx4YSxiYSl7Y29uc3QgU2E9c2l6ZUZyb21TaGFwZSQxKGFhKSx3YT1zaXplRnJvbVNoYXBlJDEoaGEuc2hhcGUpL1NhLEVhPXJlc2hhcGUkMih7aW5wdXRzOnt4OmhhfSxhdHRyczp7c2hhcGU6W3dhLFNhXX0sYmFja2VuZDpiYX0pLGthPXJlZHVjZSQxKEVhLCJmbG9hdDMyIiwibWVhbiIsYmEpLEFhPXJlc2hhcGUkMih7aW5wdXRzOnt4OmthfSxhdHRyczp7c2hhcGU6eGF9LGJhY2tlbmQ6YmF9KTtyZXR1cm4gYmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLGJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGthKSxBYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBtZWFuQ29uZmlnJDE9e2tlcm5lbE5hbWU6TWVhbiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzooe2lucHV0czpoYSxhdHRyczphYSxiYWNrZW5kOnhhfSk9Pntjb25zdHt4OmJhfT1oYSx7a2VlcERpbXM6U2EsYXhpczpUYX09YWEsd2E9eGEsRWE9YmEuc2hhcGUubGVuZ3RoLGthPXBhcnNlQXhpc1BhcmFtJDEoVGEsYmEuc2hhcGUpO2xldCBBYT1rYTtjb25zdCBGYT1nZXRBeGVzUGVybXV0YXRpb24kMShBYSxFYSksTGE9RmEhPW51bGwsZWw9d2Euc2hvdWxkRXhlY3V0ZU9uQ1BVKFtiYV0pLHRsPVtdO2xldCBubD1iYTtpZihMYSl7aWYoZWwpe2NvbnN0IGlsPXdhLnRleERhdGEuZ2V0KG5sLmRhdGFJZCkudmFsdWVzLGNsPW5ldyBBcnJheShFYSk7Zm9yKGxldCBobD0wO2hsPGNsLmxlbmd0aDtobCsrKWNsW2hsXT1iYS5zaGFwZVtGYVtobF1dO2NvbnN0IHVsPXRyYW5zcG9zZUltcGxDUFUkMShpbCxiYS5zaGFwZSxiYS5kdHlwZSxGYSxjbCk7bmw9d2EubWFrZVRlbnNvckluZm8oY2wsYmEuZHR5cGUpO2NvbnN0IGRsPXdhLnRleERhdGEuZ2V0KG5sLmRhdGFJZCk7ZGwudmFsdWVzPXVsfWVsc2Ugbmw9dHJhbnNwb3NlSW1wbCQyKGJhLEZhLHdhKTt0bC5wdXNoKG5sKSxBYT1nZXRJbm5lck1vc3RBeGVzJDEoQWEubGVuZ3RoLEVhKX1hc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcyQxKCJzdW0iLEFhLEVhKTtjb25zdFtzbCxybF09Y29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyQxKG5sLnNoYXBlLEFhKTtsZXQgb2w9c2w7U2EmJihvbD1leHBhbmRTaGFwZVRvS2VlcERpbSQxKHNsLGthKSk7Y29uc3QgYWw9bWVhbkltcGwkMShubCxybCxvbCx3YSk7Zm9yKGNvbnN0IGxsIG9mIHRsKXdhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGxsKTtyZXR1cm4gYWx9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtaW4kMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmEsRWE9U2Euc2hhcGUubGVuZ3RoLGthPXBhcnNlQXhpc1BhcmFtJDEoVGEsU2Euc2hhcGUpO2xldCBBYT1rYTtjb25zdCBGYT1nZXRBeGVzUGVybXV0YXRpb24kMShBYSxFYSk7bGV0IExhPVNhO0ZhIT1udWxsJiYoTGE9dHJhbnNwb3NlJDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpGYX19KSxBYT1nZXRJbm5lck1vc3RBeGVzJDEoQWEubGVuZ3RoLFNhLnNoYXBlLmxlbmd0aCkpLGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zJDEoIm1pbiIsQWEsRWEpO2NvbnN0W2VsLHRsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzJDEoTGEuc2hhcGUsQWEpLG5sPXNpemVGcm9tU2hhcGUkMSh0bCksc2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSxubF19fSkscmw9cmVkdWNlJDEoc2wsc2wuZHR5cGUsIm1pbiIseGEpO2xldCBvbDtpZih3YSl7Y29uc3QgYWw9ZXhwYW5kU2hhcGVUb0tlZXBEaW0kMShlbCxrYSk7b2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmFsfX0pfWVsc2Ugb2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmVsfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ocmwpLEZhIT1udWxsJiZ4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSksb2x9Y29uc3QgbWluQ29uZmlnJDE9e2tlcm5lbE5hbWU6TWluJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1pbiQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBNSU5JTVVNJDE9Q0hFQ0tfTkFOX1NOSVBQRVQkMitgCiAgcmV0dXJuIG1pbihhLCBiKTsKYCxNSU5JTVVNX1BBQ0tFRCQxPWAKICB2ZWM0IHJlc3VsdCA9IHZlYzQobWluKGEsIGIpKTsKICBidmVjNCBpc05hTkEgPSBpc25hbihhKTsKICBidmVjNCBpc05hTkIgPSBpc25hbihiKTsKICBidmVjNCBpc05hTiA9IGJ2ZWM0KGlzTmFOQS54IHx8IGlzTmFOQi54LCBpc05hTkEueSB8fCBpc05hTkIueSwgaXNOYU5BLnogfHwgaXNOYU5CLnosIGlzTmFOQS53IHx8IGlzTmFOQi53KTsKICBgK0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCQxK2AKICByZXR1cm4gcmVzdWx0OwpgLG1pbmltdW0kMT1iaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpNSU5JTVVNJDEscGFja2VkT3BTbmlwcGV0Ok1JTklNVU1fUEFDS0VEJDEsY3B1S2VybmVsSW1wbDptaW5pbXVtSW1wbENQVSQxfSksbWluaW11bUNvbmZpZyQxPXtrZXJuZWxOYW1lOk1pbmltdW0kMixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bWluaW11bSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgTWlycm9yUGFkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0sdGhpcy5vdXRwdXRTaGFwZT14YS5tYXAoKEZhLExhKT0+RmFbMF0rYWFbTGFdK0ZhWzFdKTtjb25zdCBTYT1hYS5sZW5ndGgsVGE9Z2V0Q29vcmRzRGF0YVR5cGUkMShTYSksd2E9eGEubWFwKEZhPT5GYVswXSkuam9pbigiLCIpLEVhPXhhLm1hcCgoRmEsTGEpPT5GYVswXSthYVtMYV0pLmpvaW4oIiwiKSxrYT1bImNvb3Jkc1swXSIsImNvb3Jkc1sxXSIsImNvb3Jkc1syXSIsImNvb3Jkc1szXSJdLnNsaWNlKDAsU2EpLEFhPWJhPT09InJlZmxlY3QiPzA6MTtpZihTYT09PTEpe3RoaXMudXNlckNvZGU9YAogICAgICAgIGludCBzdGFydCA9ICR7d2F9OwogICAgICAgIGludCBlbmQgPSAke0VhfTsKCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaW50IG91dEMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIGlmIChvdXRDIDwgc3RhcnQpIHsKICAgICAgICAgICAgb3V0QyA9IHN0YXJ0ICogMiAtIG91dEMgLSAke0FhfTsKICAgICAgICAgIH0gZWxzZSBpZihvdXRDID49IGVuZCkgewogICAgICAgICAgICBvdXRDID0gKGVuZCAtIDEpICogMiAtIG91dEMgKyAke0FhfTsKICAgICAgICAgIH0KICAgICAgICAgIHNldE91dHB1dChnZXRYKG91dEMgLSBzdGFydCkpOwogICAgICAgIH0KICAgICAgYDtyZXR1cm59dGhpcy51c2VyQ29kZT1gCiAgICAgICR7VGF9IHN0YXJ0ID0gJHtUYX0oJHt3YX0pOwogICAgICAke1RhfSBlbmQgPSAke1RhfSgke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtUYX0gb3V0QyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtTYX07IGkrKykgewogICAgICAgICAgaWYgKG91dENbaV0gPCBzdGFydFtpXSkgewogICAgICAgICAgICBvdXRDW2ldID0gc3RhcnRbaV0gKiAyIC0gb3V0Q1tpXSAtICR7QWF9OwogICAgICAgICAgfSBlbHNlIGlmKG91dENbaV0gPj0gZW5kW2ldKSB7CiAgICAgICAgICAgIG91dENbaV0gPSAoZW5kW2ldIC0gMSkgKiAyIC0gb3V0Q1tpXSArICR7QWF9OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAke1RhfSBjb29yZHMgPSBvdXRDIC0gc3RhcnQ7CiAgICAgICAgc2V0T3V0cHV0KGdldFgoJHtrYX0pKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBNaXJyb3JQYWRQYWNrZWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLm91dHB1dFNoYXBlPXhhLm1hcCgobmwsc2wpPT5ubFswXSthYVtzbF0rbmxbMV0pO2NvbnN0IFNhPWFhLmxlbmd0aCxUYT1nZXRDb29yZHNEYXRhVHlwZSQxKFNhKSx3YT14YS5tYXAobmw9Pm5sWzBdKS5qb2luKCIsIiksRWE9eGEubWFwKChubCxzbCk9Pm5sWzBdK2FhW3NsXSkuam9pbigiLCIpLGthPWdldENoYW5uZWxzJDEoInJjIixTYSksQWE9Z2V0Q2hhbm5lbHMkMSgic291cmNlIixTYSksRmE9YCR7a2FbU2EtMV19IDwgJHt0aGlzLm91dHB1dFNoYXBlW1NhLTFdfWAsTGE9U2E9PT0xPyJzb3VyY2UiOmB2ZWMyKCR7QWEuc2xpY2UoLTIpLmpvaW4oKX0pYCxlbD1iYT09PSJyZWZsZWN0Ij8wOjE7bGV0IHRsPSIiO2lmKFNhPT09MSl7Y29uc3Qgbmw9YAogICAgICAgICR7VGF9IHNvdXJjZSA9IHJjOwogICAgICAgIGlmIChzb3VyY2UgPCBzdGFydCkgewogICAgICAgICAgc291cmNlID0gc3RhcnQgKiAyIC0gc291cmNlIC0gJHtlbH07CiAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UgPj0gZW5kKSB7CiAgICAgICAgICBzb3VyY2UgPSAoZW5kIC0gMSkgKiAyIC0gc291cmNlICsgJHtlbH07CiAgICAgICAgfQogICAgICAgIHNvdXJjZSAtPSBzdGFydDsKICAgICAgYDt0bD1gCiAgICAgICAgJHtUYX0gcmMgPSBvdXRwdXRMb2M7CiAgICAgICAgJHtubH0KICAgICAgICByZXN1bHRbMF0gPSBnZXRDaGFubmVsKGdldFgoJHtBYS5qb2luKCl9KSwgJHtMYX0pOwogICAgICAgICR7a2FbU2EtMV19ICs9IDE7CiAgICAgICAgaWYoJHtGYX0pIHsKICAgICAgICAgICR7bmx9CiAgICAgICAgICByZXN1bHRbMV0gPSBnZXRDaGFubmVsKGdldFgoJHtBYS5qb2luKCl9KSwgJHtMYX0pOwogICAgICAgIH0KICAgICAgYH1lbHNle2NvbnN0IG5sPWAKICAgICAgICAke1RhfSBzb3VyY2UgPSByYzsKICAgICAgICAke1RhfSBsdCA9ICR7VGF9KGxlc3NUaGFuKHNvdXJjZSwgc3RhcnQpKTsKICAgICAgICAke1RhfSBndGUgPSAke1RhfShncmVhdGVyVGhhbkVxdWFsKHNvdXJjZSwgZW5kKSk7CiAgICAgICAgJHtUYX0gb3JpZyA9IDEgLSAobHQgKyBndGUpOwogICAgICAgIHNvdXJjZSA9IG9yaWcgKiBzb3VyY2UgKwogICAgICAgICAgICAgICAgbHQgKiAoc3RhcnQgKiAyIC0gc291cmNlIC0gJHtlbH0pICsKICAgICAgICAgICAgICAgIGd0ZSAqICgoZW5kIC0gMSkgKiAyIC0gc291cmNlICsgJHtlbH0pOwogICAgICAgIHNvdXJjZSAtPSBzdGFydDsKICAgICAgYDt0bD1gCiAgICAgICAgJHtUYX0gcmMgPSBvdXRwdXRMb2M7CiAgICAgICAgJHtubH0KICAgICAgICByZXN1bHRbMF0gPSBnZXRDaGFubmVsKGdldFgoJHtBYS5qb2luKCl9KSwgJHtMYX0pOwogICAgICAgICR7a2FbU2EtMV19ICs9IDE7CiAgICAgICAgaWYoJHtGYX0pIHsKICAgICAgICAgICR7bmx9CiAgICAgICAgICByZXN1bHRbMV0gPSBnZXRDaGFubmVsKGdldFgoJHtBYS5qb2luKCl9KSwgJHtMYX0pOwogICAgICAgIH0KICAgICAgICByYyA9IG91dHB1dExvYzsKICAgICAgICAke2thW1NhLTJdfSArPSAxOwogICAgICAgIGlmKCR7a2FbU2EtMl19IDwgJHt0aGlzLm91dHB1dFNoYXBlW1NhLTJdfSkgewogICAgICAgICAgJHtubH0KICAgICAgICAgIHJlc3VsdFsyXSA9IGdldENoYW5uZWwoZ2V0WCgke0FhLmpvaW4oKX0pLCAke0xhfSk7CiAgICAgICAgICAke2thW1NhLTFdfSArPSAxOwogICAgICAgICAgaWYoJHtGYX0pIHsKICAgICAgICAgICAgJHtubH0KICAgICAgICAgICAgcmVzdWx0WzNdID0gZ2V0Q2hhbm5lbChnZXRYKCR7QWEuam9pbigpfSksICR7TGF9KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIGB9dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0ICR7VGF9IHN0YXJ0ID0gJHtUYX0oJHt3YX0pOwogICAgICBjb25zdCAke1RhfSBlbmQgPSAke1RhfSgke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtUYX0gb3V0cHV0TG9jID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICAke3RsfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWlycm9yUGFkS2VybmVsRnVuYyQxPSh7aW5wdXRzOmhhLGJhY2tlbmQ6YWEsYXR0cnM6eGF9KT0+e2NvbnN0e3g6YmF9PWhhLHtwYWRkaW5nczpTYSxtb2RlOlRhfT14YSx3YT1lbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfQVJSQVlfT1BFUkFUSU9OUyIpP25ldyBNaXJyb3JQYWRQYWNrZWRQcm9ncmFtJDEoYmEuc2hhcGUsU2EsVGEpOm5ldyBNaXJyb3JQYWRQcm9ncmFtJDEoYmEuc2hhcGUsU2EsVGEpO3JldHVybiBhYS5ydW5XZWJHTFByb2dyYW0od2EsW2JhXSxiYS5kdHlwZSl9LG1pcnJvclBhZENvbmZpZyQxPXtrZXJuZWxOYW1lOk1pcnJvclBhZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptaXJyb3JQYWRLZXJuZWxGdW5jJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE1PRCQxPWBpZiAoYiA9PSAwLjApIHJldHVybiBOQU47CiAgcmV0dXJuIG1vZChhLCBiKTtgLE1PRF9QQUNLRUQkMT1gCiAgdmVjNCByZXN1bHQgPSBtb2QoYSwgYik7CiAgYnZlYzQgaXNOYU4gPSBlcXVhbChiLCB2ZWM0KDAuMCkpOwogIGArQ0hFQ0tfTkFOX1NOSVBQRVRfUEFDS0VEJDErYAogIHJldHVybiByZXN1bHQ7CmAsbW9kJDE9YmluYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6TU9EJDEscGFja2VkT3BTbmlwcGV0Ok1PRF9QQUNLRUQkMX0pLG1vZENvbmZpZyQxPXtrZXJuZWxOYW1lOk1vZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptb2QkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IE11bHRpbm9taWFsUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJwcm9icyJdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJzZWVkIix0eXBlOiJmbG9hdCJ9XSx0aGlzLm91dHB1dFNoYXBlPVthYSxiYV0sdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CgogICAgICAgIGZsb2F0IHIgPSByYW5kb20oc2VlZCk7CiAgICAgICAgZmxvYXQgY2RmID0gMC4wOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7eGEtMX07IGkrKykgewogICAgICAgICAgY2RmICs9IGdldFByb2JzKGJhdGNoLCBpKTsKCiAgICAgICAgICBpZiAociA8IGNkZikgewogICAgICAgICAgICBzZXRPdXRwdXQoZmxvYXQoaSkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBJZiBubyBvdGhlciBldmVudCBoYXBwZW5lZCwgbGFzdCBldmVudCBoYXBwZW5lZC4KICAgICAgICBzZXRPdXRwdXQoZmxvYXQoJHt4YS0xfSkpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRElWJDE9YAppZiAoYSA9PSBiKSB7CiAgcmV0dXJuIDEuMDsKfTsKcmV0dXJuIGEgLyBiO2AsRElWX1BBQ0tFRCQxPWAKICAvLyB2ZWM0IG9uZSA9IHZlYzQoZXF1YWwoYSwgYikpOwogIC8vIHJldHVybiBvbmUgKyAodmVjNCgxLjApIC0gb25lKSAqIGEgLyBiOwogIHZlYzQgcmVzdWx0ID0gYSAvIGI7CiAgaWYoYS54ID09IGIueCkgewogICAgcmVzdWx0LnggPSAxLjsKICB9CiAgaWYoYS55ID09IGIueSkgewogICAgcmVzdWx0LnkgPSAxLjsKICB9CiAgaWYoYS56ID09IGIueikgewogICAgcmVzdWx0LnogPSAxLjsKICB9CiAgaWYoYS53ID09IGIudykgewogICAgcmVzdWx0LncgPSAxLjsKICB9CgogIHJldHVybiByZXN1bHQ7CmAscmVhbERpdiQxPWJpbmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OkRJViQxLHBhY2tlZE9wU25pcHBldDpESVZfUEFDS0VEJDEsY2hlY2tPdXRPZkJvdW5kczohMH0pLHJlYWxEaXZDb25maWckMT17a2VybmVsTmFtZTpSZWFsRGl2JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlYWxEaXYkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgU1VCJDE9InJldHVybiBhIC0gYjsiLHN1YiQyPWJpbmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlNVQiQxLHBhY2tlZE9wU25pcHBldDpTVUIkMSxzdXBwb3J0c0NvbXBsZXg6ITAsY3B1S2VybmVsSW1wbDpzdWJJbXBsQ1BVJDF9KSxzdWJDb25maWckMT17a2VybmVsTmFtZTpTdWIkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3ViJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNvZnRtYXgkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtsb2dpdHM6U2F9PWFhLHtkaW06VGF9PWJhLHdhPXBhcnNlQXhpc1BhcmFtJDEoW1RhXSxTYS5zaGFwZSksRWE9bWF4JDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cmVkdWN0aW9uSW5kaWNlczp3YSxrZWVwRGltczohMX19KSxrYT1leHBhbmRTaGFwZVRvS2VlcERpbSQxKEVhLnNoYXBlLHdhKSxBYT1yZXNoYXBlJDIoe2lucHV0czp7eDpFYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6a2F9fSksRmE9c3ViJDIoe2lucHV0czp7YTpTYSxiOkFhfSxiYWNrZW5kOnhhfSksTGE9ZXhwJDEoe2lucHV0czp7eDpGYX0sYmFja2VuZDp4YX0pLGVsPXN1bSQzKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e2F4aXM6d2Esa2VlcERpbXM6ITF9fSksdGw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6ZWx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmthfX0pLG5sPXJlYWxEaXYkMSh7aW5wdXRzOnthOkxhLGI6dGx9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEFhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhGYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGVsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh0bCksbmx9Y29uc3Qgc29mdG1heENvbmZpZyQxPXtrZXJuZWxOYW1lOlNvZnRtYXgkMyxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c29mdG1heCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtdWx0aW5vbWlhbCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2xvZ2l0czpTYX09YWEse251bVNhbXBsZXM6VGEsc2VlZDp3YSxub3JtYWxpemVkOkVhfT1iYSxrYT1FYT9TYTpzb2Z0bWF4JDEoe2lucHV0czp7bG9naXRzOlNhfSxiYWNrZW5kOnhhLGF0dHJzOntkaW06U2Euc2hhcGUubGVuZ3RoLTF9fSksQWE9a2Euc2hhcGVbMF0sRmE9a2Euc2hhcGVbMV0sTGE9bmV3IE11bHRpbm9taWFsUHJvZ3JhbSQxKEFhLEZhLFRhKSxlbD1bW3dhXV0sdGw9eGEucnVuV2ViR0xQcm9ncmFtKExhLFtrYV0sImludDMyIixlbCk7cmV0dXJuIEVhfHx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhrYSksdGx9Y29uc3QgbXVsdGlub21pYWxDb25maWckMT17a2VybmVsTmFtZTpNdWx0aW5vbWlhbCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptdWx0aW5vbWlhbCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBORUckMT1DSEVDS19OQU5fU05JUFBFVCQzK2AKICByZXR1cm4gLXg7CmAsTkVHX1BBQ0tFRCQxPWAKICB2ZWM0IHJlc3VsdCA9IC14OwogIGJ2ZWM0IGlzTmFOID0gaXNuYW4oeCk7CgogIHJlc3VsdC5yID0gaXNOYU4uciA/IHguciA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNOYU4uZyA/IHguZyA6IHJlc3VsdC5nOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6IHJlc3VsdC5iOwogIHJlc3VsdC5hID0gaXNOYU4uYSA/IHguYSA6IHJlc3VsdC5hOwoKICByZXR1cm4gcmVzdWx0OwpgO2Z1bmN0aW9uIG5lZyQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3g6YmF9PWFhO2lmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbYmFdKSl7Y29uc3QgVGE9eGEudGV4RGF0YS5nZXQoYmEuZGF0YUlkKSxbd2EsRWFdPW5lZ0ltcGxDUFUkMShUYS52YWx1ZXMsYmEuc2hhcGUsYmEuZHR5cGUpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhFYSxiYS5kdHlwZSx3YSl9bGV0IFNhO3JldHVybiBlbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfVU5BUllfT1BFUkFUSU9OUyIpP1NhPW5ldyBVbmFyeU9wUGFja2VkUHJvZ3JhbSQxKGJhLnNoYXBlLE5FR19QQUNLRUQkMSk6U2E9bmV3IFVuYXJ5T3BQcm9ncmFtJDEoYmEuc2hhcGUsTkVHJDEpLHhhLnJ1bldlYkdMUHJvZ3JhbShTYSxbYmFdLGJhLmR0eXBlKX1jb25zdCBuZWdDb25maWckMT17a2VybmVsTmFtZTpOZWckMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bmVnJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG5vbk1heFN1cHByZXNzaW9uVjNJbXBsJDI9bm9uTWF4U3VwcHJlc3Npb25WM0ltcGwkNDtmdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvblYzJDEoaGEpe3dhcm4kMSgidGYubm9uTWF4U3VwcHJlc3Npb24oKSBpbiB3ZWJnbCBsb2NrcyB0aGUgVUkgdGhyZWFkLiBDYWxsIHRmLm5vbk1heFN1cHByZXNzaW9uQXN5bmMoKSBpbnN0ZWFkIik7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtib3hlczpTYSxzY29yZXM6VGF9PWFhLHttYXhPdXRwdXRTaXplOndhLGlvdVRocmVzaG9sZDpFYSxzY29yZVRocmVzaG9sZDprYX09YmEsQWE9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxGYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLHtzZWxlY3RlZEluZGljZXM6TGF9PW5vbk1heFN1cHByZXNzaW9uVjNJbXBsJDIoQWEsRmEsd2EsRWEsa2EpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhbTGEubGVuZ3RoXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KExhKSl9Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25WM0NvbmZpZyQxPXtrZXJuZWxOYW1lOk5vbk1heFN1cHByZXNzaW9uVjMkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bm9uTWF4U3VwcHJlc3Npb25WMyQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBub25NYXhTdXBwcmVzc2lvblY0SW1wbCQyPW5vbk1heFN1cHByZXNzaW9uVjRJbXBsJDQ7ZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25WNCQxKGhhKXt3YXJuJDEoInRmLm5vbk1heFN1cHByZXNzaW9uKCkgaW4gd2ViZ2wgbG9ja3MgdGhlIFVJIHRocmVhZC4gQ2FsbCB0Zi5ub25NYXhTdXBwcmVzc2lvbkFzeW5jKCkgaW5zdGVhZCIpO2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7Ym94ZXM6U2Esc2NvcmVzOlRhfT1hYSx7bWF4T3V0cHV0U2l6ZTp3YSxpb3VUaHJlc2hvbGQ6RWEsc2NvcmVUaHJlc2hvbGQ6a2EscGFkVG9NYXhPdXRwdXRTaXplOkFhfT1iYSxGYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLExhPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCkse3NlbGVjdGVkSW5kaWNlczplbCx2YWxpZE91dHB1dHM6dGx9PW5vbk1heFN1cHByZXNzaW9uVjRJbXBsJDIoRmEsTGEsd2EsRWEsa2EsQWEpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhbZWwubGVuZ3RoXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KGVsKSkseGEubWFrZVRlbnNvckluZm8oW10sImludDMyIixuZXcgSW50MzJBcnJheShbdGxdKSldfWNvbnN0IG5vbk1heFN1cHByZXNzaW9uVjRDb25maWckMT17a2VybmVsTmFtZTpOb25NYXhTdXBwcmVzc2lvblY0JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm5vbk1heFN1cHByZXNzaW9uVjQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgbm9uTWF4U3VwcHJlc3Npb25WNUltcGwkMj1ub25NYXhTdXBwcmVzc2lvblY1SW1wbCQ0O2Z1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uVjUkMShoYSl7d2FybiQxKCJ0Zi5ub25NYXhTdXBwcmVzc2lvbigpIGluIHdlYmdsIGxvY2tzIHRoZSBVSSB0aHJlYWQuIENhbGwgdGYubm9uTWF4U3VwcHJlc3Npb25Bc3luYygpIGluc3RlYWQiKTtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2JveGVzOlNhLHNjb3JlczpUYX09YWEse21heE91dHB1dFNpemU6d2EsaW91VGhyZXNob2xkOkVhLHNjb3JlVGhyZXNob2xkOmthLHNvZnRObXNTaWdtYTpBYX09YmEsRmE9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxMYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLGVsPXdhLHRsPUVhLG5sPWthLHNsPUFhLHtzZWxlY3RlZEluZGljZXM6cmwsc2VsZWN0ZWRTY29yZXM6b2x9PW5vbk1heFN1cHByZXNzaW9uVjVJbXBsJDIoRmEsTGEsZWwsdGwsbmwsc2wpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhbcmwubGVuZ3RoXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KHJsKSkseGEubWFrZVRlbnNvckluZm8oW29sLmxlbmd0aF0sImZsb2F0MzIiLG5ldyBGbG9hdDMyQXJyYXkob2wpKV19Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25WNUNvbmZpZyQxPXtrZXJuZWxOYW1lOk5vbk1heFN1cHByZXNzaW9uVjUkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bm9uTWF4U3VwcHJlc3Npb25WNSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgT25lSG90UHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJpbmRpY2VzIl0sdGhpcy5vdXRwdXRTaGFwZT1bYWEseGFdLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGluZGV4ID0gcm91bmQoZ2V0SW5kaWNlcyhjb29yZHMueCkpOwogICAgICAgIHNldE91dHB1dChtaXgoZmxvYXQoJHtTYX0pLCBmbG9hdCgke2JhfSksCiAgICAgICAgICAgICAgICAgICAgICBmbG9hdChpbmRleCA9PSBjb29yZHMueSkpKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG9uZUhvdCQxPWhhPT57Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtpbmRpY2VzOlNhfT1hYSx7ZHR5cGU6VGEsZGVwdGg6d2Esb25WYWx1ZTpFYSxvZmZWYWx1ZTprYX09YmEsQWE9c2l6ZUZyb21TaGFwZSQxKFNhLnNoYXBlKSxGYT1uZXcgT25lSG90UHJvZ3JhbSQxKEFhLHdhLEVhLGthKSxMYT1yZXNoYXBlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W0FhXX19KSxlbD14YS5ydW5XZWJHTFByb2dyYW0oRmEsW0xhXSxUYSk7eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpO2NvbnN0IHRsPVsuLi5TYS5zaGFwZSx3YV0sbmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6ZWx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOnRsfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCksbmx9LG9uZUhvdENvbmZpZyQxPXtrZXJuZWxOYW1lOk9uZUhvdCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpvbmVIb3QkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gemVyb3NMaWtlJDIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWE7aWYoYmEuZHR5cGU9PT0iY29tcGxleDY0Iil7Y29uc3QgU2E9cmVhbCQxKHtpbnB1dHM6e2lucHV0OmJhfSxiYWNrZW5kOnhhfSksVGE9emVyb3NMaWtlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pLHdhPWltYWckMSh7aW5wdXRzOntpbnB1dDpiYX0sYmFja2VuZDp4YX0pLEVhPXplcm9zTGlrZSQyKHtpbnB1dHM6e3g6d2F9LGJhY2tlbmQ6eGF9KSxrYT1jb21wbGV4JDIoe2lucHV0czp7cmVhbDpUYSxpbWFnOkVhfSxiYWNrZW5kOnhhfSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKFNhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhUYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEVhKSxrYX1lbHNlIHJldHVybiBmaWxsJDIoe2F0dHJzOntzaGFwZTpiYS5zaGFwZSxkdHlwZTpiYS5kdHlwZSx2YWx1ZTpiYS5kdHlwZT09PSJzdHJpbmciPyIiOjB9LGJhY2tlbmQ6eGF9KX1jb25zdCB6ZXJvc0xpa2VDb25maWckMT17a2VybmVsTmFtZTpaZXJvc0xpa2UkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6emVyb3NMaWtlJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG9uZXNMaWtlJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWE7aWYoYmEuZHR5cGU9PT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIm9uZXNMaWtlIGlzIG5vdCBzdXBwb3J0ZWQgdW5kZXIgc3RyaW5nIGR0eXBlIik7aWYoYmEuZHR5cGU9PT0iY29tcGxleDY0Iil7Y29uc3QgU2E9cmVhbCQxKHtpbnB1dHM6e2lucHV0OmJhfSxiYWNrZW5kOnhhfSksVGE9b25lc0xpa2UkMSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhfSksd2E9aW1hZyQxKHtpbnB1dHM6e2lucHV0OmJhfSxiYWNrZW5kOnhhfSksRWE9emVyb3NMaWtlJDIoe2lucHV0czp7eDp3YX0sYmFja2VuZDp4YX0pLGthPWNvbXBsZXgkMih7aW5wdXRzOntyZWFsOlRhLGltYWc6RWF9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oU2EpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKFRhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh3YSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLGthfWVsc2UgcmV0dXJuIGZpbGwkMih7YXR0cnM6e3NoYXBlOmJhLnNoYXBlLGR0eXBlOmJhLmR0eXBlLHZhbHVlOjF9LGJhY2tlbmQ6eGF9KX1jb25zdCBvbmVzTGlrZUNvbmZpZyQxPXtrZXJuZWxOYW1lOk9uZXNMaWtlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm9uZXNMaWtlJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHBhY2skMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtheGlzOlNhfT1iYTtpZihhYS5sZW5ndGg9PT0xKXJldHVybiBleHBhbmREaW1zJDEoe2lucHV0czp7aW5wdXQ6YWFbMF19LGJhY2tlbmQ6eGEsYXR0cnM6e2RpbTpTYX19KTtjb25zdCBUYT1hYVswXS5zaGFwZSx3YT1hYVswXS5kdHlwZTthYS5mb3JFYWNoKEZhPT57YXNzZXJ0U2hhcGVzTWF0Y2gkMShUYSxGYS5zaGFwZSwiQWxsIHRlbnNvcnMgcGFzc2VkIHRvIHN0YWNrIG11c3QgaGF2ZSBtYXRjaGluZyBzaGFwZXMiKSxhc3NlcnQkMih3YT09PUZhLmR0eXBlLCgpPT4iQWxsIHRlbnNvcnMgcGFzc2VkIHRvIHN0YWNrIG11c3QgaGF2ZSBtYXRjaGluZyBkdHlwZXMiKX0pO2NvbnN0IEVhPVtdLGthPWFhLm1hcChGYT0+e2NvbnN0IExhPWV4cGFuZERpbXMkMSh7aW5wdXRzOntpbnB1dDpGYX0sYmFja2VuZDp4YSxhdHRyczp7ZGltOlNhfX0pO3JldHVybiBFYS5wdXNoKExhKSxMYX0pLEFhPWNvbmNhdCQxKHtpbnB1dHM6a2EsYmFja2VuZDp4YSxhdHRyczp7YXhpczpTYX19KTtyZXR1cm4gRWEuZm9yRWFjaChGYT0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpKSxBYX1jb25zdCBwYWNrQ29uZmlnJDE9e2tlcm5lbE5hbWU6UGFjayQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpwYWNrJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBQYWRQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToidmFsdWUiLHR5cGU6ImZsb2F0In1dLHRoaXMub3V0cHV0U2hhcGU9eGEubWFwKChBYSxGYSk9PkFhWzBdK2FhW0ZhXStBYVsxXSk7Y29uc3QgU2E9YWEubGVuZ3RoLFRhPWdldENvb3Jkc0RhdGFUeXBlJDEoU2EpLHdhPXhhLm1hcChBYT0+QWFbMF0pLmpvaW4oIiwiKSxFYT14YS5tYXAoKEFhLEZhKT0+QWFbMF0rYWFbRmFdKS5qb2luKCIsIiksa2E9WyJjb29yZHNbMF0iLCJjb29yZHNbMV0iLCJjb29yZHNbMl0iLCJjb29yZHNbM10iXS5zbGljZSgwLFNhKTtpZihTYT09PTEpe3RoaXMudXNlckNvZGU9YAogICAgICAgIGludCBzdGFydCA9ICR7d2F9OwogICAgICAgIGludCBlbmQgPSAke0VhfTsKCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaW50IG91dEMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIGlmIChvdXRDIDwgc3RhcnQgfHwgb3V0QyA+PSBlbmQpIHsKICAgICAgICAgICAgc2V0T3V0cHV0KHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNldE91dHB1dChnZXRYKG91dEMgLSBzdGFydCkpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgYDtyZXR1cm59dGhpcy51c2VyQ29kZT1gCiAgICAgICR7VGF9IHN0YXJ0ID0gJHtUYX0oJHt3YX0pOwogICAgICAke1RhfSBlbmQgPSAke1RhfSgke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtUYX0gb3V0QyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGlmIChhbnkobGVzc1RoYW4ob3V0Qywgc3RhcnQpKSB8fCBhbnkoZ3JlYXRlclRoYW5FcXVhbChvdXRDLCBlbmQpKSkgewogICAgICAgICAgc2V0T3V0cHV0KHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgJHtUYX0gY29vcmRzID0gb3V0QyAtIHN0YXJ0OwogICAgICAgICAgc2V0T3V0cHV0KGdldFgoJHtrYX0pKTsKICAgICAgICB9CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUGFkUGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InZhbHVlIix0eXBlOiJmbG9hdCJ9XSx0aGlzLm91dHB1dFNoYXBlPXhhLm1hcCgoc2wscmwpPT5zbFswXSthYVtybF0rc2xbMV0pO2NvbnN0IFNhPWFhLmxlbmd0aCxUYT1nZXRDb29yZHNEYXRhVHlwZSQxKFNhKSx3YT14YS5tYXAoc2w9PnNsWzBdKS5qb2luKCIsIiksRWE9eGEubWFwKChzbCxybCk9PnNsWzBdK2FhW3JsXSkuam9pbigiLCIpLGthPWdldENoYW5uZWxzJDEoInJjIixTYSksQWE9Z2V0Q2hhbm5lbHMkMSgic291cmNlIixTYSksRmE9YCR7a2FbU2EtMV19IDwgJHt0aGlzLm91dHB1dFNoYXBlW1NhLTFdfWAsTGE9U2E9PT0xPyJzb3VyY2UiOmB2ZWMyKCR7QWEuc2xpY2UoLTIpLmpvaW4oKX0pYCxlbD1bYCR7VGF9IHJjID0gb3V0cHV0TG9jO2AsYCR7a2FbU2EtMV19ICs9IDE7CiAgICAgICBpZigke0ZhfSkgewogICAgICBgLFNhPT09MT8iIjpgfQogICAgICAgcmMgPSBvdXRwdXRMb2M7CiAgICAgICAke2thW1NhLTJdfSArPSAxOwogICAgICAgaWYoJHtrYVtTYS0yXX0gPCAke3RoaXMub3V0cHV0U2hhcGVbU2EtMl19KSB7YCxTYT09PTE/IiI6YCAgJHtrYVtTYS0xXX0gKz0gMTsKICAgICAgICAgaWYoJHtGYX0pIHtgXSx0bD1TYT09PTE/InJjIDwgc3RhcnQgfHwgcmMgPj0gZW5kIjoiYW55KGxlc3NUaGFuKHJjLCBzdGFydCkpIHx8IGFueShncmVhdGVyVGhhbkVxdWFsKHJjLCBlbmQpKSI7bGV0IG5sPSIiO2ZvcihsZXQgc2w9MCxybD1TYT09PTE/Mjo0O3NsPHJsO3NsKyspbmwrPWAKICAgICAgICAke2VsW3NsXX0KICAgICAgICBpZiAoJHt0bH0pIHsKICAgICAgICAgIHJlc3VsdFske3NsfV0gPSBmbG9hdCh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICR7VGF9IHNvdXJjZSA9IHJjIC0gc3RhcnQ7CiAgICAgICAgICByZXN1bHRbJHtzbH1dID0gZ2V0Q2hhbm5lbChnZXRYKCR7QWEuam9pbigpfSksICR7TGF9KTsKICAgICAgICB9CiAgICAgIGA7bmwrPVNhPT09MT8ifSAiOiJ9fSIsdGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0ICR7VGF9IHN0YXJ0ID0gJHtUYX0oJHt3YX0pOwogICAgICBjb25zdCAke1RhfSBlbmQgPSAke1RhfSgke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtUYX0gb3V0cHV0TG9jID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICAke25sfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcGFkVjIkMT1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse3BhZGRpbmdzOlRhLGNvbnN0YW50VmFsdWU6d2F9PWJhO2lmKHNpemVGcm9tU2hhcGUkMShTYS5zaGFwZSk9PT0wKXtjb25zdCBBYT1UYS5tYXAoKEZhLExhKT0+RmFbMF0rU2Euc2hhcGVbTGFdK0ZhWzFdKTtyZXR1cm4gZmlsbCQyKHtiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpBYSx2YWx1ZTp3YSxkdHlwZTpTYS5kdHlwZX19KX1jb25zdCBFYT1lbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfQVJSQVlfT1BFUkFUSU9OUyIpP25ldyBQYWRQYWNrZWRQcm9ncmFtJDEoU2Euc2hhcGUsVGEsd2EpOm5ldyBQYWRQcm9ncmFtJDEoU2Euc2hhcGUsVGEsd2EpLGthPVtbd2FdXTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEVhLFtTYV0sU2EuZHR5cGUsa2EpfSxwYWRWMkNvbmZpZyQxPXtrZXJuZWxOYW1lOlBhZFYyJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnBhZFYyJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFBPVyQxPWAKICBpZihhIDwgMC4wICYmIGZsb29yKGIpIDwgYil7CiAgICByZXR1cm4gTkFOOwogIH0KICBpZiAoYiA9PSAwLjApIHsKICAgIHJldHVybiAxLjA7CiAgfQogIHJldHVybiAocm91bmQobW9kKGIsIDIuMCkpICE9IDEpID8KICAgICAgcG93KGFicyhhKSwgYikgOiBzaWduKGEpICogcG93KGFicyhhKSwgYik7CmAsUE9XX1BBQ0tFRCQxPWAKICAvLyBpc01vZFJvdW5kMSBoYXMgMSBmb3IgY29tcG9uZW50cyB3aXRoIHJvdW5kKG1vZChiLCAyLjApKSA9PSAxLCAwIG90aGVyd2lzZS4KICB2ZWM0IGlzTW9kUm91bmQxID0gdmVjNChlcXVhbChyb3VuZChtb2QoYiwgMi4wKSksIGl2ZWM0KDEpKSk7CiAgdmVjNCBtdWx0aXBsaWVyID0gc2lnbihhKSAqIGlzTW9kUm91bmQxICsgKHZlYzQoMS4wKSAtIGlzTW9kUm91bmQxKTsKICB2ZWM0IHJlc3VsdCA9IG11bHRpcGxpZXIgKiBwb3coYWJzKGEpLCBiKTsKCiAgLy8gRW5zdXJlIHRoYXQgYV4wID0gMSwgaW5jbHVkaW5nIDBeMCA9IDEgYXMgdGhpcyBjb3JyZXNwb25kIHRvIFRGIGFuZCBKUwogIGJ2ZWM0IGlzRXhwWmVybyA9IGVxdWFsKGIsIHZlYzQoMC4wKSk7CiAgcmVzdWx0LnIgPSBpc0V4cFplcm8uciA/IDEuMCA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNFeHBaZXJvLmcgPyAxLjAgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzRXhwWmVyby5iID8gMS4wIDogcmVzdWx0LmI7CiAgcmVzdWx0LmEgPSBpc0V4cFplcm8uYSA/IDEuMCA6IHJlc3VsdC5hOwoKICBidmVjNCBpc05hTjEgPSBsZXNzVGhhbihhLCB2ZWM0KDAuMCkpOwogIGJ2ZWM0IGlzTmFOMiA9IGxlc3NUaGFuKGZsb29yKGIpLCBiKTsKICBidmVjNCBpc05hTiA9IGJ2ZWM0KGlzTmFOMS54ICYmIGlzTmFOMi54LCBpc05hTjEueSAmJiBpc05hTjIueSwgaXNOYU4xLnogJiYgaXNOYU4yLnosIGlzTmFOMS53ICYmIGlzTmFOMi53KTsKICBgK0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCQxK2AKICByZXR1cm4gcmVzdWx0OwpgLHBvdyQyPWJpbmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlBPVyQxLHBhY2tlZE9wU25pcHBldDpQT1dfUEFDS0VEJDF9KSxwb3dDb25maWckMT17a2VybmVsTmFtZTpQb3ckMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cG93JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHByb2QkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmEsRWE9U2Euc2hhcGUubGVuZ3RoLGthPVtdLEFhPXBhcnNlQXhpc1BhcmFtJDEoVGEsU2Euc2hhcGUpO2xldCBGYT1BYTtjb25zdCBMYT1nZXRBeGVzUGVybXV0YXRpb24kMShGYSxFYSk7bGV0IGVsPVNhO0xhIT1udWxsJiYoZWw9dHJhbnNwb3NlJDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpMYX19KSxGYT1nZXRJbm5lck1vc3RBeGVzJDEoRmEubGVuZ3RoLEVhKSxrYS5wdXNoKGVsKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMkMSgicHJvZCIsRmEsRWEpO2xldCB0bDtpZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW2VsXSkpe2NvbnN0IG5sPXhhLnRleERhdGEuZ2V0KGVsLmRhdGFJZCkudmFsdWVzLHtvdXRWYWxzOnNsLG91dFNoYXBlOnJsLG91dER0eXBlOm9sfT1wcm9kSW1wbENQVSQxKGVsLnNoYXBlLGVsLmR0eXBlLG5sLEZhKTt0bD14YS5tYWtlVGVuc29ySW5mbyhybCxvbCxzbCl9ZWxzZXtjb25zdFtubCxzbF09Y29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyQxKGVsLnNoYXBlLEZhKSxybD1zaXplRnJvbVNoYXBlJDEoc2wpLG9sPXJlc2hhcGUkMih7aW5wdXRzOnt4OmVsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbLTEscmxdfX0pLGFsPXN1bU91dFR5cGUkMShTYS5kdHlwZSksbGw9cmVkdWNlJDEob2wsYWwsInByb2QiLHhhKTt0bD1yZXNoYXBlJDIoe2lucHV0czp7eDpsbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSksa2EucHVzaChvbCksa2EucHVzaChsbCl9aWYod2Epe2thLnB1c2godGwpO2NvbnN0IG5sPWV4cGFuZFNoYXBlVG9LZWVwRGltJDEodGwuc2hhcGUsQWEpO3RsPXJlc2hhcGUkMih7aW5wdXRzOnt4OnRsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpubH19KX1yZXR1cm4ga2EuZm9yRWFjaChubD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8obmwpKSx0bH1jb25zdCBwcm9kQ29uZmlnJDE9e2tlcm5lbE5hbWU6UHJvZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpwcm9kJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhZ2dlZEdhdGhlciQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3BhcmFtc05lc3RlZFNwbGl0czpTYSxwYXJhbXNEZW5zZVZhbHVlczpUYSxpbmRpY2VzOndhfT1hYSx7b3V0cHV0UmFnZ2VkUmFuazpFYX09YmEsa2E9U2EubWFwKG9sPT54YS5yZWFkU3luYyhvbC5kYXRhSWQpKSxBYT1TYS5tYXAob2w9Pm9sLnNoYXBlKSxGYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLExhPXhhLnJlYWRTeW5jKHdhLmRhdGFJZCksW2VsLHRsLG5sXT1yYWdnZWRHYXRoZXJJbXBsQ1BVJDEoa2EsQWEsRmEsVGEuc2hhcGUsVGEuZHR5cGUsTGEsd2Euc2hhcGUsRWEpLHNsPWVsLm1hcChvbD0+eGEubWFrZVRlbnNvckluZm8oW29sLmxlbmd0aF0sImludDMyIixvbCkpLHJsPXhhLm1ha2VUZW5zb3JJbmZvKG5sLFRhLmR0eXBlLHRsKTtyZXR1cm4gc2wuY29uY2F0KFtybF0pfWNvbnN0IHJhZ2dlZEdhdGhlckNvbmZpZyQxPXtrZXJuZWxOYW1lOlJhZ2dlZEdhdGhlciQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyYWdnZWRHYXRoZXIkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFnZ2VkUmFuZ2UkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtzdGFydHM6YmEsbGltaXRzOlNhLGRlbHRhczpUYX09YWEsd2E9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSxFYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksW0FhLEZhXT1yYWdnZWRSYW5nZUltcGxDUFUkMSh3YSxiYS5zaGFwZSxiYS5kdHlwZSxFYSxTYS5zaGFwZSxrYSxUYS5zaGFwZSksTGE9eGEubWFrZVRlbnNvckluZm8oW0FhLmxlbmd0aF0sImludDMyIixBYSksZWw9eGEubWFrZVRlbnNvckluZm8oW0ZhLmxlbmd0aF0sYmEuZHR5cGUsRmEpO3JldHVybltMYSxlbF19Y29uc3QgcmFnZ2VkUmFuZ2VDb25maWckMT17a2VybmVsTmFtZTpSYWdnZWRSYW5nZSQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyYWdnZWRSYW5nZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByYWdnZWRUZW5zb3JUb1RlbnNvciQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3NoYXBlOlNhLHZhbHVlczpUYSxkZWZhdWx0VmFsdWU6d2Escm93UGFydGl0aW9uVGVuc29yczpFYX09YWEse3Jvd1BhcnRpdGlvblR5cGVzOmthfT1iYSxBYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLEZhPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksTGE9eGEucmVhZFN5bmMod2EuZGF0YUlkKSxlbD1FYS5tYXAocmw9PnhhLnJlYWRTeW5jKHJsLmRhdGFJZCkpLHRsPUVhLm1hcChybD0+cmwuc2hhcGUpLFtubCxzbF09cmFnZ2VkVGVuc29yVG9UZW5zb3JJbXBsQ1BVJDEoQWEsU2Euc2hhcGUsRmEsVGEuc2hhcGUsVGEuZHR5cGUsTGEsd2Euc2hhcGUsZWwsdGwsa2EpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhubCxUYS5kdHlwZSxzbCl9Y29uc3QgcmFnZ2VkVGVuc29yVG9UZW5zb3JDb25maWckMT17a2VybmVsTmFtZTpSYWdnZWRUZW5zb3JUb1RlbnNvciQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyYWdnZWRUZW5zb3JUb1RlbnNvciQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCByYW5nZSQxPWhhPT57Y29uc3R7YmFja2VuZDphYSxhdHRyczp4YX09aGEse3N0YXJ0OmJhLHN0b3A6U2Esc3RlcDpUYSxkdHlwZTp3YX09eGEsRWE9cmFuZ2VJbXBsQ1BVJDEoYmEsU2EsVGEsd2EpO3JldHVybiBhYS5tYWtlVGVuc29ySW5mbyhbRWEubGVuZ3RoXSx3YSxFYSl9LHJhbmdlQ29uZmlnJDE9e2tlcm5lbE5hbWU6UmFuZ2UkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmFuZ2UkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgUkVDSVBST0NBTCQxPSJyZXR1cm4gMS4wIC8geDsiLHJlY2lwcm9jYWwkMT11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlJFQ0lQUk9DQUwkMX0pLHJlY2lwcm9jYWxDb25maWckMT17a2VybmVsTmFtZTpSZWNpcHJvY2FsJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlY2lwcm9jYWwkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgUkVMVSQzPUNIRUNLX05BTl9TTklQUEVUJDMrYAogIHJldHVybiAoeCA8IDAuMCkgPyAwLjAgOiB4OwpgLFJFTFVfUEFDS0VEJDE9YAogIHZlYzQgcmVzdWx0ID0geCAqIHZlYzQoZ3JlYXRlclRoYW5FcXVhbCh4LCB2ZWM0KDAuMCkpKTsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwoKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyB4LmcgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyB4LmIgOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiByZXN1bHQuYTsKCiAgcmV0dXJuIHJlc3VsdDsKYCxyZWx1JDI9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpSRUxVJDMscGFja2VkT3BTbmlwcGV0OlJFTFVfUEFDS0VEJDF9KSxyZWx1Q29uZmlnJDE9e2tlcm5lbE5hbWU6UmVsdSQyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyZWx1JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFJFTFU2JDM9Q0hFQ0tfTkFOX1NOSVBQRVQkMytgCiAgcmV0dXJuICh4IDwgMC4wKSA/IDAuMCA6IG1pbig2LjAsIHgpOwpgLFJFTFU2X1BBQ0tFRCQxPWAKICB2ZWM0IHJlc3VsdCA9IG1pbih4LCB2ZWM0KDYuKSkgKiB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoeCwgdmVjNCgwLjApKSk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKCiAgcmVzdWx0LnIgPSBpc05hTi5yID8geC5yIDogcmVzdWx0LnI7CiAgcmVzdWx0LmcgPSBpc05hTi5nID8geC5nIDogcmVzdWx0Lmc7CiAgcmVzdWx0LmIgPSBpc05hTi5iID8geC5iIDogcmVzdWx0LmI7CiAgcmVzdWx0LmEgPSBpc05hTi5hID8geC5hIDogcmVzdWx0LmE7CgogIHJldHVybiByZXN1bHQ7CmAscmVsdTYkMj11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlJFTFU2JDMscGFja2VkT3BTbmlwcGV0OlJFTFU2X1BBQ0tFRCQxfSkscmVsdTZDb25maWckMT17a2VybmVsTmFtZTpSZWx1NiQyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyZWx1NiQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUmVzaXplQmlsaW5lYXJQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLm91dHB1dFNoYXBlPVtdO2NvbnN0W3dhLEVhLGthLEFhXT1hYTt0aGlzLm91dHB1dFNoYXBlPVt3YSx4YSxiYSxBYV07Y29uc3QgRmE9W1NhJiZ4YT4xP0VhLTE6RWEsU2EmJmJhPjE/a2EtMTprYV0sTGE9W1NhJiZ4YT4xP3hhLTE6eGEsU2EmJmJhPjE/YmEtMTpiYV07bGV0IGVsO1RhP2VsPSIodmVjMih5UkMpICsgdmVjMigwLjUpKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMgLSB2ZWMyKDAuNSkiOmVsPSJ2ZWMyKHlSQykgKiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDIix0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgdmVjMiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDID0gdmVjMigKICAgICAgICAgICR7RmFbMF0vTGFbMF19LAogICAgICAgICAgJHtGYVsxXS9MYVsxXX0pOwogICAgICBjb25zdCB2ZWMyIGlucHV0U2hhcGVSQyA9IHZlYzIoJHtFYX0uMCwgJHtrYX0uMCk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQgPSBjb29yZHNbM107CiAgICAgICAgaXZlYzIgeVJDID0gY29vcmRzLnl6OwoKICAgICAgICAvLyBGcmFjdGlvbmFsIHNvdXJjZSBpbmRleC4KICAgICAgICB2ZWMyIHNvdXJjZUZyYWNJbmRleFJDID0gJHtlbH07CgogICAgICAgIC8vIENvbXB1dGUgdGhlIGZvdXIgaW50ZWdlciBpbmRpY2VzLgogICAgICAgIGl2ZWMyIHNvdXJjZUZsb29yUkMgPSBpdmVjMihtYXgoc291cmNlRnJhY0luZGV4UkMsIHZlYzIoMC4wKSkpOwogICAgICAgIGl2ZWMyIHNvdXJjZUNlaWxSQyA9IGl2ZWMyKAogICAgICAgICAgbWluKGlucHV0U2hhcGVSQyAtIDEuMCwgY2VpbChzb3VyY2VGcmFjSW5kZXhSQykpKTsKCiAgICAgICAgZmxvYXQgdG9wTGVmdCA9IGdldEEoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VGbG9vclJDLnksIGQpOwogICAgICAgIGZsb2F0IGJvdHRvbUxlZnQgPSBnZXRBKGIsIHNvdXJjZUNlaWxSQy54LCBzb3VyY2VGbG9vclJDLnksIGQpOwogICAgICAgIGZsb2F0IHRvcFJpZ2h0ID0gZ2V0QShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUNlaWxSQy55LCBkKTsKICAgICAgICBmbG9hdCBib3R0b21SaWdodCA9IGdldEEoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUNlaWxSQy55LCBkKTsKCiAgICAgICAgdmVjMiBmcmFjUkMgPSBzb3VyY2VGcmFjSW5kZXhSQyAtIHZlYzIoc291cmNlRmxvb3JSQyk7CgogICAgICAgIGZsb2F0IHRvcCA9IHRvcExlZnQgKyAodG9wUmlnaHQgLSB0b3BMZWZ0KSAqIGZyYWNSQy55OwogICAgICAgIGZsb2F0IGJvdHRvbSA9IGJvdHRvbUxlZnQgKyAoYm90dG9tUmlnaHQgLSBib3R0b21MZWZ0KSAqIGZyYWNSQy55OwogICAgICAgIGZsb2F0IG5ld1ZhbHVlID0gdG9wICsgKGJvdHRvbSAtIHRvcCkgKiBmcmFjUkMueDsKCiAgICAgICAgc2V0T3V0cHV0KG5ld1ZhbHVlKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBSZXNpemVCaWxpbmVhclBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9W107Y29uc3Rbd2EsRWEsa2EsQWFdPWFhO3RoaXMub3V0cHV0U2hhcGU9W3dhLHhhLGJhLEFhXTtjb25zdCBGYT1bU2EmJnhhPjE/RWEtMTpFYSxTYSYmYmE+MT9rYS0xOmthXSxMYT1bU2EmJnhhPjE/eGEtMTp4YSxTYSYmYmE+MT9iYS0xOmJhXTtsZXQgZWw7VGE/ZWw9Iih2ZWMzKHlSQykgKyB2ZWMzKDAuNSkpICogZWZmZWN0aXZlSW5wdXRPdmVyT3V0cHV0UmF0aW9SQyAtIHZlYzMoMC41KSI6ZWw9InZlYzMoeVJDKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMiLHRoaXMudXNlckNvZGU9YAogICAgICBjb25zdCB2ZWMzIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMgPSB2ZWMzKAogICAgICAgICAgJHtGYVswXS9MYVswXX0sCiAgICAgICAgICAke0ZhWzFdL0xhWzFdfSwKICAgICAgICAgICR7RmFbMV0vTGFbMV19KTsKICAgICAgY29uc3QgdmVjMyBpbnB1dFNoYXBlUkMgPSB2ZWMzKCR7RWF9LjAsICR7a2F9LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2thfS4wKTsKCiAgICAgIGZsb2F0IGdldEFWYWx1ZShpbnQgYiwgaW50IHIsIGludCBjLCBpbnQgZCkgewogICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoYiwgciwgYywgZCksIHZlYzIoYywgZCkpOwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQgPSBjb29yZHNbM107CiAgICAgICAgLy8gQ2FsY3VsYXRlIHZhbHVlcyBmb3IgbmV4dCBjb2x1bW4gaW4geVJDLnouCiAgICAgICAgaXZlYzMgeVJDID0gY29vcmRzLnl6eiArIGl2ZWMzKDAsIDAsIDEpOwoKICAgICAgICAvLyBGcmFjdGlvbmFsIHNvdXJjZSBpbmRleC4KICAgICAgICB2ZWMzIHNvdXJjZUZyYWNJbmRleFJDID0gJHtlbH07CgogICAgICAgIC8vIENvbXB1dGUgdGhlIGZvdXIgaW50ZWdlciBpbmRpY2VzLgogICAgICAgIGl2ZWMzIHNvdXJjZUZsb29yUkMgPSBpdmVjMyhtYXgoc291cmNlRnJhY0luZGV4UkMsIHZlYzMoMC4wKSkpOwogICAgICAgIGl2ZWMzIHNvdXJjZUNlaWxSQyA9IGl2ZWMzKAogICAgICAgICAgbWluKGlucHV0U2hhcGVSQyAtIDEuMCwgY2VpbChzb3VyY2VGcmFjSW5kZXhSQykpKTsKCiAgICAgICAgLy8gU2hvdWxkIHdlIGNhbGN1bGF0ZSBuZXh0IGNvbHVtbiBhbmQgcm93IGVsZW1lbnRzIGluIDJ4MiBwYWNrZWQgY2VsbC4KICAgICAgICBib29sIGhhc05leHRDb2wgPSBkIDwgJHtBYS0xfTsKICAgICAgICBib29sIGhhc05leHRSb3cgPSBjb29yZHMueiA8ICR7YmEtMX07CgogICAgICAgIC8vIEluIHBhcmFsbGVsLCBjb25zdHJ1Y3QgZm91ciBjb3JuZXJzIGZvciBhbGwgZm91ciBjb21wb25lbnRzIGluCiAgICAgICAgLy8gcGFja2VkIDJ4MiBjZWxsLgogICAgICAgIHZlYzQgdG9wTGVmdCA9IHZlYzQoCiAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VGbG9vclJDLnksIGQpLAogICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUZsb29yUkMueSwgZCArIDEpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUZsb29yUkMueiwgZCkKICAgICAgICAgICAgICAgICAgICAgOiAwLjAsCiAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/CiAgICAgICAgICAgIGdldEFWYWx1ZShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUZsb29yUkMueiwgZCArIDEpIDogMC4wKTsKCiAgICAgICAgdmVjNCBib3R0b21MZWZ0ID0gdmVjNCgKICAgICAgICAgIGdldEFWYWx1ZShiLCBzb3VyY2VDZWlsUkMueCwgc291cmNlRmxvb3JSQy55LCBkKSwKICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUZsb29yUkMueSwgZCArIDEpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiLCBzb3VyY2VDZWlsUkMueCwgc291cmNlRmxvb3JSQy56LCBkKQogICAgICAgICAgICAgICAgICAgICA6IDAuMCwKICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8KICAgICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZUNlaWxSQy54LCBzb3VyY2VGbG9vclJDLnosIGQgKyAxKSA6IDAuMCk7CgogICAgICAgIHZlYzQgdG9wUmlnaHQgPSB2ZWM0KAogICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZUZsb29yUkMueCwgc291cmNlQ2VpbFJDLnksIGQpLAogICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUNlaWxSQy55LCBkICsgMSkKICAgICAgICAgICAgICAgICAgICAgOiAwLjAsCiAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGIsIHNvdXJjZUZsb29yUkMueCwgc291cmNlQ2VpbFJDLnosIGQpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPwogICAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VDZWlsUkMueiwgZCArIDEpIDogMC4wKTsKCiAgICAgICAgdmVjNCBib3R0b21SaWdodCA9IHZlYzQoCiAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUNlaWxSQy55LCBkKSwKICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUNlaWxSQy55LCBkICsgMSkKICAgICAgICAgICAgICAgICAgICAgOiAwLjAsCiAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGIsIHNvdXJjZUNlaWxSQy54LCBzb3VyY2VDZWlsUkMueiwgZCkKICAgICAgICAgICAgICAgICAgICAgOiAwLjAsCiAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/CiAgICAgICAgICAgIGdldEFWYWx1ZShiLCBzb3VyY2VDZWlsUkMueCwgc291cmNlQ2VpbFJDLnosIGQgKyAxKSA6IDAuMCk7CgogICAgICAgIHZlYzMgZnJhY1JDID0gc291cmNlRnJhY0luZGV4UkMgLSB2ZWMzKHNvdXJjZUZsb29yUkMpOwoKICAgICAgICB2ZWM0IHRvcCA9IG1peCh0b3BMZWZ0LCB0b3BSaWdodCwgZnJhY1JDLnl5enopOwogICAgICAgIHZlYzQgYm90dG9tID0gbWl4KGJvdHRvbUxlZnQsIGJvdHRvbVJpZ2h0LCBmcmFjUkMueXl6eik7CiAgICAgICAgdmVjNCBuZXdWYWx1ZSA9IG1peCh0b3AsIGJvdHRvbSwgZnJhY1JDLngpOwoKICAgICAgICBzZXRPdXRwdXQobmV3VmFsdWUpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplQmlsaW5lYXIkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtpbWFnZXM6U2F9PWFhLHthbGlnbkNvcm5lcnM6VGEsaGFsZlBpeGVsQ2VudGVyczp3YSxzaXplOkVhfT1iYSxba2EsQWFdPUVhLEZhPWVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19JTUFHRV9PUEVSQVRJT05TIik/bmV3IFJlc2l6ZUJpbGluZWFyUGFja2VkUHJvZ3JhbSQxKFNhLnNoYXBlLGthLEFhLFRhLHdhKTpuZXcgUmVzaXplQmlsaW5lYXJQcm9ncmFtJDEoU2Euc2hhcGUsa2EsQWEsVGEsd2EpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRmEsW1NhXSwiZmxvYXQzMiIpfWNvbnN0IHJlc2l6ZUJpbGluZWFyQ29uZmlnJDE9e2tlcm5lbE5hbWU6UmVzaXplQmlsaW5lYXIkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmVzaXplQmlsaW5lYXIkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFJlc2l6ZUJpbGluZWFyQmFja3Byb3BQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5Il0sdGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLm91dHB1dFNoYXBlPXhhO2NvbnN0WyxTYSxUYV09eGEsWyx3YSxFYV09YWEsa2E9W2JhJiZ3YT4xP1NhLTE6U2EsYmEmJkVhPjE/VGEtMTpUYV0sQWE9W2JhJiZ3YT4xP3dhLTE6d2EsYmEmJkVhPjE/RWEtMTpFYV0sRmE9a2FbMF0vQWFbMF0sTGE9a2FbMV0vQWFbMV0sZWw9MS9GYSx0bD0xL0xhLG5sPU1hdGguY2VpbChlbCkqMisyLHNsPU1hdGguY2VpbCh0bCkqMisyO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQgPSBjb29yZHNbM107CiAgICAgICAgaW50IHIgPSBjb29yZHNbMV07CiAgICAgICAgaW50IGMgPSBjb29yZHNbMl07CgogICAgICAgIGZsb2F0IGFjY3VtdWxhdG9yID0gMC4wOwoKICAgICAgICBjb25zdCBmbG9hdCBoZWlnaHRTY2FsZSA9IGZsb2F0KCR7RmF9KTsKICAgICAgICBjb25zdCBmbG9hdCB3aWR0aFNjYWxlID0gZmxvYXQoJHtMYX0pOwoKICAgICAgICBjb25zdCBmbG9hdCBpbnZIZWlnaHRTY2FsZSA9IGZsb2F0KCR7ZWx9KTsKICAgICAgICBjb25zdCBmbG9hdCBpbnZXaWR0aFNjYWxlID0gZmxvYXQoJHt0bH0pOwoKICAgICAgICBjb25zdCBpbnQgd2luSGVpZ2h0ID0gaW50KCR7bmx9KTsKICAgICAgICBjb25zdCBpbnQgd2luV2lkdGggPSBpbnQoJHtzbH0pOwoKICAgICAgICAvLyBDb21wdXRlIGJvdW5kcyBmb3Igd2hlcmUgaW4gZHkgd2Ugd2lsbCBsb29rCiAgICAgICAgZmxvYXQgc3RhcnRSTGVycCA9IGZsb29yKGZsb2F0KHIpICogaW52SGVpZ2h0U2NhbGUpOwogICAgICAgIGludCBzdGFydER5UiA9IGludChzdGFydFJMZXJwIC0gZmxvYXQod2luSGVpZ2h0IC8gMikpOwoKICAgICAgICBmbG9hdCBzdGFydENMZXJwID0gZmxvb3IoZmxvYXQoYykgKiBpbnZXaWR0aFNjYWxlKTsKICAgICAgICBpbnQgc3RhcnREeUMgPSBpbnQoc3RhcnRDTGVycCAtIGZsb2F0KHdpbldpZHRoIC8gMikpOwoKICAgICAgICAvLyBMb29wIG92ZXIgZHkKICAgICAgICBmb3IgKGludCBkeVJPZmZzZXQgPSAwOyBkeVJPZmZzZXQgPCB3aW5IZWlnaHQ7IGR5Uk9mZnNldCsrKSB7CiAgICAgICAgICBpbnQgZHlSID0gZHlST2Zmc2V0ICsgc3RhcnREeVI7CgogICAgICAgICAgLy8gR3VhcmQgYWdhaW5zdCB0aGUgd2luZG93IGV4Y2VlZGluZyB0aGUgYm91bmRzIG9mIGR5CiAgICAgICAgICBpZiAoZHlSIDwgMCB8fCBkeVIgPj0gJHt3YX0pIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CgogICAgICAgICAgZm9yIChpbnQgZHlDT2Zmc2V0ID0gMDsgZHlDT2Zmc2V0IDwgd2luV2lkdGg7IGR5Q09mZnNldCsrKSB7CiAgICAgICAgICAgIGludCBkeUMgPSBkeUNPZmZzZXQgKyBzdGFydER5QzsKCiAgICAgICAgICAgIC8vIEd1YXJkIGFnYWluc3QgdGhlIHdpbmRvdyBleGNlZWRpbmcgdGhlIGJvdW5kcyBvZiBkeQogICAgICAgICAgICBpZiAoZHlDIDwgMCB8fCBkeUMgPj0gJHtFYX0pIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZmxvYXQgZHhSID0gZmxvYXQoZHlSKSAqIGhlaWdodFNjYWxlOwogICAgICAgICAgICBpbnQgdG9wRHhSSW5kZXggPSBpbnQoZmxvb3IoZHhSKSk7CiAgICAgICAgICAgIGludCBib3R0b21EeFJJbmRleCA9IGludChtaW4oY2VpbChkeFIpLCAke1NhLTF9LjApKTsKICAgICAgICAgICAgZmxvYXQgZHhSTGVycCA9IGR4UiAtIGZsb2F0KHRvcER4UkluZGV4KTsKICAgICAgICAgICAgZmxvYXQgaW52ZXJzZUR4UkxlcnAgPSAxLjAgLSBkeFJMZXJwOwoKICAgICAgICAgICAgZmxvYXQgZHhDID0gZmxvYXQoZHlDKSAqIHdpZHRoU2NhbGU7CiAgICAgICAgICAgIGludCBsZWZ0RHhDSW5kZXggPSBpbnQoZmxvb3IoZHhDKSk7CiAgICAgICAgICAgIGludCByaWdodER4Q0luZGV4ID0gaW50KG1pbihjZWlsKGR4QyksICR7VGEtMX0uMCkpOwogICAgICAgICAgICBmbG9hdCBkeENMZXJwID0gZHhDIC0gZmxvYXQobGVmdER4Q0luZGV4KTsKICAgICAgICAgICAgZmxvYXQgaW52ZXJzZUR4Q0xlcnAgPSAxLjAgLSBkeENMZXJwOwoKICAgICAgICAgICAgaWYgKHIgPT0gdG9wRHhSSW5kZXggJiYgYyA9PSBsZWZ0RHhDSW5kZXgpIHsKICAgICAgICAgICAgICAvLyB0b3BMZWZ0CiAgICAgICAgICAgICAgYWNjdW11bGF0b3IgKz0KICAgICAgICAgICAgICAgIGdldER5KGIsIGR5UiwgZHlDLCBkKSAqIGludmVyc2VEeFJMZXJwICogaW52ZXJzZUR4Q0xlcnA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyID09IHRvcER4UkluZGV4ICYmIGMgPT0gcmlnaHREeENJbmRleCkgewogICAgICAgICAgICAgIC8vIHRvcFJpZ2h0CiAgICAgICAgICAgICAgYWNjdW11bGF0b3IgKz0gZ2V0RHkoYiwgZHlSLCBkeUMsIGQpICogaW52ZXJzZUR4UkxlcnAgKiBkeENMZXJwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAociA9PSBib3R0b21EeFJJbmRleCAmJiBjID09IGxlZnREeENJbmRleCkgewogICAgICAgICAgICAgIC8vIGJvdHRvbUxlZnQKICAgICAgICAgICAgICBhY2N1bXVsYXRvciArPSBnZXREeShiLCBkeVIsIGR5QywgZCkgKiBkeFJMZXJwICogaW52ZXJzZUR4Q0xlcnA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyID09IGJvdHRvbUR4UkluZGV4ICYmIGMgPT0gcmlnaHREeENJbmRleCkgewogICAgICAgICAgICAgIC8vIGJvdHRvbVJpZ2h0CiAgICAgICAgICAgICAgYWNjdW11bGF0b3IgKz0gZ2V0RHkoYiwgZHlSLCBkeUMsIGQpICogZHhSTGVycCAqIGR4Q0xlcnA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gRW5kIGxvb3Agb3ZlciBkeQoKICAgICAgICBzZXRPdXRwdXQoYWNjdW11bGF0b3IpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplQmlsaW5lYXJHcmFkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhLGR5OlRhfT1hYSx7YWxpZ25Db3JuZXJzOndhfT1iYSxFYT1uZXcgUmVzaXplQmlsaW5lYXJCYWNrcHJvcFByb2dyYW0kMShUYS5zaGFwZSxTYS5zaGFwZSx3YSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShFYSxbVGFdLFRhLmR0eXBlKX1jb25zdCByZXNpemVCaWxpbmVhckdyYWRDb25maWckMT17a2VybmVsTmFtZTpSZXNpemVCaWxpbmVhckdyYWQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmVzaXplQmlsaW5lYXJHcmFkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBSZXNpemVOZWFyZXN0TmVpZ2hib3JQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLm91dHB1dFNoYXBlPVtdO2NvbnN0W3dhLEVhLGthLEFhXT1hYTt0aGlzLm91dHB1dFNoYXBlPVt3YSx4YSxiYSxBYV07Y29uc3QgRmE9W1NhJiZ4YT4xP0VhLTE6RWEsU2EmJmJhPjE/a2EtMTprYV0sTGE9W1NhJiZ4YT4xP3hhLTE6eGEsU2EmJmJhPjE/YmEtMTpiYV0sZWw9U2E/IjAuNSI6IjAuMCI7bGV0IHRsO1RhP3RsPSJtYXgoKHZlYzIoeVJDKSArIHZlYzIoMC41KSkgKiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDLCB2ZWMyKDAuMCkpIjp0bD0idmVjMih5UkMpICogZWZmZWN0aXZlSW5wdXRPdmVyT3V0cHV0UmF0aW9SQyIsdGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IHZlYzIgZWZmZWN0aXZlSW5wdXRPdmVyT3V0cHV0UmF0aW9SQyA9IHZlYzIoCiAgICAgICAgICAke0ZhWzBdL0xhWzBdfSwKICAgICAgICAgICR7RmFbMV0vTGFbMV19KTsKICAgICAgY29uc3QgdmVjMiBpbnB1dFNoYXBlUkMgPSB2ZWMyKCR7RWF9LjAsICR7a2F9LjApOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwogICAgICAgIGl2ZWMyIHlSQyA9IGNvb3Jkcy55ejsKCiAgICAgICAgLy8gRnJhY3Rpb25hbCBzb3VyY2UgaW5kZXguCiAgICAgICAgdmVjMiBzb3VyY2VGcmFjSW5kZXhSQyA9ICR7dGx9OwoKICAgICAgICAvLyBDb21wdXRlIHRoZSBjb29yZGluYXRvcnMgb2YgbmVhcmVzdCBuZWlnaGJvciBwb2ludC4KICAgICAgICBpdmVjMiBzb3VyY2VOZWFyZXN0UkMgPSBpdmVjMigKICAgICAgICAgIG1pbihpbnB1dFNoYXBlUkMgLSAxLjAsIGZsb29yKHNvdXJjZUZyYWNJbmRleFJDICsgJHtlbH0pKSk7CiAgICAgICAgZmxvYXQgbmV3VmFsdWUgPSBnZXRBKGIsIHNvdXJjZU5lYXJlc3RSQy54LCBzb3VyY2VOZWFyZXN0UkMueSwgZCk7CgogICAgICAgIHNldE91dHB1dChuZXdWYWx1ZSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUmVzaXplTmVhcmVzdE5laWdoYm9yUGFja2VkUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1bXTtjb25zdFt3YSxFYSxrYSxBYV09YWE7dGhpcy5vdXRwdXRTaGFwZT1bd2EseGEsYmEsQWFdO2NvbnN0IEZhPVtTYSYmeGE+MT9FYS0xOkVhLFNhJiZiYT4xP2thLTE6a2FdLExhPVtTYSYmeGE+MT94YS0xOnhhLFNhJiZiYT4xP2JhLTE6YmFdLGVsPVNhPyIwLjUiOiIwLjAiO2xldCB0bDtUYT90bD0ibWF4KCh2ZWMzKHlSQykgKyB2ZWMzKDAuNSkpICogZWZmZWN0aXZlSW5wdXRPdmVyT3V0cHV0UmF0aW9SQywgdmVjMygwLjApKSI6dGw9InZlYzMoeVJDKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMiLHRoaXMudXNlckNvZGU9YAogICAgICBjb25zdCB2ZWMzIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMgPSB2ZWMzKAogICAgICAgICAgJHtGYVswXS9MYVswXX0sCiAgICAgICAgICAke0ZhWzFdL0xhWzFdfSwKICAgICAgICAgICR7RmFbMV0vTGFbMV19KTsKICAgICAgY29uc3QgdmVjMyBpbnB1dFNoYXBlUkMgPSB2ZWMzKCR7RWF9LjAsICR7a2F9LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2thfS4wKTsKCiAgICAgIGZsb2F0IGdldEFWYWx1ZShpbnQgYiwgaW50IHIsIGludCBjLCBpbnQgZCkgewogICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoYiwgciwgYywgZCksIHZlYzIoYywgZCkpOwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQgPSBjb29yZHNbM107CiAgICAgICAgLy8gQ2FsY3VsYXRlIHZhbHVlcyBmb3IgbmV4dCBjb2x1bW4gaW4geVJDLnouCiAgICAgICAgaXZlYzMgeVJDID0gY29vcmRzLnl6eiArIGl2ZWMzKDAsIDAsIDEpOwoKICAgICAgICAvLyBGcmFjdGlvbmFsIHNvdXJjZSBpbmRleC4KICAgICAgICB2ZWMzIHNvdXJjZUZyYWNJbmRleFJDID0gJHt0bH07CgogICAgICAgIC8vIENvbXB1dGUgdGhlIGNvb3JkaW5hdG9ycyBvZiBuZWFyZXN0IG5laWdoYm9yIHBvaW50LgogICAgICAgIGl2ZWMzIHNvdXJjZU5lYXJlc3RSQyA9IGl2ZWMzKAogICAgICAgICAgbWluKGlucHV0U2hhcGVSQyAtIDEuMCwgZmxvb3Ioc291cmNlRnJhY0luZGV4UkMgKyAke2VsfSkpKTsKCiAgICAgICAgLy8gU2hvdWxkIHdlIGNhbGN1bGF0ZSBuZXh0IGNvbHVtbiBhbmQgcm93IGVsZW1lbnRzIGluIDJ4MiBwYWNrZWQgY2VsbC4KICAgICAgICBib29sIGhhc05leHRDb2wgPSBkIDwgJHtBYS0xfTsKICAgICAgICBib29sIGhhc05leHRSb3cgPSBjb29yZHMueiA8ICR7YmEtMX07CgogICAgICAgIHZlYzQgbmV3VmFsdWUgPSB2ZWM0KAogICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZU5lYXJlc3RSQy54LCBzb3VyY2VOZWFyZXN0UkMueSwgZCksCiAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGIsIHNvdXJjZU5lYXJlc3RSQy54LCBzb3VyY2VOZWFyZXN0UkMueSwgZCArIDEpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiLCBzb3VyY2VOZWFyZXN0UkMueCwgc291cmNlTmVhcmVzdFJDLnosIGQpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPwogICAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlTmVhcmVzdFJDLngsIHNvdXJjZU5lYXJlc3RSQy56LCBkICsgMSkgOiAwLjApOwoKICAgICAgICBzZXRPdXRwdXQobmV3VmFsdWUpOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplTmVhcmVzdE5laWdoYm9yJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhfT1hYSx7YWxpZ25Db3JuZXJzOlRhLGhhbGZQaXhlbENlbnRlcnM6d2Esc2l6ZTpFYX09YmEsW2thLEFhXT1FYSxGYT1lbnYkMSgpLmdldEJvb2woIldFQkdMX1BBQ0tfSU1BR0VfT1BFUkFUSU9OUyIpP25ldyBSZXNpemVOZWFyZXN0TmVpZ2hib3JQYWNrZWRQcm9ncmFtJDEoU2Euc2hhcGUsa2EsQWEsVGEsd2EpOm5ldyBSZXNpemVOZWFyZXN0TmVpZ2hib3JQcm9ncmFtJDEoU2Euc2hhcGUsa2EsQWEsVGEsd2EpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRmEsW1NhXSxTYS5kdHlwZSl9Y29uc3QgcmVzaXplTmVhcmVzdE5laWdoYm9yQ29uZmlnJDE9e2tlcm5lbE5hbWU6UmVzaXplTmVhcmVzdE5laWdoYm9yJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlc2l6ZU5lYXJlc3ROZWlnaGJvciQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUmVzaXplTmVhcmVzdE5laWdib3JCYWNrcHJvcFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiZHkiXSx0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMub3V0cHV0U2hhcGU9eGE7Y29uc3RbLFNhLFRhXT14YSxbLHdhLEVhXT1hYSxrYT1bYmEmJndhPjE/U2EtMTpTYSxiYSYmRWE+MT9UYS0xOlRhXSxBYT1bYmEmJndhPjE/d2EtMTp3YSxiYSYmRWE+MT9FYS0xOkVhXSxGYT1rYVswXS9BYVswXSxMYT1rYVsxXS9BYVsxXSxlbD0xL0ZhLHRsPTEvTGEsbmw9TWF0aC5jZWlsKGVsKSoyKzIsc2w9TWF0aC5jZWlsKHRsKSoyKzI7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKICAgICAgICBpbnQgciA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgYyA9IGNvb3Jkc1syXTsKCiAgICAgICAgZmxvYXQgYWNjdW11bGF0b3IgPSAwLjA7CgogICAgICAgIGNvbnN0IGZsb2F0IGhlaWdodFNjYWxlID0gZmxvYXQoJHtGYX0pOwogICAgICAgIGNvbnN0IGZsb2F0IHdpZHRoU2NhbGUgPSBmbG9hdCgke0xhfSk7CgogICAgICAgIGNvbnN0IGZsb2F0IGludkhlaWdodFNjYWxlID0gZmxvYXQoJHtlbH0pOwogICAgICAgIGNvbnN0IGZsb2F0IGludldpZHRoU2NhbGUgPSBmbG9hdCgke3RsfSk7CgogICAgICAgIGNvbnN0IGludCB3aW5IZWlnaHQgPSBpbnQoJHtubH0pOwogICAgICAgIGNvbnN0IGludCB3aW5XaWR0aCA9IGludCgke3NsfSk7CgogICAgICAgIC8vIENvbXB1dGUgYm91bmRzIGZvciB3aGVyZSBpbiBkeSB3ZSB3aWxsIGxvb2sKICAgICAgICBmbG9hdCBzdGFydFJMZXJwID0gZmxvb3IoZmxvYXQocikgKiBpbnZIZWlnaHRTY2FsZSk7CiAgICAgICAgaW50IHN0YXJ0RHlSID0gaW50KGZsb29yKHN0YXJ0UkxlcnAgLSBmbG9hdCh3aW5IZWlnaHQgLyAyKSkpOwoKICAgICAgICBmbG9hdCBzdGFydENMZXJwID0gZmxvb3IoZmxvYXQoYykgKiBpbnZXaWR0aFNjYWxlKTsKICAgICAgICBpbnQgc3RhcnREeUMgPSBpbnQoZmxvb3Ioc3RhcnRDTGVycCAtIGZsb2F0KHdpbldpZHRoIC8gMikpKTsKCiAgICAgICAgLy8gTG9vcCBvdmVyIGR5CiAgICAgICAgZm9yIChpbnQgZHlST2Zmc2V0ID0gMDsgZHlST2Zmc2V0IDwgd2luSGVpZ2h0OyBkeVJPZmZzZXQrKykgewogICAgICAgICAgaW50IGR5UiA9IGR5Uk9mZnNldCArIHN0YXJ0RHlSOwoKICAgICAgICAgIC8vIEd1YXJkIGFnYWluc3QgdGhlIHdpbmRvdyBleGNlZWRpbmcgdGhlIGJvdW5kcyBvZiBkeQogICAgICAgICAgaWYgKGR5UiA8IDAgfHwgZHlSID49ICR7d2F9KSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaW50IGR5Q09mZnNldCA9IDA7IGR5Q09mZnNldCA8IHdpbldpZHRoOyBkeUNPZmZzZXQrKykgewogICAgICAgICAgICBpbnQgZHlDID0gZHlDT2Zmc2V0ICsgc3RhcnREeUM7CgogICAgICAgICAgICAvLyBHdWFyZCBhZ2FpbnN0IHRoZSB3aW5kb3cgZXhjZWVkaW5nIHRoZSBib3VuZHMgb2YgZHkKICAgICAgICAgICAgaWYgKGR5QyA8IDAgfHwgZHlDID49ICR7RWF9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZsb2F0IHNvdXJjZUZyYWNSb3cgPQogICAgICAgICAgICAgIGZsb2F0KCR7a2FbMF19KSAqCiAgICAgICAgICAgICAgICAoZmxvYXQoZHlSKSAvIGZsb2F0KCR7QWFbMF19KSk7CgogICAgICAgICAgICBmbG9hdCBzb3VyY2VGcmFjQ29sID0KICAgICAgICAgICAgICAgIGZsb2F0KCR7a2FbMV19KSAqCiAgICAgICAgICAgICAgICAgIChmbG9hdChkeUMpIC8gZmxvYXQoJHtBYVsxXX0pKTsKCiAgICAgICAgICAgIGludCBzb3VyY2VOZWFyZXN0Um93ID0gaW50KG1pbigKICAgICAgICAgICAgICAgIGZsb2F0KGludCgke1NhfSkgLSAxKSwKICAgICAgICAgICAgICAgICR7YmF9ID8gZmxvYXQocm91bmQoc291cmNlRnJhY1JvdykpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0KGZsb29yKHNvdXJjZUZyYWNSb3cpKSkpOwoKICAgICAgICAgICAgaW50IHNvdXJjZU5lYXJlc3RDb2wgPSBpbnQobWluKAogICAgICAgICAgICAgICAgZmxvYXQoaW50KCR7VGF9KSAtIDEpLAogICAgICAgICAgICAgICAgJHtiYX0gPyBmbG9hdChyb3VuZChzb3VyY2VGcmFjQ29sKSkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQoZmxvb3Ioc291cmNlRnJhY0NvbCkpKSk7CgogICAgICAgICAgICBpZiAociA9PSBzb3VyY2VOZWFyZXN0Um93ICYmIGMgPT0gc291cmNlTmVhcmVzdENvbCkgewogICAgICAgICAgICAgIGFjY3VtdWxhdG9yICs9IGdldER5KGIsIGR5UiwgZHlDLCBkKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBFbmQgbG9vcCBvdmVyIGR5CgogICAgICAgIHNldE91dHB1dChhY2N1bXVsYXRvcik7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhLGR5OlRhfT1hYSx7YWxpZ25Db3JuZXJzOndhfT1iYSxFYT1uZXcgUmVzaXplTmVhcmVzdE5laWdib3JCYWNrcHJvcFByb2dyYW0kMShUYS5zaGFwZSxTYS5zaGFwZSx3YSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShFYSxbVGFdLFRhLmR0eXBlKX1jb25zdCByZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkQ29uZmlnJDE9e2tlcm5lbE5hbWU6UmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBSZXZlcnNlUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il07Y29uc3QgYmE9YWEubGVuZ3RoO2lmKGJhPjQpdGhyb3cgbmV3IEVycm9yKGBXZWJHTCBiYWNrZW5kOiBSZXZlcnNlIG9mIHJhbmstJHtiYX0gdGVuc29yIGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7aWYodGhpcy5vdXRwdXRTaGFwZT1hYSxiYT09PTEpe3RoaXMudXNlckNvZGU9YAogICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgIGludCBjb29yZCA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgc2V0T3V0cHV0KGdldFgoJHthYVswXX0gLSBjb29yZCAtIDEpKTsKICAgICAgICB9CiAgICAgIGA7cmV0dXJufWNvbnN0IFNhPUVhPT54YS5pbmRleE9mKEVhKSE9PS0xJiZhYVtFYV0hPT0xP2Ake2FhW0VhXX0gLSBjb29yZHNbJHtFYX1dIC0gMWA6YGNvb3Jkc1ske0VhfV1gLFRhPWFhLm1hcCgoRWEsa2EpPT5TYShrYSkpLmpvaW4oIiwiKSx3YT1nZXRDb29yZHNEYXRhVHlwZSQxKGJhKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7d2F9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIHNldE91dHB1dChnZXRYKCR7VGF9KSk7CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgUmV2ZXJzZVBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwO2NvbnN0IGJhPWFhLmxlbmd0aDtpZihiYT40KXRocm93IG5ldyBFcnJvcihgV2ViR0wgYmFja2VuZDogUmV2ZXJzZSBvZiByYW5rLSR7YmF9IHRlbnNvciBpcyBub3QgeWV0IHN1cHBvcnRlZGApO3RoaXMub3V0cHV0U2hhcGU9YWE7Y29uc3QgU2E9Z2V0Q2hhbm5lbHMkMSgicmMiLGJhKSxUYT1gJHtTYVtiYS0xXX0gKyAxIDwgJHt0aGlzLm91dHB1dFNoYXBlW2JhLTFdfWAsd2E9YCR7U2FbYmEtMl19ICsgMSA8ICR7dGhpcy5vdXRwdXRTaGFwZVtiYS0yXX1gLEVhPWdldENvb3Jkc0RhdGFUeXBlJDEoYmEpO2JhPT09MT90aGlzLnVzZXJDb2RlPWAKICAgICAgICB2b2lkIG1haW4oKXsKICAgICAgICAgIGludCByYyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICAgIHJlc3VsdC5yID0gZ2V0Q2hhbm5lbChnZXRYKCR7YWFbMF19IC0gcmMgLSAxKSwKICAgICAgICAgICAgJHthYVswXX0gLSByYyAtIDEpOwogICAgICAgICAgaWYoJHtUYX0pewogICAgICAgICAgICAgIHJlc3VsdC5nID0gZ2V0Q2hhbm5lbChnZXRYKCR7YWFbMF19IC0gKHJjICArIDEpIC0gMSksCiAgICAgICAgICAgICAgICAke2FhWzBdfSAtIChyYyAgKyAxKSAtIDEpOwogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgICAgfQogICAgICBgOnRoaXMudXNlckNvZGU9YAogICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgICR7RWF9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwogICAgICAgICAgcmVzdWx0LnIgPSAke2thKFNhLnNsaWNlKCkpfTsKICAgICAgICAgIGlmKCR7VGF9KXsKICAgICAgICAgICAgcmVzdWx0LmcgPSAke0FhKFNhLnNsaWNlKCkpfTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKCR7d2F9KSB7CiAgICAgICAgICAgIHJlc3VsdC5iID0gJHtGYShTYS5zbGljZSgpKX07CiAgICAgICAgICAgIGlmKCR7VGF9KSB7CiAgICAgICAgICAgICAgcmVzdWx0LmEgPSAke0xhKFNhLnNsaWNlKCkpfTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgICAgfQogICAgYDtmdW5jdGlvbiBrYShubCl7cmV0dXJuIGVsKG5sKX1mdW5jdGlvbiBBYShubCl7cmV0dXJuIG5sW2JhLTFdPSIoIitubFtiYS0xXSsiICsgMSkiLGVsKG5sKX1mdW5jdGlvbiBGYShubCl7cmV0dXJuIG5sW2JhLTJdPSIoIitubFtiYS0yXSsiICsgMSkiLGVsKG5sKX1mdW5jdGlvbiBMYShubCl7cmV0dXJuIG5sW2JhLTFdPSIoIitubFtiYS0xXSsiICsgMSkiLG5sW2JhLTJdPSIoIitubFtiYS0yXSsiICsgMSkiLGVsKG5sKX1mdW5jdGlvbiBlbChubCl7Y29uc3Qgc2w9YWEubWFwKChhbCxsbCk9PnRsKGxsLG5sKSkscmw9c2wuam9pbigiLCIpLG9sPXNsLnNsaWNlKC0yKS5qb2luKCIsIik7cmV0dXJuYGdldENoYW5uZWwoZ2V0WCgke3JsfSksIHZlYzIoJHtvbH0pKWB9ZnVuY3Rpb24gdGwobmwsc2wpe3JldHVybiB4YS5pbmRleE9mKG5sKSE9PS0xJiZhYVtubF0hPT0xP2Ake2FhW25sXX0gLSAke3NsW25sXX0gLSAxYDpgJHtzbFtubF19YH19fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXZlcnNlJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2RpbXM6VGF9PWJhLHdhPVNhLnNoYXBlLmxlbmd0aCxFYT1wYXJzZUF4aXNQYXJhbSQxKFRhLFNhLnNoYXBlKTtpZih3YT09PTApcmV0dXJuIGlkZW50aXR5JDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2NvbnN0IGthPWVudiQxKCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19BUlJBWV9PUEVSQVRJT05TIik/bmV3IFJldmVyc2VQYWNrZWRQcm9ncmFtJDEoU2Euc2hhcGUsRWEpOm5ldyBSZXZlcnNlUHJvZ3JhbSQxKFNhLnNoYXBlLEVhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKGthLFtTYV0sU2EuZHR5cGUpfWNvbnN0IHJldmVyc2VDb25maWckMT17a2VybmVsTmFtZTpSZXZlcnNlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJldmVyc2UkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFJvdGF0ZVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiSW1hZ2UiXSx0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJwYXJhbXMiLHR5cGU6InZlYzQifV07Y29uc3QgYmE9YWFbMV0sU2E9YWFbMl07dGhpcy5vdXRwdXRTaGFwZT1hYTtsZXQgVGE9IiI7dHlwZW9mIHhhPT0ibnVtYmVyIj9UYT1gZmxvYXQgb3V0cHV0VmFsdWUgPSAke3hhLnRvRml4ZWQoMil9O2A6VGE9YAogICAgICAgIHZlYzMgZmlsbCA9IHZlYzMoJHt4YS5qb2luKCIsIil9KTsKICAgICAgICBmbG9hdCBvdXRwdXRWYWx1ZSA9IGZpbGxbY29vcmRzWzNdXTtgLHRoaXMudXNlckNvZGU9YAogICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgaW50IHggPSBjb29yZHNbMl07CiAgICAgICAgICBpbnQgeSA9IGNvb3Jkc1sxXTsKICAgICAgICAgIGZsb2F0IGNvb3JkWEZsb2F0ID0gKGZsb2F0KHgpIC0gcGFyYW1zWzBdKSAqIHBhcmFtc1szXSAtCiAgICAgICAgICAgIChmbG9hdCh5KSAtIHBhcmFtc1sxXSkgKiBwYXJhbXNbMl07CiAgICAgICAgICBmbG9hdCBjb29yZFlGbG9hdCA9IChmbG9hdCh4KSAtIHBhcmFtc1swXSkgKiBwYXJhbXNbMl0gKwogICAgICAgICAgICAoZmxvYXQoeSkgLSBwYXJhbXNbMV0pICogcGFyYW1zWzNdOwogICAgICAgICAgaW50IGNvb3JkWCA9IGludChyb3VuZChjb29yZFhGbG9hdCArIHBhcmFtc1swXSkpOwogICAgICAgICAgaW50IGNvb3JkWSA9IGludChyb3VuZChjb29yZFlGbG9hdCArIHBhcmFtc1sxXSkpOwogICAgICAgICAgJHtUYX0KICAgICAgICAgIGlmKGNvb3JkWCA+PSAwICYmIGNvb3JkWCA8ICR7U2F9ICYmIGNvb3JkWSA+PSAwICYmIGNvb3JkWSA8ICR7YmF9KSB7CiAgICAgICAgICAgIG91dHB1dFZhbHVlID0gZ2V0SW1hZ2UoY29vcmRzWzBdLCBjb29yZFksIGNvb3JkWCwgY29vcmRzWzNdKTsKICAgICAgICAgIH0KICAgICAgICAgIHNldE91dHB1dChvdXRwdXRWYWx1ZSk7CiAgICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJvdGF0ZVdpdGhPZmZzZXRDb25maWckMT17a2VybmVsTmFtZTpSb3RhdGVXaXRoT2Zmc2V0JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOih7aW5wdXRzOmhhLGF0dHJzOmFhLGJhY2tlbmQ6eGF9KT0+e2NvbnN0e2ltYWdlOmJhfT1oYSx7cmFkaWFuczpTYSxmaWxsVmFsdWU6VGEsY2VudGVyOndhfT1hYSxFYT14YSxrYT1uZXcgUm90YXRlUHJvZ3JhbSQxKGJhLnNoYXBlLFRhKSxbQWEsRmFdPWdldEltYWdlQ2VudGVyJDEod2EsYmEuc2hhcGVbMV0sYmEuc2hhcGVbMl0pLExhPVtbQWEsRmEsTWF0aC5zaW4oU2EpLE1hdGguY29zKFNhKV1dO3JldHVybiBFYS5ydW5XZWJHTFByb2dyYW0oa2EsW2JhXSxiYS5kdHlwZSxMYSl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBST1VORCQxPWAKICAvLyBPcGVuR0wgRVMgZG9lcyBub3Qgc3VwcG9ydCByb3VuZCBmdW5jdGlvbi4KICAvLyBUaGUgYWxnb3JpdGhtIGlzIGJhc2VkIG9uIGJhbmtlcidzIHJvdW5kaW5nLgogIGZsb2F0IGJhc2UgPSBmbG9vcih4KTsKICBpZiAoKHggLSBiYXNlKSA8IDAuNSkgewogICAgcmV0dXJuIGZsb29yKHgpOwogIH0gZWxzZSBpZiAoKHggLSBiYXNlKSA+IDAuNSkgewogICAgcmV0dXJuIGNlaWwoeCk7CiAgfSBlbHNlIHsKICAgIGlmIChtb2QoYmFzZSwgMi4wKSA9PSAwLjApIHsKICAgICAgcmV0dXJuIGJhc2U7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gYmFzZSArIDEuMDsKICAgIH0KICB9CmAscm91bmQkMj11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlJPVU5EJDF9KSxyb3VuZENvbmZpZyQxPXtrZXJuZWxOYW1lOlJvdW5kJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJvdW5kJDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFJTUVJUJDE9InJldHVybiBpbnZlcnNlc3FydCh4KTsiLHJzcXJ0JDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpSU1FSVCQxLGNwdUtlcm5lbEltcGw6cnNxcnRJbXBsQ1BVJDF9KSxyc3FydENvbmZpZyQxPXtrZXJuZWxOYW1lOlJzcXJ0JDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJzcXJ0JDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBTY2F0dGVyUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhLEVhPSEwLGthPSExKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ1cGRhdGVzIiwiaW5kaWNlcyIsImRlZmF1bHRWYWx1ZSJdLHRoaXMub3V0cHV0U2hhcGU9d2E7Y29uc3QgQWE9Z2V0Q29vcmRzRGF0YVR5cGUkMShUYS5sZW5ndGgpLEZhPWdldENvb3Jkc0RhdGFUeXBlJDEod2EubGVuZ3RoKTtsZXQgTGE9IiI7YmE9PT0xP0xhPSJpIjpiYT09PTImJihMYT0iaSwgaiIpO2NvbnN0IGVsPWBnZXRJbmRpY2VzKCR7TGF9KWA7bGV0IHRsPSIiO1NhPT09MT90bD0iaSI6U2E9PT0yJiYodGw9ImksIGNvb3Jkc1sxXSIpO2NvbnN0IG5sPWBnZXRVcGRhdGVzKCR7dGx9KWA7bGV0IHNsPSIiO2thJiYoc2w9ImNvb3Jkc1swXSwgY29vcmRzWzFdIik7Y29uc3Qgcmw9YGdldERlZmF1bHRWYWx1ZSgke3NsfSlgLG9sPXhhPjE/InN0cmlkZXNbal0iOiJzdHJpZGVzIjt0aGlzLnVzZXJDb2RlPWAKICAgICAgICAke0FhfSBzdHJpZGVzID0gJHtBYX0oJHtUYX0pOwoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICAke0ZhfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIGZsb2F0IHN1bSA9IDAuMDsKICAgICAgICAgIGJvb2wgZm91bmQgPSBmYWxzZTsKICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHthYX07IGkrKykgewogICAgICAgICAgICBpbnQgZmxhdHRlbmVkSW5kZXggPSAwOwogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7eGF9OyBqKyspIHsKICAgICAgICAgICAgICBpbnQgaW5kZXggPSByb3VuZCgke2VsfSk7CiAgICAgICAgICAgICAgZmxhdHRlbmVkSW5kZXggKz0gaW5kZXggKiAke29sfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZmxhdHRlbmVkSW5kZXggPT0gY29vcmRzWzBdKSB7CiAgICAgICAgICAgICAgc3VtICs9ICR7bmx9OwogICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KG1peCgke3JsfSwgc3VtLCBmbG9hdChmb3VuZCkpKTsKICAgICAgICB9CiAgICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9sZXQgU2NhdHRlclBhY2tlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSx3YSxFYT0hMCxrYT0hMSl7dGhpcy52YXJpYWJsZU5hbWVzPVsidXBkYXRlcyIsImluZGljZXMiLCJkZWZhdWx0VmFsdWUiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLm91dHB1dFNoYXBlPXdhO2NvbnN0IEFhPWdldENvb3Jkc0RhdGFUeXBlJDEoVGEubGVuZ3RoKSxGYT1nZXRDb29yZHNEYXRhVHlwZSQxKHdhLmxlbmd0aCk7bGV0IExhPSIiO2JhPT09MT9MYT0iaSI6YmE9PT0yJiYoTGE9ImksIGoiKTtjb25zdCBlbD1gZ2V0SW5kaWNlcygke0xhfSlgO2xldCB0bD0iIjtTYT09PTE/dGw9ImkiOlNhPT09MiYmKHRsPSJpLCBjb29yZHNbMV0iKTtjb25zdCBubD1gZ2V0VXBkYXRlcygke3RsfSlgO2xldCBzbD0iIjtrYSYmKHNsPSJjb29yZHNbMF0sIGNvb3Jkc1sxXSIpO2NvbnN0IHJsPWBnZXREZWZhdWx0VmFsdWUoJHtzbH0pYCxvbD14YT4xPyJzdHJpZGVzW2pdIjoic3RyaWRlcyIsYWw9eGE+MT8ic3RyaWRlc1tqICsgMV0iOiJzdHJpZGVzIjt0aGlzLnVzZXJDb2RlPWAKICAgICAgICAke0FhfSBzdHJpZGVzID0gJHtBYX0oJHtUYX0pOwoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICAke0ZhfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIHZlYzQgc3VtID0gdmVjNCgwLik7CiAgICAgICAgICB2ZWM0IGZvdW5kID0gdmVjNCgwLik7CiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7YWF9OyBpKz0yKSB7CiAgICAgICAgICAgIGl2ZWMyIGZsYXR0ZW5lZEluZGV4ID0gaXZlYzIoMCk7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHt4YX07IGorPTIpIHsKICAgICAgICAgICAgICBpdmVjNCBpbmRleCA9IHJvdW5kKCR7ZWx9KTsKICAgICAgICAgICAgICBmbGF0dGVuZWRJbmRleCArPSBpbmRleC54eiAqICR7b2x9OwogICAgICAgICAgICAgIGlmIChqICsgMSA8ICR7eGF9KSB7CiAgICAgICAgICAgICAgICBmbGF0dGVuZWRJbmRleCArPSBpbmRleC55dyAqICR7YWx9OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZmxhdHRlbmVkSW5kZXhbMF0gPT0gY29vcmRzWzBdIHx8IGZsYXR0ZW5lZEluZGV4WzFdID09IGNvb3Jkc1swXSB8fAogICAgICAgICAgICAgICAgZmxhdHRlbmVkSW5kZXhbMF0gPT0gY29vcmRzWzBdICsgMSB8fCBmbGF0dGVuZWRJbmRleFsxXSA9PSBjb29yZHNbMF0gKyAxKSB7CiAgICAgICAgICAgICAgdmVjNCB1cGRWYWxzID0gJHtubH07CiAgICAgICAgICAgICAgaWYgKGZsYXR0ZW5lZEluZGV4WzBdID09IGNvb3Jkc1swXSkgewogICAgICAgICAgICAgICAgc3VtLnh5ICs9IHVwZFZhbHMueHk7CiAgICAgICAgICAgICAgICBmb3VuZC54eSA9IHZlYzIoMS4pOwogICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmxhdHRlbmVkSW5kZXhbMF0gPT0gY29vcmRzWzBdICsgMSkgewogICAgICAgICAgICAgICAgc3VtLnp3ICs9IHVwZFZhbHMueHk7CiAgICAgICAgICAgICAgICBmb3VuZC56dyA9IHZlYzIoMS4pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoZmxhdHRlbmVkSW5kZXhbMV0gPT0gY29vcmRzWzBdKSB7CiAgICAgICAgICAgICAgICBzdW0ueHkgKz0gdXBkVmFscy56dzsKICAgICAgICAgICAgICAgIGZvdW5kLnh5ID0gdmVjMigxLik7CiAgICAgICAgICAgICAgfSBlbHNlIGlmIChmbGF0dGVuZWRJbmRleFsxXSA9PSBjb29yZHNbMF0gKyAxKSB7CiAgICAgICAgICAgICAgICBzdW0uencgKz0gdXBkVmFscy56dzsKICAgICAgICAgICAgICAgIGZvdW5kLnp3ID0gdmVjMigxLik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBzZXRPdXRwdXQobWl4KCR7cmx9LCBzdW0sIGZvdW5kKSk7CiAgICAgICAgfQogICAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2NhdHRlck5kJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW5kaWNlczpTYSx1cGRhdGVzOlRhfT1hYSx7c2hhcGU6d2F9PWJhLHtzbGljZVJhbms6RWEsbnVtVXBkYXRlczprYSxzbGljZVNpemU6QWEsc3RyaWRlczpGYSxvdXRwdXRTaXplOkxhfT1jYWxjdWxhdGVTaGFwZXMkMShUYSxTYSx3YSksZWw9W0xhL0FhLEFhXTtpZihMYT09PTApcmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKHdhLFNhLmR0eXBlKTtjb25zdCB0bD1yZXNoYXBlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W2thLEVhXX19KSxubD1yZXNoYXBlJDIoe2lucHV0czp7eDpUYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W2thLEFhXX19KSxzbD14YS5tYWtlVGVuc29ySW5mbyhbXSwiZmxvYXQzMiIsbmV3IEZsb2F0MzJBcnJheShbMF0pKTtsZXQgcmw7ZW52JDEoKS5nZXRCb29sKCJXRUJHTF9QQUNLIik/cmw9bmV3IFNjYXR0ZXJQYWNrZWRQcm9ncmFtJDEoa2EsRWEsdGwuc2hhcGUubGVuZ3RoLG5sLnNoYXBlLmxlbmd0aCxGYSxlbCk6cmw9bmV3IFNjYXR0ZXJQcm9ncmFtJDEoa2EsRWEsdGwuc2hhcGUubGVuZ3RoLG5sLnNoYXBlLmxlbmd0aCxGYSxlbCk7Y29uc3Qgb2w9eGEucnVuV2ViR0xQcm9ncmFtKHJsLFtubCx0bCxzbF0sbmwuZHR5cGUpLGFsPXJlc2hhcGUkMih7aW5wdXRzOnt4Om9sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTp3YX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhvbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLGFsfWNvbnN0IHNjYXR0ZXJOZENvbmZpZyQxPXtrZXJuZWxOYW1lOlNjYXR0ZXJOZCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzY2F0dGVyTmQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFNlYXJjaFNvcnRlZFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsic29ydGVkU2VxdWVuY2UiLCJ2YWx1ZXMiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToibnVtSW5wdXRzIix0eXBlOiJpbnQifV0sdGhpcy5vdXRwdXRTaGFwZT1bYWEsYmFdO2NvbnN0IFRhPSJ3aGlsZSAobGVmdCA8IHJpZ2h0KSB7Iix3YT1gZm9yIChpbnQgaSA9IDA7IGkgPCAke01hdGguY2VpbChNYXRoLmxvZzIoeGErMSkpfTsgKytpKSB7IGlmIChsZWZ0ID49IHJpZ2h0KSBicmVhaztgLEVhPWVudiQxKCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yP1RhOndhLGthPVNhPT09ImxlZnQiPyI8IjoiPD0iO3RoaXMudXNlckNvZGU9YAogICAgICAgaW50IGZpbmRCb3VuZChpbnQgYmF0Y2gsIGZsb2F0IHZhbHVlKSB7CiAgICAgICAgIGludCBsZWZ0ID0gMDsKICAgICAgICAgaW50IHJpZ2h0ID0gbnVtSW5wdXRzOwogICAgICAgICBpbnQgbWlkOwogICAgICAgICAke0VhfQogICAgICAgICAgIG1pZCA9IChsZWZ0ICsgcmlnaHQpIC8gMjsKICAgICAgICAgICBpZiAoZ2V0U29ydGVkU2VxdWVuY2UoYmF0Y2gsIG1pZCkgJHtrYX0gdmFsdWUpIHsKICAgICAgICAgICAgIGxlZnQgPSBtaWQgKyAxOwogICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICByaWdodCA9IG1pZDsKICAgICAgICAgICB9CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHJpZ2h0OwogICAgICAgfQoKICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICAgaW50IHZhbHVlSW5kZXggPSBjb29yZHNbMV07CgogICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldFZhbHVlcyhiYXRjaCwgdmFsdWVJbmRleCk7CgogICAgICAgICBzZXRPdXRwdXQoZmxvYXQoZmluZEJvdW5kKGJhdGNoLCB2YWx1ZSkpKTsKICAgICAgIH0KICAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2VhcmNoU29ydGVkJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7c29ydGVkU2VxdWVuY2U6U2EsdmFsdWVzOlRhfT1hYSx7c2lkZTp3YX09YmEsRWE9bmV3IFNlYXJjaFNvcnRlZFByb2dyYW0kMShTYS5zaGFwZVswXSxTYS5zaGFwZVsxXSxUYS5zaGFwZVsxXSx3YSksa2E9W1tTYS5zaGFwZVsxXV1dO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRWEsW1NhLFRhXSwiaW50MzIiLGthKX1jb25zdCBzZWFyY2hTb3J0ZWRDb25maWckMT17a2VybmVsTmFtZTpTZWFyY2hTb3J0ZWQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c2VhcmNoU29ydGVkJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBTZWxlY3RQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bImMiLCJhIiwiYiJdLHRoaXMub3V0cHV0U2hhcGU9eGE7bGV0IFNhLFRhO2lmKGJhPjQpdGhyb3cgRXJyb3IoYFdoZXJlIGZvciByYW5rICR7YmF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7aWYoYmE9PT0xKVRhPSJyZXNSQyIsU2E9InJlc1JDIjtlbHNle2NvbnN0IEVhPVsicmVzUkMueCIsInJlc1JDLnkiLCJyZXNSQy56IiwicmVzUkMudyJdLGthPVtdLEFhPVtdO2ZvcihsZXQgRmE9MDtGYTx4YS5sZW5ndGg7RmErKylBYS5wdXNoKGAke0VhW0ZhXX1gKSxGYTxhYSYma2EucHVzaChgJHtFYVtGYV19YCk7U2E9a2Euam9pbigpLFRhPUFhLmpvaW4oKX1jb25zdCB3YT1nZXRDb29yZHNEYXRhVHlwZSQxKGJhKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7d2F9IHJlc1JDID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgY1ZhbCA9IGdldEMoJHtTYX0pOwogICAgICAgIGlmIChjVmFsID49IDEuMCkgewogICAgICAgICAgc2V0T3V0cHV0KGdldEEoJHtUYX0pKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc2V0T3V0cHV0KGdldEIoJHtUYX0pKTsKICAgICAgICB9CiAgICAgIH0KICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzZWxlY3QkMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtjb25kaXRpb246YmEsdDpTYSxlOlRhfT1hYSx3YT1uZXcgU2VsZWN0UHJvZ3JhbSQxKGJhLnNoYXBlLmxlbmd0aCxTYS5zaGFwZSxTYS5zaGFwZS5sZW5ndGgpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0od2EsW2JhLFNhLFRhXSx1cGNhc3RUeXBlJDEoU2EuZHR5cGUsVGEuZHR5cGUpKX1jb25zdCBzZWxlY3RDb25maWckMT17a2VybmVsTmFtZTpTZWxlY3QkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c2VsZWN0JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNFTFUkMT1gCiAgLy8gU3RhYmxlIGFuZCBBdHRyYWN0aW5nIEZpeGVkIFBvaW50ICgwLCAxKSBmb3IgTm9ybWFsaXplZCBXZWlnaHRzLgogIC8vIHNlZTogaHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzE3MDYuMDI1MTUKICBmbG9hdCBzY2FsZUFscGhhID0gJHtTRUxVX1NDQUxFQUxQSEEkMX07CiAgZmxvYXQgc2NhbGUgPSAke1NFTFVfU0NBTEUkMX07CiAgcmV0dXJuICh4ID49IDAuMCkgPyBzY2FsZSAqIHggOiBzY2FsZUFscGhhICogKGV4cCh4KSAtIDEuMCk7CmAsc2VsdSQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6U0VMVSQxfSksc2VsdUNvbmZpZyQxPXtrZXJuZWxOYW1lOlNlbHUkMixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c2VsdSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTSUdNT0lEJDM9Q0hFQ0tfTkFOX1NOSVBQRVRfVU5BUlkkMStgCiAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLTEuMCAqIHgpKTsKYCxTSUdNT0lEX1BBQ0tFRCQxPWAKICB2ZWM0IHJlc3VsdCA9IDEuMCAvICgxLjAgKyBleHAoLTEuMCAqIHgpKTsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwoKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyB4LmcgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyB4LmIgOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiByZXN1bHQuYTsKCiAgcmV0dXJuIHJlc3VsdDsKYCxzaWdtb2lkJDI9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpTSUdNT0lEJDMscGFja2VkT3BTbmlwcGV0OlNJR01PSURfUEFDS0VEJDEsY3B1S2VybmVsSW1wbDpzaWdtb2lkSW1wbENQVSQxfSksc2lnbW9pZENvbmZpZyQxPXtrZXJuZWxOYW1lOlNpZ21vaWQkMixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c2lnbW9pZCQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTSUdOJDE9YAogIGlmIChpc25hbih4KSkgeyByZXR1cm4gMC4wOyB9CiAgcmV0dXJuIHNpZ24oeCk7CmAsc2lnbiQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6U0lHTiQxfSksc2lnbkNvbmZpZyQxPXtrZXJuZWxOYW1lOlNpZ24kMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c2lnbiQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTSU4kMT1DSEVDS19OQU5fU05JUFBFVF9VTkFSWSQxK2AKICByZXR1cm4gc2luKHgpOwpgLFNJTl9QQUNLRUQkMT1gCiAgdmVjNCByZXN1bHQgPSBzaW4oeCk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKICAke0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCQxfQogIHJldHVybiByZXN1bHQ7CmAsc2luJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpTSU4kMSxwYWNrZWRPcFNuaXBwZXQ6U0lOX1BBQ0tFRCQxfSksc2luQ29uZmlnJDE9e2tlcm5lbE5hbWU6U2luJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNpbiQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTSU5IJDE9YAogIGZsb2F0IGUyeCA9IGV4cCh4KTsKICByZXR1cm4gKGUyeCAtIDEuMCAvIGUyeCkgLyAyLjA7CmAsc2luaCQxPXVuYXJ5S2VybmVsRnVuYyQxKHtvcFNuaXBwZXQ6U0lOSCQxfSksc2luaENvbmZpZyQxPXtrZXJuZWxOYW1lOlNpbmgkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c2luaCQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTT0ZUUExVUyQxPWAKICBmbG9hdCBlcHNpbG9uID0gMS4xOTIwOTI4OTU1MDc4MTI1ZS03OwogIGZsb2F0IHRocmVzaG9sZCA9IGxvZyhlcHNpbG9uKSArIDIuMDsKCiAgYm9vbCB0b29fbGFyZ2UgPSB4ID4gLXRocmVzaG9sZDsKICBib29sIHRvb19zbWFsbCA9IHggPCB0aHJlc2hvbGQ7CgogIGZsb2F0IHJlc3VsdDsKICBmbG9hdCBleHBfeCA9IGV4cCh4KTsKCiAgaWYgKHRvb19sYXJnZSl7CiAgICByZXN1bHQgPSB4OwogIH0KICBlbHNlIGlmICh0b29fc21hbGwpewogICAgcmVzdWx0ID0gZXhwX3g7CiAgfQogIGVsc2V7CiAgICByZXN1bHQgPSBsb2coZXhwX3ggKyAxLjApOwogIH0KICByZXR1cm4gcmVzdWx0OwpgLHNvZnRwbHVzJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpTT0ZUUExVUyQxfSksc29mdHBsdXNDb25maWckMT17a2VybmVsTmFtZTpTb2Z0cGx1cyQyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzb2Z0cGx1cyQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBzcGFjZVRvQmF0Y2hORCQxPWhhPT57Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YmxvY2tTaGFwZTpUYSxwYWRkaW5nczp3YX09YmE7YXNzZXJ0JDIoU2Euc2hhcGUubGVuZ3RoPD00LCgpPT4ic3BhY2VUb0JhdGNoTkQgZm9yIHJhbmsgPiA0IHdpdGggYSBXZWJHTCBiYWNrZW5kIG5vdCBpbXBsZW1lbnRlZCB5ZXQiKTtjb25zdCBFYT1UYS5yZWR1Y2UoKG9sLGFsKT0+b2wqYWwpLGthPVtbMCwwXV07a2EucHVzaCguLi53YSk7Zm9yKGxldCBvbD0xK1RhLmxlbmd0aDtvbDxTYS5zaGFwZS5sZW5ndGg7KytvbClrYS5wdXNoKFswLDBdKTtjb25zdCBBYT1bXSxGYT1wYWRWMiQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3BhZGRpbmdzOmthLGNvbnN0YW50VmFsdWU6MH19KSxMYT1nZXRSZXNoYXBlZCQxKEZhLnNoYXBlLFRhLEVhLCExKSxlbD1nZXRQZXJtdXRlZCQxKExhLmxlbmd0aCxUYS5sZW5ndGgsITEpLHRsPWdldFJlc2hhcGVkUGVybXV0ZWQkMShGYS5zaGFwZSxUYSxFYSwhMSksbmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6RmF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkxhfX0pLHNsPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6bmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06ZWx9fSkscmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOnRsfX0pO3JldHVybiBBYS5wdXNoKEZhKSxBYS5wdXNoKG5sKSxBYS5wdXNoKHNsKSxBYS5mb3JFYWNoKG9sPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhvbCkpLHJsfSxzcGFjZVRvQmF0Y2hORENvbmZpZyQxPXtrZXJuZWxOYW1lOlNwYWNlVG9CYXRjaE5EJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNwYWNlVG9CYXRjaE5EJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZUZpbGxFbXB0eVJvd3MkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtpbmRpY2VzOmJhLHZhbHVlczpTYSxkZW5zZVNoYXBlOlRhLGRlZmF1bHRWYWx1ZTp3YX09YWE7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYERlbnNlIHNoYXBlIG11c3QgYmUgYSB2ZWN0b3IsIHNhdzoKICAgICAgICAgJHtUYS5zaGFwZX1gKTtpZihiYS5zaGFwZS5sZW5ndGghPT0yKXRocm93IG5ldyBFcnJvcihgSW5kaWNlcyBtdXN0IGJlIGEgbWF0cml4LCBzYXc6CiAgICAgICAgICR7YmEuc2hhcGV9YCk7aWYoU2Euc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYFZhbHVlcyBtdXN0IGJlIGEgdmVjdG9yLCBzYXc6CiAgICAgICAgICR7U2Euc2hhcGV9YCk7aWYod2Euc2hhcGUubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoYERlZmF1bHQgdmFsdWUgbXVzdCBiZSBhIHNjYWxhciwgc2F3OgogICAgICAgICR7d2Euc2hhcGV9YCk7Y29uc3QgRWE9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSxrYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLEFhPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksRmE9eGEucmVhZFN5bmMod2EuZGF0YUlkKVswXSxbTGEsZWwsdGwsbmwsc2xdPXNwYXJzZUZpbGxFbXB0eVJvd3NJbXBsQ1BVJDEoRWEsYmEuc2hhcGUsYmEuZHR5cGUsa2EsU2EuZHR5cGUsQWEsRmEpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhlbCxiYS5kdHlwZSxMYSkseGEubWFrZVRlbnNvckluZm8oW2VsWzBdXSxTYS5kdHlwZSx0bCkseGEubWFrZVRlbnNvckluZm8oW25sLmxlbmd0aF0sImJvb2wiLG5ldyBVaW50OEFycmF5KG5sLm1hcChybD0+TnVtYmVyKHJsKSkpKSx4YS5tYWtlVGVuc29ySW5mbyhbc2wubGVuZ3RoXSxiYS5kdHlwZSxuZXcgSW50MzJBcnJheShzbCkpXX1jb25zdCBzcGFyc2VGaWxsRW1wdHlSb3dzQ29uZmlnJDE9e2tlcm5lbE5hbWU6U3BhcnNlRmlsbEVtcHR5Um93cyQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzcGFyc2VGaWxsRW1wdHlSb3dzJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVJlc2hhcGUkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtpbnB1dEluZGljZXM6YmEsaW5wdXRTaGFwZTpTYSxuZXdTaGFwZTpUYX09YWE7aWYoYmEuc2hhcGUubGVuZ3RoIT09Mil0aHJvdyBuZXcgRXJyb3IoYElucHV0IGluZGljZXMgc2hvdWxkIGJlIGEgbWF0cml4IGJ1dCByZWNlaXZlZCBzaGFwZSAke2JhLnNoYXBlfWApO2lmKFNhLnNoYXBlLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBzaGFwZSBzaG91bGQgYmUgYSB2ZWN0b3IgYnV0IHJlY2VpdmVkIHNoYXBlICR7U2Euc2hhcGV9YCk7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYFRhcmdldCBzaGFwZSBzaG91bGQgYmUgYSB2ZWN0b3IgYnV0IHJlY2VpdmVkIHNoYXBlICR7VGEuc2hhcGV9YCk7Y29uc3Qgd2E9QXJyYXkuZnJvbSh4YS5yZWFkU3luYyhTYS5kYXRhSWQpKSxFYT14YS5yZWFkU3luYyhiYS5kYXRhSWQpLGthPUFycmF5LmZyb20oeGEucmVhZFN5bmMoVGEuZGF0YUlkKSksW0FhLEZhLExhXT1zcGFyc2VSZXNoYXBlSW1wbENQVSQxKEVhLGJhLnNoYXBlLGJhLmR0eXBlLHdhLGthKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpLHhhLm1ha2VUZW5zb3JJbmZvKFtMYS5sZW5ndGhdLFRhLmR0eXBlLG5ldyBJbnQzMkFycmF5KExhKSldfWNvbnN0IHNwYXJzZVJlc2hhcGVDb25maWckMT17a2VybmVsTmFtZTpTcGFyc2VSZXNoYXBlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNwYXJzZVJlc2hhcGUkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlU2VnbWVudE1lYW4kMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtkYXRhOmJhLGluZGljZXM6U2Esc2VnbWVudElkczpUYX09YWE7aWYoYmEuc2hhcGUubGVuZ3RoPDEpdGhyb3cgbmV3IEVycm9yKCJEYXRhIHNob3VsZCBiZSBhdCBsZWFzdCAxIGRpbWVuc2lvbmFsIGJ1dCByZWNlaXZlZCBzY2FsYXIiKTtpZihTYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgSW5kaWNlcyBzaG91bGQgYmUgYSB2ZWN0b3IgYnV0IHJlY2VpdmVkIHNoYXBlCiAgICAgICAgICAgICAgJHtTYS5zaGFwZX1gKTtpZihUYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgU2VnbWVudCBpZHMgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgICAgICR7VGEuc2hhcGV9YCk7Y29uc3Qgd2E9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSxFYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksW0FhLEZhXT1zcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbENQVSQxKHdhLGJhLnNoYXBlLGJhLmR0eXBlLEVhLGthLCEwKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpfWNvbnN0IHNwYXJzZVNlZ21lbnRNZWFuQ29uZmlnJDE9e2tlcm5lbE5hbWU6U3BhcnNlU2VnbWVudE1lYW4kMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3BhcnNlU2VnbWVudE1lYW4kMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlU2VnbWVudFN1bSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2RhdGE6YmEsaW5kaWNlczpTYSxzZWdtZW50SWRzOlRhfT1hYTtpZihiYS5zaGFwZS5sZW5ndGg8MSl0aHJvdyBuZXcgRXJyb3IoIkRhdGEgc2hvdWxkIGJlIGF0IGxlYXN0IDEgZGltZW5zaW9uYWwgYnV0IHJlY2VpdmVkIHNjYWxhciIpO2lmKFNhLnNoYXBlLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBJbmRpY2VzIHNob3VsZCBiZSBhIHZlY3RvciBidXQgcmVjZWl2ZWQgc2hhcGUKICAgICAgICAgICAgICR7U2Euc2hhcGV9YCk7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYFNlZ21lbnQgaWRzIHNob3VsZCBiZSBhIHZlY3RvciBidXQgcmVjZWl2ZWQgc2hhcGUKICAgICAgICAgICAgICR7VGEuc2hhcGV9YCk7Y29uc3Qgd2E9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSxFYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksW0FhLEZhXT1zcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbENQVSQxKHdhLGJhLnNoYXBlLGJhLmR0eXBlLEVhLGthKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpfWNvbnN0IHNwYXJzZVNlZ21lbnRTdW1Db25maWckMT17a2VybmVsTmFtZTpTcGFyc2VTZWdtZW50U3VtJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNwYXJzZVNlZ21lbnRTdW0kMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlVG9EZW5zZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3NwYXJzZUluZGljZXM6U2Esc3BhcnNlVmFsdWVzOlRhLGRlZmF1bHRWYWx1ZTp3YX09YWEse291dHB1dFNoYXBlOkVhfT1iYSx7c2xpY2VSYW5rOmthLG51bVVwZGF0ZXM6QWEsc2xpY2VTaXplOkZhLHN0cmlkZXM6TGEsb3V0cHV0U2l6ZTplbH09Y2FsY3VsYXRlU2hhcGVzJDEoVGEsU2EsRWEpLHRsPSExO2lmKFRhLmR0eXBlPT09InN0cmluZyIpe2NvbnN0IG9sPXhhLmJ1ZmZlclN5bmMoU2EpLGFsPXhhLmJ1ZmZlclN5bmMoVGEpLGxsPWRlY29kZVN0cmluZyQxKHhhLnJlYWRTeW5jKHdhLmRhdGFJZClbMF0pLGlsPXNjYXR0ZXJJbXBsQ1BVJDEob2wsYWwsRWEsZWwsRmEsQWEsa2EsTGEsbGwsdGwpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhFYSxpbC5kdHlwZSxpbC52YWx1ZXMpfWNvbnN0IG5sPW5ldyBTY2F0dGVyUHJvZ3JhbSQxKEFhLGthLFNhLnNoYXBlLmxlbmd0aCxUYS5zaGFwZS5sZW5ndGgsTGEsW2VsLDFdLHRsKSxzbD14YS5ydW5XZWJHTFByb2dyYW0obmwsW1RhLFNhLHdhXSxUYS5kdHlwZSkscmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkVhfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkscmx9Y29uc3Qgc3BhcnNlVG9EZW5zZUNvbmZpZyQxPXtrZXJuZWxOYW1lOlNwYXJzZVRvRGVuc2UkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3BhcnNlVG9EZW5zZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGxpdFYkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7bnVtT3JTaXplU3BsaXRzOlRhLGF4aXM6d2F9PWJhLEVhPXBhcnNlQXhpc1BhcmFtJDEod2EsU2Euc2hhcGUpWzBdLGthPXByZXBhcmVTcGxpdFNpemUkMShTYSxUYSxFYSksQWE9U2Euc2hhcGUubGVuZ3RoLEZhPW5ldyBBcnJheShBYSkuZmlsbCgwKSxMYT1TYS5zaGFwZS5zbGljZSgpO3JldHVybiBrYS5tYXAoZWw9Pntjb25zdCB0bD1bLi4uTGFdO3RsW0VhXT1lbDtjb25zdCBubD1zbGljZSQxKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2JlZ2luOkZhLHNpemU6dGx9fSk7cmV0dXJuIEZhW0VhXSs9ZWwsbmx9KX1jb25zdCBzcGxpdFZDb25maWckMT17a2VybmVsTmFtZTpTcGxpdFYkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3BsaXRWJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNRUlQkMT0icmV0dXJuIHNxcnQoeCk7IixzcXJ0JDI9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpTUVJUJDEscGFja2VkT3BTbmlwcGV0OlNRUlQkMSxjcHVLZXJuZWxJbXBsOnNxcnRJbXBsQ1BVJDF9KSxzcXJ0Q29uZmlnJDE9e2tlcm5lbE5hbWU6U3FydCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzcXJ0JDJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNRVUFSRSQxPSJyZXR1cm4geCAqIHg7IixzcXVhcmUkMj11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlNRVUFSRSQxfSksc3F1YXJlQ29uZmlnJDE9e2tlcm5lbE5hbWU6U3F1YXJlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNxdWFyZSQyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTUVVBUkVEX0RJRkZFUkVOQ0UkMT0icmV0dXJuIChhIC0gYikgKiAoYSAtIGIpOyIsc3F1YXJlZERpZmZlcmVuY2UkMT1iaW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpTUVVBUkVEX0RJRkZFUkVOQ0UkMSxwYWNrZWRPcFNuaXBwZXQ6U1FVQVJFRF9ESUZGRVJFTkNFJDF9KSxzcXVhcmVkRGlmZmVyZW5jZUNvbmZpZyQxPXtrZXJuZWxOYW1lOlNxdWFyZWREaWZmZXJlbmNlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNxdWFyZWREaWZmZXJlbmNlJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0YXRpY1JlZ2V4UmVwbGFjZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhO2lmKFNhLmR0eXBlIT09InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKCJJbnB1dCBtdXN0IGJlIG9mIGRhdGF0eXBlIHN0cmluZyIpO2NvbnN0IFRhPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksd2E9ZnJvbVVpbnQ4VG9TdHJpbmdBcnJheSQxKFRhKSxFYT1zdGF0aWNSZWdleFJlcGxhY2VJbXBsQ1BVJDEod2EsInN0cmluZyIsYmEpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhTYS5zaGFwZSwic3RyaW5nIixFYSl9Y29uc3Qgc3RhdGljUmVnZXhSZXBsYWNlQ29uZmlnJDE9e2tlcm5lbE5hbWU6U3RhdGljUmVnZXhSZXBsYWNlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnN0YXRpY1JlZ2V4UmVwbGFjZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdGVwJDIoe2lucHV0czpoYSxhdHRyczphYSxiYWNrZW5kOnhhfSl7Y29uc3R7eDpiYX09aGEsU2E9Q0hFQ0tfTkFOX1NOSVBQRVQkMytgCiAgICByZXR1cm4geCA+IDAuMCA/IDEuMCA6IGZsb2F0KCR7YWEuYWxwaGF9KTsKICBgLFRhPW5ldyBVbmFyeU9wUHJvZ3JhbSQxKGJhLnNoYXBlLFNhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKFRhLFtiYV0sYmEuZHR5cGUpfWNvbnN0IHN0ZXBDb25maWckMT17a2VybmVsTmFtZTpTdGVwJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnN0ZXAkMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFN0cmlkZWRTbGljZVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMub3V0cHV0U2hhcGU9YmE7Y29uc3QgU2E9YmEubGVuZ3RoLFRhPWdldENvb3Jkc0RhdGFUeXBlJDEoYmEubGVuZ3RoKSx3YT1nZXRDb29yZHNEYXRhVHlwZSQxKGJhLmxlbmd0aCk7bGV0IEVhPSIiO2lmKFNhPT09MSlFYT0iY29vcmRzICogc3RyaWRlcyArIGJlZ2luIjtlbHNle2xldCBrYT0wO0VhPWJhLm1hcCgoQWEsRmEpPT4oa2ErKyxiYS5sZW5ndGg9PT0xP2Bjb29yZHMgKiBzdHJpZGVzWyR7RmF9XSArIGJlZ2luWyR7RmF9XWA6YGNvb3Jkc1ske2thLTF9XSAqIHN0cmlkZXNbJHtGYX1dICsgYmVnaW5bJHtGYX1dYCkpLmpvaW4oIiwiKX10aGlzLnVzZXJDb2RlPWAKICAgICAgJHtUYX0gYmVnaW4gPSAke1RhfSgke2FhfSk7CiAgICAgICR7VGF9IHN0cmlkZXMgPSAke1RhfSgke3hhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHt3YX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgc2V0T3V0cHV0KGdldFgoJHtFYX0pKTsKICAgICAgfQogICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0cmlkZWRTbGljZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtiZWdpbjpUYSxlbmQ6d2Esc3RyaWRlczpFYSxiZWdpbk1hc2s6a2EsZW5kTWFzazpBYSxlbGxpcHNpc01hc2s6RmEsbmV3QXhpc01hc2s6TGEsc2hyaW5rQXhpc01hc2s6ZWx9PWJhLHtmaW5hbFNoYXBlU3BhcnNlOnRsLGZpbmFsU2hhcGU6bmwsaXNJZGVudGl0eTpzbCxzbGljZURpbTA6cmwsaXNTaW1wbGVTbGljZTpvbCxiZWdpbjphbCxlbmQ6bGwsc3RyaWRlczppbH09c2xpY2VJbmZvJDEoU2Euc2hhcGUsVGEsd2EsRWEsa2EsQWEsRmEsTGEsZWwpO2xldCBjbDtpZihzbCljbD1yZXNoYXBlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSk7ZWxzZSBpZihybHx8b2wpe2Fzc2VydCQyKFNhLnNoYXBlLmxlbmd0aD49MSwoKT0+YElucHV0IG11c3QgaGF2ZSByYW5rIGF0IGxlYXN0IDEsIGdvdDogJHtTYS5zaGFwZS5sZW5ndGh9YCk7Y29uc3QgZGw9Y29tcHV0ZU91dFNoYXBlJDUoYWwsbGwsaWwpLGhsPXNsaWNlJDEoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46YWwsc2l6ZTpkbH19KTtjbD1yZXNoYXBlJDIoe2lucHV0czp7eDpobH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oaGwpfWVsc2UgaWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtTYV0pKXtjb25zdCBobD14YS5yZWFkU3luYyhTYS5kYXRhSWQpLHBsPWJ1ZmZlciQxKFNhLnNoYXBlLFNhLmR0eXBlLGhsKSxmbD1zdHJpZGVkU2xpY2VJbXBsQ1BVJDEodGwscGwsaWwsYWwpO2NsPXhhLm1ha2VUZW5zb3JJbmZvKG5sLFNhLmR0eXBlLGZsLnZhbHVlcyl9ZWxzZXtjb25zdCBobD1uZXcgU3RyaWRlZFNsaWNlUHJvZ3JhbSQxKGFsLGlsLHRsKTtjbD14YS5ydW5XZWJHTFByb2dyYW0oaGwsW1NhXSxTYS5kdHlwZSl9Y29uc3QgdWw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6Y2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOm5sfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhjbCksdWx9Y29uc3Qgc3RyaWRlZFNsaWNlQ29uZmlnJDE9e2tlcm5lbE5hbWU6U3RyaWRlZFNsaWNlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnN0cmlkZWRTbGljZSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdHJpbmdOR3JhbXMkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzZXBhcmF0b3I6U2EsbkdyYW1XaWR0aHM6VGEsbGVmdFBhZDp3YSxyaWdodFBhZDpFYSxwYWRXaWR0aDprYSxwcmVzZXJ2ZVNob3J0U2VxdWVuY2VzOkFhfT1iYSx7ZGF0YTpGYSxkYXRhU3BsaXRzOkxhfT1hYSxlbD14YS5yZWFkU3luYyhGYS5kYXRhSWQpLHRsPXhhLnJlYWRTeW5jKExhLmRhdGFJZCksW25sLHNsXT1zdHJpbmdOR3JhbXNJbXBsQ1BVJDEoZWwsdGwsU2EsVGEsd2EsRWEsa2EsQWEpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhbbmwubGVuZ3RoXSwic3RyaW5nIixubCkseGEubWFrZVRlbnNvckluZm8oTGEuc2hhcGUsImludDMyIixzbCldfWNvbnN0IHN0cmluZ05HcmFtc0NvbmZpZyQxPXtrZXJuZWxOYW1lOlN0cmluZ05HcmFtcyQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzdHJpbmdOR3JhbXMkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nU3BsaXQkMShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtza2lwRW1wdHk6U2F9PWJhLHtpbnB1dDpUYSxkZWxpbWl0ZXI6d2F9PWFhO2lmKFRhLmR0eXBlIT09InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKCJJbnB1dCBtdXN0IGJlIG9mIGRhdGF0eXBlIHN0cmluZyIpO2lmKFRhLnNoYXBlLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBtdXN0IGJlIGEgdmVjdG9yLCBnb3Qgc2hhcGU6ICR7VGEuc2hhcGV9YCk7aWYod2Euc2hhcGUubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoYERlbGltaXRlciBtdXN0IGJlIGEgc2NhbGFyLCBnb3Qgc2hhcGU6ICR7d2Euc2hhcGV9YCk7Y29uc3QgRWE9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxrYT14YS5yZWFkU3luYyh3YS5kYXRhSWQpWzBdLFtBYSxGYSxMYV09c3RyaW5nU3BsaXRJbXBsQ1BVJDEoRWEsa2EsU2EpLGVsPUZhLmxlbmd0aDtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oW2VsLDJdLCJpbnQzMiIsQWEpLHhhLm1ha2VUZW5zb3JJbmZvKFtlbF0sInN0cmluZyIsRmEpLHhhLm1ha2VUZW5zb3JJbmZvKFsyXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KExhKSldfWNvbnN0IHN0cmluZ1NwbGl0Q29uZmlnJDE9e2tlcm5lbE5hbWU6U3RyaW5nU3BsaXQkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3RyaW5nU3BsaXQkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nVG9IYXNoQnVja2V0RmFzdCQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse251bUJ1Y2tldHM6U2F9PWJhLHtpbnB1dDpUYX09YWE7aWYoVGEuZHR5cGUhPT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIklucHV0IG11c3QgYmUgb2YgZGF0YXR5cGUgc3RyaW5nIik7aWYoU2E8PTApdGhyb3cgbmV3IEVycm9yKCJOdW1iZXIgb2YgYnVja2V0cyBtdXN0IGJlIGF0IGxlYXN0IDEiKTtjb25zdCB3YT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLEVhPXN0cmluZ1RvSGFzaEJ1Y2tldEZhc3RJbXBsQ1BVJDEod2EsU2EpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhUYS5zaGFwZSwiaW50MzIiLEVhKX1jb25zdCBzdHJpbmdUb0hhc2hCdWNrZXRGYXN0Q29uZmlnJDE9e2tlcm5lbE5hbWU6U3RyaW5nVG9IYXNoQnVja2V0RmFzdCQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzdHJpbmdUb0hhc2hCdWNrZXRGYXN0JDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFRBTiQxPSJyZXR1cm4gdGFuKHgpOyIsdGFuJDE9dW5hcnlLZXJuZWxGdW5jJDEoe29wU25pcHBldDpUQU4kMX0pLHRhbkNvbmZpZyQxPXtrZXJuZWxOYW1lOlRhbiQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp0YW4kMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgVEFOSCQxPWAKICBmbG9hdCBlMnggPSBleHAoLTIuMCAqIGFicyh4KSk7CiAgcmV0dXJuIHNpZ24oeCkgKiAoMS4wIC0gZTJ4KSAvICgxLjAgKyBlMngpOwpgLHRhbmgkMT11bmFyeUtlcm5lbEZ1bmMkMSh7b3BTbmlwcGV0OlRBTkgkMX0pLHRhbmhDb25maWckMT17a2VybmVsTmFtZTpUYW5oJDIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRhbmgkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdGVuc29yU2NhdHRlclVwZGF0ZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3RlbnNvcjpTYSxpbmRpY2VzOlRhLHVwZGF0ZXM6d2F9PWFhLHtzbGljZVJhbms6RWEsbnVtVXBkYXRlczprYSxzbGljZVNpemU6QWEsc3RyaWRlczpGYSxvdXRwdXRTaXplOkxhfT1jYWxjdWxhdGVTaGFwZXMkMSh3YSxUYSxTYS5zaGFwZSksZWw9W0xhL0FhLEFhXTtpZihMYT09PTApcmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFNhLnNoYXBlLFRhLmR0eXBlKTtjb25zdCB0bD1yZXNoYXBlJDIoe2lucHV0czp7eDpUYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W2thLEVhXX19KSxubD1yZXNoYXBlJDIoe2lucHV0czp7eDp3YX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W2thLEFhXX19KSxzbD1yZXNoYXBlJDIoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6ZWx9fSkscmw9bmV3IFNjYXR0ZXJQcm9ncmFtJDEoa2EsRWEsdGwuc2hhcGUubGVuZ3RoLG5sLnNoYXBlLmxlbmd0aCxGYSxlbCwhMSwhMCksb2w9eGEucnVuV2ViR0xQcm9ncmFtKHJsLFtubCx0bCxzbF0sc2wuZHR5cGUpLGFsPXJlc2hhcGUkMih7aW5wdXRzOnt4Om9sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpTYS5zaGFwZX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpLGFsfWNvbnN0IHRlbnNvclNjYXR0ZXJVcGRhdGVDb25maWckMT17a2VybmVsTmFtZTpUZW5zb3JTY2F0dGVyVXBkYXRlJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRlbnNvclNjYXR0ZXJVcGRhdGUkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFRpbGVQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXTtjb25zdCBiYT1uZXcgQXJyYXkoYWEubGVuZ3RoKTtmb3IobGV0IHdhPTA7d2E8YmEubGVuZ3RoO3dhKyspYmFbd2FdPWFhW3dhXSp4YVt3YV07dGhpcy5vdXRwdXRTaGFwZT1iYSx0aGlzLnJhbms9YmEubGVuZ3RoO2NvbnN0IFNhPWdldENvb3Jkc0RhdGFUeXBlJDEodGhpcy5yYW5rKSxUYT1nZXRTb3VyY2VDb29yZHMkMyhhYSk7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke1NhfSByZXNSQyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIHNldE91dHB1dChnZXRBKCR7VGF9KSk7CiAgICAgIH0KICAgIGB9fTtmdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMkMyhoYSl7Y29uc3QgYWE9aGEubGVuZ3RoO2lmKGFhPjUpdGhyb3cgRXJyb3IoYFRpbGUgZm9yIHJhbmsgJHthYX0gaXMgbm90IHlldCBzdXBwb3J0ZWRgKTtpZihhYT09PTEpcmV0dXJuYGltb2QocmVzUkMsICR7aGFbMF19KWA7Y29uc3QgeGE9WyJyZXNSQy54IiwicmVzUkMueSIsInJlc1JDLnoiLCJyZXNSQy53IiwicmVzUkMudSJdLGJhPVtdO2ZvcihsZXQgU2E9MDtTYTxoYS5sZW5ndGg7U2ErKyliYS5wdXNoKGBpbW9kKCR7eGFbU2FdfSwgJHtoYVtTYV19KWApO3JldHVybiBiYS5qb2luKCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdGlsZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtyZXBzOlRhfT1iYTtpZihTYS5kdHlwZT09PSJzdHJpbmcifHxTYS5zaGFwZS5sZW5ndGg+NSl7Y29uc3Qga2E9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxBYT1TYS5kdHlwZT09PSJzdHJpbmciP2thLm1hcChlbD0+ZGVjb2RlU3RyaW5nJDEoZWwpKTprYSxGYT1idWZmZXIkMShTYS5zaGFwZSxTYS5kdHlwZSxBYSksTGE9dGlsZUltcGxDUFUkMShGYSxUYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKExhLnNoYXBlLExhLmR0eXBlLExhLnZhbHVlcyl9Y29uc3Qgd2E9bmV3IFRpbGVQcm9ncmFtJDEoU2Euc2hhcGUsVGEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0od2EsW1NhXSxTYS5kdHlwZSl9Y29uc3QgdGlsZUNvbmZpZyQxPXtrZXJuZWxOYW1lOlRpbGUkMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6dGlsZSQxfTtsZXQgU3dhcFByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsImluZGljZXMiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToibiIsdHlwZToiaW50In0se25hbWU6ImZpcnN0UGFzcyIsdHlwZToiaW50In0se25hbWU6Im5lZ2F0aXZlSW5mIix0eXBlOiJmbG9hdCJ9LHtuYW1lOiJkaXIiLHR5cGU6ImludCJ9LHtuYW1lOiJpbmMiLHR5cGU6ImludCJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudXNlckNvZGU9YAogICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgICBpbnQgZWxlbUlkeCA9IGNvb3Jkc1sxXTsKCiAgICAgICAgIC8vIFdlIGNvbXBhcmUgZWxlbWVudHMgcGFpci13aXNlIHdpdGhpbiBhIGdyb3VwIG9mIHNpemUgMiAqIGluYy4KICAgICAgICAgLy8gVGhlIGNvbXBhcmluZyBydWxlIGZvciBlYWNoIGdyb3VwIGFsdGVybmF0ZXMgYmV0d2VlbiBhc2NlbmRpbmcKICAgICAgICAgLy8gYW5kIGRlc2NlbmRpbmcuIFdpdGhpbiBlYWNoIGdyb3VwLCB3ZSBjb21wYXJlIGVhY2ggcGFpciBhdAogICAgICAgICAvLyBwb3NpdGlvbnMgaSBhbmQgaStpbmMuIFRvIGRlY2lkZSB3aGV0aGVyIGFuIGVsZW1lbnQgYXQgcG9zaXRpb24gaQogICAgICAgICAvLyBpcyB4MCBvciB4MSwgd2UgbW9kIGl0IGJ5IDIgKiBpbmMsIGlmIHRoZSByZXN1bHQgaXMgc21hbGxlciB0aGFuCiAgICAgICAgIC8vIGluYywgaXQgaXMgaW4gdGhlIGZpcnN0IGhhbGYgb2YgdGhlIGdyb3VwLCB3ZSBkZW5vdGUgaXQgYXMgeDAsCiAgICAgICAgIC8vIG90aGVyd2lzZSB3ZSBkZW5vdGUgaXQgYXMgeDEuCiAgICAgICAgIC8vIEZvciBleGFtcGxlLCBhcyBzaG93biBpbiB0aGUgQml0b25pYyB0b3AgSyBwYXBlciByZWZlcmVuY2VkIGFib3ZlLAogICAgICAgICAvLyBGaWd1cmU1KGEpIHNob3dzIHRoYXQgZWxlbWVudFsxXSBpcyBpbiB0aGUKICAgICAgICAgLy8gc2Vjb25kIGhhbGYgb2YgdGhlIGdyb3VwIHdoZW4gZ3JvdXAgc2l6ZSBpcyAyLCBidXQgaXQgaXMgaW4gdGhlCiAgICAgICAgIC8vIGZpcnN0IGhhbGYgb2YgdGhlIGdyb3VwIHdoZW4gZ3JvdXAgc2l6ZSBpcyA0LgoKICAgICAgICAgYm9vbCBpc0ZpcnN0SW5QYWlyID0gaW1vZChlbGVtSWR4LCAyICogaW5jKSA8IGluYzsKICAgICAgICAgaW50IGkgPSBpc0ZpcnN0SW5QYWlyID8gZWxlbUlkeCA6IGVsZW1JZHggLSBpbmM7CgogICAgICAgICBpbnQgaTAgPSBmaXJzdFBhc3MgPT0gMSA/IGkgOiBpbnQoZ2V0SW5kaWNlcyhiYXRjaCwgaSkpOwogICAgICAgICBpbnQgaTEgPSBmaXJzdFBhc3MgPT0gMSA/IGkgKyBpbmMgOiBpbnQoZ2V0SW5kaWNlcyhiYXRjaCwgaSArIGluYykpOwogICAgICAgICBmbG9hdCB4MCA9IGkwIDwgbiA/IGdldFgoYmF0Y2gsIGkwKSA6IG5lZ2F0aXZlSW5mOwogICAgICAgICBmbG9hdCB4MSA9IGkxIDwgbiA/IGdldFgoYmF0Y2gsIGkxKSA6IG5lZ2F0aXZlSW5mOwoKICAgICAgICAgLy8gRGVub3RlcyB3aGljaCBkaXJlY3Rpb24gaW5kaWNlcyBhcmUgaW4gKGFzY2VuZGluZyBvciBkZXNjZW5kaW5nKS4KICAgICAgICAgYm9vbCByZXZlcnNlID0gaW1vZChlbGVtSWR4LCAyICogZGlyKSA+PSBkaXI7CiAgICAgICAgIGJvb2wgaXNHcmVhdGVyID0geDAgPiB4MSB8fCAoeDAgPT0geDEgJiYgaTEgPiBpMCk7CiAgICAgICAgIGlmIChyZXZlcnNlID09IGlzR3JlYXRlcikgeyAvLyBFbGVtZW50cyBpbiBvcHBvc2l0ZSBvcmRlciBvZiBkaXJlY3Rpb24KICAgICAgICAgICBpbnQgaVRlbXAgPSBpMDsKICAgICAgICAgICBpMCA9IGkxOwogICAgICAgICAgIGkxID0gaVRlbXA7CiAgICAgICAgIH0KICAgICAgICAgaWYgKGlzRmlyc3RJblBhaXIpIHsKICAgICAgICAgICAgc2V0T3V0cHV0KGZsb2F0KGkwKSk7CiAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNldE91dHB1dChmbG9hdChpMSkpOwogICAgICAgICB9CiAgICAgICB9CiAgICAgYH19LE1lcmdlUHJvZ3JhbSQxPWNsYXNze2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiaW5kaWNlcyJdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJuIix0eXBlOiJpbnQifSx7bmFtZToiZmlyc3RQYXNzIix0eXBlOiJpbnQifSx7bmFtZToiayIsdHlwZToiaW50In1dLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgIC8vIFRha2VzIG1heCBvZiBpbmRpY2VzICgwLCBrKSwgKDEsIGsgKyAxKSwgKDIsIGsgKyAyKSAuLi4KICAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICAgaW50IGVsZW1JZHggPSBjb29yZHNbMV07CgogICAgICAgICAvLyBUaGUgb3V0cHV0IHNpemUgaXMgaGFsZiBvZiB0aGUgcHJldmlvdXMgc2l6ZS4KICAgICAgICAgLy8gSWYgdGhlIHByZXZpb3VzIHNlcXVlbmNlIGlzIHwgfCB8IHwgXyBfIF8gXyAgfCB8IHwgfCAgXyBfIF8gXyAoaz00KSwKICAgICAgICAgLy8gd2Ugb25seSBuZWVkIHRvIG91dHB1dCB0aGUgaW5kaWNlcyBhdCBwb3NpdGlvbnMgfCwgdGhlIGluZGljZXMgYXQKICAgICAgICAgLy8gcG9zaXRpb25zIF8gY2FuIGJlIHRocm93biBhd2F5LCBzZWUgRmlndXJlNShiKSBBZnRlciBQaGFzZSAyCiAgICAgICAgIC8vIChNZXJnZSBwaGFzZSkgaW4gdGhlIEJpdG9uaWMgVG9wIEsgcGFwZXIgcmVmZXJlbmNlZCBhYm92ZS4KICAgICAgICAgLy8gRm9yIGV4YW1wbGUsIHRoZSBwYXBlciBzaG93cyB3ZSBvbmx5IG5lZWQgdG8gb3V0cHV0IHRoZSBvcmFuZ2UgYmFycy4KICAgICAgICAgLy8gVGhlIG91dHB1dCBzZXF1ZW5jZSBzaG91bGQgbG9vayBsaWtlIHRoaXMgfCB8IHwgfCB8IHwgfCB8LgogICAgICAgICAvLyBCZWNhdXNlIHRoZSBzZXF1ZW5jZSBpcyBoYWx2ZWQsIHRvIG1hcCB0aGUgb3V0cHV0IGluZGV4IGJhY2sKICAgICAgICAgLy8gdG8gdGhlIHByZXZpb3VzIHNlcXVlbmNlIHRvIGZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUsCiAgICAgICAgIC8vIHdlIG5lZWQgdG8gZG91YmxlIHRoZSBpbmRleC4gV2hlbiB3ZSBkb3VibGUgdGhlIGluZGV4LAogICAgICAgICAvLyB3ZSBiYXNpY2FsbHkgaW50ZXJwb2xhdGUgYSBwb3NpdGlvbiwgc28gMmkgbG9va3MgbGlrZQogICAgICAgICAvLyB8IF8gfCBfIHwgXyB8IF8gfCBfIHwgXyB8IF8uIFdlIG1vdmUgdGhlIHwgdG8gdGhlIGZpcnN0IGsgcG9zaXRpb24KICAgICAgICAgLy8gb2YgZWFjaCAyayBwb3NpdGlvbnMgYnkgLSBlbGVtSWR4ICUgay4gRS5nLiBmb3Igb3V0cHV0IGF0CiAgICAgICAgIC8vIGluZGV4IDQsNSw2LDcsIHdlIHdhbnQgdG8gZ2V0IHRoZSBjb3JyZXNwb25kaW5nIGVsZW1lbnQgYXQKICAgICAgICAgLy8gb3JpZ2luYWwgaW5kZXggOCw5LDEwLDExLCBmb3Igb3V0cHV0IGF0IGluZGV4IDgsOSwxMCwxMSwKICAgICAgICAgLy8gd2Ugd2FudCB0byBnZXQgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBhdCBvcmlnaW5hbCBpbmRleAogICAgICAgICAvLyAxNiwxNywxOCwxOSwgc28gb24gYW5kIHNvIGZvcnRoLgoKICAgICAgICAgaW50IGkgPSBlbGVtSWR4IDwgayA/IGVsZW1JZHggOiAoZWxlbUlkeCAqIDIgLSBpbW9kKGVsZW1JZHgsIGspKTsKICAgICAgICAgaW50IGkwID0gZmlyc3RQYXNzID09IDEgPyBpIDogaW50KGdldEluZGljZXMoYmF0Y2gsIGkpKTsKICAgICAgICAgaW50IGkxID0gZmlyc3RQYXNzID09IDEgPyBpICsgayA6IGludChnZXRJbmRpY2VzKGJhdGNoLCBpICsgaykpOwoKICAgICAgICAgZmxvYXQgeDAgPSBnZXRYKGJhdGNoLCBpMCk7CiAgICAgICAgIGZsb2F0IHgxID0gaTEgPCBuID8gZ2V0WChiYXRjaCwgaTEpIDogeDA7CgogICAgICAgICBzZXRPdXRwdXQoeDAgPj0geDEgPyBmbG9hdChpMCkgOiBmbG9hdChpMSkpOwogICAgICAgfQogICAgIGB9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCQxKGhhLGFhKXthYSE9PW51bGwmJmhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGFhKX1mdW5jdGlvbiByb3VuZFVwVG9Qb3cyJDEoaGEpe2xldCBhYT0xO2Zvcig7YWE8aGE7KWFhKj0yO3JldHVybiBhYX1mdW5jdGlvbiB0b3BLJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2s6VGEsc29ydGVkOndhfT1iYSxFYT1lbnYkMSgpLmdldE51bWJlcigiVE9QS19MQVNUX0RJTV9DUFVfSEFORE9GRl9TSVpFX1RIUkVTSE9MRCIpLGthPWVudiQxKCkuZ2V0TnVtYmVyKCJUT1BLX0tfQ1BVX0hBTkRPRkZfVEhSRVNIT0xEIiksQWE9U2Euc2hhcGUsRmE9QWFbQWEubGVuZ3RoLTFdO2lmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbU2FdKXx8RmE8RWF8fFRhPmthKXtjb25zdCBmbD14YS5yZWFkU3luYyhTYS5kYXRhSWQpLFttbCxnbF09dG9wS0ltcGxDUFUkMShmbCxBYSxTYS5kdHlwZSxUYSx3YSk7cmV0dXJuW3hhLm1ha2VUZW5zb3JJbmZvKG1sLnNoYXBlLG1sLmR0eXBlLG1sLnZhbHVlcykseGEubWFrZVRlbnNvckluZm8oZ2wuc2hhcGUsZ2wuZHR5cGUsZ2wudmFsdWVzKV19aWYoVGE9PT0wKXJldHVybiBBYVtBYS5sZW5ndGgtMV09MCxbeGEubWFrZVRlbnNvckluZm8oQWEsU2EuZHR5cGUsW10pLHhhLm1ha2VUZW5zb3JJbmZvKEFhLCJpbnQzMiIsW10pXTtpZihGYT09PTEpcmV0dXJuW1NhLGZpbGwkMih7YXR0cnM6e3NoYXBlOkFhLGR0eXBlOiJpbnQzMiIsdmFsdWU6MH0sYmFja2VuZDp4YX0pXTtjb25zdCBMYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLGVsPUxhIT09bnVsbCYmTGEuaXNQYWNrZWQsdGw9ZWw/eGEudW5wYWNrVGVuc29yKFNhKTpTYSxzbD1zaXplRnJvbVNoYXBlJDEoQWEpL0ZhLHJsPXJlc2hhcGUkMih7aW5wdXRzOnt4OnRsfSxhdHRyczp7c2hhcGU6W3NsLEZhXX0sYmFja2VuZDp4YX0pO2VsJiZkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCQxKHhhLHRsKTtjb25zdCBvbD1yb3VuZFVwVG9Qb3cyJDEoVGEpLGFsPXJvdW5kVXBUb1BvdzIkMShGYSk7bGV0IGxsPW51bGw7Y29uc3QgaWw9KCk9PmxsPT09bnVsbD9bcmwscmxdOltybCxsbF0sY2w9KGZsLG1sLGdsKT0+e2NvbnN0ICRsPWlsKCkseGw9bmV3IFN3YXBQcm9ncmFtJDEoZ2wpLGJsPVtbRmFdLFtsbD09PW51bGw/MTowXSxbTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZXSxbZmxdLFttbF1dLFNsPWxsO2xsPXhhLnJ1bldlYkdMUHJvZ3JhbSh4bCwkbCwiaW50MzIiLGJsKSxkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCQxKHhhLFNsKX07Zm9yKGxldCBmbD0xO2ZsPG9sO2ZsKj0yKXtjb25zdCBtbD1mbCoyO2ZvcihsZXQgZ2w9Zmw7Z2w+PTE7Z2wvPTIpY2wobWwsZ2wsW3NsLGFsXSl9Zm9yKGxldCBmbD1hbDtmbD5vbDtmbC89Mil7Y29uc3QgbWw9aWwoKSxnbD1uZXcgTWVyZ2VQcm9ncmFtJDEoW3NsLGZsLzJdKSx4bD1bW0ZhXSxbbGw9PT1udWxsPzE6MF0sW29sXV0seWw9bGw7bGw9eGEucnVuV2ViR0xQcm9ncmFtKGdsLG1sLCJpbnQzMiIseGwpLGRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvT3JOdWxsJDEoeGEseWwpO2NvbnN0IGJsPW9sLzIsU2w9YmwqMjtmb3IobGV0IENsPWJsO0NsPj0xO0NsLz0yKWNsKFNsLENsLGxsLnNoYXBlKX1sZXQgdWw9bGw7bGw9c2xpY2UkMSh7aW5wdXRzOnt4OmxsfSxiYWNrZW5kOnhhLGF0dHJzOntiZWdpbjowLHNpemU6W3NsLFRhXX19KSxkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCQxKHhhLHVsKTtsZXQgZGw9Z2F0aGVyVjIkMSh7aW5wdXRzOnt4OnJsLGluZGljZXM6bGx9LGJhY2tlbmQ6eGEsYXR0cnM6e2F4aXM6MSxiYXRjaERpbXM6MX19KTtkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCQxKHhhLHJsKTtjb25zdCBobD1BYS5zbGljZSgwLC0xKTtobC5wdXNoKFRhKSx1bD1sbCxsbD1yZXNoYXBlJDIoe2lucHV0czp7eDpsbH0sYXR0cnM6e3NoYXBlOmhsfSxiYWNrZW5kOnhhfSksZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm9Pck51bGwkMSh4YSx1bCk7Y29uc3QgcGw9ZGw7cmV0dXJuIGRsPXJlc2hhcGUkMih7aW5wdXRzOnt4OmRsfSxhdHRyczp7c2hhcGU6aGx9LGJhY2tlbmQ6eGF9KSxkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCQxKHhhLHBsKSxbZGwsbGxdfWNvbnN0IHRvcEtDb25maWckMT17a2VybmVsTmFtZTpUb3BLJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRvcEskMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IFRyYW5zZm9ybVByb2dyYW0kMT1jbGFzc3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSx3YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiSW1hZ2UiLCJUcmFuc2Zvcm1zIl0sdGhpcy5vdXRwdXRTaGFwZT13YTtjb25zdCBFYT1iYT09PSJuZWFyZXN0Ij8xOjI7bGV0IGthO3N3aXRjaChTYSl7Y2FzZSJjb25zdGFudCI6a2E9MTticmVhaztjYXNlInJlZmxlY3QiOmthPTI7YnJlYWs7Y2FzZSJ3cmFwIjprYT0zO2JyZWFrO2Nhc2UibmVhcmVzdCI6a2E9NDticmVhaztkZWZhdWx0OmthPTE7YnJlYWt9dGhpcy51c2VyQ29kZT1gCiAgICAgICAgICAgIGZsb2F0IG1hcENvb3JkKGZsb2F0IG91dENvb3JkLCBmbG9hdCBsZW4pIHsKICAgICAgICAgICAgICBmbG9hdCBpbkNvb3JkID0gb3V0Q29vcmQ7CiAgICAgICAgICAgICAgaWYoJHtrYX0gPT0gMikgewogICAgICAgICAgICAgICAgaWYgKGluQ29vcmQgPCAwLjApIHsKICAgICAgICAgICAgICAgICAgaWYgKGxlbiA8PSAxLjApIHsKICAgICAgICAgICAgICAgICAgICBpbkNvb3JkID0gMC4wOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZsb2F0IHN6MiA9IDIuMCAqIGxlbjsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5Db29yZCA8IHN6MikgewogICAgICAgICAgICAgICAgICAgICAgaW5Db29yZCA9IHN6MiAqIGZsb2F0KGludChmbG9hdCgtaW5Db29yZCAvIHN6MikpKSArCiAgICAgICAgICAgICAgICAgICAgICBpbkNvb3JkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpbkNvb3JkID0gaW5Db29yZCA8IC1sZW4gPyBpbkNvb3JkICsgc3oyIDogLWluQ29vcmQgLSAxLjA7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5Db29yZCA+IGxlbiAtIDEuMCkgewogICAgICAgICAgICAgICAgICBpZiAobGVuIDw9IDEuMCkgewogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgPSAwLjA7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgc3oyID0gMi4wICogbGVuOwogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgLT0gc3oyICogZmxvYXQoaW50KGZsb2F0KGluQ29vcmQgLyBzejIpKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGluQ29vcmQgPj0gbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgICBpbkNvb3JkID0gc3oyIC0gaW5Db29yZCAtIDEuMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjbGFtcChpbkNvb3JkLCAwLjAsIGxlbiAtIDEuMCk7CiAgICAgICAgICAgICAgfSBlbHNlIGlmICgke2thfSA9PSAzKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5Db29yZCA8IDAuMCkgewogICAgICAgICAgICAgICAgICBpZiAobGVuIDw9IDEuMCkgewogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgPSAwLjA7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgc3ogPSBsZW4gLSAxLjA7CiAgICAgICAgICAgICAgICAgICAgaW5Db29yZCArPSBsZW4gKiAoZmxvYXQoaW50KGZsb2F0KC1pbkNvb3JkIC8gc3opKSkgKyAxLjApOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluQ29vcmQgPiBsZW4gLSAxLjApIHsKICAgICAgICAgICAgICAgICAgaWYgKGxlbiA8PSAxLjApIHsKICAgICAgICAgICAgICAgICAgICBpbkNvb3JkID0gMC4wOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZsb2F0IHN6ID0gbGVuIC0gMS4wOwogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgLT0gbGVuICogZmxvYXQoaW50KGZsb2F0KGluQ29vcmQgLyBzeikpKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNsYW1wKGluQ29vcmQsIDAuMCwgbGVuIC0gMS4wKTsKICAgICAgICAgICAgICB9IGVsc2UgaWYgKCR7a2F9ID09IDQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGFtcChvdXRDb29yZCwgMC4wLCBsZW4gLSAxLjApOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb3V0Q29vcmQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmbG9hdCByZWFkV2l0aEZpbGxWYWx1ZShpbnQgYmF0Y2gsIGludCBjb29yZFksIGludCBjb29yZFgsCiAgICAgICAgICAgICAgaW50IGNoYW5uZWwpIHsKICAgICAgICAgICAgICBmbG9hdCBvdXRwdXRWYWx1ZTsKICAgICAgICAgICAgICBpZiAoMCA8PSBjb29yZFkgJiYgY29vcmRZIDwgJHthYX0gJiYgMCA8PSBjb29yZFggJiYgY29vcmRYIDwgJHt4YX0pIHsKICAgICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSBnZXRJbWFnZShiYXRjaCwgY29vcmRZLCBjb29yZFgsIGNoYW5uZWwpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IGZsb2F0KCR7VGF9KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dFZhbHVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICAgICAgZmxvYXQgb3V0cHV0VmFsdWU7CiAgICAgICAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgICAgICAgIGludCB4ID0gY29vcmRzWzJdOwogICAgICAgICAgICAgIGludCB5ID0gY29vcmRzWzFdOwogICAgICAgICAgICAgIGludCBjaGFubmVsID0gY29vcmRzWzNdOwogICAgICAgICAgICAgIGZsb2F0IHhmID0gZmxvYXQoeCk7CiAgICAgICAgICAgICAgZmxvYXQgeWYgPSBmbG9hdCh5KTsKICAgICAgICAgICAgICBmbG9hdCBhMSA9IGdldFRyYW5zZm9ybXMoYmF0Y2gsIDApOwogICAgICAgICAgICAgIGZsb2F0IGEyID0gZ2V0VHJhbnNmb3JtcyhiYXRjaCwgMSk7CiAgICAgICAgICAgICAgZmxvYXQgYTMgPSBnZXRUcmFuc2Zvcm1zKGJhdGNoLCAyKTsKICAgICAgICAgICAgICBmbG9hdCBiMSA9IGdldFRyYW5zZm9ybXMoYmF0Y2gsIDMpOwogICAgICAgICAgICAgIGZsb2F0IGIyID0gZ2V0VHJhbnNmb3JtcyhiYXRjaCwgNCk7CiAgICAgICAgICAgICAgZmxvYXQgYjMgPSBnZXRUcmFuc2Zvcm1zKGJhdGNoLCA1KTsKICAgICAgICAgICAgICBmbG9hdCBjMSA9IGdldFRyYW5zZm9ybXMoYmF0Y2gsIDYpOwogICAgICAgICAgICAgIGZsb2F0IGMyID0gZ2V0VHJhbnNmb3JtcyhiYXRjaCwgNyk7CiAgICAgICAgICAgICAgZmxvYXQgcHJvamVjdGlvbiA9IGMxICogeGYgKyBjMiAqIHlmICsgMS4wOwogICAgICAgICAgICAgIGlmIChwcm9qZWN0aW9uID09IDAuMCkgewogICAgICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSBmbG9hdCgke1RhfSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZsb2F0IGluWCA9IChhMSAqIHhmICsgYTIgKiB5ZiArIGEzKSAvIHByb2plY3Rpb247CiAgICAgICAgICAgICAgICBmbG9hdCBpblkgPSAoYjEgKiB4ZiArIGIyICogeWYgKyBiMykgLyBwcm9qZWN0aW9uOwogICAgICAgICAgICAgICAgZmxvYXQgbWFwWCA9IG1hcENvb3JkKGluWCwgZmxvYXQoJHt4YX0pKTsKICAgICAgICAgICAgICAgIGZsb2F0IG1hcFkgPSBtYXBDb29yZChpblksIGZsb2F0KCR7YWF9KSk7CgogICAgICAgICAgICAgICAgaWYgKCR7RWF9ID09IDEpIHsKICAgICAgICAgICAgICAgICAgaW50IGNvb3JkWSA9IGludChyb3VuZChtYXBZKSk7CiAgICAgICAgICAgICAgICAgIGludCBjb29yZFggPSBpbnQocm91bmQobWFwWCkpOwogICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IHJlYWRXaXRoRmlsbFZhbHVlKGJhdGNoLCBjb29yZFksIGNvb3JkWCwKICAgICAgICAgICAgICAgICAgICBjaGFubmVsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGZsb2F0IHlGbG9vciA9IGZsb29yKG1hcFkpOwogICAgICAgICAgICAgICAgICBmbG9hdCB4Rmxvb3IgPSBmbG9vcihtYXBYKTsKICAgICAgICAgICAgICAgICAgZmxvYXQgeUNlaWwgPSB5Rmxvb3IgKyAxLjA7CiAgICAgICAgICAgICAgICAgIGZsb2F0IHhDZWlsID0geEZsb29yICsgMS4wOwogICAgICAgICAgICAgICAgICBmbG9hdCB2YWx1ZVlGbG9vciA9ICh4Q2VpbCAtIG1hcFgpICoKICAgICAgICAgICAgICAgICAgcmVhZFdpdGhGaWxsVmFsdWUoYmF0Y2gsIGludCh5Rmxvb3IpLCBpbnQoeEZsb29yKSwgY2hhbm5lbCkgKwogICAgICAgICAgICAgICAgICAobWFwWCAtIHhGbG9vcikgKgogICAgICAgICAgICAgICAgICByZWFkV2l0aEZpbGxWYWx1ZShiYXRjaCwgaW50KHlGbG9vciksIGludCh4Q2VpbCksIGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICBmbG9hdCB2YWx1ZVlDZWlsID0gKHhDZWlsIC0gbWFwWCkgKgogICAgICAgICAgICAgICAgICByZWFkV2l0aEZpbGxWYWx1ZShiYXRjaCwgaW50KHlDZWlsKSwgaW50KHhGbG9vciksIGNoYW5uZWwpICsKICAgICAgICAgICAgICAgICAgKG1hcFggLSB4Rmxvb3IpICoKICAgICAgICAgICAgICAgICAgcmVhZFdpdGhGaWxsVmFsdWUoYmF0Y2gsIGludCh5Q2VpbCksIGludCh4Q2VpbCksIGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9ICh5Q2VpbCAtIG1hcFkpICogdmFsdWVZRmxvb3IgKwogICAgICAgICAgICAgICAgICAobWFwWSAtIHlGbG9vcikgKiB2YWx1ZVlDZWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBzZXRPdXRwdXQob3V0cHV0VmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgYH19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRyYW5zZm9ybSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2ltYWdlOlNhLHRyYW5zZm9ybXM6VGF9PWFhLHtpbnRlcnBvbGF0aW9uOndhLGZpbGxNb2RlOkVhLGZpbGxWYWx1ZTprYSxvdXRwdXRTaGFwZTpBYX09YmEsW0ZhLExhLGVsLHRsXT1TYS5zaGFwZSxbbmwsc2xdPUFhPz9bTGEsZWxdLHJsPVtGYSxubCxzbCx0bF0sb2w9bmV3IFRyYW5zZm9ybVByb2dyYW0kMShMYSxlbCx3YSxFYSxrYSxybCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShvbCxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgdHJhbnNmb3JtQ29uZmlnJDE9e2tlcm5lbE5hbWU6VHJhbnNmb3JtJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRyYW5zZm9ybSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHVuaXF1ZSQxKGhhKXtjb25zdHtpbnB1dHM6YWEsYXR0cnM6eGEsYmFja2VuZDpiYX09aGEse2F4aXM6U2F9PXhhLHt4OlRhfT1hYTthc3NlcnROb3RDb21wbGV4JDEoVGEsInVuaXF1ZSIpLGNvbnNvbGUud2FybigiV0FSTklORzogIiwiVUkgbWlnaHQgYmUgbG9ja2VkIHRlbXBvcmFyaWx5IGFzIGRhdGEgaXMgYmVpbmcgZG93bmxvYWRlZCIpO2NvbnN0IHdhPWJhLnJlYWRTeW5jKFRhLmRhdGFJZCkse291dHB1dFZhbHVlczpFYSxvdXRwdXRTaGFwZTprYSxpbmRpY2VzOkFhfT11bmlxdWVJbXBsQ1BVJDEod2EsU2EsVGEuc2hhcGUsVGEuZHR5cGUpO3JldHVybltiYS5tYWtlVGVuc29ySW5mbyhrYSxUYS5kdHlwZSxFYSksYmEubWFrZVRlbnNvckluZm8oW0FhLmxlbmd0aF0sImludDMyIixBYSldfWNvbnN0IHVuaXF1ZUNvbmZpZyQxPXtrZXJuZWxOYW1lOlVuaXF1ZSQxLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp1bmlxdWUkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5wYWNrJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7dmFsdWU6U2F9PWFhO2xldHtheGlzOlRhfT1iYTtUYTwwJiYoVGErPVNhLnNoYXBlLmxlbmd0aCk7Y29uc3Qgd2E9U2EsRWE9d2Euc2hhcGUubGVuZ3RoLGthPVNhLnNoYXBlW1RhXSxBYT1uZXcgQXJyYXkoRWEtMSk7bGV0IEZhPTA7Zm9yKGxldCBzbD0wO3NsPEVhO3NsKyspc2whPT1UYSYmKEFhW0ZhKytdPXdhLnNoYXBlW3NsXSk7Y29uc3QgTGE9W10sZWw9bmV3IEFycmF5KEVhKS5maWxsKDApLHRsPXdhLnNoYXBlLnNsaWNlKCk7dGxbVGFdPTE7Y29uc3Qgbmw9bmV3IEFycmF5KGthKTtmb3IobGV0IHNsPTA7c2w8bmwubGVuZ3RoO3NsKyspe2VsW1RhXT1zbDtjb25zdCBybD1zbGljZSQxKHtpbnB1dHM6e3g6d2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2JlZ2luOmVsLHNpemU6dGx9fSksb2w9cmVzaGFwZSQyKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkFhfX0pO25sW3NsXT1vbCxMYS5wdXNoKHJsKX1yZXR1cm4gTGEuZm9yRWFjaChzbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpKSxubH1jb25zdCB1bnBhY2tDb25maWckMT17a2VybmVsTmFtZTpVbnBhY2skMSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6dW5wYWNrJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2xldCBTZWdtZW50T3BQcm9ncmFtJDE9Y2xhc3N7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJzZWdtZW50SWRzIl07Y29uc3QgYmE9YWEud2luZG93U2l6ZSxTYT1hYS5iYXRjaFNpemUsVGE9YWEuaW5TaXplLHdhPWFhLm51bVNlZ21lbnRzLEVhPXdhKk1hdGguY2VpbChUYS9iYSk7dGhpcy5vdXRwdXRTaGFwZT1bU2EsRWFdO2NvbnN0IGthPSIwLjAiLEFhPSJzdW1WYWx1ZSIsRmE9TWF0aC5mbG9vcihiYS80KSo0LExhPWJhJTQsZWw9YAogICAgICAgIHN1bVZhbHVlICs9IGRvdCh2YWx1ZXMsIHNlZ0ZpbHRlcik7CiAgICBgO2xldCB0bD0iIjtUYSViYT4wJiYodGw9YAogICAgICAgIGlmIChpbklkeCA8IDAgfHwgaW5JZHggPj0gJHtUYX0pIHsKICAgICAgICAgIHJldHVybiBpbml0aWFsaXphdGlvblZhbHVlOwogICAgICAgIH0KICAgICAgYCk7bGV0IG5sPSIiO1RhJWJhPjAmJihubD1gCiAgICAgICAgaWYgKGluSWR4IDwgMCB8fCBpbklkeCA+PSAke1RhfSkgewogICAgICAgICAgcmV0dXJuIC0xLjA7CiAgICAgICAgfQogICAgICBgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgZmxvYXQgaW5pdGlhbGl6YXRpb25WYWx1ZSA9ICR7a2F9OwoKICAgICAgZmxvYXQgZ2V0VmFsdWUoaW50IGJhdGNoLCBpbnQgaW5JZHgpIHsKICAgICAgICAke3RsfQogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCBpbklkeCk7CiAgICAgIH0KCiAgICAgIGZsb2F0IGdldFNlZ21lbnRJZEF0SW5kZXgoaW50IGluSWR4KSB7CiAgICAgICAgJHtubH0KICAgICAgICByZXR1cm4gZ2V0U2VnbWVudElkcyhpbklkeCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgaW50IG91dElkeCA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgaW5PZmZzZXQgPSBpbnQoZmxvb3IoZmxvYXQob3V0SWR4KSAvIGZsb2F0KAogICAgICAgICAgJHt3YX0pKSAqIGZsb2F0KCR7YmF9KSk7CiAgICAgICAgaW50IGN1cnJlbnRTZWcgPSBpbnQobW9kKGZsb2F0KG91dElkeCksIGZsb2F0KCR7d2F9KSkpOwoKICAgICAgICBmbG9hdCBzdW1WYWx1ZSA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke0ZhfTsgaSArPSA0KSB7CiAgICAgICAgICBpbnQgaW5JZHggPSBpbk9mZnNldCArIGk7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAyKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMykKICAgICAgICAgICk7CgogICAgICAgICAgdmVjNCBzZWdGaWx0ZXIgPSB2ZWM0KAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCkpID09IGN1cnJlbnRTZWcgPyAxIDogMCwKICAgICAgICAgICAgaW50KGdldFNlZ21lbnRJZEF0SW5kZXgoaW5JZHggKyAxKSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCArIDIpKSA9PSBjdXJyZW50U2VnID8gMSA6IDAsCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4ICsgMykpID09IGN1cnJlbnRTZWcgPyAxIDogMAogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0KCiAgICAgICAgaW50IGluSWR4ID0gaW5PZmZzZXQgKyAke0ZhfTsKICAgICAgICBpZiAoJHtMYT09PTF9KSB7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICk7CgogICAgICAgICAgaW50IGluSWR4U2VnID0gaW50KGdldFNlZ21lbnRJZEF0SW5kZXgoaW5JZHgpKTsKCiAgICAgICAgICB2ZWM0IHNlZ0ZpbHRlciA9IHZlYzQoCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4KSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICAwLAogICAgICAgICAgICAwLAogICAgICAgICAgICAwCiAgICAgICAgICApOwoKICAgICAgICAgICR7ZWx9CiAgICAgICAgfSBlbHNlIGlmICgke0xhPT09Mn0pIHsKICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4KSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMSksCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICk7CgogICAgICAgICAgdmVjNCBzZWdGaWx0ZXIgPSB2ZWM0KAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCkpID09IGN1cnJlbnRTZWcgPyAxIDogMCwKICAgICAgICAgICAgaW50KGdldFNlZ21lbnRJZEF0SW5kZXgoaW5JZHggKyAxKSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgMAogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0gZWxzZSBpZiAoJHtMYT09PTN9KSB7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAyKSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgKTsKCiAgICAgICAgICB2ZWM0IHNlZ0ZpbHRlciA9IHZlYzQoCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4KSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCArIDEpKSA9PSBjdXJyZW50U2VnID8gMSA6IDAsCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4ICsgMikpID09IGN1cnJlbnRTZWcgPyAxIDogMCwKICAgICAgICAgICAgMAogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoJHtBYX0pOwogICAgICB9CiAgICBgfX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5zb3J0ZWRTZWdtZW50U3VtJDEoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxzZWdtZW50SWRzOlRhfT1hYSx7bnVtU2VnbWVudHM6d2F9PWJhLEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1bXTtsZXQgQWE9MDtjb25zdCBGYT1nZXRBeGVzUGVybXV0YXRpb24kMShbQWFdLEVhKTtsZXQgTGE9U2E7RmEhPW51bGwmJihMYT10cmFuc3Bvc2UkMSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkZhfX0pLGthLnB1c2goTGEpLEFhPWdldElubmVyTW9zdEF4ZXMkMSgxLEVhKVswXSk7Y29uc3QgZWw9Y29tcHV0ZU91dFNoYXBlJDMoTGEuc2hhcGUsQWEsd2EpLHRsPXNpemVGcm9tU2hhcGUkMShbTGEuc2hhcGVbQWFdXSksbmw9cmVzaGFwZSQyKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSx0bF19fSk7a2EucHVzaChubCk7Y29uc3Qgc2w9c3VtT3V0VHlwZSQxKFNhLmR0eXBlKSxybD0oaWwsY2wsdWwsZGwsaGwpPT57Y29uc3QgcGw9aWwuc2hhcGVbMF0sZmw9aWwuc2hhcGVbMV0sbWw9c2VnT3BDb21wdXRlT3B0aW1hbFdpbmRvd1NpemUkMShmbCxobCksZ2w9e3dpbmRvd1NpemU6bWwsaW5TaXplOmZsLGJhdGNoU2l6ZTpwbCxudW1TZWdtZW50czpobH0sJGw9bmV3IFNlZ21lbnRPcFByb2dyYW0kMShnbCxjbCkseGw9eGEuY29tcGlsZUFuZFJ1bigkbCxbaWwsdWxdLGRsKTtpZihrYS5wdXNoKHhsKSx4bC5zaGFwZVsxXT09PWhsKXJldHVybiB4bDtjb25zdCB5bD1yYW5nZSQxKHtiYWNrZW5kOnhhLGF0dHJzOntzdGFydDowLHN0b3A6aGwsc3RlcDoxLGR0eXBlOiJmbG9hdDMyIn19KSxibD10aWxlJDEoe2lucHV0czp7eDp5bH0sYmFja2VuZDp4YSxhdHRyczp7cmVwczpbZmwvbWxdfX0pO3JldHVybiBrYS5wdXNoKHlsKSxrYS5wdXNoKGJsKSxybCh4bCxjbCxibCxkbCxobCl9LG9sPXJsKG5sLCJ1bnNvcnRlZFNlZ21lbnRTdW0iLFRhLHNsLHdhKSxhbD1yZXNoYXBlJDIoe2lucHV0czp7eDpvbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6ZWx9fSk7bGV0IGxsPWFsO2lmKEZhIT1udWxsKXtrYS5wdXNoKGFsKTtjb25zdCBpbD1nZXRVbmRvQXhlc1Blcm11dGF0aW9uJDEoRmEpO2xsPXRyYW5zcG9zZSQxKHtpbnB1dHM6e3g6bGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06aWx9fSl9cmV0dXJuIGthLmZvckVhY2goaWw9PnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGlsKSksbGx9Y29uc3QgdW5zb3J0ZWRTZWdtZW50U3VtQ29uZmlnJDE9e2tlcm5lbE5hbWU6VW5zb3J0ZWRTZWdtZW50U3VtJDEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnVuc29ydGVkU2VnbWVudFN1bSQxfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBrZXJuZWxDb25maWdzJDE9W19mdXNlZE1hdE11bENvbmZpZyQxLGFic0NvbmZpZyQxLGFjb3NDb25maWckMSxhY29zaENvbmZpZyQxLGFkZENvbmZpZyQxLGFkZE5Db25maWckMSxhbGxDb25maWckMSxhbnlDb25maWckMSxhcmdNYXhDb25maWckMSxhcmdNaW5Db25maWckMSxhc2luQ29uZmlnJDEsYXNpbmhDb25maWckMSxhdGFuQ29uZmlnJDEsYXRhbjJDb25maWckMSxhdGFuaENvbmZpZyQxLGF2Z1Bvb2xDb25maWckMSxhdmdQb29sM0RDb25maWckMSxhdmdQb29sM0RHcmFkQ29uZmlnJDEsYXZnUG9vbEdyYWRDb25maWckMSxiYXRjaE1hdE11bENvbmZpZyQxLGJhdGNoTm9ybUNvbmZpZyQxLGJhdGNoVG9TcGFjZU5EQ29uZmlnJDEsYmluY291bnRDb25maWckMSxiaXR3aXNlQW5kQ29uZmlnJDEsYnJvYWRjYXN0QXJnc0NvbmZpZyQxLGNhc3RDb25maWckMSxjZWlsQ29uZmlnJDEsY2xpcEJ5VmFsdWVDb25maWckMSxjb21wbGV4Q29uZmlnJDEsY29tcGxleEFic0NvbmZpZyQxLGNvbmNhdENvbmZpZyQxLGNvbnYyRENvbmZpZyQxLGNvbnYyREJhY2twcm9wRmlsdGVyQ29uZmlnJDEsY29udjJEQmFja3Byb3BJbnB1dENvbmZpZyQxLGNvbnYzRENvbmZpZyQxLGNvbnYzREJhY2twcm9wRmlsdGVyVjJDb25maWckMSxjb252M0RCYWNrcHJvcElucHV0Q29uZmlnJDEsY29zQ29uZmlnJDEsY29zaENvbmZpZyQxLGNyb3BBbmRSZXNpemVDb25maWckMSxjdW1wcm9kQ29uZmlnJDEsY3Vtc3VtQ29uZmlnJDEsZGVuc2VCaW5jb3VudENvbmZpZyQxLGRlcHRoVG9TcGFjZUNvbmZpZyQxLGRlcHRod2lzZUNvbnYyZE5hdGl2ZUNvbmZpZyQxLGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyQ29uZmlnJDEsZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dENvbmZpZyQxLGRpYWdDb25maWckMSxkaWxhdGlvbjJEQ29uZmlnJDEsZWluc3VtQ29uZmlnJDEsZWx1Q29uZmlnJDEsZWx1R3JhZENvbmZpZyQxLGVxdWFsQ29uZmlnJDEsZXJmQ29uZmlnJDEsZXhwQ29uZmlnJDEsZXhwYW5kRGltc0NvbmZpZyQxLGV4cG0xQ29uZmlnJDEsZmZ0Q29uZmlnJDEsZmlsbENvbmZpZyQxLGZsaXBMZWZ0UmlnaHRDb25maWckMSxmbG9vckNvbmZpZyQxLGZsb29yRGl2Q29uZmlnJDEsZnJvbVBpeGVsc0NvbmZpZyQxLGZ1c2VkQ29udjJEQ29uZmlnJDEsZnVzZWREZXB0aHdpc2VDb252MkRDb25maWckMSxnYXRoZXJOZENvbmZpZyQxLGdhdGhlclYyQ29uZmlnJDEsZ3JlYXRlckNvbmZpZyQxLGdyZWF0ZXJFcXVhbENvbmZpZyQxLGlkZW50aXR5Q29uZmlnJDEsaWZmdENvbmZpZyQxLGltYWdDb25maWckMSxpc0Zpbml0ZUNvbmZpZyQxLGlzSW5mQ29uZmlnJDEsaXNOYU5Db25maWckMSxsZWFreVJlbHVDb25maWckMSxsZXNzQ29uZmlnJDEsbGVzc0VxdWFsQ29uZmlnJDEsbGluU3BhY2VDb25maWckMSxsb2dDb25maWckMSxsb2cxcENvbmZpZyQxLGxvZ2ljYWxBbmRDb25maWckMSxsb2dpY2FsTm90Q29uZmlnJDEsbG9naWNhbE9yQ29uZmlnJDEsTFJOQ29uZmlnJDEsTFJOR3JhZENvbmZpZyQxLG1heENvbmZpZyQxLG1heGltdW1Db25maWckMSxtYXhQb29sQ29uZmlnJDEsbWF4UG9vbDNEQ29uZmlnJDEsbWF4UG9vbDNER3JhZENvbmZpZyQxLG1heFBvb2xHcmFkQ29uZmlnJDEsbWF4UG9vbFdpdGhBcmdtYXhDb25maWckMSxtZWFuQ29uZmlnJDEsbWluQ29uZmlnJDEsbWluaW11bUNvbmZpZyQxLG1pcnJvclBhZENvbmZpZyQxLG1vZENvbmZpZyQxLG11bHRpbm9taWFsQ29uZmlnJDEsbXVsdGlwbHlDb25maWckMSxuZWdDb25maWckMSxub25NYXhTdXBwcmVzc2lvblYzQ29uZmlnJDEsbm9uTWF4U3VwcHJlc3Npb25WNENvbmZpZyQxLG5vbk1heFN1cHByZXNzaW9uVjVDb25maWckMSxub3RFcXVhbENvbmZpZyQxLG9uZUhvdENvbmZpZyQxLG9uZXNMaWtlQ29uZmlnJDEscGFja0NvbmZpZyQxLHBhZFYyQ29uZmlnJDEscG93Q29uZmlnJDEscHJlbHVDb25maWckMSxwcm9kQ29uZmlnJDEscmFnZ2VkR2F0aGVyQ29uZmlnJDEscmFnZ2VkUmFuZ2VDb25maWckMSxyYWdnZWRUZW5zb3JUb1RlbnNvckNvbmZpZyQxLHJhbmdlQ29uZmlnJDEscmVhbENvbmZpZyQxLHJlYWxEaXZDb25maWckMSxyZWNpcHJvY2FsQ29uZmlnJDEscmVsdUNvbmZpZyQxLHJlbHU2Q29uZmlnJDEscmVzaGFwZUNvbmZpZyQxLHJlc2l6ZUJpbGluZWFyQ29uZmlnJDEscmVzaXplQmlsaW5lYXJHcmFkQ29uZmlnJDEscmVzaXplTmVhcmVzdE5laWdoYm9yQ29uZmlnJDEscmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZENvbmZpZyQxLHJldmVyc2VDb25maWckMSxyb3RhdGVXaXRoT2Zmc2V0Q29uZmlnJDEscm91bmRDb25maWckMSxyc3FydENvbmZpZyQxLHNjYXR0ZXJOZENvbmZpZyQxLHNlYXJjaFNvcnRlZENvbmZpZyQxLHNlbGVjdENvbmZpZyQxLHNlbHVDb25maWckMSxzaWdtb2lkQ29uZmlnJDEsc2lnbkNvbmZpZyQxLHNpbkNvbmZpZyQxLHNpbmhDb25maWckMSxzbGljZUNvbmZpZyQxLHNvZnRtYXhDb25maWckMSxzb2Z0cGx1c0NvbmZpZyQxLHNwYWNlVG9CYXRjaE5EQ29uZmlnJDEsc3BhcnNlRmlsbEVtcHR5Um93c0NvbmZpZyQxLHNwYXJzZVJlc2hhcGVDb25maWckMSxzcGFyc2VTZWdtZW50TWVhbkNvbmZpZyQxLHNwYXJzZVNlZ21lbnRTdW1Db25maWckMSxzcGFyc2VUb0RlbnNlQ29uZmlnJDEsc3BsaXRWQ29uZmlnJDEsc3FydENvbmZpZyQxLHNxdWFyZUNvbmZpZyQxLHNxdWFyZWREaWZmZXJlbmNlQ29uZmlnJDEsc3RhdGljUmVnZXhSZXBsYWNlQ29uZmlnJDEsc3RlcENvbmZpZyQxLHN0cmlkZWRTbGljZUNvbmZpZyQxLHN0cmluZ05HcmFtc0NvbmZpZyQxLHN0cmluZ1NwbGl0Q29uZmlnJDEsc3RyaW5nVG9IYXNoQnVja2V0RmFzdENvbmZpZyQxLHN1YkNvbmZpZyQxLHN1bUNvbmZpZyQxLHRhbkNvbmZpZyQxLHRhbmhDb25maWckMSx0ZW5zb3JTY2F0dGVyVXBkYXRlQ29uZmlnJDEsdGlsZUNvbmZpZyQxLHRvcEtDb25maWckMSx0cmFuc2Zvcm1Db25maWckMSx0cmFuc3Bvc2VDb25maWckMSx1bmlxdWVDb25maWckMSx1bnBhY2tDb25maWckMSx1bnNvcnRlZFNlZ21lbnRTdW1Db25maWckMSx6ZXJvc0xpa2VDb25maWckMV07Zm9yKGNvbnN0IGhhIG9mIGtlcm5lbENvbmZpZ3MkMSlyZWdpc3Rlcktlcm5lbCQxKGhhKTt2YXIgdD10eXBlb2Ygc2VsZjwidSI/c2VsZjp7fTtmdW5jdGlvbiBlKGhhKXtlOntmb3IodmFyIGFhPVsiQ0xPU1VSRV9GTEFHUyJdLHhhPXQsYmE9MDtiYTxhYS5sZW5ndGg7YmErKylpZigoeGE9eGFbYWFbYmFdXSk9PW51bGwpe2FhPW51bGw7YnJlYWsgZX1hYT14YX1yZXR1cm4oaGE9YWEmJmFhW2hhXSkhPW51bGwmJmhhfWZ1bmN0aW9uIG4oKXt0aHJvdyBFcnJvcigiSW52YWxpZCBVVEY4Iil9ZnVuY3Rpb24gcihoYSxhYSl7cmV0dXJuIGFhPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhYSksaGE9PW51bGw/YWE6aGErYWF9bGV0IHMsaTtjb25zdCBvPXR5cGVvZiBUZXh0RGVjb2RlcjwidSI7bGV0IGE7Y29uc3QgaD10eXBlb2YgVGV4dEVuY29kZXI8InUiO2Z1bmN0aW9uIGMoaGEpe2lmKGgpaGE9KGF8fChhPW5ldyBUZXh0RW5jb2RlcikpLmVuY29kZShoYSk7ZWxzZXtsZXQgeGE9MDtjb25zdCBiYT1uZXcgVWludDhBcnJheSgzKmhhLmxlbmd0aCk7Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aDtTYSsrKXt2YXIgYWE9aGEuY2hhckNvZGVBdChTYSk7aWYoMTI4PmFhKWJhW3hhKytdPWFhO2Vsc2V7aWYoMjA0OD5hYSliYVt4YSsrXT1hYT4+NnwxOTI7ZWxzZXtpZig1NTI5Njw9YWEmJjU3MzQzPj1hYSl7aWYoNTYzMTk+PWFhJiZTYTxoYS5sZW5ndGgpe2NvbnN0IFRhPWhhLmNoYXJDb2RlQXQoKytTYSk7aWYoNTYzMjA8PVRhJiY1NzM0Mz49VGEpe2FhPTEwMjQqKGFhLTU1Mjk2KStUYS01NjMyMCs2NTUzNixiYVt4YSsrXT1hYT4+MTh8MjQwLGJhW3hhKytdPWFhPj4xMiY2M3wxMjgsYmFbeGErK109YWE+PjYmNjN8MTI4LGJhW3hhKytdPTYzJmFhfDEyODtjb250aW51ZX1TYS0tfWFhPTY1NTMzfWJhW3hhKytdPWFhPj4xMnwyMjQsYmFbeGErK109YWE+PjYmNjN8MTI4fWJhW3hhKytdPTYzJmFhfDEyOH19aGE9eGE9PT1iYS5sZW5ndGg/YmE6YmEuc3ViYXJyYXkoMCx4YSl9cmV0dXJuIGhhfXZhciB1LGw9ZSg2MTA0MDEzMDEpLGQ9ZSgxODg1ODg3MzYpO2NvbnN0IGY9dC5uYXZpZ2F0b3I7ZnVuY3Rpb24gcChoYSl7cmV0dXJuISFsJiYhIXUmJnUuYnJhbmRzLnNvbWUoKHticmFuZDphYX0pPT5hYSYmYWEuaW5kZXhPZihoYSkhPS0xKX1mdW5jdGlvbiBnKGhhKXt2YXIgYWE7cmV0dXJuKGFhPXQubmF2aWdhdG9yKSYmKGFhPWFhLnVzZXJBZ2VudCl8fChhYT0iIiksYWEuaW5kZXhPZihoYSkhPS0xfWZ1bmN0aW9uIG0oKXtyZXR1cm4hIWwmJiEhdSYmMDx1LmJyYW5kcy5sZW5ndGh9ZnVuY3Rpb24geSgpe3JldHVybiBtKCk/cCgiQ2hyb21pdW0iKTooZygiQ2hyb21lIil8fGcoIkNyaU9TIikpJiYhKCFtKCkmJmcoIkVkZ2UiKSl8fGcoIlNpbGsiKX11PWYmJmYudXNlckFnZW50RGF0YXx8bnVsbDt2YXIgXz0hbSgpJiYoZygiVHJpZGVudCIpfHxnKCJNU0lFIikpOyFnKCJBbmRyb2lkIil8fHkoKSx5KCksZygiU2FmYXJpIikmJih5KCl8fCFtKCkmJmcoIkNvYXN0Iil8fCFtKCkmJmcoIk9wZXJhIil8fCFtKCkmJmcoIkVkZ2UiKXx8KG0oKT9wKCJNaWNyb3NvZnQgRWRnZSIpOmcoIkVkZy8iKSl8fG0oKSYmcCgiT3BlcmEiKSk7dmFyIHY9e30sRT1udWxsO2Z1bmN0aW9uIHcoaGEpe3ZhciBhYT1oYS5sZW5ndGgseGE9MyphYS80O3hhJTM/eGE9TWF0aC5mbG9vcih4YSk6Ij0uIi5pbmRleE9mKGhhW2FhLTFdKSE9LTEmJih4YT0iPS4iLmluZGV4T2YoaGFbYWEtMl0pIT0tMT94YS0yOnhhLTEpO3ZhciBiYT1uZXcgVWludDhBcnJheSh4YSksU2E9MDtyZXR1cm4gZnVuY3Rpb24oVGEsd2Epe2Z1bmN0aW9uIEVhKHRsKXtmb3IoO2thPFRhLmxlbmd0aDspe3ZhciBubD1UYS5jaGFyQXQoa2ErKyksc2w9RVtubF07aWYoc2whPW51bGwpcmV0dXJuIHNsO2lmKCEvXltcc1x4YTBdKiQvLnRlc3QobmwpKXRocm93IEVycm9yKCJVbmtub3duIGJhc2U2NCBlbmNvZGluZyBhdCBjaGFyOiAiK25sKX1yZXR1cm4gdGx9VCgpO2Zvcih2YXIga2E9MDs7KXt2YXIgQWE9RWEoLTEpLEZhPUVhKDApLExhPUVhKDY0KSxlbD1FYSg2NCk7aWYoZWw9PT02NCYmQWE9PT0tMSlicmVhazt3YShBYTw8MnxGYT4+NCksTGEhPTY0JiYod2EoRmE8PDQmMjQwfExhPj4yKSxlbCE9NjQmJndhKExhPDw2JjE5MnxlbCkpfX0oaGEsZnVuY3Rpb24oVGEpe2JhW1NhKytdPVRhfSksU2EhPT14YT9iYS5zdWJhcnJheSgwLFNhKTpiYX1mdW5jdGlvbiBUKCl7aWYoIUUpe0U9e307Zm9yKHZhciBoYT0iQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkiLnNwbGl0KCIiKSxhYT1bIisvPSIsIisvIiwiLV89IiwiLV8uIiwiLV8iXSx4YT0wOzU+eGE7eGErKyl7dmFyIGJhPWhhLmNvbmNhdChhYVt4YV0uc3BsaXQoIiIpKTt2W3hhXT1iYTtmb3IodmFyIFNhPTA7U2E8YmEubGVuZ3RoO1NhKyspe3ZhciBUYT1iYVtTYV07RVtUYV09PT12b2lkIDAmJihFW1RhXT1TYSl9fX19dmFyIEE9dHlwZW9mIFVpbnQ4QXJyYXk8InUiLGI9IV8mJnR5cGVvZiBidG9hPT0iZnVuY3Rpb24iO2Z1bmN0aW9uIGsoaGEpe2lmKCFiKXt2YXIgYWE7YWE9PT12b2lkIDAmJihhYT0wKSxUKCksYWE9dlthYV07dmFyIHhhPUFycmF5KE1hdGguZmxvb3IoaGEubGVuZ3RoLzMpKSxiYT1hYVs2NF18fCIiO2xldCBrYT0wLEFhPTA7Zm9yKDtrYTxoYS5sZW5ndGgtMjtrYSs9Myl7dmFyIFNhPWhhW2thXSxUYT1oYVtrYSsxXSx3YT1oYVtrYSsyXSxFYT1hYVtTYT4+Ml07U2E9YWFbKDMmU2EpPDw0fFRhPj40XSxUYT1hYVsoMTUmVGEpPDwyfHdhPj42XSx3YT1hYVs2MyZ3YV0seGFbQWErK109RWErU2ErVGErd2F9c3dpdGNoKEVhPTAsd2E9YmEsaGEubGVuZ3RoLWthKXtjYXNlIDI6d2E9YWFbKDE1JihFYT1oYVtrYSsxXSkpPDwyXXx8YmE7Y2FzZSAxOmhhPWhhW2thXSx4YVtBYV09YWFbaGE+PjJdK2FhWygzJmhhKTw8NHxFYT4+NF0rd2ErYmF9cmV0dXJuIHhhLmpvaW4oIiIpfWZvcihhYT0iIix4YT0wLGJhPWhhLmxlbmd0aC0xMDI0MDt4YTxiYTspYWErPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxoYS5zdWJhcnJheSh4YSx4YSs9MTAyNDApKTtyZXR1cm4gYWErPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCx4YT9oYS5zdWJhcnJheSh4YSk6aGEpLGJ0b2EoYWEpfWNvbnN0IHg9L1stXy5dL2csUz17Ii0iOiIrIixfOiIvIiwiLiI6Ij0ifTtmdW5jdGlvbiBMKGhhKXtyZXR1cm4gU1toYV18fCIifWZ1bmN0aW9uIEYoaGEpe2lmKCFiKXJldHVybiB3KGhhKTt4LnRlc3QoaGEpJiYoaGE9aGEucmVwbGFjZSh4LEwpKSxoYT1hdG9iKGhhKTtjb25zdCBhYT1uZXcgVWludDhBcnJheShoYS5sZW5ndGgpO2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7eGErKylhYVt4YV09aGEuY2hhckNvZGVBdCh4YSk7cmV0dXJuIGFhfWZ1bmN0aW9uIFIoaGEpe3JldHVybiBBJiZoYSE9bnVsbCYmaGEgaW5zdGFuY2VvZiBVaW50OEFycmF5fWxldCBNO2Z1bmN0aW9uIFAoKXtyZXR1cm4gTXx8KE09bmV3IFVpbnQ4QXJyYXkoMCkpfXZhciBPPXt9O2xldCBDO2Z1bmN0aW9uIEkoaGEpe2lmKGhhIT09Tyl0aHJvdyBFcnJvcigiaWxsZWdhbCBleHRlcm5hbCBjYWxsZXIiKX1mdW5jdGlvbiBEKCl7cmV0dXJuIEN8fChDPW5ldyBVKG51bGwsTykpfWZ1bmN0aW9uIE4oaGEpe0koTyk7dmFyIGFhPWhhLmc7cmV0dXJuKGFhPWFhPT1udWxsfHxSKGFhKT9hYTp0eXBlb2YgYWE9PSJzdHJpbmciP0YoYWEpOm51bGwpPT1udWxsP2FhOmhhLmc9YWF9dmFyIFU9Y2xhc3N7Y29uc3RydWN0b3IoaGEsYWEpe2lmKEkoYWEpLHRoaXMuZz1oYSxoYSE9bnVsbCYmaGEubGVuZ3RoPT09MCl0aHJvdyBFcnJvcigiQnl0ZVN0cmluZyBzaG91bGQgYmUgY29uc3RydWN0ZWQgd2l0aCBub24tZW1wdHkgdmFsdWVzIil9aCgpe2NvbnN0IGhhPU4odGhpcyk7cmV0dXJuIGhhP25ldyBVaW50OEFycmF5KGhhKTpQKCl9fTtmdW5jdGlvbiBCKGhhLGFhKXtyZXR1cm4gRXJyb3IoYEludmFsaWQgd2lyZSB0eXBlOiAke2hhfSAoYXQgcG9zaXRpb24gJHthYX0pYCl9ZnVuY3Rpb24gRygpe3JldHVybiBFcnJvcigiRmFpbGVkIHRvIHJlYWQgdmFyaW50LCBlbmNvZGluZyBpcyBpbnZhbGlkLiIpfWZ1bmN0aW9uIGooaGEsYWEpe3JldHVybiBFcnJvcihgVHJpZWQgdG8gcmVhZCBwYXN0IHRoZSBlbmQgb2YgdGhlIGRhdGEgJHthYX0gPiAke2hhfWApfWZ1bmN0aW9uIFYoaGEpe2lmKHR5cGVvZiBoYT09InN0cmluZyIpcmV0dXJue2J1ZmZlcjpGKGhhKSxOOiExfTtpZihBcnJheS5pc0FycmF5KGhhKSlyZXR1cm57YnVmZmVyOm5ldyBVaW50OEFycmF5KGhhKSxOOiExfTtpZihoYS5jb25zdHJ1Y3Rvcj09PVVpbnQ4QXJyYXkpcmV0dXJue2J1ZmZlcjpoYSxOOiExfTtpZihoYS5jb25zdHJ1Y3Rvcj09PUFycmF5QnVmZmVyKXJldHVybntidWZmZXI6bmV3IFVpbnQ4QXJyYXkoaGEpLE46ITF9O2lmKGhhLmNvbnN0cnVjdG9yPT09VSlyZXR1cm57YnVmZmVyOk4oaGEpfHxQKCksTjohMH07aWYoaGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybntidWZmZXI6bmV3IFVpbnQ4QXJyYXkoaGEuYnVmZmVyLGhhLmJ5dGVPZmZzZXQsaGEuYnl0ZUxlbmd0aCksTjohMX07dGhyb3cgRXJyb3IoIlR5cGUgbm90IGNvbnZlcnRpYmxlIHRvIGEgVWludDhBcnJheSwgZXhwZWN0ZWQgYSBVaW50OEFycmF5LCBhbiBBcnJheUJ1ZmZlciwgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcsIGEgQnl0ZVN0cmluZyBvciBhbiBBcnJheSBvZiBudW1iZXJzIil9ZnVuY3Rpb24gWCgpe3JldHVybiB0eXBlb2YgQmlnSW50PT0iZnVuY3Rpb24ifWNvbnN0IEg9dHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNsaWNlPT0iZnVuY3Rpb24iO2xldCBXLHo9MCxLPTA7ZnVuY3Rpb24gWShoYSl7Y29uc3QgYWE9MD5oYTtsZXQgeGE9KGhhPU1hdGguYWJzKGhhKSk+Pj4wO2lmKGhhPU1hdGguZmxvb3IoKGhhLXhhKS80Mjk0OTY3Mjk2KSxhYSl7Y29uc3RbYmEsU2FdPW50KHhhLGhhKTtoYT1TYSx4YT1iYX16PXhhPj4+MCxLPWhhPj4+MH1mdW5jdGlvbiAkKGhhKXtjb25zdCBhYT1XfHwoVz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDgpKSk7YWEuc2V0RmxvYXQzMigwLCtoYSwhMCksSz0wLHo9YWEuZ2V0VWludDMyKDAsITApfWZ1bmN0aW9uIHEoaGEsYWEpe3JldHVybiA0Mjk0OTY3Mjk2KmFhKyhoYT4+PjApfWZ1bmN0aW9uIEooaGEsYWEpe2NvbnN0IHhhPTIxNDc0ODM2NDgmYWE7cmV0dXJuIHhhJiYoYWE9fmFhPj4+MCwoaGE9MSt+aGE+Pj4wKT09MCYmKGFhPWFhKzE+Pj4wKSksaGE9cShoYSxhYSkseGE/LWhhOmhhfWZ1bmN0aW9uIFooaGEsYWEpe2lmKGhhPj4+PTAsMjA5NzE1MT49KGFhPj4+PTApKXZhciB4YT0iIisoNDI5NDk2NzI5NiphYStoYSk7ZWxzZSBYKCk/eGE9IiIrKEJpZ0ludChhYSk8PEJpZ0ludCgzMil8QmlnSW50KGhhKSk6KGhhPSgxNjc3NzIxNSZoYSkrNjc3NzIxNiooeGE9MTY3NzcyMTUmKGhhPj4+MjR8YWE8PDgpKSs2NzEwNjU2KihhYT1hYT4+MTYmNjU1MzUpLHhhKz04MTQ3NDk3KmFhLGFhKj0yLDFlNzw9aGEmJih4YSs9TWF0aC5mbG9vcihoYS8xZTcpLGhhJT0xZTcpLDFlNzw9eGEmJihhYSs9TWF0aC5mbG9vcih4YS8xZTcpLHhhJT0xZTcpLHhhPWFhK1EoeGEpK1EoaGEpKTtyZXR1cm4geGF9ZnVuY3Rpb24gUShoYSl7cmV0dXJuIGhhPVN0cmluZyhoYSksIjAwMDAwMDAiLnNsaWNlKGhhLmxlbmd0aCkraGF9ZnVuY3Rpb24gdHQoKXt2YXIgaGE9eixhYT1LO2lmKDIxNDc0ODM2NDgmYWEpaWYoWCgpKWhhPSIiKyhCaWdJbnQoMHxhYSk8PEJpZ0ludCgzMil8QmlnSW50KGhhPj4+MCkpO2Vsc2V7Y29uc3RbeGEsYmFdPW50KGhhLGFhKTtoYT0iLSIrWih4YSxiYSl9ZWxzZSBoYT1aKGhhLGFhKTtyZXR1cm4gaGF9ZnVuY3Rpb24gZXQoaGEpe2lmKDE2PmhhLmxlbmd0aClZKE51bWJlcihoYSkpO2Vsc2UgaWYoWCgpKWhhPUJpZ0ludChoYSksej1OdW1iZXIoaGEmQmlnSW50KDQyOTQ5NjcyOTUpKT4+PjAsSz1OdW1iZXIoaGE+PkJpZ0ludCgzMikmQmlnSW50KDQyOTQ5NjcyOTUpKTtlbHNle2NvbnN0IGFhPSsoaGFbMF09PT0iLSIpO0s9ej0wO2NvbnN0IHhhPWhhLmxlbmd0aDtmb3IobGV0IGJhPWFhLFNhPSh4YS1hYSklNithYTtTYTw9eGE7YmE9U2EsU2ErPTYpe2NvbnN0IFRhPU51bWJlcihoYS5zbGljZShiYSxTYSkpO0sqPTFlNix6PTFlNip6K1RhLDQyOTQ5NjcyOTY8PXomJihLKz1NYXRoLnRydW5jKHovNDI5NDk2NzI5NiksSz4+Pj0wLHo+Pj49MCl9aWYoYWEpe2NvbnN0W2JhLFNhXT1udCh6LEspO3o9YmEsSz1TYX19fWZ1bmN0aW9uIG50KGhhLGFhKXtyZXR1cm4gYWE9fmFhLGhhP2hhPTErfmhhOmFhKz0xLFtoYSxhYV19ZnVuY3Rpb24gcnQoaGEsYWEpe2xldCB4YSxiYT0wLFNhPTAsVGE9MDtjb25zdCB3YT1oYS5oO2xldCBFYT1oYS5nO2RvIHhhPXdhW0VhKytdLGJhfD0oMTI3JnhhKTw8VGEsVGErPTc7d2hpbGUoMzI+VGEmJjEyOCZ4YSk7Zm9yKDMyPFRhJiYoU2F8PSgxMjcmeGEpPj40KSxUYT0zOzMyPlRhJiYxMjgmeGE7VGErPTcpeGE9d2FbRWErK10sU2F8PSgxMjcmeGEpPDxUYTtpZihsdChoYSxFYSksMTI4PnhhKXJldHVybiBhYShiYT4+PjAsU2E+Pj4wKTt0aHJvdyBHKCl9ZnVuY3Rpb24gc3QoaGEpe2xldCBhYT0wLHhhPWhhLmc7Y29uc3QgYmE9eGErMTAsU2E9aGEuaDtmb3IoO3hhPGJhOyl7Y29uc3QgVGE9U2FbeGErK107aWYoYWF8PVRhLCgxMjgmVGEpPT0wKXJldHVybiBsdChoYSx4YSksISEoMTI3JmFhKX10aHJvdyBHKCl9ZnVuY3Rpb24gaXQoaGEpe2NvbnN0IGFhPWhhLmg7bGV0IHhhPWhhLmcsYmE9YWFbeGErK10sU2E9MTI3JmJhO2lmKDEyOCZiYSYmKGJhPWFhW3hhKytdLFNhfD0oMTI3JmJhKTw8NywxMjgmYmEmJihiYT1hYVt4YSsrXSxTYXw9KDEyNyZiYSk8PDE0LDEyOCZiYSYmKGJhPWFhW3hhKytdLFNhfD0oMTI3JmJhKTw8MjEsMTI4JmJhJiYoYmE9YWFbeGErK10sU2F8PWJhPDwyOCwxMjgmYmEmJjEyOCZhYVt4YSsrXSYmMTI4JmFhW3hhKytdJiYxMjgmYWFbeGErK10mJjEyOCZhYVt4YSsrXSYmMTI4JmFhW3hhKytdKSkpKSl0aHJvdyBHKCk7cmV0dXJuIGx0KGhhLHhhKSxTYX1mdW5jdGlvbiBvdChoYSl7cmV0dXJuIGl0KGhhKT4+PjB9ZnVuY3Rpb24gYXQoaGEpe3ZhciBhYT1oYS5oO2NvbnN0IHhhPWhhLmcsYmE9YWFbeGFdLFNhPWFhW3hhKzFdLFRhPWFhW3hhKzJdO3JldHVybiBhYT1hYVt4YSszXSxsdChoYSxoYS5nKzQpLChiYTw8MHxTYTw8OHxUYTw8MTZ8YWE8PDI0KT4+PjB9ZnVuY3Rpb24gaHQoaGEpe3ZhciBhYT1hdChoYSk7aGE9MiooYWE+PjMxKSsxO2NvbnN0IHhhPWFhPj4+MjMmMjU1O3JldHVybiBhYSY9ODM4ODYwNyx4YT09MjU1P2FhP05hTjoxLzAqaGE6eGE9PTA/aGEqTWF0aC5wb3coMiwtMTQ5KSphYTpoYSpNYXRoLnBvdygyLHhhLTE1MCkqKGFhK01hdGgucG93KDIsMjMpKX1mdW5jdGlvbiBjdChoYSl7cmV0dXJuIGl0KGhhKX1mdW5jdGlvbiB1dChoYSxhYSx7Y2E6eGE9ITF9PXt9KXtoYS5jYT14YSxhYSYmKGFhPVYoYWEpLGhhLmg9YWEuYnVmZmVyLGhhLm09YWEuTixoYS5qPTAsaGEubD1oYS5oLmxlbmd0aCxoYS5nPWhhLmopfWZ1bmN0aW9uIGx0KGhhLGFhKXtpZihoYS5nPWFhLGFhPmhhLmwpdGhyb3cgaihoYS5sLGFhKX1mdW5jdGlvbiBkdChoYSxhYSl7aWYoMD5hYSl0aHJvdyBFcnJvcihgVHJpZWQgdG8gcmVhZCBhIG5lZ2F0aXZlIGJ5dGUgbGVuZ3RoOiAke2FhfWApO2NvbnN0IHhhPWhhLmcsYmE9eGErYWE7aWYoYmE+aGEubCl0aHJvdyBqKGFhLGhhLmwteGEpO3JldHVybiBoYS5nPWJhLHhhfWZ1bmN0aW9uIGZ0KGhhLGFhKXtpZihhYT09MClyZXR1cm4gRCgpO3ZhciB4YT1kdChoYSxhYSk7cmV0dXJuIGhhLmNhJiZoYS5tP3hhPWhhLmguc3ViYXJyYXkoeGEseGErYWEpOihoYT1oYS5oLHhhPXhhPT09KGFhPXhhK2FhKT9QKCk6SD9oYS5zbGljZSh4YSxhYSk6bmV3IFVpbnQ4QXJyYXkoaGEuc3ViYXJyYXkoeGEsYWEpKSkseGEubGVuZ3RoPT0wP0QoKTpuZXcgVSh4YSxPKX12YXIgcHQ9W107ZnVuY3Rpb24gZ3QoaGEpe3ZhciBhYT1oYS5nO2lmKGFhLmc9PWFhLmwpcmV0dXJuITE7aGEubD1oYS5nLmc7dmFyIHhhPW90KGhhLmcpO2lmKGFhPXhhPj4+MywhKDA8PSh4YSY9NykmJjU+PXhhKSl0aHJvdyBCKHhhLGhhLmwpO2lmKDE+YWEpdGhyb3cgRXJyb3IoYEludmFsaWQgZmllbGQgbnVtYmVyOiAke2FhfSAoYXQgcG9zaXRpb24gJHtoYS5sfSlgKTtyZXR1cm4gaGEubT1hYSxoYS5oPXhhLCEwfWZ1bmN0aW9uIG10KGhhKXtzd2l0Y2goaGEuaCl7Y2FzZSAwOmhhLmghPTA/bXQoaGEpOnN0KGhhLmcpO2JyZWFrO2Nhc2UgMTpsdChoYT1oYS5nLGhhLmcrOCk7YnJlYWs7Y2FzZSAyOmlmKGhhLmghPTIpbXQoaGEpO2Vsc2V7dmFyIGFhPW90KGhhLmcpO2x0KGhhPWhhLmcsaGEuZythYSl9YnJlYWs7Y2FzZSA1Omx0KGhhPWhhLmcsaGEuZys0KTticmVhaztjYXNlIDM6Zm9yKGFhPWhhLm07Oyl7aWYoIWd0KGhhKSl0aHJvdyBFcnJvcigiVW5tYXRjaGVkIHN0YXJ0LWdyb3VwIHRhZzogc3RyZWFtIEVPRiIpO2lmKGhhLmg9PTQpe2lmKGhhLm0hPWFhKXRocm93IEVycm9yKCJVbm1hdGNoZWQgZW5kLWdyb3VwIHRhZyIpO2JyZWFrfW10KGhhKX1icmVhaztkZWZhdWx0OnRocm93IEIoaGEuaCxoYS5sKX19ZnVuY3Rpb24geXQoaGEsYWEseGEpe2NvbnN0IGJhPWhhLmcubCxTYT1vdChoYS5nKSxUYT1oYS5nLmcrU2E7bGV0IHdhPVRhLWJhO2lmKDA+PXdhJiYoaGEuZy5sPVRhLHhhKGFhLGhhLHZvaWQgMCx2b2lkIDAsdm9pZCAwKSx3YT1UYS1oYS5nLmcpLHdhKXRocm93IEVycm9yKGBNZXNzYWdlIHBhcnNpbmcgZW5kZWQgdW5leHBlY3RlZGx5LiBFeHBlY3RlZCB0byByZWFkICR7U2F9IGJ5dGVzLCBpbnN0ZWFkIHJlYWQgJHtTYS13YX0gYnl0ZXMsIGVpdGhlciB0aGUgZGF0YSBlbmRlZCB1bmV4cGVjdGVkbHkgb3IgdGhlIG1lc3NhZ2UgbWlzcmVwb3J0ZWQgaXRzIG93biBsZW5ndGhgKTtyZXR1cm4gaGEuZy5nPVRhLGhhLmcubD1iYSxhYX1mdW5jdGlvbiBfdChoYSl7dmFyIGFhPW90KGhhLmcpLHhhPWR0KGhhPWhhLmcsYWEpO2lmKGhhPWhhLmgsbyl7dmFyIGJhLFNhPWhhOyhiYT1pKXx8KGJhPWk9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFsOiEwfSkpLGFhPXhhK2FhLFNhPXhhPT09MCYmYWE9PT1TYS5sZW5ndGg/U2E6U2Euc3ViYXJyYXkoeGEsYWEpO3RyeXt2YXIgVGE9YmEuZGVjb2RlKFNhKX1jYXRjaChFYSl7aWYocz09PXZvaWQgMCl7dHJ5e2JhLmRlY29kZShuZXcgVWludDhBcnJheShbMTI4XSkpfWNhdGNoe310cnl7YmEuZGVjb2RlKG5ldyBVaW50OEFycmF5KFs5N10pKSxzPSEwfWNhdGNoe3M9ITF9fXRocm93IXMmJihpPXZvaWQgMCksRWF9fWVsc2V7YWE9KFRhPXhhKSthYSx4YT1bXTtsZXQgRWEsa2E9bnVsbDtmb3IoO1RhPGFhOyl7dmFyIHdhPWhhW1RhKytdOzEyOD53YT94YS5wdXNoKHdhKToyMjQ+d2E/VGE+PWFhP24oKTooRWE9aGFbVGErK10sMTk0PndhfHwoMTkyJkVhKSE9MTI4PyhUYS0tLG4oKSk6eGEucHVzaCgoMzEmd2EpPDw2fDYzJkVhKSk6MjQwPndhP1RhPj1hYS0xP24oKTooRWE9aGFbVGErK10sKDE5MiZFYSkhPTEyOHx8d2E9PT0yMjQmJjE2MD5FYXx8d2E9PT0yMzcmJjE2MDw9RWF8fCgxOTImKGJhPWhhW1RhKytdKSkhPTEyOD8oVGEtLSxuKCkpOnhhLnB1c2goKDE1JndhKTw8MTJ8KDYzJkVhKTw8Nnw2MyZiYSkpOjI0ND49d2E/VGE+PWFhLTI/bigpOihFYT1oYVtUYSsrXSwoMTkyJkVhKSE9MTI4fHxFYS0xNDQrKHdhPDwyOCk+PjMwfHwoMTkyJihiYT1oYVtUYSsrXSkpIT0xMjh8fCgxOTImKFNhPWhhW1RhKytdKSkhPTEyOD8oVGEtLSxuKCkpOih3YT0oNyZ3YSk8PDE4fCg2MyZFYSk8PDEyfCg2MyZiYSk8PDZ8NjMmU2Esd2EtPTY1NTM2LHhhLnB1c2goNTUyOTYrKHdhPj4xMCYxMDIzKSw1NjMyMCsoMTAyMyZ3YSkpKSk6bigpLDgxOTI8PXhhLmxlbmd0aCYmKGthPXIoa2EseGEpLHhhLmxlbmd0aD0wKX1UYT1yKGthLHhhKX1yZXR1cm4gVGF9ZnVuY3Rpb24gdnQoaGEpe2NvbnN0IGFhPW90KGhhLmcpO3JldHVybiBmdChoYS5nLGFhKX1mdW5jdGlvbiBFdChoYSxhYSx4YSl7dmFyIGJhPW90KGhhLmcpO2ZvcihiYT1oYS5nLmcrYmE7aGEuZy5nPGJhOyl4YS5wdXNoKGFhKGhhLmcpKX12YXIgd3Q9W107ZnVuY3Rpb24gVHQoaGEpe3JldHVybiBoYT8vXlxkKyQvLnRlc3QoaGEpPyhldChoYSksbmV3IEF0KHosSykpOm51bGw6YnR8fChidD1uZXcgQXQoMCwwKSl9dmFyIEF0PWNsYXNze2NvbnN0cnVjdG9yKGhhLGFhKXt0aGlzLmg9aGE+Pj4wLHRoaXMuZz1hYT4+PjB9fTtsZXQgYnQ7ZnVuY3Rpb24ga3QoaGEpe3JldHVybiBoYT8vXi0/XGQrJC8udGVzdChoYSk/KGV0KGhhKSxuZXcgeHQoeixLKSk6bnVsbDpTdHx8KFN0PW5ldyB4dCgwLDApKX12YXIgeHQ9Y2xhc3N7Y29uc3RydWN0b3IoaGEsYWEpe3RoaXMuaD1oYT4+PjAsdGhpcy5nPWFhPj4+MH19O2xldCBTdDtmdW5jdGlvbiBMdChoYSxhYSx4YSl7Zm9yKDswPHhhfHwxMjc8YWE7KWhhLmcucHVzaCgxMjcmYWF8MTI4KSxhYT0oYWE+Pj43fHhhPDwyNSk+Pj4wLHhhPj4+PTc7aGEuZy5wdXNoKGFhKX1mdW5jdGlvbiBGdChoYSxhYSl7Zm9yKDsxMjc8YWE7KWhhLmcucHVzaCgxMjcmYWF8MTI4KSxhYT4+Pj03O2hhLmcucHVzaChhYSl9ZnVuY3Rpb24gUnQoaGEsYWEpe2lmKDA8PWFhKUZ0KGhhLGFhKTtlbHNle2ZvcihsZXQgeGE9MDs5PnhhO3hhKyspaGEuZy5wdXNoKDEyNyZhYXwxMjgpLGFhPj49NztoYS5nLnB1c2goMSl9fWZ1bmN0aW9uIE10KGhhLGFhKXtoYS5nLnB1c2goYWE+Pj4wJjI1NSksaGEuZy5wdXNoKGFhPj4+OCYyNTUpLGhhLmcucHVzaChhYT4+PjE2JjI1NSksaGEuZy5wdXNoKGFhPj4+MjQmMjU1KX1mdW5jdGlvbiBQdChoYSxhYSl7YWEubGVuZ3RoIT09MCYmKGhhLmwucHVzaChhYSksaGEuaCs9YWEubGVuZ3RoKX1mdW5jdGlvbiBPdChoYSxhYSx4YSl7RnQoaGEuZyw4KmFhK3hhKX1mdW5jdGlvbiBDdChoYSxhYSl7cmV0dXJuIE90KGhhLGFhLDIpLGFhPWhhLmcuZW5kKCksUHQoaGEsYWEpLGFhLnB1c2goaGEuaCksYWF9ZnVuY3Rpb24gSXQoaGEsYWEpe3ZhciB4YT1hYS5wb3AoKTtmb3IoeGE9aGEuaCtoYS5nLmxlbmd0aCgpLXhhOzEyNzx4YTspYWEucHVzaCgxMjcmeGF8MTI4KSx4YT4+Pj03LGhhLmgrKzthYS5wdXNoKHhhKSxoYS5oKyt9ZnVuY3Rpb24gRHQoaGEsYWEseGEpe090KGhhLGFhLDIpLEZ0KGhhLmcseGEubGVuZ3RoKSxQdChoYSxoYS5nLmVuZCgpKSxQdChoYSx4YSl9ZnVuY3Rpb24gTnQoaGEsYWEseGEsYmEpe3hhIT1udWxsJiYoYWE9Q3QoaGEsYWEpLGJhKHhhLGhhKSxJdChoYSxhYSkpfWNsYXNzIFV0e2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhKXt0aGlzLmc9YWEsdGhpcy5oPXhhLHRoaXMubD1iYSx0aGlzLnBhPVNhfX1mdW5jdGlvbiBCdChoYSl7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGhhKX1mdW5jdGlvbiBHdChoYSl7cmV0dXJuIHR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJnR5cGVvZiBTeW1ib2woKT09InN5bWJvbCI/U3ltYm9sKCk6aGF9dmFyIGp0PUd0KCksVnQ9R3QoIjBkaSIpLFh0PWp0PyhoYSxhYSk9PntoYVtqdF18PWFhfTooaGEsYWEpPT57aGEuZyE9PXZvaWQgMD9oYS5nfD1hYTpPYmplY3QuZGVmaW5lUHJvcGVydGllcyhoYSx7Zzp7dmFsdWU6YWEsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLGVudW1lcmFibGU6ITF9fSl9LEh0PWp0PyhoYSxhYSk9PntoYVtqdF0mPX5hYX06KGhhLGFhKT0+e2hhLmchPT12b2lkIDAmJihoYS5nJj1+YWEpfTtmdW5jdGlvbiBXdChoYSxhYSx4YSl7cmV0dXJuIHhhP2hhfGFhOmhhJn5hYX12YXIgenQ9anQ/aGE9PjB8aGFbanRdOmhhPT4wfGhhLmcsS3Q9anQ/aGE9PmhhW2p0XTpoYT0+aGEuZyxZdD1qdD8oaGEsYWEpPT4oaGFbanRdPWFhLGhhKTooaGEsYWEpPT4oaGEuZyE9PXZvaWQgMD9oYS5nPWFhOk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGhhLHtnOnt2YWx1ZTphYSxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsZW51bWVyYWJsZTohMX19KSxoYSk7ZnVuY3Rpb24gJHQoaGEpe3JldHVybiBYdChoYSwzNCksaGF9ZnVuY3Rpb24gcXQoaGEsYWEpe1l0KGFhLC0xNDU5MSYoMHxoYSkpfWZ1bmN0aW9uIEp0KGhhLGFhKXtZdChhYSwtMTQ1NTcmKDM0fGhhKSl9ZnVuY3Rpb24gWnQoaGEpe3JldHVybihoYT1oYT4+MTQmMTAyMyk9PT0wPzUzNjg3MDkxMjpoYX12YXIgUXQsdGU9e30sZWU9e307ZnVuY3Rpb24gbmUoaGEpe3JldHVybiEoIWhhfHx0eXBlb2YgaGEhPSJvYmplY3QifHxoYS5KYSE9PWVlKX1mdW5jdGlvbiByZShoYSl7cmV0dXJuIGhhIT09bnVsbCYmdHlwZW9mIGhhPT0ib2JqZWN0IiYmIUFycmF5LmlzQXJyYXkoaGEpJiZoYS5jb25zdHJ1Y3Rvcj09PU9iamVjdH1mdW5jdGlvbiBzZShoYSxhYSx4YSl7aWYoaGEhPW51bGwpe2lmKHR5cGVvZiBoYT09InN0cmluZyIpaGE9aGE/bmV3IFUoaGEsTyk6RCgpO2Vsc2UgaWYoaGEuY29uc3RydWN0b3IhPT1VKWlmKFIoaGEpKWhhPWhhLmxlbmd0aD9uZXcgVSh4YT9oYTpuZXcgVWludDhBcnJheShoYSksTyk6RCgpO2Vsc2V7aWYoIWFhKXRocm93IEVycm9yKCk7aGE9dm9pZCAwfX1yZXR1cm4gaGF9ZnVuY3Rpb24gaWUoaGEsYWEseGEpe2lmKCFBcnJheS5pc0FycmF5KGhhKXx8aGEubGVuZ3RoKXJldHVybiExO2NvbnN0IGJhPXp0KGhhKTtyZXR1cm4hISgxJmJhKXx8ISghYWF8fCEoQXJyYXkuaXNBcnJheShhYSk/YWEuaW5jbHVkZXMoeGEpOmFhLmhhcyh4YSkpKSYmKFl0KGhhLDF8YmEpLCEwKX1jb25zdCBvZT1bXTtmdW5jdGlvbiBhZShoYSl7aWYoMiZoYSl0aHJvdyBFcnJvcigpfVl0KG9lLDU1KSxRdD1PYmplY3QuZnJlZXplKG9lKTtjbGFzcyBoZXtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy5sPTAsdGhpcy5nPWFhLHRoaXMuaD14YSx0aGlzLm09YmF9bmV4dCgpe2lmKHRoaXMubDx0aGlzLmcubGVuZ3RoKXtjb25zdCBhYT10aGlzLmdbdGhpcy5sKytdO3JldHVybntkb25lOiExLHZhbHVlOnRoaXMuaD90aGlzLmguY2FsbCh0aGlzLm0sYWEpOmFhfX1yZXR1cm57ZG9uZTohMCx2YWx1ZTp2b2lkIDB9fVtTeW1ib2wuaXRlcmF0b3JdKCl7cmV0dXJuIG5ldyBoZSh0aGlzLmcsdGhpcy5oLHRoaXMubSl9fWxldCBjZSx1ZTtmdW5jdGlvbiBsZShoYSxhYSl7KGFhPWNlP2FhW2NlXTp2b2lkIDApJiYoaGFbY2VdPUJ0KGFhKSl9ZnVuY3Rpb24gZGUoaGEpe3JldHVybihoYT1FcnJvcihoYSkpLl9fY2xvc3VyZV9fZXJyb3JfX2NvbnRleHRfXzk4NDM4Mnx8KGhhLl9fY2xvc3VyZV9fZXJyb3JfX2NvbnRleHRfXzk4NDM4Mj17fSksaGEuX19jbG9zdXJlX19lcnJvcl9fY29udGV4dF9fOTg0MzgyLnNldmVyaXR5PSJ3YXJuaW5nIixoYX1mdW5jdGlvbiBmZShoYSl7cmV0dXJuIGhhPT1udWxsfHx0eXBlb2YgaGE9PSJudW1iZXIiP2hhOmhhPT09Ik5hTiJ8fGhhPT09IkluZmluaXR5Inx8aGE9PT0iLUluZmluaXR5Ij9OdW1iZXIoaGEpOnZvaWQgMH1mdW5jdGlvbiBwZShoYSl7cmV0dXJuIGhhPT1udWxsfHx0eXBlb2YgaGE9PSJib29sZWFuIj9oYTp0eXBlb2YgaGE9PSJudW1iZXIiPyEhaGE6dm9pZCAwfU9iamVjdC5mcmVlemUobmV3IGNsYXNze30pLE9iamVjdC5mcmVlemUobmV3IGNsYXNze30pO2NvbnN0IGdlPS9eLT8oWzEtOV1bMC05XSp8MCkoXC5bMC05XSspPyQvO2Z1bmN0aW9uIG1lKGhhKXtjb25zdCBhYT10eXBlb2YgaGE7cmV0dXJuIGFhPT09Im51bWJlciI/TnVtYmVyLmlzRmluaXRlKGhhKTphYT09PSJzdHJpbmciJiZnZS50ZXN0KGhhKX1mdW5jdGlvbiB5ZShoYSl7aWYoaGE9PW51bGwpcmV0dXJuIGhhO2lmKHR5cGVvZiBoYT09InN0cmluZyIpe2lmKCFoYSlyZXR1cm47aGE9K2hhfXJldHVybiB0eXBlb2YgaGE9PSJudW1iZXIiJiZOdW1iZXIuaXNGaW5pdGUoaGEpPzB8aGE6dm9pZCAwfWZ1bmN0aW9uIF9lKGhhKXtpZihoYT09bnVsbClyZXR1cm4gaGE7aWYodHlwZW9mIGhhPT0ic3RyaW5nIil7aWYoIWhhKXJldHVybjtoYT0raGF9cmV0dXJuIHR5cGVvZiBoYT09Im51bWJlciImJk51bWJlci5pc0Zpbml0ZShoYSk/aGE+Pj4wOnZvaWQgMH1mdW5jdGlvbiB2ZShoYSl7cmV0dXJuIGhhWzBdIT09Ii0iJiYoMjA+aGEubGVuZ3RofHxoYS5sZW5ndGg9PT0yMCYmMTg0NDY3Pk51bWJlcihoYS5zdWJzdHJpbmcoMCw2KSkpfWZ1bmN0aW9uIEVlKGhhKXtyZXR1cm4gaGFbMF09PT0iLSI/MjA+aGEubGVuZ3RofHxoYS5sZW5ndGg9PT0yMCYmLTkyMjMzNzxOdW1iZXIoaGEuc3Vic3RyaW5nKDAsNykpOjE5PmhhLmxlbmd0aHx8aGEubGVuZ3RoPT09MTkmJjkyMjMzNz5OdW1iZXIoaGEuc3Vic3RyaW5nKDAsNikpfWZ1bmN0aW9uIHdlKGhhKXtyZXR1cm4gaGE9TWF0aC50cnVuYyhoYSksTnVtYmVyLmlzU2FmZUludGVnZXIoaGEpfHwoWShoYSksaGE9Sih6LEspKSxoYX1mdW5jdGlvbiBUZShoYSl7dmFyIGFhPU1hdGgudHJ1bmMoTnVtYmVyKGhhKSk7cmV0dXJuIE51bWJlci5pc1NhZmVJbnRlZ2VyKGFhKT9TdHJpbmcoYWEpOigoYWE9aGEuaW5kZXhPZigiLiIpKSE9PS0xJiYoaGE9aGEuc3Vic3RyaW5nKDAsYWEpKSxFZShoYSl8fChldChoYSksaGE9dHQoKSksaGEpfWZ1bmN0aW9uIEFlKGhhKXtyZXR1cm4gaGE9PW51bGw/aGE6bWUoaGEpP3R5cGVvZiBoYT09Im51bWJlciI/d2UoaGEpOlRlKGhhKTp2b2lkIDB9ZnVuY3Rpb24gYmUoaGEpe2lmKHR5cGVvZiBoYSE9InN0cmluZyIpdGhyb3cgRXJyb3IoKTtyZXR1cm4gaGF9ZnVuY3Rpb24ga2UoaGEpe2lmKGhhIT1udWxsJiZ0eXBlb2YgaGEhPSJzdHJpbmciKXRocm93IEVycm9yKCk7cmV0dXJuIGhhfWZ1bmN0aW9uIHhlKGhhKXtyZXR1cm4gaGE9PW51bGx8fHR5cGVvZiBoYT09InN0cmluZyI/aGE6dm9pZCAwfWZ1bmN0aW9uIFNlKGhhLGFhLHhhLGJhKXtpZihoYSE9bnVsbCYmdHlwZW9mIGhhPT0ib2JqZWN0IiYmaGEuWD09PXRlKXJldHVybiBoYTtpZighQXJyYXkuaXNBcnJheShoYSkpcmV0dXJuIHhhPzImYmE/KGhhPWFhW1Z0XSk/YWE9aGE6KCR0KChoYT1uZXcgYWEpLnUpLGFhPWFhW1Z0XT1oYSk6YWE9bmV3IGFhOmFhPXZvaWQgMCxhYTtsZXQgU2E9eGE9enQoaGEpO3JldHVybiBTYT09PTAmJihTYXw9MzImYmEpLFNhfD0yJmJhLFNhIT09eGEmJll0KGhhLFNhKSxuZXcgYWEoaGEpfWZ1bmN0aW9uIExlKGhhLGFhLHhhKXtpZihhYSl7dmFyIGJhPSEhYmE7aWYoIW1lKGFhPWhhKSl0aHJvdyBkZSgiaW50NjQiKTt0eXBlb2YgYWE9PSJzdHJpbmciP2JhPVRlKGFhKTpiYT8oYmE9TWF0aC50cnVuYyhhYSksTnVtYmVyLmlzU2FmZUludGVnZXIoYmEpP2JhPVN0cmluZyhiYSk6RWUoYWE9U3RyaW5nKGJhKSk/YmE9YWE6KFkoYmEpLGJhPXR0KCkpKTpiYT13ZShhYSl9ZWxzZSBiYT1BZShoYSk7cmV0dXJuIHR5cGVvZih4YT0oaGE9YmEpPT1udWxsP3hhPzA6dm9pZCAwOmhhKT09InN0cmluZyImJihiYT0reGEsTnVtYmVyLmlzU2FmZUludGVnZXIoYmEpKT9iYTp4YX1sZXQgRmUsUmUsTWU7ZnVuY3Rpb24gUGUoaGEpe3N3aXRjaCh0eXBlb2YgaGEpe2Nhc2UiYm9vbGVhbiI6cmV0dXJuIFJlfHwoUmU9WzAsdm9pZCAwLCEwXSk7Y2FzZSJudW1iZXIiOnJldHVybiAwPGhhP3ZvaWQgMDpoYT09PTA/TWV8fChNZT1bMCx2b2lkIDBdKTpbLWhhLHZvaWQgMF07Y2FzZSJzdHJpbmciOnJldHVyblswLGhhXTtjYXNlIm9iamVjdCI6cmV0dXJuIGhhfX1mdW5jdGlvbiBPZShoYSxhYSl7cmV0dXJuIENlKGhhLGFhWzBdLGFhWzFdKX1mdW5jdGlvbiBDZShoYSxhYSx4YSl7aWYoaGE9PW51bGwmJihoYT1GZSksRmU9dm9pZCAwLGhhPT1udWxsKXt2YXIgYmE9OTY7eGE/KGhhPVt4YV0sYmF8PTUxMik6aGE9W10sYWEmJihiYT0tMTY3NjA4MzMmYmF8KDEwMjMmYWEpPDwxNCl9ZWxzZXtpZighQXJyYXkuaXNBcnJheShoYSl8fDIwNDgmKGJhPXp0KGhhKSkpdGhyb3cgRXJyb3IoKTtpZig2NCZiYSlyZXR1cm4gaGE7aWYoYmF8PTY0LHhhJiYoYmF8PTUxMix4YSE9PWhhWzBdKSl0aHJvdyBFcnJvcigpO2U6e2NvbnN0IFNhPSh4YT1oYSkubGVuZ3RoO2lmKFNhKXtjb25zdCBUYT1TYS0xO2lmKHJlKHhhW1RhXSkpe2lmKDEwMjQ8PShhYT1UYS0oKyEhKDUxMiYoYmF8PTI1NikpLTEpKSl0aHJvdyBFcnJvcigpO2JhPS0xNjc2MDgzMyZiYXwoMTAyMyZhYSk8PDE0O2JyZWFrIGV9fWlmKGFhKXtpZigxMDI0PChhYT1NYXRoLm1heChhYSxTYS0oKyEhKDUxMiZiYSktMSkpKSl0aHJvdyBFcnJvcigpO2JhPS0xNjc2MDgzMyZiYXwoMTAyMyZhYSk8PDE0fX19cmV0dXJuIFl0KGhhLGJhKSxoYX1jb25zdCBJZT17fTtsZXQgRGU9ZnVuY3Rpb24oKXt0cnl7cmV0dXJuIG5ldyBjbGFzcyBleHRlbmRzIE1hcHtjb25zdHJ1Y3Rvcigpe3N1cGVyKCl9fSwhMX1jYXRjaHtyZXR1cm4hMH19KCk7Y2xhc3MgTmV7Y29uc3RydWN0b3IoKXt0aGlzLmc9bmV3IE1hcH1nZXQoYWEpe3JldHVybiB0aGlzLmcuZ2V0KGFhKX1zZXQoYWEseGEpe3JldHVybiB0aGlzLmcuc2V0KGFhLHhhKSx0aGlzLnNpemU9dGhpcy5nLnNpemUsdGhpc31kZWxldGUoYWEpe3JldHVybiBhYT10aGlzLmcuZGVsZXRlKGFhKSx0aGlzLnNpemU9dGhpcy5nLnNpemUsYWF9Y2xlYXIoKXt0aGlzLmcuY2xlYXIoKSx0aGlzLnNpemU9dGhpcy5nLnNpemV9aGFzKGFhKXtyZXR1cm4gdGhpcy5nLmhhcyhhYSl9ZW50cmllcygpe3JldHVybiB0aGlzLmcuZW50cmllcygpfWtleXMoKXtyZXR1cm4gdGhpcy5nLmtleXMoKX12YWx1ZXMoKXtyZXR1cm4gdGhpcy5nLnZhbHVlcygpfWZvckVhY2goYWEseGEpe3JldHVybiB0aGlzLmcuZm9yRWFjaChhYSx4YSl9W1N5bWJvbC5pdGVyYXRvcl0oKXtyZXR1cm4gdGhpcy5lbnRyaWVzKCl9fWNvbnN0IFVlPURlPyhPYmplY3Quc2V0UHJvdG90eXBlT2YoTmUucHJvdG90eXBlLE1hcC5wcm90b3R5cGUpLE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE5lLnByb3RvdHlwZSx7c2l6ZTp7dmFsdWU6MCxjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMCx3cml0YWJsZTohMH19KSxOZSk6Y2xhc3MgZXh0ZW5kcyBNYXB7Y29uc3RydWN0b3IoKXtzdXBlcigpfX07ZnVuY3Rpb24gQmUoaGEpe3JldHVybiBoYX1mdW5jdGlvbiBHZShoYSl7aWYoMiZoYS5MKXRocm93IEVycm9yKCJDYW5ub3QgbXV0YXRlIGFuIGltbXV0YWJsZSBNYXAiKX12YXIgamU9Y2xhc3MgZXh0ZW5kcyBVZXtjb25zdHJ1Y3RvcihoYSxhYSx4YT1CZSxiYT1CZSl7c3VwZXIoKTtsZXQgU2E9enQoaGEpO1NhfD02NCxZdChoYSxTYSksdGhpcy5MPVNhLHRoaXMuVT1hYSx0aGlzLlM9eGEsdGhpcy5aPXRoaXMuVT9WZTpiYTtmb3IobGV0IFRhPTA7VGE8aGEubGVuZ3RoO1RhKyspe2NvbnN0IHdhPWhhW1RhXSxFYT14YSh3YVswXSwhMSwhMCk7bGV0IGthPXdhWzFdO2FhP2thPT09dm9pZCAwJiYoa2E9bnVsbCk6a2E9YmEod2FbMV0sITEsITAsdm9pZCAwLHZvaWQgMCxTYSksc3VwZXIuc2V0KEVhLGthKX19b2EoaGE9WGUpe2lmKHRoaXMuc2l6ZSE9PTApcmV0dXJuIHRoaXMuWShoYSl9WShoYT1YZSl7Y29uc3QgYWE9W10seGE9c3VwZXIuZW50cmllcygpO2Zvcih2YXIgYmE7IShiYT14YS5uZXh0KCkpLmRvbmU7KShiYT1iYS52YWx1ZSlbMF09aGEoYmFbMF0pLGJhWzFdPWhhKGJhWzFdKSxhYS5wdXNoKGJhKTtyZXR1cm4gYWF9Y2xlYXIoKXtHZSh0aGlzKSxzdXBlci5jbGVhcigpfWRlbGV0ZShoYSl7cmV0dXJuIEdlKHRoaXMpLHN1cGVyLmRlbGV0ZSh0aGlzLlMoaGEsITAsITEpKX1lbnRyaWVzKCl7dmFyIGhhPXRoaXMubmEoKTtyZXR1cm4gbmV3IGhlKGhhLEhlLHRoaXMpfWtleXMoKXtyZXR1cm4gdGhpcy5JYSgpfXZhbHVlcygpe3ZhciBoYT10aGlzLm5hKCk7cmV0dXJuIG5ldyBoZShoYSxqZS5wcm90b3R5cGUuZ2V0LHRoaXMpfWZvckVhY2goaGEsYWEpe3N1cGVyLmZvckVhY2goKHhhLGJhKT0+e2hhLmNhbGwoYWEsdGhpcy5nZXQoYmEpLGJhLHRoaXMpfSl9c2V0KGhhLGFhKXtyZXR1cm4gR2UodGhpcyksKGhhPXRoaXMuUyhoYSwhMCwhMSkpPT1udWxsP3RoaXM6YWE9PW51bGw/KHN1cGVyLmRlbGV0ZShoYSksdGhpcyk6c3VwZXIuc2V0KGhhLHRoaXMuWihhYSwhMCwhMCx0aGlzLlUsITEsdGhpcy5MKSl9T2EoaGEpe2NvbnN0IGFhPXRoaXMuUyhoYVswXSwhMSwhMCk7aGE9aGFbMV0saGE9dGhpcy5VP2hhPT09dm9pZCAwP251bGw6aGE6dGhpcy5aKGhhLCExLCEwLHZvaWQgMCwhMSx0aGlzLkwpLHN1cGVyLnNldChhYSxoYSl9aGFzKGhhKXtyZXR1cm4gc3VwZXIuaGFzKHRoaXMuUyhoYSwhMSwhMSkpfWdldChoYSl7aGE9dGhpcy5TKGhhLCExLCExKTtjb25zdCBhYT1zdXBlci5nZXQoaGEpO2lmKGFhIT09dm9pZCAwKXt2YXIgeGE9dGhpcy5VO3JldHVybiB4YT8oKHhhPXRoaXMuWihhYSwhMSwhMCx4YSx0aGlzLnRhLHRoaXMuTCkpIT09YWEmJnN1cGVyLnNldChoYSx4YSkseGEpOmFhfX1uYSgpe3JldHVybiBBcnJheS5mcm9tKHN1cGVyLmtleXMoKSl9SWEoKXtyZXR1cm4gc3VwZXIua2V5cygpfVtTeW1ib2wuaXRlcmF0b3JdKCl7cmV0dXJuIHRoaXMuZW50cmllcygpfX07ZnVuY3Rpb24gVmUoaGEsYWEseGEsYmEsU2EsVGEpe3JldHVybiBoYT1TZShoYSxiYSx4YSxUYSksU2EmJihoYT10bihoYSkpLGhhfWZ1bmN0aW9uIFhlKGhhKXtyZXR1cm4gaGF9ZnVuY3Rpb24gSGUoaGEpe3JldHVybltoYSx0aGlzLmdldChoYSldfWxldCBXZTtmdW5jdGlvbiB6ZSgpe3JldHVybiBXZXx8KFdlPW5ldyBqZSgkdChbXSksdm9pZCAwLHZvaWQgMCx2b2lkIDAsSWUpKX1mdW5jdGlvbiBLZShoYSxhYSx4YSxiYSxTYSl7aWYoaGEhPW51bGwpe2lmKEFycmF5LmlzQXJyYXkoaGEpKWhhPWllKGhhLHZvaWQgMCwwKT92b2lkIDA6U2EmJjImenQoaGEpP2hhOlllKGhhLGFhLHhhLGJhIT09dm9pZCAwLFNhKTtlbHNlIGlmKHJlKGhhKSl7Y29uc3QgVGE9e307Zm9yKGxldCB3YSBpbiBoYSlUYVt3YV09S2UoaGFbd2FdLGFhLHhhLGJhLFNhKTtoYT1UYX1lbHNlIGhhPWFhKGhhLGJhKTtyZXR1cm4gaGF9fWZ1bmN0aW9uIFllKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1iYXx8eGE/enQoaGEpOjA7YmE9YmE/ISEoMzImVGEpOnZvaWQgMDtjb25zdCB3YT1CdChoYSk7Zm9yKGxldCBFYT0wO0VhPHdhLmxlbmd0aDtFYSsrKXdhW0VhXT1LZSh3YVtFYV0sYWEseGEsYmEsU2EpO3JldHVybiB4YSYmKGxlKHdhLGhhKSx4YShUYSx3YSkpLHdhfWZ1bmN0aW9uICRlKGhhKXtyZXR1cm4gS2UoaGEscWUsdm9pZCAwLHZvaWQgMCwhMSl9ZnVuY3Rpb24gcWUoaGEpe3JldHVybiBoYS5YPT09dGU/aGEudG9KU09OKCk6aGEgaW5zdGFuY2VvZiBqZT9oYS5vYSgkZSk6ZnVuY3Rpb24oYWEpe3N3aXRjaCh0eXBlb2YgYWEpe2Nhc2UibnVtYmVyIjpyZXR1cm4gaXNGaW5pdGUoYWEpP2FhOlN0cmluZyhhYSk7Y2FzZSJib29sZWFuIjpyZXR1cm4gYWE/MTowO2Nhc2Uib2JqZWN0IjppZihhYSlpZihBcnJheS5pc0FycmF5KGFhKSl7aWYoaWUoYWEsdm9pZCAwLDApKXJldHVybn1lbHNle2lmKFIoYWEpKXJldHVybiBrKGFhKTtpZihhYSBpbnN0YW5jZW9mIFUpe2NvbnN0IHhhPWFhLmc7cmV0dXJuIHhhPT1udWxsPyIiOnR5cGVvZiB4YT09InN0cmluZyI/eGE6YWEuZz1rKHhhKX1pZihhYSBpbnN0YW5jZW9mIGplKXJldHVybiBhYS5vYSgpfX1yZXR1cm4gYWF9KGhhKX1mdW5jdGlvbiBKZShoYSxhYSx4YT1KdCl7aWYoaGEhPW51bGwpe2lmKEEmJmhhIGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gYWE/aGE6bmV3IFVpbnQ4QXJyYXkoaGEpO2lmKEFycmF5LmlzQXJyYXkoaGEpKXt2YXIgYmE9enQoaGEpO3JldHVybiAyJmJhP2hhOihhYSYmKGFhPWJhPT09MHx8ISEoMzImYmEpJiYhKDY0JmJhfHwhKDE2JmJhKSkpLGFhP1l0KGhhLC0xMjI5MyYoMzR8YmEpKTpZZShoYSxKZSw0JmJhP0p0OnhhLCEwLCEwKSl9cmV0dXJuIGhhLlg9PT10ZT8oeGE9aGEudSxoYT0yJihiYT1LdCh4YSkpP2hhOlplKGhhLHhhLGJhLCEwKSk6aGEgaW5zdGFuY2VvZiBqZSYmISgyJmhhLkwpJiYoeGE9JHQoaGEuWShKZSkpLGhhPW5ldyBqZSh4YSxoYS5VLGhhLlMsaGEuWikpLGhhfX1mdW5jdGlvbiBaZShoYSxhYSx4YSxiYSl7cmV0dXJuIGhhPWhhLmNvbnN0cnVjdG9yLEZlPWFhPVFlKGFhLHhhLGJhKSxhYT1uZXcgaGEoYWEpLEZlPXZvaWQgMCxhYX1mdW5jdGlvbiBRZShoYSxhYSx4YSl7Y29uc3QgYmE9eGF8fDImYWE/SnQ6cXQsU2E9ISEoMzImYWEpO3JldHVybiBoYT1mdW5jdGlvbihUYSx3YSxFYSl7Y29uc3Qga2E9QnQoVGEpO3ZhciBBYT1rYS5sZW5ndGg7Y29uc3QgRmE9MjU2JndhP2thW0FhLTFdOnZvaWQgMDtmb3IoQWErPUZhPy0xOjAsd2E9NTEyJndhPzE6MDt3YTxBYTt3YSsrKWthW3dhXT1FYShrYVt3YV0pO2lmKEZhKXt3YT1rYVt3YV09e307Zm9yKGNvbnN0IExhIGluIEZhKXdhW0xhXT1FYShGYVtMYV0pfXJldHVybiBsZShrYSxUYSksa2F9KGhhLGFhLFRhPT5KZShUYSxTYSxiYSkpLFh0KGhhLDMyfCh4YT8yOjApKSxoYX1mdW5jdGlvbiB0bihoYSl7Y29uc3QgYWE9aGEudSx4YT1LdChhYSk7cmV0dXJuIDImeGE/WmUoaGEsYWEseGEsITEpOmhhfWZ1bmN0aW9uIGVuKGhhLGFhKXtyZXR1cm4gbm4oaGE9aGEudSxLdChoYSksYWEpfWZ1bmN0aW9uIG5uKGhhLGFhLHhhLGJhKXtpZih4YT09PS0xKXJldHVybiBudWxsO2lmKHhhPj1adChhYSkpe2lmKDI1NiZhYSlyZXR1cm4gaGFbaGEubGVuZ3RoLTFdW3hhXX1lbHNle3ZhciBTYT1oYS5sZW5ndGg7aWYoYmEmJjI1NiZhYSYmKGJhPWhhW1NhLTFdW3hhXSkhPW51bGwpcmV0dXJuIGJhO2lmKChhYT14YSsoKyEhKDUxMiZhYSktMSkpPFNhKXJldHVybiBoYVthYV19fWZ1bmN0aW9uIHJuKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1oYS51O2xldCBUYT1LdChTYSk7cmV0dXJuIGFlKFRhKSxzbihTYSxUYSxhYSx4YSxiYSksaGF9ZnVuY3Rpb24gc24oaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPVp0KGFhKTtpZih4YT49VGF8fFNhKXtsZXQgd2E9YWE7aWYoMjU2JmFhKVNhPWhhW2hhLmxlbmd0aC0xXTtlbHNle2lmKGJhPT1udWxsKXJldHVybiB3YTtTYT1oYVtUYSsoKyEhKDUxMiZhYSktMSldPXt9LHdhfD0yNTZ9cmV0dXJuIFNhW3hhXT1iYSx4YTxUYSYmKGhhW3hhKygrISEoNTEyJmFhKS0xKV09dm9pZCAwKSx3YSE9PWFhJiZZdChoYSx3YSksd2F9cmV0dXJuIGhhW3hhKygrISEoNTEyJmFhKS0xKV09YmEsMjU2JmFhJiZ4YSBpbihoYT1oYVtoYS5sZW5ndGgtMV0pJiZkZWxldGUgaGFbeGFdLGFhfWZ1bmN0aW9uIG9uKGhhLGFhLHhhLGJhLFNhKXt2YXIgVGE9MiZhYTtsZXQgd2E9bm4oaGEsYWEseGEsU2EpO0FycmF5LmlzQXJyYXkod2EpfHwod2E9UXQpO2NvbnN0IEVhPSEoMiZiYSk7YmE9ISgxJmJhKTtjb25zdCBrYT0hISgzMiZhYSk7bGV0IEFhPXp0KHdhKTtyZXR1cm4gQWEhPT0wfHwha2F8fFRhfHxFYT8xJkFhfHwoQWF8PTEsWXQod2EsQWEpKTooQWF8PTMzLFl0KHdhLEFhKSksVGE/KGhhPSExLDImQWF8fCgkdCh3YSksaGE9ISEoNCZBYSkpLChiYXx8aGEpJiZPYmplY3QuZnJlZXplKHdhKSk6KFRhPSEhKDImQWEpfHwhISgyMDQ4JkFhKSxiYSYmVGE/KHdhPUJ0KHdhKSxiYT0xLGthJiYhRWEmJihiYXw9MzIpLFl0KHdhLGJhKSxzbihoYSxhYSx4YSx3YSxTYSkpOkVhJiYzMiZBYSYmIVRhJiZIdCh3YSwzMikpLHdhfWZ1bmN0aW9uIGFuKGhhLGFhKXtoYT1oYS51O2xldCB4YT1LdChoYSk7Y29uc3QgYmE9bm4oaGEseGEsYWEpLFNhPWZlKGJhKTtyZXR1cm4gU2EhPW51bGwmJlNhIT09YmEmJnNuKGhhLHhhLGFhLFNhKSxTYX1mdW5jdGlvbiBobihoYSl7aGE9aGEudTtsZXQgYWE9S3QoaGEpO2NvbnN0IHhhPW5uKGhhLGFhLDEpLGJhPXNlKHhhLCEwLCEhKDM0JmFhKSk7cmV0dXJuIGJhIT1udWxsJiZiYSE9PXhhJiZzbihoYSxhYSwxLGJhKSxiYX1mdW5jdGlvbiBjbihoYSxhYSx4YSl7aGE9aGEudTtsZXQgYmE9S3QoaGEpO2NvbnN0IFNhPTImYmE/MToyO2xldCBUYT11bihoYSxiYSxhYSk7dmFyIHdhPXp0KFRhKTtpZighKDQmd2EpKXsoNCZ3YXx8T2JqZWN0LmlzRnJvemVuKFRhKSkmJihUYT1CdChUYSksd2E9U24od2EsYmEsITEpLGJhPXNuKGhhLGJhLGFhLFRhKSk7dmFyIEVhPTA7bGV0IGthPTA7Zm9yKDtFYTxUYS5sZW5ndGg7RWErKyl7Y29uc3QgQWE9eGEoVGFbRWFdKTtBYSE9bnVsbCYmKFRhW2thKytdPUFhKX1rYTxFYSYmKFRhLmxlbmd0aD1rYSksd2E9V3Qod2E9bG4od2EsYmEsITEpLDIwLCEwKSx3YT1XdCh3YSw0MDk2LCExKSx3YT1XdCh3YSw4MTkyLCExKSxZdChUYSx3YSksMiZ3YSYmT2JqZWN0LmZyZWV6ZShUYSl9cmV0dXJuIGRuKHdhKXx8KHhhPXdhLCh3YT0oRWE9U2E9PT0xKT9XdCh3YSwyLCEwKTpXdCh3YSwzMiwhMSkpIT09eGEmJll0KFRhLHdhKSxFYSYmT2JqZWN0LmZyZWV6ZShUYSkpLFNhPT09MiYmZG4od2EpJiYoVGE9QnQoVGEpLHdhPVNuKHdhLGJhLCExKSxZdChUYSx3YSksc24oaGEsYmEsYWEsVGEpKSxUYX1mdW5jdGlvbiB1bihoYSxhYSx4YSl7cmV0dXJuIGhhPW5uKGhhLGFhLHhhKSxBcnJheS5pc0FycmF5KGhhKT9oYTpRdH1mdW5jdGlvbiBsbihoYSxhYSx4YSl7cmV0dXJuIGhhPT09MCYmKGhhPVNuKGhhLGFhLHhhKSksV3QoaGEsMSwhMCl9ZnVuY3Rpb24gZG4oaGEpe3JldHVybiEhKDImaGEpJiYhISg0JmhhKXx8ISEoMjA0OCZoYSl9ZnVuY3Rpb24gZm4oaGEpe2hhPUJ0KGhhKTtmb3IobGV0IGFhPTA7YWE8aGEubGVuZ3RoO2FhKyspe2NvbnN0IHhhPWhhW2FhXT1CdChoYVthYV0pO0FycmF5LmlzQXJyYXkoeGFbMV0pJiYoeGFbMV09JHQoeGFbMV0pKX1yZXR1cm4gaGF9ZnVuY3Rpb24gcG4oaGEsYWEseGEpe3tjb25zdCB3YT1oYS51O2xldCBFYT1LdCh3YSk7aWYoYWUoRWEpLHhhPT1udWxsKXNuKHdhLEVhLGFhKTtlbHNle3ZhciBiYSxTYT1oYT16dCh4YSksVGE9ISEoMiZoYSl8fE9iamVjdC5pc0Zyb3plbih4YSk7aWYoKGJhPSFUYSkmJihiYT0hMSksISg0JmhhKSlmb3IoaGE9MjEsVGEmJih4YT1CdCh4YSksU2E9MCxoYT1TbihoYSxFYSwhMCkpLFRhPTA7VGE8eGEubGVuZ3RoO1RhKyspeGFbVGFdPWJlKHhhW1RhXSk7YmEmJih4YT1CdCh4YSksU2E9MCxoYT1TbihoYSxFYSwhMCkpLGhhIT09U2EmJll0KHhhLGhhKSxzbih3YSxFYSxhYSx4YSl9fX1mdW5jdGlvbiBnbihoYSxhYSx4YSxiYSl7aGE9aGEudTtsZXQgU2E9S3QoaGEpO2FlKFNhKSxzbihoYSxTYSxhYSwoYmE9PT0iMCI/TnVtYmVyKHhhKT09PTA6eGE9PT1iYSk/dm9pZCAwOnhhKX1mdW5jdGlvbiBtbihoYSxhYSx4YSxiYSl7Y29uc3QgU2E9S3QoaGEpO2FlKFNhKSxoYT1vbihoYSxTYSxhYSwyKSxiYT14YShiYSwhISg0JihhYT16dChoYSkpKSYmISEoNDA5NiZhYSkpLGhhLnB1c2goYmEpfWZ1bmN0aW9uIHluKGhhKXtyZXR1cm4gaGF9ZnVuY3Rpb24gX24oaGEsYWEpe3JldHVybiB2bihoYT1oYS51LEt0KGhhKSxkaSk9PT1hYT9hYTotMX1mdW5jdGlvbiB2bihoYSxhYSx4YSl7bGV0IGJhPTA7Zm9yKGxldCBTYT0wO1NhPHhhLmxlbmd0aDtTYSsrKXtjb25zdCBUYT14YVtTYV07bm4oaGEsYWEsVGEpIT1udWxsJiYoYmEhPT0wJiYoYWE9c24oaGEsYWEsYmEpKSxiYT1UYSl9cmV0dXJuIGJhfWZ1bmN0aW9uIEVuKGhhLGFhLHhhLGJhKXtsZXQgU2E9S3QoaGEpO2FlKFNhKTtjb25zdCBUYT1ubihoYSxTYSx4YSxiYSk7bGV0IHdhO2lmKFRhIT1udWxsJiZUYS5YPT09dGUpcmV0dXJuKGFhPXRuKFRhKSkhPT1UYSYmc24oaGEsU2EseGEsYWEsYmEpLGFhLnU7aWYoQXJyYXkuaXNBcnJheShUYSkpe2NvbnN0IEVhPXp0KFRhKTt3YT0yJkVhP1FlKFRhLEVhLCExKTpUYSx3YT1PZSh3YSxhYSl9ZWxzZSB3YT1PZSh2b2lkIDAsYWEpO3JldHVybiB3YSE9PVRhJiZzbihoYSxTYSx4YSx3YSxiYSksd2F9ZnVuY3Rpb24gd24oaGEsYWEseGEsYmEpe2hhPWhhLnU7bGV0IFNhPUt0KGhhKTtjb25zdCBUYT1ubihoYSxTYSx4YSxiYSk7cmV0dXJuKGFhPVNlKFRhLGFhLCExLFNhKSkhPT1UYSYmYWEhPW51bGwmJnNuKGhhLFNhLHhhLGFhLGJhKSxhYX1mdW5jdGlvbiBUbihoYSxhYSx4YSxiYT0hMSl7aWYoKGFhPXduKGhhLGFhLHhhLGJhKSk9PW51bGwpcmV0dXJuIGFhO2hhPWhhLnU7bGV0IFNhPUt0KGhhKTtpZighKDImU2EpKXtjb25zdCBUYT10bihhYSk7VGEhPT1hYSYmc24oaGEsU2EseGEsYWE9VGEsYmEpfXJldHVybiBhYX1mdW5jdGlvbiBBbihoYSxhYSx4YSxiYSxTYSxUYSl7dmFyIHdhPSEhKDImYWEpLEVhPXdhPzE6Mjtjb25zdCBrYT1FYT09PTE7RWE9RWE9PT0yLFNhPSEhU2EsVGEmJihUYT0hd2EpLHdhPXVuKGhhLGFhLGJhKTt2YXIgQWE9enQod2EpO2NvbnN0IEZhPSEhKDQmQWEpO2lmKCFGYSl7dmFyIExhPXdhLGVsPWFhO2NvbnN0IHRsPSEhKDImKEFhPWxuKEFhLGFhLFNhKSkpO3RsJiYoZWw9V3QoZWwsMiwhMCkpO2xldCBubD0hdGwsc2w9ITAscmw9MCxvbD0wO2Zvcig7cmw8TGEubGVuZ3RoO3JsKyspe2NvbnN0IGFsPVNlKExhW3JsXSx4YSwhMSxlbCk7aWYoYWwgaW5zdGFuY2VvZiB4YSl7aWYoIXRsKXtjb25zdCBsbD0hISgyJnp0KGFsLnUpKTtubCYmKG5sPSFsbCksc2wmJihzbD1sbCl9TGFbb2wrK109YWx9fW9sPHJsJiYoTGEubGVuZ3RoPW9sKSxBYT1XdChBYSw0LCEwKSxBYT1XdChBYSwxNixzbCksQWE9V3QoQWEsOCxubCksWXQoTGEsQWEpLHRsJiZPYmplY3QuZnJlZXplKExhKX1pZih4YT0hISg4JkFhKXx8a2EmJiF3YS5sZW5ndGgsVGEmJiF4YSl7Zm9yKGRuKEFhKSYmKHdhPUJ0KHdhKSxBYT1TbihBYSxhYSxTYSksYWE9c24oaGEsYWEsYmEsd2EpKSxUYT13YSx4YT1BYSxMYT0wO0xhPFRhLmxlbmd0aDtMYSsrKShBYT1UYVtMYV0pIT09KGVsPXRuKEFhKSkmJihUYVtMYV09ZWwpO3hhPVd0KHhhLDgsITApLHhhPVd0KHhhLDE2LCFUYS5sZW5ndGgpLFl0KFRhLHhhKSxBYT14YX1yZXR1cm4gZG4oQWEpfHwoVGE9QWEsa2E/QWE9V3QoQWEsIXdhLmxlbmd0aHx8MTYmQWEmJighRmF8fDMyJkFhKT8yOjIwNDgsITApOlNhfHwoQWE9V3QoQWEsMzIsITEpKSxBYSE9PVRhJiZZdCh3YSxBYSksa2EmJk9iamVjdC5mcmVlemUod2EpKSxFYSYmZG4oQWEpJiYod2E9QnQod2EpLEFhPVNuKEFhLGFhLFNhKSxZdCh3YSxBYSksc24oaGEsYWEsYmEsd2EpKSx3YX1mdW5jdGlvbiBibihoYSxhYSx4YSl7aGE9aGEudTtjb25zdCBiYT1LdChoYSk7cmV0dXJuIEFuKGhhLGJhLGFhLHhhLCExLCEoMiZiYSkpfWZ1bmN0aW9uIGtuKGhhLGFhLHhhLGJhLFNhKXtyZXR1cm4gYmE9PW51bGwmJihiYT12b2lkIDApLHJuKGhhLHhhLGJhLFNhKX1mdW5jdGlvbiB4bihoYSxhYSx4YSxiYSl7YmE9PW51bGwmJihiYT12b2lkIDApLGhhPWhhLnU7bGV0IFNhPUt0KGhhKTthZShTYSksKHhhPXZuKGhhLFNhLHhhKSkmJnhhIT09YWEmJmJhIT1udWxsJiYoU2E9c24oaGEsU2EseGEpKSxzbihoYSxTYSxhYSxiYSl9ZnVuY3Rpb24gU24oaGEsYWEseGEpe3JldHVybiBoYT1XdChoYSwyLCEhKDImYWEpKSxoYT1XdChoYSwzMiwhISgzMiZhYSkmJnhhKSxXdChoYSwyMDQ4LCExKX1mdW5jdGlvbiBMbihoYSxhYSx4YSxiYSl7aGE9aGEudTtjb25zdCBTYT1LdChoYSk7YWUoU2EpLGFhPUFuKGhhLFNhLHhhLGFhLCEwKSx4YT1iYT8/bmV3IHhhLGFhLnB1c2goeGEpLDImenQoeGEudSk/SHQoYWEsOCk6SHQoYWEsMTYpfWZ1bmN0aW9uIEZuKGhhLGFhKXtyZXR1cm4geWUoZW4oaGEsYWEpKX1mdW5jdGlvbiBSbihoYSxhYSl7cmV0dXJuIHhlKGVuKGhhLGFhKSl9ZnVuY3Rpb24gTW4oaGEpe3JldHVybiBoYT8/MH1mdW5jdGlvbiBQbihoYSxhYSl7cmV0dXJuIE1uKGFuKGhhLGFhKSl9ZnVuY3Rpb24gT24oaGEsYWEseGEpe2lmKHhhIT1udWxsJiZ0eXBlb2YgeGEhPSJib29sZWFuIil0aHJvdyBoYT10eXBlb2YgeGEsRXJyb3IoYEV4cGVjdGVkIGJvb2xlYW4gYnV0IGdvdCAke2hhIT0ib2JqZWN0Ij9oYTp4YT9BcnJheS5pc0FycmF5KHhhKT8iYXJyYXkiOmhhOiJudWxsIn06ICR7eGF9YCk7cm4oaGEsYWEseGEpfWZ1bmN0aW9uIENuKGhhLGFhLHhhKXtpZih4YSE9bnVsbCl7aWYodHlwZW9mIHhhIT0ibnVtYmVyInx8IU51bWJlci5pc0Zpbml0ZSh4YSkpdGhyb3cgZGUoImludDMyIik7eGF8PTB9cm4oaGEsYWEseGEpfWZ1bmN0aW9uIEluKGhhLGFhLHhhKXtpZih4YSE9bnVsbCYmdHlwZW9mIHhhIT0ibnVtYmVyIil0aHJvdyBFcnJvcihgVmFsdWUgb2YgZmxvYXQvZG91YmxlIGZpZWxkIG11c3QgYmUgYSBudW1iZXIsIGZvdW5kICR7dHlwZW9mIHhhfTogJHt4YX1gKTtybihoYSxhYSx4YSl9ZnVuY3Rpb24gRG4oaGEsYWEseGEpe2FhLmc/YWEubShoYSxhYS5nLGFhLmgseGEsITApOmFhLm0oaGEsYWEuaCx4YSwhMCl9amUucHJvdG90eXBlLnRvSlNPTj12b2lkIDAsamUucHJvdG90eXBlLkphPWVlO3ZhciBObj1jbGFzc3tjb25zdHJ1Y3RvcihoYSxhYSl7dGhpcy51PUNlKGhhLGFhKX10b0pTT04oKXtyZXR1cm4gVW4odGhpcyxZZSh0aGlzLnUscWUsdm9pZCAwLHZvaWQgMCwhMSksITApfWwoKXt2YXIgaGE9bW87cmV0dXJuIGhhLmc/aGEubCh0aGlzLGhhLmcsaGEuaCwhMCk6aGEubCh0aGlzLGhhLmgsaGEuZGVmYXVsdFZhbHVlLCEwKX1jbG9uZSgpe2NvbnN0IGhhPXRoaXMudTtyZXR1cm4gWmUodGhpcyxoYSxLdChoYSksITEpfU4oKXtyZXR1cm4hISgyJnp0KHRoaXMudSkpfX07ZnVuY3Rpb24gVW4oaGEsYWEseGEpe3ZhciBiYT1kP3ZvaWQgMDpoYS5jb25zdHJ1Y3Rvci5BO2NvbnN0IFNhPUt0KHhhP2hhLnU6YWEpO2lmKCEoaGE9YWEubGVuZ3RoKSlyZXR1cm4gYWE7bGV0IFRhLHdhO2lmKHJlKHhhPWFhW2hhLTFdKSl7ZTp7dmFyIEVhPXhhO2xldCBGYT17fSxMYT0hMTtmb3IodmFyIGthIGluIEVhKXtsZXQgZWw9RWFba2FdO2lmKEFycmF5LmlzQXJyYXkoZWwpKXtsZXQgdGw9ZWw7KGllKGVsLGJhLCtrYSl8fG5lKGVsKSYmZWwuc2l6ZT09PTApJiYoZWw9bnVsbCksZWwhPXRsJiYoTGE9ITApfWVsIT1udWxsP0ZhW2thXT1lbDpMYT0hMH1pZihMYSl7Zm9yKHZhciBBYSBpbiBGYSl7RWE9RmE7YnJlYWsgZX1FYT1udWxsfX1FYSE9eGEmJihUYT0hMCksaGEtLX1mb3Ioa2E9KyEhKDUxMiZTYSktMTswPGhhJiYoeGE9YWFbQWE9aGEtMV0sQWEtPWthLHhhPT1udWxsfHxpZSh4YSxiYSxBYSl8fG5lKHhhKSYmeGEuc2l6ZT09PTApO2hhLS0pd2E9ITA7cmV0dXJuKFRhfHx3YSkmJihhYT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhYSwwLGhhKSxFYSYmYWEucHVzaChFYSkpLGFhfWZ1bmN0aW9uIEJuKGhhKXtyZXR1cm4gQXJyYXkuaXNBcnJheShoYSk/aGFbMF1pbnN0YW5jZW9mIFV0P2hhOltHcixoYV06W2hhLHZvaWQgMF19ZnVuY3Rpb24gR24oaGEsYWEpe2lmKEFycmF5LmlzQXJyYXkoYWEpKXt2YXIgeGE9enQoYWEpO2lmKDQmeGEpcmV0dXJuIGFhO2Zvcih2YXIgYmE9MCxTYT0wO2JhPGFhLmxlbmd0aDtiYSsrKXtjb25zdCBUYT1oYShhYVtiYV0pO1RhIT1udWxsJiYoYWFbU2ErK109VGEpfXJldHVybiBTYTxiYSYmKGFhLmxlbmd0aD1TYSksWXQoYWEsLTEyMjg5Jig1fHhhKSksMiZ4YSYmT2JqZWN0LmZyZWV6ZShhYSksYWF9fU5uLnByb3RvdHlwZS5YPXRlLE5uLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiBVbih0aGlzLHRoaXMudSwhMSkudG9TdHJpbmcoKX07Y29uc3Qgam49U3ltYm9sKCk7ZnVuY3Rpb24gVm4oaGEpe2xldCBhYT1oYVtqbl07aWYoIWFhKXtjb25zdCB4YT1xbihoYSksYmE9aHIoaGEpLFNhPWJhLmw7YWE9U2E/KFRhLHdhKT0+U2EoVGEsd2EsYmEpOihUYSx3YSk9Pntmb3IoO2d0KHdhKSYmd2EuaCE9NDspe3ZhciBFYT13YS5tLGthPWJhW0VhXTtpZigha2Epe3ZhciBBYT1iYS5lYTtBYSYmKEFhPUFhW0VhXSkmJihrYT1iYVtFYV09WG4oQWEpKX1rYSYma2Eod2EsVGEsRWEpfHwoRWE9KGthPXdhKS5sLG10KGthKSxrYS5pYT9rYT12b2lkIDA6KEFhPWthLmcuZy1FYSxrYS5nLmc9RWEsa2E9ZnQoa2EuZyxBYSkpLEVhPVRhLGthJiYoY2V8fChjZT1TeW1ib2woKSksKEFhPUVhW2NlXSk/QWEucHVzaChrYSk6RWFbY2VdPVtrYV0pKX14YT09PVdufHx4YT09PXpufHx4YS5qfHwoVGFbdWV8fCh1ZT1TeW1ib2woKSldPXhhKX0saGFbam5dPWFhfXJldHVybiBhYX1mdW5jdGlvbiBYbihoYSl7Y29uc3QgYWE9KGhhPUJuKGhhKSlbMF0uZztpZihoYT1oYVsxXSl7Y29uc3QgeGE9Vm4oaGEpLGJhPWhyKGhhKS5UO3JldHVybihTYSxUYSx3YSk9PmFhKFNhLFRhLHdhLGJhLHhhKX1yZXR1cm4gYWF9Y2xhc3MgSG57fWxldCBXbix6bjtjb25zdCBLbj1TeW1ib2woKTtmdW5jdGlvbiBZbihoYSxhYSx4YSl7Y29uc3QgYmE9eGFbMV07bGV0IFNhO2lmKGJhKXtjb25zdCBUYT1iYVtLbl07U2E9VGE/VGEuVDpQZShiYVswXSksaGFbYWFdPVRhPz9iYX1TYSYmU2E9PT1SZT8oaGEuZ3x8KGhhLmc9bmV3IFNldCkpLmFkZChhYSk6eGFbMF0mJihoYS5ofHwoaGEuaD1uZXcgU2V0KSkuYWRkKGFhKX1mdW5jdGlvbiAkbihoYSxhYSl7cmV0dXJuW2hhLmwsIWFhfHwwPGFhWzBdP3ZvaWQgMDphYV19ZnVuY3Rpb24gcW4oaGEpe3ZhciBhYT1oYVtLbl07aWYoYWEpcmV0dXJuIGFhO2lmKCEoYWE9Wm4oaGEsaGFbS25dPW5ldyBIbiwkbiwkbixZbikpLmVhJiYhYWEuaCYmIWFhLmcpe2xldCB4YT0hMDtmb3IobGV0IGJhIGluIGFhKWlzTmFOKGJhKXx8KHhhPSExKTt4YT8oUGUoaGFbMF0pPT09UmU/em4/YWE9em46KChhYT1uZXcgSG4pLlQ9UGUoITApLGFhPXpuPWFhKTphYT1Xbnx8KFduPW5ldyBIbiksYWE9aGFbS25dPWFhKTphYS5qPSEwfXJldHVybiBhYX1mdW5jdGlvbiBKbihoYSxhYSx4YSl7aGFbYWFdPXhhfWZ1bmN0aW9uIFpuKGhhLGFhLHhhLGJhLFNhPUpuKXthYS5UPVBlKGhhWzBdKTtsZXQgVGE9MDt2YXIgd2E9aGFbKytUYV07d2EmJndhLmNvbnN0cnVjdG9yPT09T2JqZWN0JiYoYWEuZWE9d2EsdHlwZW9mKHdhPWhhWysrVGFdKT09ImZ1bmN0aW9uIiYmKGFhLmw9d2EsYWEubT1oYVsrK1RhXSx3YT1oYVsrK1RhXSkpO2NvbnN0IEVhPXt9O2Zvcig7QXJyYXkuaXNBcnJheSh3YSkmJnR5cGVvZiB3YVswXT09Im51bWJlciImJjA8d2FbMF07KXtmb3IodmFyIGthPTA7a2E8d2EubGVuZ3RoO2thKyspRWFbd2Fba2FdXT13YTt3YT1oYVsrK1RhXX1mb3Ioa2E9MTt3YSE9PXZvaWQgMDspe2xldCBMYTt0eXBlb2Ygd2E9PSJudW1iZXIiJiYoa2ErPXdhLHdhPWhhWysrVGFdKTt2YXIgQWE9dm9pZCAwO2lmKHdhIGluc3RhbmNlb2YgVXQ/TGE9d2E6KExhPWpyLFRhLS0pLExhLnBhKXt3YT1oYVsrK1RhXSxBYT1oYTt2YXIgRmE9VGE7dHlwZW9mIHdhPT0iZnVuY3Rpb24iJiYod2E9d2EoKSxBYVtGYV09d2EpLEFhPXdhfWZvcihGYT1rYSsxLHR5cGVvZih3YT1oYVsrK1RhXSk9PSJudW1iZXIiJiYwPndhJiYoRmEtPXdhLHdhPWhhWysrVGFdKTtrYTxGYTtrYSsrKXtjb25zdCBlbD1FYVtrYV07U2EoYWEsa2EsQWE/YmEoTGEsQWEsZWwpOnhhKExhLGVsKSl9fXJldHVybiBhYX1jb25zdCBRbj1TeW1ib2woKTtmdW5jdGlvbiB0cihoYSl7bGV0IGFhPWhhW1FuXTtpZighYWEpe2NvbnN0IHhhPXNyKGhhKTthYT0oYmEsU2EpPT5scihiYSxTYSx4YSksaGFbUW5dPWFhfXJldHVybiBhYX1jb25zdCBlcj1TeW1ib2woKTtmdW5jdGlvbiBucihoYSl7cmV0dXJuIGhhLmh9ZnVuY3Rpb24gcnIoaGEsYWEpe2xldCB4YSxiYTtjb25zdCBTYT1oYS5oO3JldHVybihUYSx3YSxFYSk9PlNhKFRhLHdhLEVhLGJhfHwoYmE9c3IoYWEpLlQpLHhhfHwoeGE9dHIoYWEpKSl9ZnVuY3Rpb24gc3IoaGEpe2xldCBhYT1oYVtlcl07cmV0dXJuIGFhfHwoYWE9Wm4oaGEsaGFbZXJdPXt9LG5yLHJyKSxjcihoYSksYWEpfWNvbnN0IGlyPVN5bWJvbCgpO2Z1bmN0aW9uIG9yKGhhLGFhKXtjb25zdCB4YT1oYS5nO3JldHVybiBhYT8oYmEsU2EsVGEpPT54YShiYSxTYSxUYSxhYSk6eGF9ZnVuY3Rpb24gYXIoaGEsYWEseGEpe2NvbnN0IGJhPWhhLmc7bGV0IFNhLFRhO3JldHVybih3YSxFYSxrYSk9PmJhKHdhLEVhLGthLFRhfHwoVGE9aHIoYWEpLlQpLFNhfHwoU2E9Vm4oYWEpKSx4YSl9ZnVuY3Rpb24gaHIoaGEpe2xldCBhYT1oYVtpcl07cmV0dXJuIGFhfHwocW4oaGEpLGFhPVpuKGhhLGhhW2lyXT17fSxvcixhciksY3IoaGEpLGFhKX1mdW5jdGlvbiBjcihoYSl7aXIgaW4gaGEmJktuIGluIGhhJiZlciBpbiBoYSYmKGhhLmxlbmd0aD0wKX1mdW5jdGlvbiB1cihoYSxhYSl7dmFyIHhhPWhhW2FhXTtpZih4YSlyZXR1cm4geGE7aWYoKHhhPWhhLmVhKSYmKHhhPXhhW2FhXSkpe3ZhciBiYT0oeGE9Qm4oeGEpKVswXS5oO2lmKHhhPXhhWzFdKXtjb25zdCBTYT10cih4YSksVGE9c3IoeGEpLlQ7eGE9KHhhPWhhLm0pP3hhKFRhLFNhKTood2EsRWEsa2EpPT5iYSh3YSxFYSxrYSxUYSxTYSl9ZWxzZSB4YT1iYTtyZXR1cm4gaGFbYWFdPXhhfX1mdW5jdGlvbiBscihoYSxhYSx4YSl7Zm9yKHZhciBiYT1LdChoYSksU2E9KyEhKDUxMiZiYSktMSxUYT1oYS5sZW5ndGgsd2E9NTEyJmJhPzE6MCxFYT1UYSsoMjU2JmJhPy0xOjApO3dhPEVhO3dhKyspe2NvbnN0IGthPWhhW3dhXTtpZihrYT09bnVsbCljb250aW51ZTtjb25zdCBBYT13YS1TYSxGYT11cih4YSxBYSk7RmEmJkZhKGFhLGthLEFhKX1pZigyNTYmYmEpe2JhPWhhW1RhLTFdO2ZvcihsZXQga2EgaW4gYmEpU2E9K2thLE51bWJlci5pc05hTihTYSl8fChUYT1iYVtrYV0pIT1udWxsJiYoRWE9dXIoeGEsU2EpKSYmRWEoYWEsVGEsU2EpfWlmKGhhPWNlP2hhW2NlXTp2b2lkIDApZm9yKFB0KGFhLGFhLmcuZW5kKCkpLHhhPTA7eGE8aGEubGVuZ3RoO3hhKyspUHQoYWEsTihoYVt4YV0pfHxQKCkpfWZ1bmN0aW9uIGRyKGhhLGFhKXtyZXR1cm4gbmV3IFV0KGhhLGFhLCExLCExKX1mdW5jdGlvbiBmcihoYSxhYSl7cmV0dXJuIG5ldyBVdChoYSxhYSwhMCwhMSl9ZnVuY3Rpb24gcHIoaGEsYWEpe3JldHVybiBuZXcgVXQoaGEsYWEsITEsITApfWZ1bmN0aW9uIGdyKGhhLGFhLHhhKXtzbihoYSxLdChoYSksYWEseGEpfXZhciBtcj1wcihmdW5jdGlvbihoYSxhYSx4YSxiYSxTYSl7cmV0dXJuIGhhLmg9PT0yJiYoaGE9eXQoaGEsT2UoW3ZvaWQgMCx2b2lkIDBdLGJhKSxTYSksYWUoYmE9S3QoYWEpKSwoU2E9bm4oYWEsYmEseGEpKWluc3RhbmNlb2YgamU/MiZTYS5MPygoU2E9U2EuWSgpKS5wdXNoKGhhKSxzbihhYSxiYSx4YSxTYSkpOlNhLk9hKGhhKTpBcnJheS5pc0FycmF5KFNhKT8oMiZ6dChTYSkmJnNuKGFhLGJhLHhhLFNhPWZuKFNhKSksU2EucHVzaChoYSkpOnNuKGFhLGJhLHhhLFtoYV0pLCEwKX0sZnVuY3Rpb24oaGEsYWEseGEsYmEsU2Epe2lmKGFhIGluc3RhbmNlb2YgamUpYWEuZm9yRWFjaCgoVGEsd2EpPT57TnQoaGEseGEsT2UoW3dhLFRhXSxiYSksU2EpfSk7ZWxzZSBpZihBcnJheS5pc0FycmF5KGFhKSlmb3IobGV0IFRhPTA7VGE8YWEubGVuZ3RoO1RhKyspe2NvbnN0IHdhPWFhW1RhXTtBcnJheS5pc0FycmF5KHdhKSYmTnQoaGEseGEsT2Uod2EsYmEpLFNhKX19KTtmdW5jdGlvbiB5cihoYSxhYSx4YSl7ZTppZihhYSE9bnVsbCl7aWYobWUoYWEpKXtpZih0eXBlb2YgYWE9PSJzdHJpbmciKXthYT1UZShhYSk7YnJlYWsgZX1pZih0eXBlb2YgYWE9PSJudW1iZXIiKXthYT13ZShhYSk7YnJlYWsgZX19YWE9dm9pZCAwfWFhIT1udWxsJiYodHlwZW9mIGFhPT0ic3RyaW5nIiYma3QoYWEpLGFhIT1udWxsJiYoT3QoaGEseGEsMCksdHlwZW9mIGFhPT0ibnVtYmVyIj8oaGE9aGEuZyxZKGFhKSxMdChoYSx6LEspKTooeGE9a3QoYWEpLEx0KGhhLmcseGEuaCx4YS5nKSkpKX1mdW5jdGlvbiBfcihoYSxhYSx4YSl7KGFhPXllKGFhKSkhPW51bGwmJmFhIT1udWxsJiYoT3QoaGEseGEsMCksUnQoaGEuZyxhYSkpfWZ1bmN0aW9uIHZyKGhhLGFhLHhhKXsoYWE9cGUoYWEpKSE9bnVsbCYmKE90KGhhLHhhLDApLGhhLmcuZy5wdXNoKGFhPzE6MCkpfWZ1bmN0aW9uIEVyKGhhLGFhLHhhKXsoYWE9eGUoYWEpKSE9bnVsbCYmRHQoaGEseGEsYyhhYSkpfWZ1bmN0aW9uIHdyKGhhLGFhLHhhLGJhLFNhKXtOdChoYSx4YSxhYSBpbnN0YW5jZW9mIE5uP2FhLnU6QXJyYXkuaXNBcnJheShhYSk/T2UoYWEsYmEpOnZvaWQgMCxTYSl9ZnVuY3Rpb24gVHIoaGEsYWEseGEpeyhhYT1hYT09bnVsbHx8dHlwZW9mIGFhPT0ic3RyaW5nInx8UihhYSl8fGFhIGluc3RhbmNlb2YgVT9hYTp2b2lkIDApIT1udWxsJiZEdChoYSx4YSxWKGFhKS5idWZmZXIpfWZ1bmN0aW9uIEFyKGhhLGFhLHhhKXtyZXR1cm4oaGEuaD09PTV8fGhhLmg9PT0yKSYmKGFhPW9uKGFhLEt0KGFhKSx4YSwyLCExKSxoYS5oPT0yP0V0KGhhLGh0LGFhKTphYS5wdXNoKGh0KGhhLmcpKSwhMCl9dmFyIGJyLGtyPWRyKGZ1bmN0aW9uKGhhLGFhLHhhKXtpZihoYS5oIT09MSlyZXR1cm4hMTt2YXIgYmE9aGEuZztoYT1hdChiYSk7Y29uc3QgU2E9YXQoYmEpO2JhPTIqKFNhPj4zMSkrMTtjb25zdCBUYT1TYT4+PjIwJjIwNDc7cmV0dXJuIGhhPTQyOTQ5NjcyOTYqKDEwNDg1NzUmU2EpK2hhLGdyKGFhLHhhLFRhPT0yMDQ3P2hhP05hTjoxLzAqYmE6VGE9PTA/YmEqTWF0aC5wb3coMiwtMTA3NCkqaGE6YmEqTWF0aC5wb3coMixUYS0xMDc1KSooaGErNDUwMzU5OTYyNzM3MDQ5NikpLCEwfSxmdW5jdGlvbihoYSxhYSx4YSl7KGFhPWZlKGFhKSkhPW51bGwmJihPdChoYSx4YSwxKSxoYT1oYS5nLCh4YT1XfHwoVz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDgpKSkpLnNldEZsb2F0NjQoMCwrYWEsITApLHo9eGEuZ2V0VWludDMyKDAsITApLEs9eGEuZ2V0VWludDMyKDQsITApLE10KGhhLHopLE10KGhhLEspKX0pLHhyPWRyKGZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gaGEuaD09PTUmJihncihhYSx4YSxodChoYS5nKSksITApfSxmdW5jdGlvbihoYSxhYSx4YSl7KGFhPWZlKGFhKSkhPW51bGwmJihPdChoYSx4YSw1KSxoYT1oYS5nLCQoYWEpLE10KGhhLHopKX0pLFNyPWZyKEFyLGZ1bmN0aW9uKGhhLGFhLHhhKXtpZigoYWE9R24oZmUsYWEpKSE9bnVsbClmb3IobGV0IHdhPTA7d2E8YWEubGVuZ3RoO3dhKyspe3ZhciBiYT1oYSxTYT14YSxUYT1hYVt3YV07VGEhPW51bGwmJihPdChiYSxTYSw1KSxiYT1iYS5nLCQoVGEpLE10KGJhLHopKX19KSxMcj1mcihBcixmdW5jdGlvbihoYSxhYSx4YSl7aWYoKGFhPUduKGZlLGFhKSkhPW51bGwmJmFhLmxlbmd0aCl7T3QoaGEseGEsMiksRnQoaGEuZyw0KmFhLmxlbmd0aCk7Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aDtiYSsrKXhhPWhhLmcsJChhYVtiYV0pLE10KHhhLHopfX0pLEZyPWRyKGZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gaGEuaD09PTAmJihncihhYSx4YSxydChoYS5nLEopKSwhMCl9LHlyKSxScj1kcihmdW5jdGlvbihoYSxhYSx4YSl7cmV0dXJuIGhhLmg9PT0wJiYoZ3IoYWEseGEsKGhhPXJ0KGhhLmcsSikpPT09MD92b2lkIDA6aGEpLCEwKX0seXIpLE1yPWRyKGZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gaGEuaD09PTAmJihncihhYSx4YSxydChoYS5nLHEpKSwhMCl9LGZ1bmN0aW9uKGhhLGFhLHhhKXtlOmlmKGFhIT1udWxsKXtpZihtZShhYSkpe2lmKHR5cGVvZiBhYT09InN0cmluZyIpe3ZhciBiYT1NYXRoLnRydW5jKE51bWJlcihhYSkpO051bWJlci5pc1NhZmVJbnRlZ2VyKGJhKSYmMDw9YmE/YWE9U3RyaW5nKGJhKTooKGJhPWFhLmluZGV4T2YoIi4iKSkhPT0tMSYmKGFhPWFhLnN1YnN0cmluZygwLGJhKSksdmUoYWEpfHwoZXQoYWEpLGFhPVooeixLKSkpO2JyZWFrIGV9aWYodHlwZW9mIGFhPT0ibnVtYmVyIil7YWE9MDw9KGFhPU1hdGgudHJ1bmMoYWEpKSYmTnVtYmVyLmlzU2FmZUludGVnZXIoYWEpP2FhOmZ1bmN0aW9uKFNhKXtpZigwPlNhKXtZKFNhKTtjb25zdCBUYT1aKHosSyk7cmV0dXJuIFNhPU51bWJlcihUYSksTnVtYmVyLmlzU2FmZUludGVnZXIoU2EpP1NhOlRhfXJldHVybiB2ZShTdHJpbmcoU2EpKT9TYTooWShTYSkscSh6LEspKX0oYWEpO2JyZWFrIGV9fWFhPXZvaWQgMH1hYSE9bnVsbCYmKHR5cGVvZiBhYT09InN0cmluZyImJlR0KGFhKSxhYSE9bnVsbCYmKE90KGhhLHhhLDApLHR5cGVvZiBhYT09Im51bWJlciI/KGhhPWhhLmcsWShhYSksTHQoaGEseixLKSk6KHhhPVR0KGFhKSxMdChoYS5nLHhhLmgseGEuZykpKSl9KSxQcj1kcihmdW5jdGlvbihoYSxhYSx4YSl7cmV0dXJuIGhhLmg9PT0wJiYoZ3IoYWEseGEsaXQoaGEuZykpLCEwKX0sX3IpLE9yPWZyKGZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4oaGEuaD09PTB8fGhhLmg9PT0yKSYmKGFhPW9uKGFhLEt0KGFhKSx4YSwyLCExKSxoYS5oPT0yP0V0KGhhLGl0LGFhKTphYS5wdXNoKGl0KGhhLmcpKSwhMCl9LGZ1bmN0aW9uKGhhLGFhLHhhKXtpZigoYWE9R24oeWUsYWEpKSE9bnVsbCYmYWEubGVuZ3RoKXt4YT1DdChoYSx4YSk7Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aDtiYSsrKVJ0KGhhLmcsYWFbYmFdKTtJdChoYSx4YSl9fSksQ3I9ZHIoZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiBoYS5oPT09MCYmKGdyKGFhLHhhLChoYT1pdChoYS5nKSk9PT0wP3ZvaWQgMDpoYSksITApfSxfciksSXI9ZHIoZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiBoYS5oPT09MCYmKGdyKGFhLHhhLHN0KGhhLmcpKSwhMCl9LHZyKSxEcj1kcihmdW5jdGlvbihoYSxhYSx4YSl7cmV0dXJuIGhhLmg9PT0wJiYoZ3IoYWEseGEsKGhhPXN0KGhhLmcpKT09PSExP3ZvaWQgMDpoYSksITApfSx2ciksTnI9ZnIoZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiBoYS5oPT09MiYmKG1uKGFhLHhhLHluLGhhPV90KGhhKSksITApfSxmdW5jdGlvbihoYSxhYSx4YSl7aWYoKGFhPUduKHhlLGFhKSkhPW51bGwpZm9yKGxldCB3YT0wO3dhPGFhLmxlbmd0aDt3YSsrKXt2YXIgYmE9aGEsU2E9eGEsVGE9YWFbd2FdO1RhIT1udWxsJiZEdChiYSxTYSxjKFRhKSl9fSksVXI9ZHIoZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiBoYS5oPT09MiYmKGdyKGFhLHhhLChoYT1fdChoYSkpPT09IiI/dm9pZCAwOmhhKSwhMCl9LEVyKSxCcj1kcihmdW5jdGlvbihoYSxhYSx4YSl7cmV0dXJuIGhhLmg9PT0yJiYoZ3IoYWEseGEsX3QoaGEpKSwhMCl9LEVyKSxHcj1wcihmdW5jdGlvbihoYSxhYSx4YSxiYSxTYSl7cmV0dXJuIGhhLmg9PT0yJiYoeXQoaGEsRW4oYWEsYmEseGEsITApLFNhKSwhMCl9LHdyKSxqcj1wcihmdW5jdGlvbihoYSxhYSx4YSxiYSxTYSl7cmV0dXJuIGhhLmg9PT0yJiYoeXQoaGEsRW4oYWEsYmEseGEpLFNhKSwhMCl9LHdyKTticj1uZXcgVXQoZnVuY3Rpb24oaGEsYWEseGEsYmEsU2Epe2lmKGhhLmghPT0yKXJldHVybiExO2JhPU9lKHZvaWQgMCxiYSk7bGV0IFRhPUt0KGFhKTthZShUYSk7bGV0IHdhPW9uKGFhLFRhLHhhLDMpO3JldHVybiBUYT1LdChhYSksNCZ6dCh3YSkmJih3YT1CdCh3YSksWXQod2EsLTIwNzkmKDF8enQod2EpKSksc24oYWEsVGEseGEsd2EpKSx3YS5wdXNoKGJhKSx5dChoYSxiYSxTYSksITB9LGZ1bmN0aW9uKGhhLGFhLHhhLGJhLFNhKXtpZihBcnJheS5pc0FycmF5KGFhKSlmb3IobGV0IFRhPTA7VGE8YWEubGVuZ3RoO1RhKyspd3IoaGEsYWFbVGFdLHhhLGJhLFNhKX0sITAsITApO3ZhciBWcj1wcihmdW5jdGlvbihoYSxhYSx4YSxiYSxTYSxUYSl7aWYoaGEuaCE9PTIpcmV0dXJuITE7bGV0IHdhPUt0KGFhKTtyZXR1cm4gYWUod2EpLChUYT12bihhYSx3YSxUYSkpJiZ4YSE9PVRhJiZzbihhYSx3YSxUYSkseXQoaGEsYWE9RW4oYWEsYmEseGEpLFNhKSwhMH0sd3IpLFhyPWRyKGZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4gaGEuaD09PTImJihncihhYSx4YSx2dChoYSkpLCEwKX0sVHIpLEhyPWZyKGZ1bmN0aW9uKGhhLGFhLHhhKXtyZXR1cm4oaGEuaD09PTB8fGhhLmg9PT0yKSYmKGFhPW9uKGFhLEt0KGFhKSx4YSwyLCExKSxoYS5oPT0yP0V0KGhhLG90LGFhKTphYS5wdXNoKG90KGhhLmcpKSwhMCl9LGZ1bmN0aW9uKGhhLGFhLHhhKXtpZigoYWE9R24oX2UsYWEpKSE9bnVsbClmb3IobGV0IHdhPTA7d2E8YWEubGVuZ3RoO3dhKyspe3ZhciBiYT1oYSxTYT14YSxUYT1hYVt3YV07VGEhPW51bGwmJihPdChiYSxTYSwwKSxGdChiYS5nLFRhKSl9fSksV3I9ZHIoZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiBoYS5oPT09MCYmKGdyKGFhLHhhLGl0KGhhLmcpKSwhMCl9LGZ1bmN0aW9uKGhhLGFhLHhhKXsoYWE9eWUoYWEpKSE9bnVsbCYmKGFhPXBhcnNlSW50KGFhLDEwKSxPdChoYSx4YSwwKSxSdChoYS5nLGFhKSl9KSx6cj1mcihmdW5jdGlvbihoYSxhYSx4YSl7cmV0dXJuKGhhLmg9PT0wfHxoYS5oPT09MikmJihhYT1vbihhYSxLdChhYSkseGEsMiwhMSksaGEuaD09Mj9FdChoYSxjdCxhYSk6YWEucHVzaChpdChoYS5nKSksITApfSxmdW5jdGlvbihoYSxhYSx4YSl7aWYoKGFhPUduKHllLGFhKSkhPW51bGwmJmFhLmxlbmd0aCl7eGE9Q3QoaGEseGEpO2ZvcihsZXQgYmE9MDtiYTxhYS5sZW5ndGg7YmErKylSdChoYS5nLGFhW2JhXSk7SXQoaGEseGEpfX0pO2NsYXNzIEtye2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLmg9YWEsdGhpcy5nPXhhLHRoaXMubD1Ubix0aGlzLm09a24sdGhpcy5kZWZhdWx0VmFsdWU9dm9pZCAwfX1mdW5jdGlvbiBZcihoYSxhYSl7cmV0dXJuIG5ldyBLcihoYSxhYSl9ZnVuY3Rpb24gJHIoaGEsYWEpe3JldHVybih4YSxiYSk9PntlOntpZih3dC5sZW5ndGgpe2NvbnN0IFRhPXd0LnBvcCgpO1RhLm8oYmEpLHV0KFRhLmcseGEsYmEpLHhhPVRhfWVsc2UgeGE9bmV3IGNsYXNze2NvbnN0cnVjdG9yKFRhLHdhKXtpZihwdC5sZW5ndGgpe2NvbnN0IEVhPXB0LnBvcCgpO3V0KEVhLFRhLHdhKSxUYT1FYX1lbHNlIFRhPW5ldyBjbGFzc3tjb25zdHJ1Y3RvcihFYSxrYSl7dGhpcy5oPW51bGwsdGhpcy5tPSExLHRoaXMuZz10aGlzLmw9dGhpcy5qPTAsdXQodGhpcyxFYSxrYSl9Y2xlYXIoKXt0aGlzLmg9bnVsbCx0aGlzLm09ITEsdGhpcy5nPXRoaXMubD10aGlzLmo9MCx0aGlzLmNhPSExfX0oVGEsd2EpO3RoaXMuZz1UYSx0aGlzLmw9dGhpcy5nLmcsdGhpcy5oPXRoaXMubT0tMSx0aGlzLm8od2EpfW8oe2lhOlRhPSExfT17fSl7dGhpcy5pYT1UYX19KHhhLGJhKTt0cnl7Y29uc3QgVGE9bmV3IGhhLHdhPVRhLnU7Vm4oYWEpKHdhLHhhKTt2YXIgU2E9VGE7YnJlYWsgZX1maW5hbGx5e3hhLmcuY2xlYXIoKSx4YS5tPS0xLHhhLmg9LTEsMTAwPnd0Lmxlbmd0aCYmd3QucHVzaCh4YSl9U2E9dm9pZCAwfXJldHVybiBTYX19ZnVuY3Rpb24gcXIoaGEpe3JldHVybiBmdW5jdGlvbigpe2NvbnN0IGFhPW5ldyBjbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMubD1bXSx0aGlzLmg9MCx0aGlzLmc9bmV3IGNsYXNze2NvbnN0cnVjdG9yKCl7dGhpcy5nPVtdfWxlbmd0aCgpe3JldHVybiB0aGlzLmcubGVuZ3RofWVuZCgpe2NvbnN0IHdhPXRoaXMuZztyZXR1cm4gdGhpcy5nPVtdLHdhfX19fTtscih0aGlzLnUsYWEsc3IoaGEpKSxQdChhYSxhYS5nLmVuZCgpKTtjb25zdCB4YT1uZXcgVWludDhBcnJheShhYS5oKSxiYT1hYS5sLFNhPWJhLmxlbmd0aDtsZXQgVGE9MDtmb3IobGV0IHdhPTA7d2E8U2E7d2ErKyl7Y29uc3QgRWE9YmFbd2FdO3hhLnNldChFYSxUYSksVGErPUVhLmxlbmd0aH1yZXR1cm4gYWEubD1beGFdLHhhfX12YXIgSnI9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sWnI9WzAsVXIsZHIoZnVuY3Rpb24oaGEsYWEseGEpe3JldHVybiBoYS5oPT09MiYmKGdyKGFhLHhhLChoYT12dChoYSkpPT09RCgpP3ZvaWQgMDpoYSksITApfSxmdW5jdGlvbihoYSxhYSx4YSl7aWYoYWEhPW51bGwpe2lmKGFhIGluc3RhbmNlb2YgTm4pe2NvbnN0IGJhPWFhLlFhO3JldHVybiB2b2lkKGJhJiYoYWE9YmEoYWEpLGFhIT1udWxsJiZEdChoYSx4YSxWKGFhKS5idWZmZXIpKSl9aWYoQXJyYXkuaXNBcnJheShhYSkpcmV0dXJufVRyKGhhLGFhLHhhKX0pXSxRcj1bMCxCcl0sdHM9WzAsUHIsV3IsSXIsLTEsT3IsV3IsLTFdLGVzPVswLElyLC0xXSxucz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKCl7c3VwZXIoKX19O25zLkE9WzZdO3ZhciBycz1bMCxJcixCcixJcixXciwtMSx6cixCciwtMSxlcyxXcl0sc3M9WzAsQnIsLTJdLGlzPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoKXtzdXBlcigpfX0sb3M9WzBdLGFzPVswLFByLElyLC0zXSxocz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSwyKX19LGNzPXt9LHVzPVstMixjcyxJcl07Y3NbMzM2NzgzODYzXT1bMCxCcixJciwtMSxQcixbMCxbMSwyLDMsNCw1XSxWcixvcyxWcixycyxWcixzcyxWcixhcyxWcix0c10sUXJdO3ZhciBscz1bMCxVcixEcl0sZHM9WzAsUnIsLTEsRHIsLTMsUnIsT3IsVXIsQ3IsUnIsLTEsRHIsQ3IsRHIsLTIsVXJdLGZzPVstMSx7fV0scHM9WzAsQnIsMSxmc10sZ3M9WzAsQnIsTnIsZnNdO2Z1bmN0aW9uIG1zKGhhLGFhKXtnbihoYSwyLGtlKGFhKSwiIil9ZnVuY3Rpb24geXMoaGEsYWEpe21uKGhhLnUsMyxiZSxhYSl9ZnVuY3Rpb24gX3MoaGEsYWEpe21uKGhhLnUsNCxiZSxhYSl9dmFyIHZzPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhLDUwMCl9byhoYSl7cmV0dXJuIGtuKHRoaXMsMCw3LGhhKX19O3ZzLkE9WzMsNCw1LDYsOCwxMywxNywxMDA1XTt2YXIgRXM9Wy01MDAsVXIsLTEsTnIsLTMsdXMsYnIsWnIsQ3IsLTEscHMsZ3MsYnIsbHMsVXIsZHMsQ3IsTnIsOTg3LE5yXSx3cz1bMCxVciwtMSxmc10sVHM9Wy01MDAsQnIsLTEsWy0xLHt9XSw5OTgsQnJdLEFzPVstNTAwLEJyLE5yLC0xLFstMix7fSxJcl0sOTk3LE5yLC0xXSxicz1bLTUwMCxCcixOcixmcyw5OTgsTnJdO2Z1bmN0aW9uIGtzKGhhLGFhKXtMbihoYSwxLHZzLGFhKX1mdW5jdGlvbiB4cyhoYSxhYSl7bW4oaGEudSwxMCxiZSxhYSl9ZnVuY3Rpb24gU3MoaGEsYWEpe21uKGhhLnUsMTUsYmUsYWEpfXZhciBMcz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSw1MDApfW8oaGEpe3JldHVybiBrbih0aGlzLDAsMTAwMSxoYSl9fTtMcy5BPVsxLDYsNyw5LDEwLDE1LDE2LDE3LDE0LDEwMDJdO3ZhciBGcz1bLTUwMCxicixFcyw0LGJyLFRzLGJyLEFzLENyLGJyLGJzLE5yLENyLHBzLGdzLGJyLHdzLE5yLC0yLGRzLFVyLC0xLERyLDk3OSxmcyxicixacl0sUnM9JHIoTHMsRnMpO0xzLnByb3RvdHlwZS5nPXFyKEZzKTt2YXIgTXM9WzAsYnIsWzAsUHIsLTJdXSxQcz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxPcz1bMCxQcix4cixCciwtMV0sQ3M9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfWcoKXtyZXR1cm4gYm4odGhpcyxQcywxKX19O0NzLkE9WzFdO3ZhciBJcz1bMCxicixPc10sRHM9JHIoQ3MsSXMpLE5zPVswLFByLHhyXSxVcz1bMCxQciwtMSxNc10sQnM9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sR3M9WzAsUHIsLTNdLGpzPVswLHhyLC0zXSxWcz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxYcz1bMCx4ciwtMSxCcix4cl0sSHM9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfWgoKXtyZXR1cm4gVG4odGhpcyxCcywyKX1nKCl7cmV0dXJuIGJuKHRoaXMsVnMsNSl9fTtIcy5BPVs1XTt2YXIgV3M9WzAsV3IsR3MsanMsVXMsYnIsWHNdLHpzPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19O3pzLkE9WzEsMiwzLDgsOV07dmFyIEtzPSRyKHpzLFswLE5yLE9yLExyLFdzLEJyLC0xLEZyLGJyLE5zLE5yLEZyXSksWXM9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sJHM9WzAseHIsLTRdLHFzPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19O3FzLkE9WzFdO3ZhciBKcz0kcihxcyxbMCxiciwkc10pLFpzPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LFFzPVswLHhyLC00XSx0aT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fTt0aS5BPVsxXTt2YXIgZWk9JHIodGksWzAsYnIsUXNdKSxuaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fTtuaS5BPVszXTt2YXIgcmk9WzAsUHIsLTEsTHIsV3JdLHNpPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoKXtzdXBlcigpfX07c2kucHJvdG90eXBlLmc9cXIoWzAseHIsLTQsRnJdKTt2YXIgaWk9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sb2k9WzAsMSxQcixCcixJc10sYWk9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX07YWkuQT1bMV07dmFyIGhpPSRyKGFpLFswLGJyLG9pLEZyXSksY2k9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX07Y2kuQT1bMV07dmFyIHVpPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX1xYSgpe2NvbnN0IGhhPWhuKHRoaXMpO3JldHVybiBoYT8/RCgpfX0sbGk9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sZGk9WzEsMl0sZmk9WzAsZGksVnIsWzAsTHJdLFZyLFswLFhyXSxQcixCcl0scGk9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX07cGkuQT1bMV07dmFyIGdpPSRyKHBpLFswLGJyLGZpLEZyXSksbWk9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX07bWkuQT1bNCw1XTt2YXIgeWk9WzAsQnIsUHIseHIsTnIsLTFdLF9pPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LHZpPVswLElyLC0xXSxFaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSx3aT1bMSwyLDMsNCw1XSxUaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9Zygpe3JldHVybiBobih0aGlzKSE9bnVsbH1oKCl7cmV0dXJuIFJuKHRoaXMsMikhPW51bGx9fSxBaT1bMCxYcixCcixbMCxQcixGciwtMV0sWzAsTXIsRnJdXSxiaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9Zygpe3JldHVybiBwZShlbih0aGlzLDIpKT8/ITF9fSxraT1bMCxBaSxJcixbMCx3aSxWcixhcyxWcixycyxWcix0cyxWcixvcyxWcixzc10sV3JdLHhpPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LFNpPVswLGtpLHhyLC0xLFByXSxMaT1Zcig1MDIxNDE4OTcseGkpO2NzWzUwMjE0MTg5N109U2k7dmFyIEZpPVswLEFpXTtjc1s1MTI0OTkyMDBdPUZpO3ZhciBSaT1bMCxGaV07Y3NbNTE1NzIzNTA2XT1SaTt2YXIgTWk9JHIoY2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sWzAsWzAsV3IsLTEsU3IsSHJdLHJpXSksUGk9WzAsa2ldO2NzWzUwODk4MTc2OF09UGk7dmFyIE9pPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LENpPVswLGtpLHhyLFBpLElyXSxJaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxEaT1bMCxraSxTaSxDaSx4cixSaV07Y3NbNTA4OTY4MTQ5XT1DaTt2YXIgTmk9WXIoNTA4OTY4MTUwLElpKTtjc1s1MDg5NjgxNTBdPURpO3ZhciBVaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxCaT1Zcig1MTM5MTYyMjAsVWkpO2NzWzUxMzkxNjIyMF09WzAsa2ksRGksUHJdO3ZhciBHaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9aCgpe3JldHVybiBUbih0aGlzLG1pLDIpfWcoKXtybih0aGlzLDIpfX0samk9WzAsa2kseWldO2NzWzQ3ODgyNTQ2NV09amk7dmFyIFZpPVswLGtpXTtjc1s0Nzg4MjU0MjJdPVZpO3ZhciBYaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxIaT1bMCxraSxWaSxqaSwtMV0sV2k9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0semk9WzAsa2kseHIsUHJdLEtpPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LFlpPVswLGtpLHhyXSwkaT1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxxaT1bMCxraSx6aSxZaSx4cl0sSmk9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sWmk9WzAsa2kscWksSGldO2NzWzQ2MzM3MDQ1Ml09SGksY3NbNDY0ODY0Mjg4XT16aSxjc1s0NzQ0NzI0NzBdPVlpO3ZhciBRaT1Zcig0NjI3MTMyMDIsJGkpO2NzWzQ2MjcxMzIwMl09cWk7dmFyIHRvPVlyKDQ3OTA5NzA1NCxKaSk7Y3NbNDc5MDk3MDU0XT1aaTt2YXIgZW89Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sbm89WzAsa2ldLHJvPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LHNvPVswLGtpLHhyLC0xLFByXTtjc1s1MTQ3NzQ4MTNdPXNvO3ZhciBpbz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxvbz1bMCxraSx4cixJcl07Y3NbNTE4OTI4Mzg0XT1vbzt2YXIgYW89Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3Rvcigpe3N1cGVyKCl9fTthby5wcm90b3R5cGUuZz1xcihbMCxraSxZaSxubyxTaSxDaSxzbyxvb10pO3ZhciBobz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxjbz1Zcig0NTYzODMzODMsaG8pO2NzWzQ1NjM4MzM4M109WzAsa2kseWldO3ZhciB1bz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxsbz1Zcig0NzYzNDgxODcsdW8pO2NzWzQ3NjM0ODE4N109WzAsa2ksdmldO3ZhciBmbz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxwbz1bMCxXciwtMV0sZ289Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX07Z28uQT1bM107dmFyIG1vPVlyKDQ1ODEwNTg3NixjbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9Zygpe3ZhciBoYT10aGlzLnU7Y29uc3QgYWE9S3QoaGEpO3ZhciB4YT0yJmFhO3JldHVybiBoYT1mdW5jdGlvbihiYSxTYSxUYSl7dmFyIHdhPWdvO2NvbnN0IEVhPTImU2E7bGV0IGthPSExO2lmKFRhPT1udWxsKXtpZihFYSlyZXR1cm4gemUoKTtUYT1bXX1lbHNlIGlmKFRhLmNvbnN0cnVjdG9yPT09amUpe2lmKCEoMiZUYS5MKXx8RWEpcmV0dXJuIFRhO1RhPVRhLlkoKX1lbHNlIEFycmF5LmlzQXJyYXkoVGEpP2thPSEhKDImenQoVGEpKTpUYT1bXTtpZihFYSl7aWYoIVRhLmxlbmd0aClyZXR1cm4gemUoKTtrYXx8KGthPSEwLCR0KFRhKSl9ZWxzZSBrYSYmKGthPSExLFRhPWZuKFRhKSk7cmV0dXJuIGthfHwoNjQmenQoVGEpP0h0KFRhLDMyKTozMiZTYSYmWHQoVGEsMzIpKSxzbihiYSxTYSwyLHdhPW5ldyBqZShUYSx3YSxMZSx2b2lkIDApLCExKSx3YX0oaGEsYWEsbm4oaGEsYWEsMikpLGhhPT1udWxsfHwheGEmJmdvJiYoaGEudGE9ITApLHhhPWhhfX0pO2NzWzQ1ODEwNTg3Nl09WzAscG8sbXIsWyEwLEZyLFswLEJyLC0xLE5yXV1dO3ZhciB5bz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxfbz1Zcig0NTgxMDU3NTgseW8pO2NzWzQ1ODEwNTc1OF09WzAsa2ksQnIscG9dO3ZhciB2bz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fTt2by5BPVs1LDZdO3ZhciBFbz1Zcig0NDM0NDIwNTgsdm8pO2NzWzQ0MzQ0MjA1OF09WzAsa2ksQnIsUHIseHIsTnIsLTFdO3ZhciB3bz1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxUbz1Zcig1MTY1ODcyMzAsd28pO2Z1bmN0aW9uIEFvKGhhLGFhKXtyZXR1cm4gYWE9YWE/YWEuY2xvbmUoKTpuZXcgbWksaGEuZGlzcGxheU5hbWVzTG9jYWxlIT09dm9pZCAwP3JuKGFhLDEsa2UoaGEuZGlzcGxheU5hbWVzTG9jYWxlKSk6aGEuZGlzcGxheU5hbWVzTG9jYWxlPT09dm9pZCAwJiZybihhYSwxKSxoYS5tYXhSZXN1bHRzIT09dm9pZCAwP0NuKGFhLDIsaGEubWF4UmVzdWx0cyk6Im1heFJlc3VsdHMiaW4gaGEmJnJuKGFhLDIpLGhhLnNjb3JlVGhyZXNob2xkIT09dm9pZCAwP0luKGFhLDMsaGEuc2NvcmVUaHJlc2hvbGQpOiJzY29yZVRocmVzaG9sZCJpbiBoYSYmcm4oYWEsMyksaGEuY2F0ZWdvcnlBbGxvd2xpc3QhPT12b2lkIDA/cG4oYWEsNCxoYS5jYXRlZ29yeUFsbG93bGlzdCk6ImNhdGVnb3J5QWxsb3dsaXN0ImluIGhhJiZybihhYSw0KSxoYS5jYXRlZ29yeURlbnlsaXN0IT09dm9pZCAwP3BuKGFhLDUsaGEuY2F0ZWdvcnlEZW55bGlzdCk6ImNhdGVnb3J5RGVueWxpc3QiaW4gaGEmJnJuKGFhLDUpLGFhfWZ1bmN0aW9uIGJvKGhhLGFhPS0xLHhhPSIiKXtyZXR1cm57Y2F0ZWdvcmllczpoYS5tYXAoYmE9Pih7aW5kZXg6TW4oRm4oYmEsMSkpPz8tMSxzY29yZTpQbihiYSwyKT8/MCxjYXRlZ29yeU5hbWU6Um4oYmEsMyk/PyIiPz8iIixkaXNwbGF5TmFtZTpSbihiYSw0KT8/IiI/PyIifSkpLGhlYWRJbmRleDphYSxoZWFkTmFtZTp4YX19ZnVuY3Rpb24ga28oaGEpe3ZhciB3YSxFYTt2YXIgYWE9Y24oaGEsMyxmZSkseGE9Y24oaGEsMix5ZSksYmE9Y24oaGEsMSx4ZSksU2E9Y24oaGEsOSx4ZSk7Y29uc3QgVGE9e2NhdGVnb3JpZXM6W10sa2V5cG9pbnRzOltdfTtmb3IobGV0IGthPTA7a2E8YWEubGVuZ3RoO2thKyspVGEuY2F0ZWdvcmllcy5wdXNoKHtzY29yZTphYVtrYV0saW5kZXg6eGFba2FdPz8tMSxjYXRlZ29yeU5hbWU6YmFba2FdPz8iIixkaXNwbGF5TmFtZTpTYVtrYV0/PyIifSk7aWYoKGFhPSh3YT1UbihoYSxIcyw0KSk9PW51bGw/dm9pZCAwOndhLmgoKSkmJihUYS5ib3VuZGluZ0JveD17b3JpZ2luWDpGbihhYSwxKT8/MCxvcmlnaW5ZOkZuKGFhLDIpPz8wLHdpZHRoOkZuKGFhLDMpPz8wLGhlaWdodDpGbihhYSw0KT8/MCxhbmdsZTowfSksKEVhPVRuKGhhLEhzLDQpKT09bnVsbD92b2lkIDA6RWEuZygpLmxlbmd0aClmb3IoY29uc3Qga2Egb2YgVG4oaGEsSHMsNCkuZygpKVRhLmtleXBvaW50cy5wdXNoKHt4OmFuKGthLDEpPz8wLHk6YW4oa2EsMik/PzAsc2NvcmU6YW4oa2EsNCk/PzAsbGFiZWw6Um4oa2EsMyk/PyIifSk7cmV0dXJuIFRhfWZ1bmN0aW9uIHhvKGhhKXtjb25zdCBhYT1bXTtmb3IoY29uc3QgeGEgb2YgYm4oaGEsWnMsMSkpYWEucHVzaCh7eDpQbih4YSwxKT8/MCx5OlBuKHhhLDIpPz8wLHo6UG4oeGEsMyk/PzAsdmlzaWJpbGl0eTpQbih4YSw0KT8/MH0pO3JldHVybiBhYX1mdW5jdGlvbiBTbyhoYSl7Y29uc3QgYWE9W107Zm9yKGNvbnN0IHhhIG9mIGJuKGhhLFlzLDEpKWFhLnB1c2goe3g6UG4oeGEsMSk/PzAseTpQbih4YSwyKT8/MCx6OlBuKHhhLDMpPz8wLHZpc2liaWxpdHk6UG4oeGEsNCk/PzB9KTtyZXR1cm4gYWF9ZnVuY3Rpb24gTG8oaGEpe3JldHVybiBBcnJheS5mcm9tKGhhLGFhPT4xMjc8YWE/YWEtMjU2OmFhKX1mdW5jdGlvbiBGbyhoYSxhYSl7aWYoaGEubGVuZ3RoIT09YWEubGVuZ3RoKXRocm93IEVycm9yKGBDYW5ub3QgY29tcHV0ZSBjb3NpbmUgc2ltaWxhcml0eSBiZXR3ZWVuIGVtYmVkZGluZ3Mgb2YgZGlmZmVyZW50IHNpemVzICgke2hhLmxlbmd0aH0gdnMuICR7YWEubGVuZ3RofSkuYCk7bGV0IHhhPTAsYmE9MCxTYT0wO2ZvcihsZXQgVGE9MDtUYTxoYS5sZW5ndGg7VGErKyl4YSs9aGFbVGFdKmFhW1RhXSxiYSs9aGFbVGFdKmhhW1RhXSxTYSs9YWFbVGFdKmFhW1RhXTtpZigwPj1iYXx8MD49U2EpdGhyb3cgRXJyb3IoIkNhbm5vdCBjb21wdXRlIGNvc2luZSBzaW1pbGFyaXR5IG9uIGVtYmVkZGluZyB3aXRoIDAgbm9ybS4iKTtyZXR1cm4geGEvTWF0aC5zcXJ0KGJhKlNhKX1sZXQgUm87Y3NbNTE2NTg3MjMwXT1bMCxraSxzbyxvbyx4cl07Y29uc3QgTW89bmV3IFVpbnQ4QXJyYXkoWzAsOTcsMTE1LDEwOSwxLDAsMCwwLDEsNSwxLDk2LDAsMSwxMjMsMywyLDEsMCwxMCwxMCwxLDgsMCw2NSwwLDI1MywxNSwyNTMsOTgsMTFdKTthc3luYyBmdW5jdGlvbiBQbygpe2lmKFJvPT09dm9pZCAwKXRyeXthd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShNbyksUm89ITB9Y2F0Y2h7Um89ITF9cmV0dXJuIFJvfWFzeW5jIGZ1bmN0aW9uIE9vKGhhLGFhPSIiKXtjb25zdCB4YT1hd2FpdCBQbygpPyJ3YXNtX2ludGVybmFsIjoid2FzbV9ub3NpbWRfaW50ZXJuYWwiO3JldHVybnt3YXNtTG9hZGVyUGF0aDpgJHthYX0vJHtoYX1fJHt4YX0uanNgLHdhc21CaW5hcnlQYXRoOmAke2FhfS8ke2hhfV8ke3hhfS53YXNtYH19dmFyIENvPWNsYXNze307ZnVuY3Rpb24gSW8oKXtjb25zdCBoYT1uYXZpZ2F0b3IudXNlckFnZW50O3JldHVybiBoYS5pbmNsdWRlcygiU2FmYXJpIikmJiFoYS5pbmNsdWRlcygiQ2hyb21lIil9YXN5bmMgZnVuY3Rpb24gRG8oaGEpe2lmKHR5cGVvZiBpbXBvcnRTY3JpcHRzIT0iZnVuY3Rpb24iKXtjb25zdCBhYT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKTtyZXR1cm4gYWEuc3JjPWhhLnRvU3RyaW5nKCksYWEuY3Jvc3NPcmlnaW49ImFub255bW91cyIsbmV3IFByb21pc2UoKHhhLGJhKT0+e2FhLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCgpPT57eGEoKX0sITEpLGFhLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIixTYT0+e2JhKFNhKX0sITEpLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYWEpfSl9aW1wb3J0U2NyaXB0cyhoYS50b1N0cmluZygpKX1mdW5jdGlvbiBObyhoYSl7cmV0dXJuIGhhLnZpZGVvV2lkdGghPT12b2lkIDA/W2hhLnZpZGVvV2lkdGgsaGEudmlkZW9IZWlnaHRdOmhhLm5hdHVyYWxXaWR0aCE9PXZvaWQgMD9baGEubmF0dXJhbFdpZHRoLGhhLm5hdHVyYWxIZWlnaHRdOmhhLmRpc3BsYXlXaWR0aCE9PXZvaWQgMD9baGEuZGlzcGxheVdpZHRoLGhhLmRpc3BsYXlIZWlnaHRdOltoYS53aWR0aCxoYS5oZWlnaHRdfWZ1bmN0aW9uIFVvKGhhLGFhLHhhKXtoYS5tfHxjb25zb2xlLmVycm9yKCJObyB3YXNtIG11bHRpc3RyZWFtIHN1cHBvcnQgZGV0ZWN0ZWQ6IGVuc3VyZSBkZXBlbmRlbmN5IGluY2x1c2lvbiBvZiA6Z2xfZ3JhcGhfcnVubmVyX2ludGVybmFsX211bHRpX2lucHV0IHRhcmdldCIpLHhhKGFhPWhhLmkuc3RyaW5nVG9OZXdVVEY4KGFhKSksaGEuaS5fZnJlZShhYSl9ZnVuY3Rpb24gQm8oaGEsYWEseGEpe2lmKCFoYS5pLmNhbnZhcyl0aHJvdyBFcnJvcigiTm8gT3BlbkdMIGNhbnZhcyBjb25maWd1cmVkLiIpO2lmKHhhP2hhLmkuX2JpbmRUZXh0dXJlVG9TdHJlYW0oeGEpOmhhLmkuX2JpbmRUZXh0dXJlVG9DYW52YXMoKSwhKHhhPWhhLmkuY2FudmFzLmdldENvbnRleHQoIndlYmdsMiIpfHxoYS5pLmNhbnZhcy5nZXRDb250ZXh0KCJ3ZWJnbCIpKSl0aHJvdyBFcnJvcigiRmFpbGVkIHRvIG9idGFpbiBXZWJHTCBjb250ZXh0IGZyb20gdGhlIHByb3ZpZGVkIGNhbnZhcy4gYGdldENvbnRleHQoKWAgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCB3aXRoIGB3ZWJnbGAgb3IgYHdlYmdsMmAuIik7aGEuaS5ncHVPcmlnaW5Gb3JXZWJUZXh0dXJlc0lzQm90dG9tTGVmdCYmeGEucGl4ZWxTdG9yZWkoeGEuVU5QQUNLX0ZMSVBfWV9XRUJHTCwhMCkseGEudGV4SW1hZ2UyRCh4YS5URVhUVVJFXzJELDAseGEuUkdCQSx4YS5SR0JBLHhhLlVOU0lHTkVEX0JZVEUsYWEpLGhhLmkuZ3B1T3JpZ2luRm9yV2ViVGV4dHVyZXNJc0JvdHRvbUxlZnQmJnhhLnBpeGVsU3RvcmVpKHhhLlVOUEFDS19GTElQX1lfV0VCR0wsITEpO2NvbnN0W2JhLFNhXT1ObyhhYSk7cmV0dXJuIWhhLmx8fGJhPT09aGEuaS5jYW52YXMud2lkdGgmJlNhPT09aGEuaS5jYW52YXMuaGVpZ2h0fHwoaGEuaS5jYW52YXMud2lkdGg9YmEsaGEuaS5jYW52YXMuaGVpZ2h0PVNhKSxbYmEsU2FdfWZ1bmN0aW9uIEdvKGhhLGFhLHhhKXtoYS5tfHxjb25zb2xlLmVycm9yKCJObyB3YXNtIG11bHRpc3RyZWFtIHN1cHBvcnQgZGV0ZWN0ZWQ6IGVuc3VyZSBkZXBlbmRlbmN5IGluY2x1c2lvbiBvZiA6Z2xfZ3JhcGhfcnVubmVyX2ludGVybmFsX211bHRpX2lucHV0IHRhcmdldCIpO2NvbnN0IGJhPW5ldyBVaW50MzJBcnJheShhYS5sZW5ndGgpO2ZvcihsZXQgU2E9MDtTYTxhYS5sZW5ndGg7U2ErKyliYVtTYV09aGEuaS5zdHJpbmdUb05ld1VURjgoYWFbU2FdKTthYT1oYS5pLl9tYWxsb2MoNCpiYS5sZW5ndGgpLGhhLmkuSEVBUFUzMi5zZXQoYmEsYWE+PjIpLHhhKGFhKTtmb3IoY29uc3QgU2Egb2YgYmEpaGEuaS5fZnJlZShTYSk7aGEuaS5fZnJlZShhYSl9ZnVuY3Rpb24gam8oaGEsYWEseGEpe2hhLmkuc2ltcGxlTGlzdGVuZXJzPWhhLmkuc2ltcGxlTGlzdGVuZXJzfHx7fSxoYS5pLnNpbXBsZUxpc3RlbmVyc1thYV09eGF9ZnVuY3Rpb24gVm8oaGEsYWEseGEpe2xldCBiYT1bXTtoYS5pLnNpbXBsZUxpc3RlbmVycz1oYS5pLnNpbXBsZUxpc3RlbmVyc3x8e30saGEuaS5zaW1wbGVMaXN0ZW5lcnNbYWFdPShTYSxUYSx3YSk9PntUYT8oeGEoYmEsd2EpLGJhPVtdKTpiYS5wdXNoKFNhKX19Q28uZm9yVmlzaW9uVGFza3M9ZnVuY3Rpb24oaGEpe3JldHVybiBPbygidmlzaW9uIixoYSl9LENvLmZvclRleHRUYXNrcz1mdW5jdGlvbihoYSl7cmV0dXJuIE9vKCJ0ZXh0IixoYSl9LENvLmZvckdlbkFpVGFza3M9ZnVuY3Rpb24oaGEpe3JldHVybiBPbygiZ2VuYWkiLGhhKX0sQ28uZm9yQXVkaW9UYXNrcz1mdW5jdGlvbihoYSl7cmV0dXJuIE9vKCJhdWRpbyIsaGEpfSxDby5pc1NpbWRTdXBwb3J0ZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gUG8oKX07YXN5bmMgZnVuY3Rpb24gWG8oaGEsYWEseGEsYmEpe3JldHVybiBoYT1hd2FpdChhc3luYyhTYSxUYSx3YSxFYSxrYSk9PntpZihUYSYmYXdhaXQgRG8oVGEpLCFzZWxmLk1vZHVsZUZhY3Rvcnl8fHdhJiYoYXdhaXQgRG8od2EpLCFzZWxmLk1vZHVsZUZhY3RvcnkpKXRocm93IEVycm9yKCJNb2R1bGVGYWN0b3J5IG5vdCBzZXQuIik7cmV0dXJuIHNlbGYuTW9kdWxlJiZrYSYmKChUYT1zZWxmLk1vZHVsZSkubG9jYXRlRmlsZT1rYS5sb2NhdGVGaWxlLGthLm1haW5TY3JpcHRVcmxPckJsb2ImJihUYS5tYWluU2NyaXB0VXJsT3JCbG9iPWthLm1haW5TY3JpcHRVcmxPckJsb2IpKSxrYT1hd2FpdCBzZWxmLk1vZHVsZUZhY3Rvcnkoc2VsZi5Nb2R1bGV8fGthKSxzZWxmLk1vZHVsZUZhY3Rvcnk9c2VsZi5Nb2R1bGU9dm9pZCAwLG5ldyBTYShrYSxFYSl9KShoYSx4YS53YXNtTG9hZGVyUGF0aCx4YS5hc3NldExvYWRlclBhdGgsYWEse2xvY2F0ZUZpbGU6U2E9PlNhLmVuZHNXaXRoKCIud2FzbSIpP3hhLndhc21CaW5hcnlQYXRoLnRvU3RyaW5nKCk6eGEuYXNzZXRCaW5hcnlQYXRoJiZTYS5lbmRzV2l0aCgiLmRhdGEiKT94YS5hc3NldEJpbmFyeVBhdGgudG9TdHJpbmcoKTpTYX0pLGF3YWl0IGhhLm8oYmEpLGhhfWZ1bmN0aW9uIEhvKGhhLGFhKXtjb25zdCB4YT1UbihoYS5iYXNlT3B0aW9ucyxUaSwxKXx8bmV3IFRpO3R5cGVvZiBhYT09InN0cmluZyI/KHJuKHhhLDIsa2UoYWEpKSxybih4YSwxKSk6YWEgaW5zdGFuY2VvZiBVaW50OEFycmF5JiYocm4oeGEsMSxzZShhYSwhMSwhMSkpLHJuKHhhLDIpKSxrbihoYS5iYXNlT3B0aW9ucywwLDEseGEpfWZ1bmN0aW9uIFdvKGhhKXt0cnl7Y29uc3QgYWE9aGEuSC5sZW5ndGg7aWYoYWE9PT0xKXRocm93IEVycm9yKGhhLkhbMF0ubWVzc2FnZSk7aWYoMTxhYSl0aHJvdyBFcnJvcigiRW5jb3VudGVyZWQgbXVsdGlwbGUgZXJyb3JzOiAiK2hhLkgubWFwKHhhPT54YS5tZXNzYWdlKS5qb2luKCIsICIpKX1maW5hbGx5e2hhLkg9W119fWZ1bmN0aW9uIHpvKGhhLGFhKXtoYS5DPU1hdGgubWF4KGhhLkMsYWEpfWZ1bmN0aW9uIEtvKGhhLGFhKXtoYS5CPW5ldyB2cyxtcyhoYS5CLCJQYXNzVGhyb3VnaENhbGN1bGF0b3IiKSx5cyhoYS5CLCJmcmVlX21lbW9yeSIpLF9zKGhhLkIsImZyZWVfbWVtb3J5X3VudXNlZF9vdXQiKSx4cyhhYSwiZnJlZV9tZW1vcnkiKSxrcyhhYSxoYS5CKX1mdW5jdGlvbiBZbyhoYSxhYSl7eXMoaGEuQixhYSksX3MoaGEuQixhYSsiX3VudXNlZF9vdXQiKX1mdW5jdGlvbiAkbyhoYSl7aGEuZy5hZGRCb29sVG9TdHJlYW0oITAsImZyZWVfbWVtb3J5IixoYS5DKX12YXIgcW89Y2xhc3N7Y29uc3RydWN0b3IoaGEpe3RoaXMuZz1oYSx0aGlzLkg9W10sdGhpcy5DPTAsdGhpcy5nLnNldEF1dG9SZW5kZXJUb1NjcmVlbighMSl9bChoYSxhYT0hMCl7dmFyIHhhLGJhLFNhLFRhLHdhLEVhO2lmKGFhKXtjb25zdCBrYT1oYS5iYXNlT3B0aW9uc3x8e307aWYoKHhhPWhhLmJhc2VPcHRpb25zKSE9bnVsbCYmeGEubW9kZWxBc3NldEJ1ZmZlciYmKChiYT1oYS5iYXNlT3B0aW9ucykhPW51bGwmJmJhLm1vZGVsQXNzZXRQYXRoKSl0aHJvdyBFcnJvcigiQ2Fubm90IHNldCBib3RoIGJhc2VPcHRpb25zLm1vZGVsQXNzZXRQYXRoIGFuZCBiYXNlT3B0aW9ucy5tb2RlbEFzc2V0QnVmZmVyIik7aWYoISgoU2E9VG4odGhpcy5iYXNlT3B0aW9ucyxUaSwxKSkhPW51bGwmJlNhLmcoKXx8KFRhPVRuKHRoaXMuYmFzZU9wdGlvbnMsVGksMSkpIT1udWxsJiZUYS5oKCl8fCh3YT1oYS5iYXNlT3B0aW9ucykhPW51bGwmJndhLm1vZGVsQXNzZXRCdWZmZXJ8fChFYT1oYS5iYXNlT3B0aW9ucykhPW51bGwmJkVhLm1vZGVsQXNzZXRQYXRoKSl0aHJvdyBFcnJvcigiRWl0aGVyIGJhc2VPcHRpb25zLm1vZGVsQXNzZXRQYXRoIG9yIGJhc2VPcHRpb25zLm1vZGVsQXNzZXRCdWZmZXIgbXVzdCBiZSBzZXQiKTtpZihmdW5jdGlvbihBYSxGYSl7bGV0IExhPVRuKEFhLmJhc2VPcHRpb25zLEVpLDMpO2lmKCFMYSl7dmFyIGVsPUxhPW5ldyBFaSx0bD1uZXcgaXM7eG4oZWwsNCx3aSx0bCl9ImRlbGVnYXRlImluIEZhJiYoRmEuZGVsZWdhdGU9PT0iR1BVIj8oRmE9TGEsZWw9bmV3IG5zLHhuKEZhLDIsd2ksZWwpKTooRmE9TGEsZWw9bmV3IGlzLHhuKEZhLDQsd2ksZWwpKSksa24oQWEuYmFzZU9wdGlvbnMsMCwzLExhKX0odGhpcyxrYSksa2EubW9kZWxBc3NldFBhdGgpcmV0dXJuIGZldGNoKGthLm1vZGVsQXNzZXRQYXRoLnRvU3RyaW5nKCkpLnRoZW4oQWE9PntpZihBYS5vaylyZXR1cm4gQWEuYXJyYXlCdWZmZXIoKTt0aHJvdyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIG1vZGVsOiAke2thLm1vZGVsQXNzZXRQYXRofSAoJHtBYS5zdGF0dXN9KWApfSkudGhlbihBYT0+e3RyeXt0aGlzLmcuaS5GU191bmxpbmsoIi9tb2RlbC5kYXQiKX1jYXRjaHt9dGhpcy5nLmkuRlNfY3JlYXRlRGF0YUZpbGUoIi8iLCJtb2RlbC5kYXQiLG5ldyBVaW50OEFycmF5KEFhKSwhMCwhMSwhMSksSG8odGhpcywiL21vZGVsLmRhdCIpLHRoaXMubSgpLHRoaXMuSygpfSk7SG8odGhpcyxrYS5tb2RlbEFzc2V0QnVmZmVyKX1yZXR1cm4gdGhpcy5tKCksdGhpcy5LKCksUHJvbWlzZS5yZXNvbHZlKCl9Sygpe31mYSgpe2xldCBoYTtpZih0aGlzLmcuZmEoYWE9PntoYT1ScyhhYSl9KSwhaGEpdGhyb3cgRXJyb3IoIkZhaWxlZCB0byByZXRyaWV2ZSBDYWxjdWxhdG9yR3JhcGhDb25maWciKTtyZXR1cm4gaGF9c2V0R3JhcGgoaGEsYWEpe3RoaXMuZy5hdHRhY2hFcnJvckxpc3RlbmVyKCh4YSxiYSk9Pnt0aGlzLkgucHVzaChFcnJvcihiYSkpfSksdGhpcy5nLk1hKCksdGhpcy5nLnNldEdyYXBoKGhhLGFhKSx0aGlzLkI9dm9pZCAwLFdvKHRoaXMpfWZpbmlzaFByb2Nlc3NpbmcoKXt0aGlzLmcuZmluaXNoUHJvY2Vzc2luZygpLFdvKHRoaXMpfWNsb3NlKCl7dGhpcy5CPXZvaWQgMCx0aGlzLmcuY2xvc2VHcmFwaCgpfX07ZnVuY3Rpb24gSm8oaGEsYWEpe2lmKCFoYSl0aHJvdyBFcnJvcihgVW5hYmxlIHRvIG9idGFpbiByZXF1aXJlZCBXZWJHTCByZXNvdXJjZTogJHthYX1gKTtyZXR1cm4gaGF9cW8ucHJvdG90eXBlLmNsb3NlPXFvLnByb3RvdHlwZS5jbG9zZTtjbGFzcyBab3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy5nPWFhLHRoaXMuaD14YSx0aGlzLm09YmEsdGhpcy5sPVNhfWJpbmQoKXt0aGlzLmcuYmluZFZlcnRleEFycmF5KHRoaXMuaCl9Y2xvc2UoKXt0aGlzLmcuZGVsZXRlVmVydGV4QXJyYXkodGhpcy5oKSx0aGlzLmcuZGVsZXRlQnVmZmVyKHRoaXMubSksdGhpcy5nLmRlbGV0ZUJ1ZmZlcih0aGlzLmwpfX1mdW5jdGlvbiBRbyhoYSxhYSx4YSl7Y29uc3QgYmE9aGEuZztpZih4YT1KbyhiYS5jcmVhdGVTaGFkZXIoeGEpLCJGYWlsZWQgdG8gY3JlYXRlIFdlYkdMIHNoYWRlciIpLGJhLnNoYWRlclNvdXJjZSh4YSxhYSksYmEuY29tcGlsZVNoYWRlcih4YSksIWJhLmdldFNoYWRlclBhcmFtZXRlcih4YSxiYS5DT01QSUxFX1NUQVRVUykpdGhyb3cgRXJyb3IoYENvdWxkIG5vdCBjb21waWxlIFdlYkdMIHNoYWRlcjogJHtiYS5nZXRTaGFkZXJJbmZvTG9nKHhhKX1gKTtyZXR1cm4gYmEuYXR0YWNoU2hhZGVyKGhhLmgseGEpLHhhfWZ1bmN0aW9uIHRhKGhhLGFhKXtjb25zdCB4YT1oYS5nLGJhPUpvKHhhLmNyZWF0ZVZlcnRleEFycmF5KCksIkZhaWxlZCB0byBjcmVhdGUgdmVydGV4IGFycmF5Iik7eGEuYmluZFZlcnRleEFycmF5KGJhKTtjb25zdCBTYT1Kbyh4YS5jcmVhdGVCdWZmZXIoKSwiRmFpbGVkIHRvIGNyZWF0ZSBidWZmZXIiKTt4YS5iaW5kQnVmZmVyKHhhLkFSUkFZX0JVRkZFUixTYSkseGEuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoaGEuUCkseGEudmVydGV4QXR0cmliUG9pbnRlcihoYS5QLDIseGEuRkxPQVQsITEsMCwwKSx4YS5idWZmZXJEYXRhKHhhLkFSUkFZX0JVRkZFUixuZXcgRmxvYXQzMkFycmF5KFstMSwtMSwtMSwxLDEsMSwxLC0xXSkseGEuU1RBVElDX0RSQVcpO2NvbnN0IFRhPUpvKHhhLmNyZWF0ZUJ1ZmZlcigpLCJGYWlsZWQgdG8gY3JlYXRlIGJ1ZmZlciIpO3JldHVybiB4YS5iaW5kQnVmZmVyKHhhLkFSUkFZX0JVRkZFUixUYSkseGEuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoaGEuTykseGEudmVydGV4QXR0cmliUG9pbnRlcihoYS5PLDIseGEuRkxPQVQsITEsMCwwKSx4YS5idWZmZXJEYXRhKHhhLkFSUkFZX0JVRkZFUixuZXcgRmxvYXQzMkFycmF5KGFhP1swLDEsMCwwLDEsMCwxLDFdOlswLDAsMCwxLDEsMSwxLDBdKSx4YS5TVEFUSUNfRFJBVykseGEuYmluZEJ1ZmZlcih4YS5BUlJBWV9CVUZGRVIsbnVsbCkseGEuYmluZFZlcnRleEFycmF5KG51bGwpLG5ldyBabyh4YSxiYSxTYSxUYSl9ZnVuY3Rpb24gZWEoaGEsYWEpe2lmKGhhLmcpe2lmKGFhIT09aGEuZyl0aHJvdyBFcnJvcigiQ2Fubm90IGNoYW5nZSBHTCBjb250ZXh0IG9uY2UgaW5pdGlhbGl6ZWQiKX1lbHNlIGhhLmc9YWF9ZnVuY3Rpb24gbmEoaGEsYWEseGEsYmEpe3JldHVybiBlYShoYSxhYSksaGEuaHx8KGhhLm0oKSxoYS5EKCkpLHhhPyhoYS5zfHwoaGEucz10YShoYSwhMCkpLHhhPWhhLnMpOihoYS52fHwoaGEudj10YShoYSwhMSkpLHhhPWhhLnYpLGFhLnVzZVByb2dyYW0oaGEuaCkseGEuYmluZCgpLGhhLmwoKSxoYT1iYSgpLHhhLmcuYmluZFZlcnRleEFycmF5KG51bGwpLGhhfWZ1bmN0aW9uIHJhKGhhLGFhLHhhKXtyZXR1cm4gZWEoaGEsYWEpLGhhPUpvKGFhLmNyZWF0ZVRleHR1cmUoKSwiRmFpbGVkIHRvIGNyZWF0ZSB0ZXh0dXJlIiksYWEuYmluZFRleHR1cmUoYWEuVEVYVFVSRV8yRCxoYSksYWEudGV4UGFyYW1ldGVyaShhYS5URVhUVVJFXzJELGFhLlRFWFRVUkVfV1JBUF9TLGFhLkNMQU1QX1RPX0VER0UpLGFhLnRleFBhcmFtZXRlcmkoYWEuVEVYVFVSRV8yRCxhYS5URVhUVVJFX1dSQVBfVCxhYS5DTEFNUF9UT19FREdFKSxhYS50ZXhQYXJhbWV0ZXJpKGFhLlRFWFRVUkVfMkQsYWEuVEVYVFVSRV9NSU5fRklMVEVSLHhhPz9hYS5MSU5FQVIpLGFhLnRleFBhcmFtZXRlcmkoYWEuVEVYVFVSRV8yRCxhYS5URVhUVVJFX01BR19GSUxURVIseGE/P2FhLkxJTkVBUiksYWEuYmluZFRleHR1cmUoYWEuVEVYVFVSRV8yRCxudWxsKSxoYX1mdW5jdGlvbiBzYShoYSxhYSx4YSl7ZWEoaGEsYWEpLGhhLkJ8fChoYS5CPUpvKGFhLmNyZWF0ZUZyYW1lYnVmZmVyKCksIkZhaWxlZCB0byBjcmVhdGUgZnJhbWVidWZmZS4iKSksYWEuYmluZEZyYW1lYnVmZmVyKGFhLkZSQU1FQlVGRkVSLGhhLkIpLGFhLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGFhLkZSQU1FQlVGRkVSLGFhLkNPTE9SX0FUVEFDSE1FTlQwLGFhLlRFWFRVUkVfMkQseGEsMCl9ZnVuY3Rpb24gaWEoaGEpe3ZhciBhYTsoYWE9aGEuZyk9PW51bGx8fGFhLmJpbmRGcmFtZWJ1ZmZlcihoYS5nLkZSQU1FQlVGRkVSLG51bGwpfXZhciBvYT1jbGFzc3tIKCl7cmV0dXJuYAogIHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VGV4OwogIHVuaWZvcm0gc2FtcGxlcjJEIGlucHV0VGV4dHVyZTsKICB2b2lkIG1haW4oKSB7CiAgICBnbF9GcmFnQ29sb3IgPSB0ZXh0dXJlMkQoaW5wdXRUZXh0dXJlLCB2VGV4KTsKICB9CiBgfW0oKXtjb25zdCBoYT10aGlzLmc7aWYodGhpcy5oPUpvKGhhLmNyZWF0ZVByb2dyYW0oKSwiRmFpbGVkIHRvIGNyZWF0ZSBXZWJHTCBwcm9ncmFtIiksdGhpcy5iYT1Rbyh0aGlzLGAKICBhdHRyaWJ1dGUgdmVjMiBhVmVydGV4OwogIGF0dHJpYnV0ZSB2ZWMyIGFUZXg7CiAgdmFyeWluZyB2ZWMyIHZUZXg7CiAgdm9pZCBtYWluKHZvaWQpIHsKICAgIGdsX1Bvc2l0aW9uID0gdmVjNChhVmVydGV4LCAwLjAsIDEuMCk7CiAgICB2VGV4ID0gYVRleDsKICB9YCxoYS5WRVJURVhfU0hBREVSKSx0aGlzLmFhPVFvKHRoaXMsdGhpcy5IKCksaGEuRlJBR01FTlRfU0hBREVSKSxoYS5saW5rUHJvZ3JhbSh0aGlzLmgpLCFoYS5nZXRQcm9ncmFtUGFyYW1ldGVyKHRoaXMuaCxoYS5MSU5LX1NUQVRVUykpdGhyb3cgRXJyb3IoYEVycm9yIGR1cmluZyBwcm9ncmFtIGxpbmtpbmc6ICR7aGEuZ2V0UHJvZ3JhbUluZm9Mb2codGhpcy5oKX1gKTt0aGlzLlA9aGEuZ2V0QXR0cmliTG9jYXRpb24odGhpcy5oLCJhVmVydGV4IiksdGhpcy5PPWhhLmdldEF0dHJpYkxvY2F0aW9uKHRoaXMuaCwiYVRleCIpfUQoKXt9bCgpe31jbG9zZSgpe2lmKHRoaXMuaCl7Y29uc3QgaGE9dGhpcy5nO2hhLmRlbGV0ZVByb2dyYW0odGhpcy5oKSxoYS5kZWxldGVTaGFkZXIodGhpcy5iYSksaGEuZGVsZXRlU2hhZGVyKHRoaXMuYWEpfXRoaXMuQiYmdGhpcy5nLmRlbGV0ZUZyYW1lYnVmZmVyKHRoaXMuQiksdGhpcy52JiZ0aGlzLnYuY2xvc2UoKSx0aGlzLnMmJnRoaXMucy5jbG9zZSgpfX07ZnVuY3Rpb24gY2EoaGEsYWEpe3N3aXRjaChhYSl7Y2FzZSAwOnJldHVybiBoYS5nLmZpbmQoeGE9PnhhIGluc3RhbmNlb2YgVWludDhBcnJheSk7Y2FzZSAxOnJldHVybiBoYS5nLmZpbmQoeGE9PnhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5KTtjYXNlIDI6cmV0dXJuIGhhLmcuZmluZCh4YT0+dHlwZW9mIFdlYkdMVGV4dHVyZTwidSImJnhhIGluc3RhbmNlb2YgV2ViR0xUZXh0dXJlKTtkZWZhdWx0OnRocm93IEVycm9yKGBUeXBlIGlzIG5vdCBzdXBwb3J0ZWQ6ICR7YWF9YCl9fWZ1bmN0aW9uIHVhKGhhKXt2YXIgYWE9Y2EoaGEsMSk7aWYoIWFhKXtpZihhYT1jYShoYSwwKSlhYT1uZXcgRmxvYXQzMkFycmF5KGFhKS5tYXAoYmE9PmJhLzI1NSk7ZWxzZXthYT1uZXcgRmxvYXQzMkFycmF5KGhhLndpZHRoKmhhLmhlaWdodCk7Y29uc3QgYmE9ZGEoaGEpO3ZhciB4YT1wYShoYSk7aWYoc2EoeGEsYmEsbGEoaGEpKSwiaVBhZCBTaW11bGF0b3I7aVBob25lIFNpbXVsYXRvcjtpUG9kIFNpbXVsYXRvcjtpUGFkO2lQaG9uZTtpUG9kIi5zcGxpdCgiOyIpLmluY2x1ZGVzKG5hdmlnYXRvci5wbGF0Zm9ybSl8fG5hdmlnYXRvci51c2VyQWdlbnQuaW5jbHVkZXMoIk1hYyIpJiYib250b3VjaGVuZCJpbiBzZWxmLmRvY3VtZW50KXt4YT1uZXcgRmxvYXQzMkFycmF5KGhhLndpZHRoKmhhLmhlaWdodCo0KSxiYS5yZWFkUGl4ZWxzKDAsMCxoYS53aWR0aCxoYS5oZWlnaHQsYmEuUkdCQSxiYS5GTE9BVCx4YSk7Zm9yKGxldCBTYT0wLFRhPTA7U2E8YWEubGVuZ3RoOysrU2EsVGErPTQpYWFbU2FdPXhhW1RhXX1lbHNlIGJhLnJlYWRQaXhlbHMoMCwwLGhhLndpZHRoLGhhLmhlaWdodCxiYS5SRUQsYmEuRkxPQVQsYWEpfWhhLmcucHVzaChhYSl9cmV0dXJuIGFhfWZ1bmN0aW9uIGxhKGhhKXtsZXQgYWE9Y2EoaGEsMik7aWYoIWFhKXtjb25zdCB4YT1kYShoYSk7YWE9Z2EoaGEpO2NvbnN0IGJhPXVhKGhhKSxTYT1mYShoYSk7eGEudGV4SW1hZ2UyRCh4YS5URVhUVVJFXzJELDAsU2EsaGEud2lkdGgsaGEuaGVpZ2h0LDAseGEuUkVELHhhLkZMT0FULGJhKSxtYShoYSl9cmV0dXJuIGFhfWZ1bmN0aW9uIGRhKGhhKXtpZighaGEuY2FudmFzKXRocm93IEVycm9yKCJDb252ZXJzaW9uIHRvIGRpZmZlcmVudCBpbWFnZSBmb3JtYXRzIHJlcXVpcmUgdGhhdCBhIGNhbnZhcyBpcyBwYXNzZWQgd2hlbiBpbml0aWFsaXppbmcgdGhlIGltYWdlLiIpO3JldHVybiBoYS5ofHwoaGEuaD1KbyhoYS5jYW52YXMuZ2V0Q29udGV4dCgid2ViZ2wyIiksIllvdSBjYW5ub3QgdXNlIGEgY2FudmFzIHRoYXQgaXMgYWxyZWFkeSBib3VuZCB0byBhIGRpZmZlcmVudCB0eXBlIG9mIHJlbmRlcmluZyBjb250ZXh0LiIpKSxoYS5ofWZ1bmN0aW9uIGZhKGhhKXtpZihoYT1kYShoYSksIXlhKWlmKGhhLmdldEV4dGVuc2lvbigiRVhUX2NvbG9yX2J1ZmZlcl9mbG9hdCIpJiZoYS5nZXRFeHRlbnNpb24oIk9FU190ZXh0dXJlX2Zsb2F0X2xpbmVhciIpJiZoYS5nZXRFeHRlbnNpb24oIkVYVF9mbG9hdF9ibGVuZCIpKXlhPWhhLlIzMkY7ZWxzZXtpZighaGEuZ2V0RXh0ZW5zaW9uKCJFWFRfY29sb3JfYnVmZmVyX2hhbGZfZmxvYXQiKSl0aHJvdyBFcnJvcigiR1BVIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgNC1jaGFubmVsIGZsb2F0MzIgb3IgZmxvYXQxNiBmb3JtYXRzIik7eWE9aGEuUjE2Rn1yZXR1cm4geWF9ZnVuY3Rpb24gcGEoaGEpe3JldHVybiBoYS5sfHwoaGEubD1uZXcgb2EpLGhhLmx9ZnVuY3Rpb24gZ2EoaGEpe2NvbnN0IGFhPWRhKGhhKTthYS52aWV3cG9ydCgwLDAsaGEud2lkdGgsaGEuaGVpZ2h0KSxhYS5hY3RpdmVUZXh0dXJlKGFhLlRFWFRVUkUwKTtsZXQgeGE9Y2EoaGEsMik7cmV0dXJuIHhhfHwoeGE9cmEocGEoaGEpLGFhLGhhLm0/YWEuTElORUFSOmFhLk5FQVJFU1QpLGhhLmcucHVzaCh4YSksaGEuaj0hMCksYWEuYmluZFRleHR1cmUoYWEuVEVYVFVSRV8yRCx4YSkseGF9ZnVuY3Rpb24gbWEoaGEpe2hhLmguYmluZFRleHR1cmUoaGEuaC5URVhUVVJFXzJELG51bGwpfXZhciB5YSxfYT1jbGFzc3tjb25zdHJ1Y3RvcihoYSxhYSx4YSxiYSxTYSxUYSx3YSl7dGhpcy5nPWhhLHRoaXMubT1hYSx0aGlzLmo9eGEsdGhpcy5jYW52YXM9YmEsdGhpcy5sPVNhLHRoaXMud2lkdGg9VGEsdGhpcy5oZWlnaHQ9d2EsdGhpcy5qJiYtLXZhPT09MCYmY29uc29sZS5lcnJvcigiWW91IHNlZW0gdG8gYmUgY3JlYXRpbmcgTVBNYXNrIGluc3RhbmNlcyB3aXRob3V0IGludm9raW5nIC5jbG9zZSgpLiBUaGlzIGxlYWtzIHJlc291cmNlcy4iKX1IYSgpe3JldHVybiEhY2EodGhpcywwKX1sYSgpe3JldHVybiEhY2EodGhpcywxKX1SKCl7cmV0dXJuISFjYSh0aGlzLDIpfWthKCl7cmV0dXJuKGFhPWNhKGhhPXRoaXMsMCkpfHwoYWE9dWEoaGEpLGFhPW5ldyBVaW50OEFycmF5KGFhLm1hcCh4YT0+MjU1KnhhKSksaGEuZy5wdXNoKGFhKSksYWE7dmFyIGhhLGFhfWphKCl7cmV0dXJuIHVhKHRoaXMpfU0oKXtyZXR1cm4gbGEodGhpcyl9Y2xvbmUoKXtjb25zdCBoYT1bXTtmb3IoY29uc3QgYWEgb2YgdGhpcy5nKXtsZXQgeGE7aWYoYWEgaW5zdGFuY2VvZiBVaW50OEFycmF5KXhhPW5ldyBVaW50OEFycmF5KGFhKTtlbHNlIGlmKGFhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5KXhhPW5ldyBGbG9hdDMyQXJyYXkoYWEpO2Vsc2V7aWYoIShhYSBpbnN0YW5jZW9mIFdlYkdMVGV4dHVyZSkpdGhyb3cgRXJyb3IoYFR5cGUgaXMgbm90IHN1cHBvcnRlZDogJHthYX1gKTt7Y29uc3QgYmE9ZGEodGhpcyksU2E9cGEodGhpcyk7YmEuYWN0aXZlVGV4dHVyZShiYS5URVhUVVJFMSkseGE9cmEoU2EsYmEsdGhpcy5tP2JhLkxJTkVBUjpiYS5ORUFSRVNUKSxiYS5iaW5kVGV4dHVyZShiYS5URVhUVVJFXzJELHhhKTtjb25zdCBUYT1mYSh0aGlzKTtiYS50ZXhJbWFnZTJEKGJhLlRFWFRVUkVfMkQsMCxUYSx0aGlzLndpZHRoLHRoaXMuaGVpZ2h0LDAsYmEuUkVELGJhLkZMT0FULG51bGwpLGJhLmJpbmRUZXh0dXJlKGJhLlRFWFRVUkVfMkQsbnVsbCksc2EoU2EsYmEseGEpLG5hKFNhLGJhLCExLCgpPT57Z2EodGhpcyksYmEuY2xlYXJDb2xvcigwLDAsMCwwKSxiYS5jbGVhcihiYS5DT0xPUl9CVUZGRVJfQklUKSxiYS5kcmF3QXJyYXlzKGJhLlRSSUFOR0xFX0ZBTiwwLDQpLG1hKHRoaXMpfSksaWEoU2EpLG1hKHRoaXMpfX1oYS5wdXNoKHhhKX1yZXR1cm4gbmV3IF9hKGhhLHRoaXMubSx0aGlzLlIoKSx0aGlzLmNhbnZhcyx0aGlzLmwsdGhpcy53aWR0aCx0aGlzLmhlaWdodCl9Y2xvc2UoKXt0aGlzLmomJmRhKHRoaXMpLmRlbGV0ZVRleHR1cmUoY2EodGhpcywyKSksdmE9LTF9fTtfYS5wcm90b3R5cGUuY2xvc2U9X2EucHJvdG90eXBlLmNsb3NlLF9hLnByb3RvdHlwZS5jbG9uZT1fYS5wcm90b3R5cGUuY2xvbmUsX2EucHJvdG90eXBlLmdldEFzV2ViR0xUZXh0dXJlPV9hLnByb3RvdHlwZS5NLF9hLnByb3RvdHlwZS5nZXRBc0Zsb2F0MzJBcnJheT1fYS5wcm90b3R5cGUuamEsX2EucHJvdG90eXBlLmdldEFzVWludDhBcnJheT1fYS5wcm90b3R5cGUua2EsX2EucHJvdG90eXBlLmhhc1dlYkdMVGV4dHVyZT1fYS5wcm90b3R5cGUuUixfYS5wcm90b3R5cGUuaGFzRmxvYXQzMkFycmF5PV9hLnByb3RvdHlwZS5sYSxfYS5wcm90b3R5cGUuaGFzVWludDhBcnJheT1fYS5wcm90b3R5cGUuSGE7dmFyIHZhPTI1MDtmdW5jdGlvbiBSYShoYSxhYSl7c3dpdGNoKGFhKXtjYXNlIDA6cmV0dXJuIGhhLmcuZmluZCh4YT0+eGEgaW5zdGFuY2VvZiBJbWFnZURhdGEpO2Nhc2UgMTpyZXR1cm4gaGEuZy5maW5kKHhhPT50eXBlb2YgSW1hZ2VCaXRtYXA8InUiJiZ4YSBpbnN0YW5jZW9mIEltYWdlQml0bWFwKTtjYXNlIDI6cmV0dXJuIGhhLmcuZmluZCh4YT0+dHlwZW9mIFdlYkdMVGV4dHVyZTwidSImJnhhIGluc3RhbmNlb2YgV2ViR0xUZXh0dXJlKTtkZWZhdWx0OnRocm93IEVycm9yKGBUeXBlIGlzIG5vdCBzdXBwb3J0ZWQ6ICR7YWF9YCl9fWZ1bmN0aW9uIE1hKGhhKXt2YXIgYWE9UmEoaGEsMCk7aWYoIWFhKXthYT1PYShoYSk7Y29uc3QgeGE9Q2EoaGEpLGJhPW5ldyBVaW50OEFycmF5KGhhLndpZHRoKmhhLmhlaWdodCo0KTtzYSh4YSxhYSxQYShoYSkpLGFhLnJlYWRQaXhlbHMoMCwwLGhhLndpZHRoLGhhLmhlaWdodCxhYS5SR0JBLGFhLlVOU0lHTkVEX0JZVEUsYmEpLGlhKHhhKSxhYT1uZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheShiYS5idWZmZXIpLGhhLndpZHRoLGhhLmhlaWdodCksaGEuZy5wdXNoKGFhKX1yZXR1cm4gYWF9ZnVuY3Rpb24gUGEoaGEpe2xldCBhYT1SYShoYSwyKTtpZighYWEpe2NvbnN0IHhhPU9hKGhhKTthYT1JYShoYSk7Y29uc3QgYmE9UmEoaGEsMSl8fE1hKGhhKTt4YS50ZXhJbWFnZTJEKHhhLlRFWFRVUkVfMkQsMCx4YS5SR0JBLHhhLlJHQkEseGEuVU5TSUdORURfQllURSxiYSksRGEoaGEpfXJldHVybiBhYX1mdW5jdGlvbiBPYShoYSl7aWYoIWhhLmNhbnZhcyl0aHJvdyBFcnJvcigiQ29udmVyc2lvbiB0byBkaWZmZXJlbnQgaW1hZ2UgZm9ybWF0cyByZXF1aXJlIHRoYXQgYSBjYW52YXMgaXMgcGFzc2VkIHdoZW4gaW5paXRpYWxpemluZyB0aGUgaW1hZ2UuIik7cmV0dXJuIGhhLmh8fChoYS5oPUpvKGhhLmNhbnZhcy5nZXRDb250ZXh0KCJ3ZWJnbDIiKSwiWW91IGNhbm5vdCB1c2UgYSBjYW52YXMgdGhhdCBpcyBhbHJlYWR5IGJvdW5kIHRvIGEgZGlmZmVyZW50IHR5cGUgb2YgcmVuZGVyaW5nIGNvbnRleHQuIikpLGhhLmh9ZnVuY3Rpb24gQ2EoaGEpe3JldHVybiBoYS5sfHwoaGEubD1uZXcgb2EpLGhhLmx9ZnVuY3Rpb24gSWEoaGEpe2NvbnN0IGFhPU9hKGhhKTthYS52aWV3cG9ydCgwLDAsaGEud2lkdGgsaGEuaGVpZ2h0KSxhYS5hY3RpdmVUZXh0dXJlKGFhLlRFWFRVUkUwKTtsZXQgeGE9UmEoaGEsMik7cmV0dXJuIHhhfHwoeGE9cmEoQ2EoaGEpLGFhKSxoYS5nLnB1c2goeGEpLGhhLm09ITApLGFhLmJpbmRUZXh0dXJlKGFhLlRFWFRVUkVfMkQseGEpLHhhfWZ1bmN0aW9uIERhKGhhKXtoYS5oLmJpbmRUZXh0dXJlKGhhLmguVEVYVFVSRV8yRCxudWxsKX1mdW5jdGlvbiBOYShoYSl7Y29uc3QgYWE9T2EoaGEpO3JldHVybiBuYShDYShoYSksYWEsITAsKCk9PmZ1bmN0aW9uKHhhLGJhKXtjb25zdCBTYT14YS5jYW52YXM7aWYoU2Eud2lkdGg9PT14YS53aWR0aCYmU2EuaGVpZ2h0PT09eGEuaGVpZ2h0KXJldHVybiBiYSgpO2NvbnN0IFRhPVNhLndpZHRoLHdhPVNhLmhlaWdodDtyZXR1cm4gU2Eud2lkdGg9eGEud2lkdGgsU2EuaGVpZ2h0PXhhLmhlaWdodCx4YT1iYSgpLFNhLndpZHRoPVRhLFNhLmhlaWdodD13YSx4YX0oaGEsKCk9PntpZihhYS5iaW5kRnJhbWVidWZmZXIoYWEuRlJBTUVCVUZGRVIsbnVsbCksYWEuY2xlYXJDb2xvcigwLDAsMCwwKSxhYS5jbGVhcihhYS5DT0xPUl9CVUZGRVJfQklUKSxhYS5kcmF3QXJyYXlzKGFhLlRSSUFOR0xFX0ZBTiwwLDQpLCEoaGEuY2FudmFzIGluc3RhbmNlb2YgT2Zmc2NyZWVuQ2FudmFzKSl0aHJvdyBFcnJvcigiQ29udmVyc2lvbiB0byBJbWFnZUJpdG1hcCByZXF1aXJlcyB0aGF0IHRoZSBNZWRpYVBpcGUgVGFza3MgaXMgaW5pdGlhbGl6ZWQgd2l0aCBhbiBPZmZzY3JlZW5DYW52YXMiKTtyZXR1cm4gaGEuY2FudmFzLnRyYW5zZmVyVG9JbWFnZUJpdG1hcCgpfSkpfXZhciBVYT1jbGFzc3tjb25zdHJ1Y3RvcihoYSxhYSx4YSxiYSxTYSxUYSx3YSl7dGhpcy5nPWhhLHRoaXMuaj1hYSx0aGlzLm09eGEsdGhpcy5jYW52YXM9YmEsdGhpcy5sPVNhLHRoaXMud2lkdGg9VGEsdGhpcy5oZWlnaHQ9d2EsKHRoaXMuanx8dGhpcy5tKSYmLS1CYT09PTAmJmNvbnNvbGUuZXJyb3IoIllvdSBzZWVtIHRvIGJlIGNyZWF0aW5nIE1QSW1hZ2UgaW5zdGFuY2VzIHdpdGhvdXQgaW52b2tpbmcgLmNsb3NlKCkuIFRoaXMgbGVha3MgcmVzb3VyY2VzLiIpfUdhKCl7cmV0dXJuISFSYSh0aGlzLDApfW1hKCl7cmV0dXJuISFSYSh0aGlzLDEpfVIoKXtyZXR1cm4hIVJhKHRoaXMsMil9RWEoKXtyZXR1cm4gTWEodGhpcyl9RGEoKXt2YXIgaGE9UmEodGhpcywxKTtyZXR1cm4gaGF8fChQYSh0aGlzKSxJYSh0aGlzKSxoYT1OYSh0aGlzKSxEYSh0aGlzKSx0aGlzLmcucHVzaChoYSksdGhpcy5qPSEwKSxoYX1NKCl7cmV0dXJuIFBhKHRoaXMpfWNsb25lKCl7Y29uc3QgaGE9W107Zm9yKGNvbnN0IGFhIG9mIHRoaXMuZyl7bGV0IHhhO2lmKGFhIGluc3RhbmNlb2YgSW1hZ2VEYXRhKXhhPW5ldyBJbWFnZURhdGEoYWEuZGF0YSx0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KTtlbHNlIGlmKGFhIGluc3RhbmNlb2YgV2ViR0xUZXh0dXJlKXtjb25zdCBiYT1PYSh0aGlzKSxTYT1DYSh0aGlzKTtiYS5hY3RpdmVUZXh0dXJlKGJhLlRFWFRVUkUxKSx4YT1yYShTYSxiYSksYmEuYmluZFRleHR1cmUoYmEuVEVYVFVSRV8yRCx4YSksYmEudGV4SW1hZ2UyRChiYS5URVhUVVJFXzJELDAsYmEuUkdCQSx0aGlzLndpZHRoLHRoaXMuaGVpZ2h0LDAsYmEuUkdCQSxiYS5VTlNJR05FRF9CWVRFLG51bGwpLGJhLmJpbmRUZXh0dXJlKGJhLlRFWFRVUkVfMkQsbnVsbCksc2EoU2EsYmEseGEpLG5hKFNhLGJhLCExLCgpPT57SWEodGhpcyksYmEuY2xlYXJDb2xvcigwLDAsMCwwKSxiYS5jbGVhcihiYS5DT0xPUl9CVUZGRVJfQklUKSxiYS5kcmF3QXJyYXlzKGJhLlRSSUFOR0xFX0ZBTiwwLDQpLERhKHRoaXMpfSksaWEoU2EpLERhKHRoaXMpfWVsc2V7aWYoIShhYSBpbnN0YW5jZW9mIEltYWdlQml0bWFwKSl0aHJvdyBFcnJvcihgVHlwZSBpcyBub3Qgc3VwcG9ydGVkOiAke2FhfWApO1BhKHRoaXMpLElhKHRoaXMpLHhhPU5hKHRoaXMpLERhKHRoaXMpfWhhLnB1c2goeGEpfXJldHVybiBuZXcgVWEoaGEsdGhpcy5tYSgpLHRoaXMuUigpLHRoaXMuY2FudmFzLHRoaXMubCx0aGlzLndpZHRoLHRoaXMuaGVpZ2h0KX1jbG9zZSgpe3RoaXMuaiYmUmEodGhpcywxKS5jbG9zZSgpLHRoaXMubSYmT2EodGhpcykuZGVsZXRlVGV4dHVyZShSYSh0aGlzLDIpKSxCYT0tMX19O1VhLnByb3RvdHlwZS5jbG9zZT1VYS5wcm90b3R5cGUuY2xvc2UsVWEucHJvdG90eXBlLmNsb25lPVVhLnByb3RvdHlwZS5jbG9uZSxVYS5wcm90b3R5cGUuZ2V0QXNXZWJHTFRleHR1cmU9VWEucHJvdG90eXBlLk0sVWEucHJvdG90eXBlLmdldEFzSW1hZ2VCaXRtYXA9VWEucHJvdG90eXBlLkRhLFVhLnByb3RvdHlwZS5nZXRBc0ltYWdlRGF0YT1VYS5wcm90b3R5cGUuRWEsVWEucHJvdG90eXBlLmhhc1dlYkdMVGV4dHVyZT1VYS5wcm90b3R5cGUuUixVYS5wcm90b3R5cGUuaGFzSW1hZ2VCaXRtYXA9VWEucHJvdG90eXBlLm1hLFVhLnByb3RvdHlwZS5oYXNJbWFnZURhdGE9VWEucHJvdG90eXBlLkdhO3ZhciBCYT0yNTA7ZnVuY3Rpb24gR2EoLi4uaGEpe3JldHVybiBoYS5tYXAoKFthYSx4YV0pPT4oe3N0YXJ0OmFhLGVuZDp4YX0pKX1jb25zdCBqYT1mdW5jdGlvbihoYSl7cmV0dXJuIGNsYXNzIGV4dGVuZHMgaGF7TWEoKXt0aGlzLmkuX3JlZ2lzdGVyTW9kZWxSZXNvdXJjZXNHcmFwaFNlcnZpY2UoKX19fSgoVmE9Y2xhc3N7Y29uc3RydWN0b3IoaGEsYWEpe3RoaXMubD0hMCx0aGlzLmk9aGEsdGhpcy5nPW51bGwsdGhpcy5oPTAsdGhpcy5tPXR5cGVvZiB0aGlzLmkuX2FkZEludFRvSW5wdXRTdHJlYW09PSJmdW5jdGlvbiIsYWEhPT12b2lkIDA/dGhpcy5pLmNhbnZhcz1hYTp0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzPiJ1Inx8SW8oKT8oY29uc29sZS53YXJuKCJPZmZzY3JlZW5DYW52YXMgbm90IHN1cHBvcnRlZCBhbmQgR3JhcGhSdW5uZXIgY29uc3RydWN0b3IgZ2xDYW52YXMgcGFyYW1ldGVyIGlzIHVuZGVmaW5lZC4gQ3JlYXRpbmcgYmFja3VwIGNhbnZhcy4iKSx0aGlzLmkuY2FudmFzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNhbnZhcyIpKTp0aGlzLmkuY2FudmFzPW5ldyBPZmZzY3JlZW5DYW52YXMoMSwxKX1hc3luYyBpbml0aWFsaXplR3JhcGgoaGEpe2NvbnN0IGFhPWF3YWl0KGF3YWl0IGZldGNoKGhhKSkuYXJyYXlCdWZmZXIoKTtoYT0hKGhhLmVuZHNXaXRoKCIucGJ0eHQiKXx8aGEuZW5kc1dpdGgoIi50ZXh0cHJvdG8iKSksdGhpcy5zZXRHcmFwaChuZXcgVWludDhBcnJheShhYSksaGEpfXNldEdyYXBoRnJvbVN0cmluZyhoYSl7dGhpcy5zZXRHcmFwaChuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoaGEpLCExKX1zZXRHcmFwaChoYSxhYSl7Y29uc3QgeGE9aGEubGVuZ3RoLGJhPXRoaXMuaS5fbWFsbG9jKHhhKTt0aGlzLmkuSEVBUFU4LnNldChoYSxiYSksYWE/dGhpcy5pLl9jaGFuZ2VCaW5hcnlHcmFwaCh4YSxiYSk6dGhpcy5pLl9jaGFuZ2VUZXh0R3JhcGgoeGEsYmEpLHRoaXMuaS5fZnJlZShiYSl9Y29uZmlndXJlQXVkaW8oaGEsYWEseGEsYmEsU2Epe3RoaXMuaS5fY29uZmlndXJlQXVkaW98fGNvbnNvbGUud2FybignQXR0ZW1wdGluZyB0byB1c2UgY29uZmlndXJlQXVkaW8gd2l0aG91dCBzdXBwb3J0IGZvciBpbnB1dCBhdWRpby4gSXMgYnVpbGQgZGVwICI6Z2xfZ3JhcGhfcnVubmVyX2F1ZGlvIiBtaXNzaW5nPycpLFVvKHRoaXMsYmF8fCJpbnB1dF9hdWRpbyIsVGE9PntVbyh0aGlzLFNhPVNhfHwiYXVkaW9faGVhZGVyIix3YT0+e3RoaXMuaS5fY29uZmlndXJlQXVkaW8oVGEsd2EsaGEsYWEseGEpfSl9KX1zZXRBdXRvUmVzaXplQ2FudmFzKGhhKXt0aGlzLmw9aGF9c2V0QXV0b1JlbmRlclRvU2NyZWVuKGhhKXt0aGlzLmkuX3NldEF1dG9SZW5kZXJUb1NjcmVlbihoYSl9c2V0R3B1QnVmZmVyVmVydGljYWxGbGlwKGhhKXt0aGlzLmkuZ3B1T3JpZ2luRm9yV2ViVGV4dHVyZXNJc0JvdHRvbUxlZnQ9aGF9ZmEoaGEpe2pvKHRoaXMsIl9fZ3JhcGhfY29uZmlnX18iLGFhPT57aGEoYWEpfSksVW8odGhpcywiX19ncmFwaF9jb25maWdfXyIsYWE9Pnt0aGlzLmkuX2dldEdyYXBoQ29uZmlnKGFhLHZvaWQgMCl9KSxkZWxldGUgdGhpcy5pLnNpbXBsZUxpc3RlbmVycy5fX2dyYXBoX2NvbmZpZ19ffWF0dGFjaEVycm9yTGlzdGVuZXIoaGEpe3RoaXMuaS5lcnJvckxpc3RlbmVyPWhhfWF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoaGEsYWEpe3RoaXMuaS5lbXB0eVBhY2tldExpc3RlbmVycz10aGlzLmkuZW1wdHlQYWNrZXRMaXN0ZW5lcnN8fHt9LHRoaXMuaS5lbXB0eVBhY2tldExpc3RlbmVyc1toYV09YWF9YWRkQXVkaW9Ub1N0cmVhbShoYSxhYSx4YSl7dGhpcy5hZGRBdWRpb1RvU3RyZWFtV2l0aFNoYXBlKGhhLDAsMCxhYSx4YSl9YWRkQXVkaW9Ub1N0cmVhbVdpdGhTaGFwZShoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9NCpoYS5sZW5ndGg7dGhpcy5oIT09VGEmJih0aGlzLmcmJnRoaXMuaS5fZnJlZSh0aGlzLmcpLHRoaXMuZz10aGlzLmkuX21hbGxvYyhUYSksdGhpcy5oPVRhKSx0aGlzLmkuSEVBUEYzMi5zZXQoaGEsdGhpcy5nLzQpLFVvKHRoaXMsYmEsd2E9Pnt0aGlzLmkuX2FkZEF1ZGlvVG9JbnB1dFN0cmVhbSh0aGlzLmcsYWEseGEsd2EsU2EpfSl9YWRkR3B1QnVmZmVyVG9TdHJlYW0oaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pntjb25zdFtTYSxUYV09Qm8odGhpcyxoYSxiYSk7dGhpcy5pLl9hZGRCb3VuZFRleHR1cmVUb1N0cmVhbShiYSxTYSxUYSx4YSl9KX1hZGRCb29sVG9TdHJlYW0oaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pnt0aGlzLmkuX2FkZEJvb2xUb0lucHV0U3RyZWFtKGhhLGJhLHhhKX0pfWFkZERvdWJsZVRvU3RyZWFtKGhhLGFhLHhhKXtVbyh0aGlzLGFhLGJhPT57dGhpcy5pLl9hZGREb3VibGVUb0lucHV0U3RyZWFtKGhhLGJhLHhhKX0pfWFkZEZsb2F0VG9TdHJlYW0oaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pnt0aGlzLmkuX2FkZEZsb2F0VG9JbnB1dFN0cmVhbShoYSxiYSx4YSl9KX1hZGRJbnRUb1N0cmVhbShoYSxhYSx4YSl7VW8odGhpcyxhYSxiYT0+e3RoaXMuaS5fYWRkSW50VG9JbnB1dFN0cmVhbShoYSxiYSx4YSl9KX1hZGRTdHJpbmdUb1N0cmVhbShoYSxhYSx4YSl7VW8odGhpcyxhYSxiYT0+e1VvKHRoaXMsaGEsU2E9Pnt0aGlzLmkuX2FkZFN0cmluZ1RvSW5wdXRTdHJlYW0oU2EsYmEseGEpfSl9KX1hZGRTdHJpbmdSZWNvcmRUb1N0cmVhbShoYSxhYSx4YSl7VW8odGhpcyxhYSxiYT0+e0dvKHRoaXMsT2JqZWN0LmtleXMoaGEpLFNhPT57R28odGhpcyxPYmplY3QudmFsdWVzKGhhKSxUYT0+e3RoaXMuaS5fYWRkRmxhdEhhc2hNYXBUb0lucHV0U3RyZWFtKFNhLFRhLE9iamVjdC5rZXlzKGhhKS5sZW5ndGgsYmEseGEpfSl9KX0pfWFkZFByb3RvVG9TdHJlYW0oaGEsYWEseGEsYmEpe1VvKHRoaXMseGEsU2E9PntVbyh0aGlzLGFhLFRhPT57Y29uc3Qgd2E9dGhpcy5pLl9tYWxsb2MoaGEubGVuZ3RoKTt0aGlzLmkuSEVBUFU4LnNldChoYSx3YSksdGhpcy5pLl9hZGRQcm90b1RvSW5wdXRTdHJlYW0od2EsaGEubGVuZ3RoLFRhLFNhLGJhKSx0aGlzLmkuX2ZyZWUod2EpfSl9KX1hZGRFbXB0eVBhY2tldFRvU3RyZWFtKGhhLGFhKXtVbyh0aGlzLGhhLHhhPT57dGhpcy5pLl9hZGRFbXB0eVBhY2tldFRvSW5wdXRTdHJlYW0oeGEsYWEpfSl9YWRkQm9vbFZlY3RvclRvU3RyZWFtKGhhLGFhLHhhKXtVbyh0aGlzLGFhLGJhPT57Y29uc3QgU2E9dGhpcy5pLl9hbGxvY2F0ZUJvb2xWZWN0b3IoaGEubGVuZ3RoKTtpZighU2EpdGhyb3cgRXJyb3IoIlVuYWJsZSB0byBhbGxvY2F0ZSBuZXcgYm9vbCB2ZWN0b3Igb24gaGVhcC4iKTtmb3IoY29uc3QgVGEgb2YgaGEpdGhpcy5pLl9hZGRCb29sVmVjdG9yRW50cnkoU2EsVGEpO3RoaXMuaS5fYWRkQm9vbFZlY3RvclRvSW5wdXRTdHJlYW0oU2EsYmEseGEpfSl9YWRkRG91YmxlVmVjdG9yVG9TdHJlYW0oaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pntjb25zdCBTYT10aGlzLmkuX2FsbG9jYXRlRG91YmxlVmVjdG9yKGhhLmxlbmd0aCk7aWYoIVNhKXRocm93IEVycm9yKCJVbmFibGUgdG8gYWxsb2NhdGUgbmV3IGRvdWJsZSB2ZWN0b3Igb24gaGVhcC4iKTtmb3IoY29uc3QgVGEgb2YgaGEpdGhpcy5pLl9hZGREb3VibGVWZWN0b3JFbnRyeShTYSxUYSk7dGhpcy5pLl9hZGREb3VibGVWZWN0b3JUb0lucHV0U3RyZWFtKFNhLGJhLHhhKX0pfWFkZEZsb2F0VmVjdG9yVG9TdHJlYW0oaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pntjb25zdCBTYT10aGlzLmkuX2FsbG9jYXRlRmxvYXRWZWN0b3IoaGEubGVuZ3RoKTtpZighU2EpdGhyb3cgRXJyb3IoIlVuYWJsZSB0byBhbGxvY2F0ZSBuZXcgZmxvYXQgdmVjdG9yIG9uIGhlYXAuIik7Zm9yKGNvbnN0IFRhIG9mIGhhKXRoaXMuaS5fYWRkRmxvYXRWZWN0b3JFbnRyeShTYSxUYSk7dGhpcy5pLl9hZGRGbG9hdFZlY3RvclRvSW5wdXRTdHJlYW0oU2EsYmEseGEpfSl9YWRkSW50VmVjdG9yVG9TdHJlYW0oaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pntjb25zdCBTYT10aGlzLmkuX2FsbG9jYXRlSW50VmVjdG9yKGhhLmxlbmd0aCk7aWYoIVNhKXRocm93IEVycm9yKCJVbmFibGUgdG8gYWxsb2NhdGUgbmV3IGludCB2ZWN0b3Igb24gaGVhcC4iKTtmb3IoY29uc3QgVGEgb2YgaGEpdGhpcy5pLl9hZGRJbnRWZWN0b3JFbnRyeShTYSxUYSk7dGhpcy5pLl9hZGRJbnRWZWN0b3JUb0lucHV0U3RyZWFtKFNhLGJhLHhhKX0pfWFkZFN0cmluZ1ZlY3RvclRvU3RyZWFtKGhhLGFhLHhhKXtVbyh0aGlzLGFhLGJhPT57Y29uc3QgU2E9dGhpcy5pLl9hbGxvY2F0ZVN0cmluZ1ZlY3RvcihoYS5sZW5ndGgpO2lmKCFTYSl0aHJvdyBFcnJvcigiVW5hYmxlIHRvIGFsbG9jYXRlIG5ldyBzdHJpbmcgdmVjdG9yIG9uIGhlYXAuIik7Zm9yKGNvbnN0IFRhIG9mIGhhKVVvKHRoaXMsVGEsd2E9Pnt0aGlzLmkuX2FkZFN0cmluZ1ZlY3RvckVudHJ5KFNhLHdhKX0pO3RoaXMuaS5fYWRkU3RyaW5nVmVjdG9yVG9JbnB1dFN0cmVhbShTYSxiYSx4YSl9KX1hZGRCb29sVG9JbnB1dFNpZGVQYWNrZXQoaGEsYWEpe1VvKHRoaXMsYWEseGE9Pnt0aGlzLmkuX2FkZEJvb2xUb0lucHV0U2lkZVBhY2tldChoYSx4YSl9KX1hZGREb3VibGVUb0lucHV0U2lkZVBhY2tldChoYSxhYSl7VW8odGhpcyxhYSx4YT0+e3RoaXMuaS5fYWRkRG91YmxlVG9JbnB1dFNpZGVQYWNrZXQoaGEseGEpfSl9YWRkRmxvYXRUb0lucHV0U2lkZVBhY2tldChoYSxhYSl7VW8odGhpcyxhYSx4YT0+e3RoaXMuaS5fYWRkRmxvYXRUb0lucHV0U2lkZVBhY2tldChoYSx4YSl9KX1hZGRJbnRUb0lucHV0U2lkZVBhY2tldChoYSxhYSl7VW8odGhpcyxhYSx4YT0+e3RoaXMuaS5fYWRkSW50VG9JbnB1dFNpZGVQYWNrZXQoaGEseGEpfSl9YWRkU3RyaW5nVG9JbnB1dFNpZGVQYWNrZXQoaGEsYWEpe1VvKHRoaXMsYWEseGE9PntVbyh0aGlzLGhhLGJhPT57dGhpcy5pLl9hZGRTdHJpbmdUb0lucHV0U2lkZVBhY2tldChiYSx4YSl9KX0pfWFkZFByb3RvVG9JbnB1dFNpZGVQYWNrZXQoaGEsYWEseGEpe1VvKHRoaXMseGEsYmE9PntVbyh0aGlzLGFhLFNhPT57Y29uc3QgVGE9dGhpcy5pLl9tYWxsb2MoaGEubGVuZ3RoKTt0aGlzLmkuSEVBUFU4LnNldChoYSxUYSksdGhpcy5pLl9hZGRQcm90b1RvSW5wdXRTaWRlUGFja2V0KFRhLGhhLmxlbmd0aCxTYSxiYSksdGhpcy5pLl9mcmVlKFRhKX0pfSl9YWRkQm9vbFZlY3RvclRvSW5wdXRTaWRlUGFja2V0KGhhLGFhKXtVbyh0aGlzLGFhLHhhPT57Y29uc3QgYmE9dGhpcy5pLl9hbGxvY2F0ZUJvb2xWZWN0b3IoaGEubGVuZ3RoKTtpZighYmEpdGhyb3cgRXJyb3IoIlVuYWJsZSB0byBhbGxvY2F0ZSBuZXcgYm9vbCB2ZWN0b3Igb24gaGVhcC4iKTtmb3IoY29uc3QgU2Egb2YgaGEpdGhpcy5pLl9hZGRCb29sVmVjdG9yRW50cnkoYmEsU2EpO3RoaXMuaS5fYWRkQm9vbFZlY3RvclRvSW5wdXRTaWRlUGFja2V0KGJhLHhhKX0pfWFkZERvdWJsZVZlY3RvclRvSW5wdXRTaWRlUGFja2V0KGhhLGFhKXtVbyh0aGlzLGFhLHhhPT57Y29uc3QgYmE9dGhpcy5pLl9hbGxvY2F0ZURvdWJsZVZlY3RvcihoYS5sZW5ndGgpO2lmKCFiYSl0aHJvdyBFcnJvcigiVW5hYmxlIHRvIGFsbG9jYXRlIG5ldyBkb3VibGUgdmVjdG9yIG9uIGhlYXAuIik7Zm9yKGNvbnN0IFNhIG9mIGhhKXRoaXMuaS5fYWRkRG91YmxlVmVjdG9yRW50cnkoYmEsU2EpO3RoaXMuaS5fYWRkRG91YmxlVmVjdG9yVG9JbnB1dFNpZGVQYWNrZXQoYmEseGEpfSl9YWRkRmxvYXRWZWN0b3JUb0lucHV0U2lkZVBhY2tldChoYSxhYSl7VW8odGhpcyxhYSx4YT0+e2NvbnN0IGJhPXRoaXMuaS5fYWxsb2NhdGVGbG9hdFZlY3RvcihoYS5sZW5ndGgpO2lmKCFiYSl0aHJvdyBFcnJvcigiVW5hYmxlIHRvIGFsbG9jYXRlIG5ldyBmbG9hdCB2ZWN0b3Igb24gaGVhcC4iKTtmb3IoY29uc3QgU2Egb2YgaGEpdGhpcy5pLl9hZGRGbG9hdFZlY3RvckVudHJ5KGJhLFNhKTt0aGlzLmkuX2FkZEZsb2F0VmVjdG9yVG9JbnB1dFNpZGVQYWNrZXQoYmEseGEpfSl9YWRkSW50VmVjdG9yVG9JbnB1dFNpZGVQYWNrZXQoaGEsYWEpe1VvKHRoaXMsYWEseGE9Pntjb25zdCBiYT10aGlzLmkuX2FsbG9jYXRlSW50VmVjdG9yKGhhLmxlbmd0aCk7aWYoIWJhKXRocm93IEVycm9yKCJVbmFibGUgdG8gYWxsb2NhdGUgbmV3IGludCB2ZWN0b3Igb24gaGVhcC4iKTtmb3IoY29uc3QgU2Egb2YgaGEpdGhpcy5pLl9hZGRJbnRWZWN0b3JFbnRyeShiYSxTYSk7dGhpcy5pLl9hZGRJbnRWZWN0b3JUb0lucHV0U2lkZVBhY2tldChiYSx4YSl9KX1hZGRTdHJpbmdWZWN0b3JUb0lucHV0U2lkZVBhY2tldChoYSxhYSl7VW8odGhpcyxhYSx4YT0+e2NvbnN0IGJhPXRoaXMuaS5fYWxsb2NhdGVTdHJpbmdWZWN0b3IoaGEubGVuZ3RoKTtpZighYmEpdGhyb3cgRXJyb3IoIlVuYWJsZSB0byBhbGxvY2F0ZSBuZXcgc3RyaW5nIHZlY3RvciBvbiBoZWFwLiIpO2Zvcihjb25zdCBTYSBvZiBoYSlVbyh0aGlzLFNhLFRhPT57dGhpcy5pLl9hZGRTdHJpbmdWZWN0b3JFbnRyeShiYSxUYSl9KTt0aGlzLmkuX2FkZFN0cmluZ1ZlY3RvclRvSW5wdXRTaWRlUGFja2V0KGJhLHhhKX0pfWF0dGFjaEJvb2xMaXN0ZW5lcihoYSxhYSl7am8odGhpcyxoYSxhYSksVW8odGhpcyxoYSx4YT0+e3RoaXMuaS5fYXR0YWNoQm9vbExpc3RlbmVyKHhhKX0pfWF0dGFjaEJvb2xWZWN0b3JMaXN0ZW5lcihoYSxhYSl7Vm8odGhpcyxoYSxhYSksVW8odGhpcyxoYSx4YT0+e3RoaXMuaS5fYXR0YWNoQm9vbFZlY3Rvckxpc3RlbmVyKHhhKX0pfWF0dGFjaEludExpc3RlbmVyKGhhLGFhKXtqbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLHhhPT57dGhpcy5pLl9hdHRhY2hJbnRMaXN0ZW5lcih4YSl9KX1hdHRhY2hJbnRWZWN0b3JMaXN0ZW5lcihoYSxhYSl7Vm8odGhpcyxoYSxhYSksVW8odGhpcyxoYSx4YT0+e3RoaXMuaS5fYXR0YWNoSW50VmVjdG9yTGlzdGVuZXIoeGEpfSl9YXR0YWNoRG91YmxlTGlzdGVuZXIoaGEsYWEpe2pvKHRoaXMsaGEsYWEpLFVvKHRoaXMsaGEseGE9Pnt0aGlzLmkuX2F0dGFjaERvdWJsZUxpc3RlbmVyKHhhKX0pfWF0dGFjaERvdWJsZVZlY3Rvckxpc3RlbmVyKGhhLGFhKXtWbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLHhhPT57dGhpcy5pLl9hdHRhY2hEb3VibGVWZWN0b3JMaXN0ZW5lcih4YSl9KX1hdHRhY2hGbG9hdExpc3RlbmVyKGhhLGFhKXtqbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLHhhPT57dGhpcy5pLl9hdHRhY2hGbG9hdExpc3RlbmVyKHhhKX0pfWF0dGFjaEZsb2F0VmVjdG9yTGlzdGVuZXIoaGEsYWEpe1ZvKHRoaXMsaGEsYWEpLFVvKHRoaXMsaGEseGE9Pnt0aGlzLmkuX2F0dGFjaEZsb2F0VmVjdG9yTGlzdGVuZXIoeGEpfSl9YXR0YWNoU3RyaW5nTGlzdGVuZXIoaGEsYWEpe2pvKHRoaXMsaGEsYWEpLFVvKHRoaXMsaGEseGE9Pnt0aGlzLmkuX2F0dGFjaFN0cmluZ0xpc3RlbmVyKHhhKX0pfWF0dGFjaFN0cmluZ1ZlY3Rvckxpc3RlbmVyKGhhLGFhKXtWbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLHhhPT57dGhpcy5pLl9hdHRhY2hTdHJpbmdWZWN0b3JMaXN0ZW5lcih4YSl9KX1hdHRhY2hQcm90b0xpc3RlbmVyKGhhLGFhLHhhKXtqbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLGJhPT57dGhpcy5pLl9hdHRhY2hQcm90b0xpc3RlbmVyKGJhLHhhfHwhMSl9KX1hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKGhhLGFhLHhhKXtWbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLGJhPT57dGhpcy5pLl9hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKGJhLHhhfHwhMSl9KX1hdHRhY2hBdWRpb0xpc3RlbmVyKGhhLGFhLHhhKXt0aGlzLmkuX2F0dGFjaEF1ZGlvTGlzdGVuZXJ8fGNvbnNvbGUud2FybignQXR0ZW1wdGluZyB0byB1c2UgYXR0YWNoQXVkaW9MaXN0ZW5lciB3aXRob3V0IHN1cHBvcnQgZm9yIG91dHB1dCBhdWRpby4gSXMgYnVpbGQgZGVwICI6Z2xfZ3JhcGhfcnVubmVyX2F1ZGlvX291dCIgbWlzc2luZz8nKSxqbyh0aGlzLGhhLChiYSxTYSk9PntiYT1uZXcgRmxvYXQzMkFycmF5KGJhLmJ1ZmZlcixiYS5ieXRlT2Zmc2V0LGJhLmxlbmd0aC80KSxhYShiYSxTYSl9KSxVbyh0aGlzLGhhLGJhPT57dGhpcy5pLl9hdHRhY2hBdWRpb0xpc3RlbmVyKGJhLHhhfHwhMSl9KX1maW5pc2hQcm9jZXNzaW5nKCl7dGhpcy5pLl93YWl0VW50aWxJZGxlKCl9Y2xvc2VHcmFwaCgpe3RoaXMuaS5fY2xvc2VHcmFwaCgpLHRoaXMuaS5zaW1wbGVMaXN0ZW5lcnM9dm9pZCAwLHRoaXMuaS5lbXB0eVBhY2tldExpc3RlbmVycz12b2lkIDB9fSxjbGFzcyBleHRlbmRzIFZhe2dldCBoYSgpe3JldHVybiB0aGlzLml9c2EoaGEsYWEseGEpe1VvKHRoaXMsYWEsYmE9Pntjb25zdFtTYSxUYV09Qm8odGhpcyxoYSxiYSk7dGhpcy5oYS5fYWRkQm91bmRUZXh0dXJlQXNJbWFnZVRvU3RyZWFtKGJhLFNhLFRhLHhhKX0pfVcoaGEsYWEpe2pvKHRoaXMsaGEsYWEpLFVvKHRoaXMsaGEseGE9Pnt0aGlzLmhhLl9hdHRhY2hJbWFnZUxpc3RlbmVyKHhhKX0pfWRhKGhhLGFhKXtWbyh0aGlzLGhhLGFhKSxVbyh0aGlzLGhhLHhhPT57dGhpcy5oYS5fYXR0YWNoSW1hZ2VWZWN0b3JMaXN0ZW5lcih4YSl9KX19KSk7dmFyIFZhLFhhPWNsYXNzIGV4dGVuZHMgamF7fTthc3luYyBmdW5jdGlvbiBIYShoYSxhYSx4YSl7cmV0dXJuIGFzeW5jIGZ1bmN0aW9uKGJhLFNhLFRhLHdhKXtyZXR1cm4gWG8oYmEsU2EsVGEsd2EpfShoYSx4YS5jYW52YXM/Pyh0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzPiJ1Inx8SW8oKT9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKTp2b2lkIDApLGFhLHhhKX1mdW5jdGlvbiBXYShoYSxhYSx4YSxiYSl7aWYoaGEuVil7Y29uc3QgVGE9bmV3IHNpO2lmKHhhIT1udWxsJiZ4YS5yZWdpb25PZkludGVyZXN0KXtpZighaGEucmEpdGhyb3cgRXJyb3IoIlRoaXMgdGFzayBkb2Vzbid0IHN1cHBvcnQgcmVnaW9uLW9mLWludGVyZXN0LiIpO3ZhciBTYT14YS5yZWdpb25PZkludGVyZXN0O2lmKFNhLmxlZnQ+PVNhLnJpZ2h0fHxTYS50b3A+PVNhLmJvdHRvbSl0aHJvdyBFcnJvcigiRXhwZWN0ZWQgUmVjdEYgd2l0aCBsZWZ0IDwgcmlnaHQgYW5kIHRvcCA8IGJvdHRvbS4iKTtpZigwPlNhLmxlZnR8fDA+U2EudG9wfHwxPFNhLnJpZ2h0fHwxPFNhLmJvdHRvbSl0aHJvdyBFcnJvcigiRXhwZWN0ZWQgUmVjdEYgdmFsdWVzIHRvIGJlIGluIFswLDFdLiIpO0luKFRhLDEsKFNhLmxlZnQrU2EucmlnaHQpLzIpLEluKFRhLDIsKFNhLnRvcCtTYS5ib3R0b20pLzIpLEluKFRhLDQsU2EucmlnaHQtU2EubGVmdCksSW4oVGEsMyxTYS5ib3R0b20tU2EudG9wKX1lbHNlIEluKFRhLDEsLjUpLEluKFRhLDIsLjUpLEluKFRhLDQsMSksSW4oVGEsMywxKTtpZih4YSE9bnVsbCYmeGEucm90YXRpb25EZWdyZWVzKXtpZigoeGE9PW51bGw/dm9pZCAwOnhhLnJvdGF0aW9uRGVncmVlcyklOTAhPTApdGhyb3cgRXJyb3IoIkV4cGVjdGVkIHJvdGF0aW9uIHRvIGJlIGEgbXVsdGlwbGUgb2YgOTDCsC4iKTtpZihJbihUYSw1LC1NYXRoLlBJKnhhLnJvdGF0aW9uRGVncmVlcy8xODApLCh4YT09bnVsbD92b2lkIDA6eGEucm90YXRpb25EZWdyZWVzKSUxODAhPTApe2NvbnN0W3dhLEVhXT1ObyhhYSk7eGE9UG4oVGEsMykqRWEvd2EsU2E9UG4oVGEsNCkqd2EvRWEsSW4oVGEsNCx4YSksSW4oVGEsMyxTYSl9fWhhLmcuYWRkUHJvdG9Ub1N0cmVhbShUYS5nKCksIm1lZGlhcGlwZS5Ob3JtYWxpemVkUmVjdCIsaGEuVixiYSl9aGEuZy5zYShhYSxoYS5iYSxiYT8/cGVyZm9ybWFuY2Uubm93KCkpLGhhLmZpbmlzaFByb2Nlc3NpbmcoKX1mdW5jdGlvbiB6YShoYSxhYSx4YSl7dmFyIGJhO2lmKChiYT1oYS5iYXNlT3B0aW9ucykhPW51bGwmJmJhLmcoKSl0aHJvdyBFcnJvcigiVGFzayBpcyBub3QgaW5pdGlhbGl6ZWQgd2l0aCBpbWFnZSBtb2RlLiAncnVubmluZ01vZGUnIG11c3QgYmUgc2V0IHRvICdJTUFHRScuIik7V2EoaGEsYWEseGEsaGEuQysxKX1mdW5jdGlvbiBLYShoYSxhYSx4YSxiYSl7dmFyIFNhO2lmKCEoKFNhPWhhLmJhc2VPcHRpb25zKSE9bnVsbCYmU2EuZygpKSl0aHJvdyBFcnJvcigiVGFzayBpcyBub3QgaW5pdGlhbGl6ZWQgd2l0aCB2aWRlbyBtb2RlLiAncnVubmluZ01vZGUnIG11c3QgYmUgc2V0IHRvICdWSURFTycuIik7V2EoaGEsYWEseGEsYmEpfWZ1bmN0aW9uIFlhKGhhLGFhLHhhLGJhKXt2YXIgU2E9YWEuZGF0YTtjb25zdCBUYT1hYS53aWR0aCx3YT1UYSooYWE9YWEuaGVpZ2h0KTtpZigoU2EgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxTYSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSkmJlNhLmxlbmd0aCE9PXdhKXRocm93IEVycm9yKCJVbnN1cHBvcnRlZCBjaGFubmVsIGNvdW50OiAiK1NhLmxlbmd0aC93YSk7cmV0dXJuIGhhPW5ldyBfYShbU2FdLHhhLCExLGhhLmcuaS5jYW52YXMsaGEuTyxUYSxhYSksYmE/aGEuY2xvbmUoKTpoYX12YXIgJGE9Y2xhc3MgZXh0ZW5kcyBxb3tjb25zdHJ1Y3RvcihoYSxhYSx4YSxiYSl7c3VwZXIoaGEpLHRoaXMuZz1oYSx0aGlzLmJhPWFhLHRoaXMuVj14YSx0aGlzLnJhPWJhLHRoaXMuTz1uZXcgb2F9bChoYSxhYT0hMCl7aWYoInJ1bm5pbmdNb2RlImluIGhhJiZPbih0aGlzLmJhc2VPcHRpb25zLDIsISFoYS5ydW5uaW5nTW9kZSYmaGEucnVubmluZ01vZGUhPT0iSU1BR0UiKSxoYS5jYW52YXMhPT12b2lkIDAmJnRoaXMuZy5pLmNhbnZhcyE9PWhhLmNhbnZhcyl0aHJvdyBFcnJvcigiWW91IG11c3QgY3JlYXRlIGEgbmV3IHRhc2sgdG8gcmVzZXQgdGhlIGNhbnZhcy4iKTtyZXR1cm4gc3VwZXIubChoYSxhYSl9Y2xvc2UoKXt0aGlzLk8uY2xvc2UoKSxzdXBlci5jbG9zZSgpfX07JGEucHJvdG90eXBlLmNsb3NlPSRhLnByb3RvdHlwZS5jbG9zZTt2YXIgcWE9Y2xhc3MgZXh0ZW5kcyAkYXtjb25zdHJ1Y3RvcihoYSxhYSl7c3VwZXIobmV3IFhhKGhhLGFhKSwiaW1hZ2VfaW4iLCJub3JtX3JlY3RfaW4iLCExKSx0aGlzLmo9e2RldGVjdGlvbnM6W119LGtuKGhhPXRoaXMuaD1uZXcgeGksMCwxLGFhPW5ldyBiaSksSW4odGhpcy5oLDIsLjUpLEluKHRoaXMuaCwzLC4zKX1nZXQgYmFzZU9wdGlvbnMoKXtyZXR1cm4gVG4odGhpcy5oLGJpLDEpfXNldCBiYXNlT3B0aW9ucyhoYSl7a24odGhpcy5oLDAsMSxoYSl9byhoYSl7cmV0dXJuIm1pbkRldGVjdGlvbkNvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMuaCwyLGhhLm1pbkRldGVjdGlvbkNvbmZpZGVuY2U/Py41KSwibWluU3VwcHJlc3Npb25UaHJlc2hvbGQiaW4gaGEmJkluKHRoaXMuaCwzLGhhLm1pblN1cHByZXNzaW9uVGhyZXNob2xkPz8uMyksdGhpcy5sKGhhKX1GKGhhLGFhKXtyZXR1cm4gdGhpcy5qPXtkZXRlY3Rpb25zOltdfSx6YSh0aGlzLGhhLGFhKSx0aGlzLmp9RyhoYSxhYSx4YSl7cmV0dXJuIHRoaXMuaj17ZGV0ZWN0aW9uczpbXX0sS2EodGhpcyxoYSx4YSxhYSksdGhpcy5qfW0oKXt2YXIgaGE9bmV3IExzO3hzKGhhLCJpbWFnZV9pbiIpLHhzKGhhLCJub3JtX3JlY3RfaW4iKSxTcyhoYSwiZGV0ZWN0aW9ucyIpO2NvbnN0IGFhPW5ldyBocztEbihhYSxMaSx0aGlzLmgpO2NvbnN0IHhhPW5ldyB2czttcyh4YSwibWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5mYWNlX2RldGVjdG9yLkZhY2VEZXRlY3RvckdyYXBoIikseXMoeGEsIklNQUdFOmltYWdlX2luIikseXMoeGEsIk5PUk1fUkVDVDpub3JtX3JlY3RfaW4iKSxfcyh4YSwiREVURUNUSU9OUzpkZXRlY3Rpb25zIikseGEubyhhYSksa3MoaGEseGEpLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJkZXRlY3Rpb25zIiwoYmEsU2EpPT57Zm9yKGNvbnN0IFRhIG9mIGJhKWJhPUtzKFRhKSx0aGlzLmouZGV0ZWN0aW9ucy5wdXNoKGtvKGJhKSk7em8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiZGV0ZWN0aW9ucyIsYmE9Pnt6byh0aGlzLGJhKX0pLGhhPWhhLmcoKSx0aGlzLnNldEdyYXBoKG5ldyBVaW50OEFycmF5KGhhKSwhMCl9fTtxYS5wcm90b3R5cGUuZGV0ZWN0Rm9yVmlkZW89cWEucHJvdG90eXBlLkcscWEucHJvdG90eXBlLmRldGVjdD1xYS5wcm90b3R5cGUuRixxYS5wcm90b3R5cGUuc2V0T3B0aW9ucz1xYS5wcm90b3R5cGUubyxxYS5jcmVhdGVGcm9tTW9kZWxQYXRoPWFzeW5jIGZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gSGEocWEsaGEse2Jhc2VPcHRpb25zOnttb2RlbEFzc2V0UGF0aDphYX19KX0scWEuY3JlYXRlRnJvbU1vZGVsQnVmZmVyPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gSGEocWEsaGEse2Jhc2VPcHRpb25zOnttb2RlbEFzc2V0QnVmZmVyOmFhfX0pfSxxYS5jcmVhdGVGcm9tT3B0aW9ucz1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKHFhLGhhLGFhKX07dmFyIEphPUdhKFs2MSwxNDZdLFsxNDYsOTFdLFs5MSwxODFdLFsxODEsODRdLFs4NCwxN10sWzE3LDMxNF0sWzMxNCw0MDVdLFs0MDUsMzIxXSxbMzIxLDM3NV0sWzM3NSwyOTFdLFs2MSwxODVdLFsxODUsNDBdLFs0MCwzOV0sWzM5LDM3XSxbMzcsMF0sWzAsMjY3XSxbMjY3LDI2OV0sWzI2OSwyNzBdLFsyNzAsNDA5XSxbNDA5LDI5MV0sWzc4LDk1XSxbOTUsODhdLFs4OCwxNzhdLFsxNzgsODddLFs4NywxNF0sWzE0LDMxN10sWzMxNyw0MDJdLFs0MDIsMzE4XSxbMzE4LDMyNF0sWzMyNCwzMDhdLFs3OCwxOTFdLFsxOTEsODBdLFs4MCw4MV0sWzgxLDgyXSxbODIsMTNdLFsxMywzMTJdLFszMTIsMzExXSxbMzExLDMxMF0sWzMxMCw0MTVdLFs0MTUsMzA4XSksWmE9R2EoWzI2MywyNDldLFsyNDksMzkwXSxbMzkwLDM3M10sWzM3MywzNzRdLFszNzQsMzgwXSxbMzgwLDM4MV0sWzM4MSwzODJdLFszODIsMzYyXSxbMjYzLDQ2Nl0sWzQ2NiwzODhdLFszODgsMzg3XSxbMzg3LDM4Nl0sWzM4NiwzODVdLFszODUsMzg0XSxbMzg0LDM5OF0sWzM5OCwzNjJdKSxRYT1HYShbMjc2LDI4M10sWzI4MywyODJdLFsyODIsMjk1XSxbMjk1LDI4NV0sWzMwMCwyOTNdLFsyOTMsMzM0XSxbMzM0LDI5Nl0sWzI5NiwzMzZdKSx0aD1HYShbNDc0LDQ3NV0sWzQ3NSw0NzZdLFs0NzYsNDc3XSxbNDc3LDQ3NF0pLGVoPUdhKFszMyw3XSxbNywxNjNdLFsxNjMsMTQ0XSxbMTQ0LDE0NV0sWzE0NSwxNTNdLFsxNTMsMTU0XSxbMTU0LDE1NV0sWzE1NSwxMzNdLFszMywyNDZdLFsyNDYsMTYxXSxbMTYxLDE2MF0sWzE2MCwxNTldLFsxNTksMTU4XSxbMTU4LDE1N10sWzE1NywxNzNdLFsxNzMsMTMzXSksbmg9R2EoWzQ2LDUzXSxbNTMsNTJdLFs1Miw2NV0sWzY1LDU1XSxbNzAsNjNdLFs2MywxMDVdLFsxMDUsNjZdLFs2NiwxMDddKSxyaD1HYShbNDY5LDQ3MF0sWzQ3MCw0NzFdLFs0NzEsNDcyXSxbNDcyLDQ2OV0pLHNoPUdhKFsxMCwzMzhdLFszMzgsMjk3XSxbMjk3LDMzMl0sWzMzMiwyODRdLFsyODQsMjUxXSxbMjUxLDM4OV0sWzM4OSwzNTZdLFszNTYsNDU0XSxbNDU0LDMyM10sWzMyMywzNjFdLFszNjEsMjg4XSxbMjg4LDM5N10sWzM5NywzNjVdLFszNjUsMzc5XSxbMzc5LDM3OF0sWzM3OCw0MDBdLFs0MDAsMzc3XSxbMzc3LDE1Ml0sWzE1MiwxNDhdLFsxNDgsMTc2XSxbMTc2LDE0OV0sWzE0OSwxNTBdLFsxNTAsMTM2XSxbMTM2LDE3Ml0sWzE3Miw1OF0sWzU4LDEzMl0sWzEzMiw5M10sWzkzLDIzNF0sWzIzNCwxMjddLFsxMjcsMTYyXSxbMTYyLDIxXSxbMjEsNTRdLFs1NCwxMDNdLFsxMDMsNjddLFs2NywxMDldLFsxMDksMTBdKSxpaD1bLi4uSmEsLi4uWmEsLi4uUWEsLi4uZWgsLi4ubmgsLi4uc2hdLG9oPUdhKFsxMjcsMzRdLFszNCwxMzldLFsxMzksMTI3XSxbMTEsMF0sWzAsMzddLFszNywxMV0sWzIzMiwyMzFdLFsyMzEsMTIwXSxbMTIwLDIzMl0sWzcyLDM3XSxbMzcsMzldLFszOSw3Ml0sWzEyOCwxMjFdLFsxMjEsNDddLFs0NywxMjhdLFsyMzIsMTIxXSxbMTIxLDEyOF0sWzEyOCwyMzJdLFsxMDQsNjldLFs2OSw2N10sWzY3LDEwNF0sWzE3NSwxNzFdLFsxNzEsMTQ4XSxbMTQ4LDE3NV0sWzExOCw1MF0sWzUwLDEwMV0sWzEwMSwxMThdLFs3MywzOV0sWzM5LDQwXSxbNDAsNzNdLFs5LDE1MV0sWzE1MSwxMDhdLFsxMDgsOV0sWzQ4LDExNV0sWzExNSwxMzFdLFsxMzEsNDhdLFsxOTQsMjA0XSxbMjA0LDIxMV0sWzIxMSwxOTRdLFs3NCw0MF0sWzQwLDE4NV0sWzE4NSw3NF0sWzgwLDQyXSxbNDIsMTgzXSxbMTgzLDgwXSxbNDAsOTJdLFs5MiwxODZdLFsxODYsNDBdLFsyMzAsMjI5XSxbMjI5LDExOF0sWzExOCwyMzBdLFsyMDIsMjEyXSxbMjEyLDIxNF0sWzIxNCwyMDJdLFs4MywxOF0sWzE4LDE3XSxbMTcsODNdLFs3Niw2MV0sWzYxLDE0Nl0sWzE0Niw3Nl0sWzE2MCwyOV0sWzI5LDMwXSxbMzAsMTYwXSxbNTYsMTU3XSxbMTU3LDE3M10sWzE3Myw1Nl0sWzEwNiwyMDRdLFsyMDQsMTk0XSxbMTk0LDEwNl0sWzEzNSwyMTRdLFsyMTQsMTkyXSxbMTkyLDEzNV0sWzIwMywxNjVdLFsxNjUsOThdLFs5OCwyMDNdLFsyMSw3MV0sWzcxLDY4XSxbNjgsMjFdLFs1MSw0NV0sWzQ1LDRdLFs0LDUxXSxbMTQ0LDI0XSxbMjQsMjNdLFsyMywxNDRdLFs3NywxNDZdLFsxNDYsOTFdLFs5MSw3N10sWzIwNSw1MF0sWzUwLDE4N10sWzE4NywyMDVdLFsyMDEsMjAwXSxbMjAwLDE4XSxbMTgsMjAxXSxbOTEsMTA2XSxbMTA2LDE4Ml0sWzE4Miw5MV0sWzkwLDkxXSxbOTEsMTgxXSxbMTgxLDkwXSxbODUsODRdLFs4NCwxN10sWzE3LDg1XSxbMjA2LDIwM10sWzIwMywzNl0sWzM2LDIwNl0sWzE0OCwxNzFdLFsxNzEsMTQwXSxbMTQwLDE0OF0sWzkyLDQwXSxbNDAsMzldLFszOSw5Ml0sWzE5MywxODldLFsxODksMjQ0XSxbMjQ0LDE5M10sWzE1OSwxNThdLFsxNTgsMjhdLFsyOCwxNTldLFsyNDcsMjQ2XSxbMjQ2LDE2MV0sWzE2MSwyNDddLFsyMzYsM10sWzMsMTk2XSxbMTk2LDIzNl0sWzU0LDY4XSxbNjgsMTA0XSxbMTA0LDU0XSxbMTkzLDE2OF0sWzE2OCw4XSxbOCwxOTNdLFsxMTcsMjI4XSxbMjI4LDMxXSxbMzEsMTE3XSxbMTg5LDE5M10sWzE5Myw1NV0sWzU1LDE4OV0sWzk4LDk3XSxbOTcsOTldLFs5OSw5OF0sWzEyNiw0N10sWzQ3LDEwMF0sWzEwMCwxMjZdLFsxNjYsNzldLFs3OSwyMThdLFsyMTgsMTY2XSxbMTU1LDE1NF0sWzE1NCwyNl0sWzI2LDE1NV0sWzIwOSw0OV0sWzQ5LDEzMV0sWzEzMSwyMDldLFsxMzUsMTM2XSxbMTM2LDE1MF0sWzE1MCwxMzVdLFs0NywxMjZdLFsxMjYsMjE3XSxbMjE3LDQ3XSxbMjIzLDUyXSxbNTIsNTNdLFs1MywyMjNdLFs0NSw1MV0sWzUxLDEzNF0sWzEzNCw0NV0sWzIxMSwxNzBdLFsxNzAsMTQwXSxbMTQwLDIxMV0sWzY3LDY5XSxbNjksMTA4XSxbMTA4LDY3XSxbNDMsMTA2XSxbMTA2LDkxXSxbOTEsNDNdLFsyMzAsMTE5XSxbMTE5LDEyMF0sWzEyMCwyMzBdLFsyMjYsMTMwXSxbMTMwLDI0N10sWzI0NywyMjZdLFs2Myw1M10sWzUzLDUyXSxbNTIsNjNdLFsyMzgsMjBdLFsyMCwyNDJdLFsyNDIsMjM4XSxbNDYsNzBdLFs3MCwxNTZdLFsxNTYsNDZdLFs3OCw2Ml0sWzYyLDk2XSxbOTYsNzhdLFs0Niw1M10sWzUzLDYzXSxbNjMsNDZdLFsxNDMsMzRdLFszNCwyMjddLFsyMjcsMTQzXSxbMTIzLDExN10sWzExNywxMTFdLFsxMTEsMTIzXSxbNDQsMTI1XSxbMTI1LDE5XSxbMTksNDRdLFsyMzYsMTM0XSxbMTM0LDUxXSxbNTEsMjM2XSxbMjE2LDIwNl0sWzIwNiwyMDVdLFsyMDUsMjE2XSxbMTU0LDE1M10sWzE1MywyMl0sWzIyLDE1NF0sWzM5LDM3XSxbMzcsMTY3XSxbMTY3LDM5XSxbMjAwLDIwMV0sWzIwMSwyMDhdLFsyMDgsMjAwXSxbMzYsMTQyXSxbMTQyLDEwMF0sWzEwMCwzNl0sWzU3LDIxMl0sWzIxMiwyMDJdLFsyMDIsNTddLFsyMCw2MF0sWzYwLDk5XSxbOTksMjBdLFsyOCwxNThdLFsxNTgsMTU3XSxbMTU3LDI4XSxbMzUsMjI2XSxbMjI2LDExM10sWzExMywzNV0sWzE2MCwxNTldLFsxNTksMjddLFsyNywxNjBdLFsyMDQsMjAyXSxbMjAyLDIxMF0sWzIxMCwyMDRdLFsxMTMsMjI1XSxbMjI1LDQ2XSxbNDYsMTEzXSxbNDMsMjAyXSxbMjAyLDIwNF0sWzIwNCw0M10sWzYyLDc2XSxbNzYsNzddLFs3Nyw2Ml0sWzEzNywxMjNdLFsxMjMsMTE2XSxbMTE2LDEzN10sWzQxLDM4XSxbMzgsNzJdLFs3Miw0MV0sWzIwMywxMjldLFsxMjksMTQyXSxbMTQyLDIwM10sWzY0LDk4XSxbOTgsMjQwXSxbMjQwLDY0XSxbNDksMTAyXSxbMTAyLDY0XSxbNjQsNDldLFs0MSw3M10sWzczLDc0XSxbNzQsNDFdLFsyMTIsMjE2XSxbMjE2LDIwN10sWzIwNywyMTJdLFs0Miw3NF0sWzc0LDE4NF0sWzE4NCw0Ml0sWzE2OSwxNzBdLFsxNzAsMjExXSxbMjExLDE2OV0sWzE3MCwxNDldLFsxNDksMTc2XSxbMTc2LDE3MF0sWzEwNSw2Nl0sWzY2LDY5XSxbNjksMTA1XSxbMTIyLDZdLFs2LDE2OF0sWzE2OCwxMjJdLFsxMjMsMTQ3XSxbMTQ3LDE4N10sWzE4NywxMjNdLFs5Niw3N10sWzc3LDkwXSxbOTAsOTZdLFs2NSw1NV0sWzU1LDEwN10sWzEwNyw2NV0sWzg5LDkwXSxbOTAsMTgwXSxbMTgwLDg5XSxbMTAxLDEwMF0sWzEwMCwxMjBdLFsxMjAsMTAxXSxbNjMsMTA1XSxbMTA1LDEwNF0sWzEwNCw2M10sWzkzLDEzN10sWzEzNywyMjddLFsyMjcsOTNdLFsxNSw4Nl0sWzg2LDg1XSxbODUsMTVdLFsxMjksMTAyXSxbMTAyLDQ5XSxbNDksMTI5XSxbMTQsODddLFs4Nyw4Nl0sWzg2LDE0XSxbNTUsOF0sWzgsOV0sWzksNTVdLFsxMDAsNDddLFs0NywxMjFdLFsxMjEsMTAwXSxbMTQ1LDIzXSxbMjMsMjJdLFsyMiwxNDVdLFs4OCw4OV0sWzg5LDE3OV0sWzE3OSw4OF0sWzYsMTIyXSxbMTIyLDE5Nl0sWzE5Niw2XSxbODgsOTVdLFs5NSw5Nl0sWzk2LDg4XSxbMTM4LDE3Ml0sWzE3MiwxMzZdLFsxMzYsMTM4XSxbMjE1LDU4XSxbNTgsMTcyXSxbMTcyLDIxNV0sWzExNSw0OF0sWzQ4LDIxOV0sWzIxOSwxMTVdLFs0Miw4MF0sWzgwLDgxXSxbODEsNDJdLFsxOTUsM10sWzMsNTFdLFs1MSwxOTVdLFs0MywxNDZdLFsxNDYsNjFdLFs2MSw0M10sWzE3MSwxNzVdLFsxNzUsMTk5XSxbMTk5LDE3MV0sWzgxLDgyXSxbODIsMzhdLFszOCw4MV0sWzUzLDQ2XSxbNDYsMjI1XSxbMjI1LDUzXSxbMTQ0LDE2M10sWzE2MywxMTBdLFsxMTAsMTQ0XSxbNTIsNjVdLFs2NSw2Nl0sWzY2LDUyXSxbMjI5LDIyOF0sWzIyOCwxMTddLFsxMTcsMjI5XSxbMzQsMTI3XSxbMTI3LDIzNF0sWzIzNCwzNF0sWzEwNywxMDhdLFsxMDgsNjldLFs2OSwxMDddLFsxMDksMTA4XSxbMTA4LDE1MV0sWzE1MSwxMDldLFs0OCw2NF0sWzY0LDIzNV0sWzIzNSw0OF0sWzYyLDc4XSxbNzgsMTkxXSxbMTkxLDYyXSxbMTI5LDIwOV0sWzIwOSwxMjZdLFsxMjYsMTI5XSxbMTExLDM1XSxbMzUsMTQzXSxbMTQzLDExMV0sWzExNywxMjNdLFsxMjMsNTBdLFs1MCwxMTddLFsyMjIsNjVdLFs2NSw1Ml0sWzUyLDIyMl0sWzE5LDEyNV0sWzEyNSwxNDFdLFsxNDEsMTldLFsyMjEsNTVdLFs1NSw2NV0sWzY1LDIyMV0sWzMsMTk1XSxbMTk1LDE5N10sWzE5NywzXSxbMjUsN10sWzcsMzNdLFszMywyNV0sWzIyMCwyMzddLFsyMzcsNDRdLFs0NCwyMjBdLFs3MCw3MV0sWzcxLDEzOV0sWzEzOSw3MF0sWzEyMiwxOTNdLFsxOTMsMjQ1XSxbMjQ1LDEyMl0sWzI0NywxMzBdLFsxMzAsMzNdLFszMywyNDddLFs3MSwyMV0sWzIxLDE2Ml0sWzE2Miw3MV0sWzE3MCwxNjldLFsxNjksMTUwXSxbMTUwLDE3MF0sWzE4OCwxNzRdLFsxNzQsMTk2XSxbMTk2LDE4OF0sWzIxNiwxODZdLFsxODYsOTJdLFs5MiwyMTZdLFsyLDk3XSxbOTcsMTY3XSxbMTY3LDJdLFsxNDEsMTI1XSxbMTI1LDI0MV0sWzI0MSwxNDFdLFsxNjQsMTY3XSxbMTY3LDM3XSxbMzcsMTY0XSxbNzIsMzhdLFszOCwxMl0sWzEyLDcyXSxbMzgsODJdLFs4MiwxM10sWzEzLDM4XSxbNjMsNjhdLFs2OCw3MV0sWzcxLDYzXSxbMjI2LDM1XSxbMzUsMTExXSxbMTExLDIyNl0sWzEwMSw1MF0sWzUwLDIwNV0sWzIwNSwxMDFdLFsyMDYsOTJdLFs5MiwxNjVdLFsxNjUsMjA2XSxbMjA5LDE5OF0sWzE5OCwyMTddLFsyMTcsMjA5XSxbMTY1LDE2N10sWzE2Nyw5N10sWzk3LDE2NV0sWzIyMCwxMTVdLFsxMTUsMjE4XSxbMjE4LDIyMF0sWzEzMywxMTJdLFsxMTIsMjQzXSxbMjQzLDEzM10sWzIzOSwyMzhdLFsyMzgsMjQxXSxbMjQxLDIzOV0sWzIxNCwxMzVdLFsxMzUsMTY5XSxbMTY5LDIxNF0sWzE5MCwxNzNdLFsxNzMsMTMzXSxbMTMzLDE5MF0sWzE3MSwyMDhdLFsyMDgsMzJdLFszMiwxNzFdLFsxMjUsNDRdLFs0NCwyMzddLFsyMzcsMTI1XSxbODYsODddLFs4NywxNzhdLFsxNzgsODZdLFs4NSw4Nl0sWzg2LDE3OV0sWzE3OSw4NV0sWzg0LDg1XSxbODUsMTgwXSxbMTgwLDg0XSxbODMsODRdLFs4NCwxODFdLFsxODEsODNdLFsyMDEsODNdLFs4MywxODJdLFsxODIsMjAxXSxbMTM3LDkzXSxbOTMsMTMyXSxbMTMyLDEzN10sWzc2LDYyXSxbNjIsMTgzXSxbMTgzLDc2XSxbNjEsNzZdLFs3NiwxODRdLFsxODQsNjFdLFs1Nyw2MV0sWzYxLDE4NV0sWzE4NSw1N10sWzIxMiw1N10sWzU3LDE4Nl0sWzE4NiwyMTJdLFsyMTQsMjA3XSxbMjA3LDE4N10sWzE4NywyMTRdLFszNCwxNDNdLFsxNDMsMTU2XSxbMTU2LDM0XSxbNzksMjM5XSxbMjM5LDIzN10sWzIzNyw3OV0sWzEyMywxMzddLFsxMzcsMTc3XSxbMTc3LDEyM10sWzQ0LDFdLFsxLDRdLFs0LDQ0XSxbMjAxLDE5NF0sWzE5NCwzMl0sWzMyLDIwMV0sWzY0LDEwMl0sWzEwMiwxMjldLFsxMjksNjRdLFsyMTMsMjE1XSxbMjE1LDEzOF0sWzEzOCwyMTNdLFs1OSwxNjZdLFsxNjYsMjE5XSxbMjE5LDU5XSxbMjQyLDk5XSxbOTksOTddLFs5NywyNDJdLFsyLDk0XSxbOTQsMTQxXSxbMTQxLDJdLFs3NSw1OV0sWzU5LDIzNV0sWzIzNSw3NV0sWzI0LDExMF0sWzExMCwyMjhdLFsyMjgsMjRdLFsyNSwxMzBdLFsxMzAsMjI2XSxbMjI2LDI1XSxbMjMsMjRdLFsyNCwyMjldLFsyMjksMjNdLFsyMiwyM10sWzIzLDIzMF0sWzIzMCwyMl0sWzI2LDIyXSxbMjIsMjMxXSxbMjMxLDI2XSxbMTEyLDI2XSxbMjYsMjMyXSxbMjMyLDExMl0sWzE4OSwxOTBdLFsxOTAsMjQzXSxbMjQzLDE4OV0sWzIyMSw1Nl0sWzU2LDE5MF0sWzE5MCwyMjFdLFsyOCw1Nl0sWzU2LDIyMV0sWzIyMSwyOF0sWzI3LDI4XSxbMjgsMjIyXSxbMjIyLDI3XSxbMjksMjddLFsyNywyMjNdLFsyMjMsMjldLFszMCwyOV0sWzI5LDIyNF0sWzIyNCwzMF0sWzI0NywzMF0sWzMwLDIyNV0sWzIyNSwyNDddLFsyMzgsNzldLFs3OSwyMF0sWzIwLDIzOF0sWzE2Niw1OV0sWzU5LDc1XSxbNzUsMTY2XSxbNjAsNzVdLFs3NSwyNDBdLFsyNDAsNjBdLFsxNDcsMTc3XSxbMTc3LDIxNV0sWzIxNSwxNDddLFsyMCw3OV0sWzc5LDE2Nl0sWzE2NiwyMF0sWzE4NywxNDddLFsxNDcsMjEzXSxbMjEzLDE4N10sWzExMiwyMzNdLFsyMzMsMjQ0XSxbMjQ0LDExMl0sWzIzMywxMjhdLFsxMjgsMjQ1XSxbMjQ1LDIzM10sWzEyOCwxMTRdLFsxMTQsMTg4XSxbMTg4LDEyOF0sWzExNCwyMTddLFsyMTcsMTc0XSxbMTc0LDExNF0sWzEzMSwxMTVdLFsxMTUsMjIwXSxbMjIwLDEzMV0sWzIxNywxOThdLFsxOTgsMjM2XSxbMjM2LDIxN10sWzE5OCwxMzFdLFsxMzEsMTM0XSxbMTM0LDE5OF0sWzE3NywxMzJdLFsxMzIsNThdLFs1OCwxNzddLFsxNDMsMzVdLFszNSwxMjRdLFsxMjQsMTQzXSxbMTEwLDE2M10sWzE2Myw3XSxbNywxMTBdLFsyMjgsMTEwXSxbMTEwLDI1XSxbMjUsMjI4XSxbMzU2LDM4OV0sWzM4OSwzNjhdLFszNjgsMzU2XSxbMTEsMzAyXSxbMzAyLDI2N10sWzI2NywxMV0sWzQ1MiwzNTBdLFszNTAsMzQ5XSxbMzQ5LDQ1Ml0sWzMwMiwzMDNdLFszMDMsMjY5XSxbMjY5LDMwMl0sWzM1NywzNDNdLFszNDMsMjc3XSxbMjc3LDM1N10sWzQ1Miw0NTNdLFs0NTMsMzU3XSxbMzU3LDQ1Ml0sWzMzMywzMzJdLFszMzIsMjk3XSxbMjk3LDMzM10sWzE3NSwxNTJdLFsxNTIsMzc3XSxbMzc3LDE3NV0sWzM0NywzNDhdLFszNDgsMzMwXSxbMzMwLDM0N10sWzMwMywzMDRdLFszMDQsMjcwXSxbMjcwLDMwM10sWzksMzM2XSxbMzM2LDMzN10sWzMzNyw5XSxbMjc4LDI3OV0sWzI3OSwzNjBdLFszNjAsMjc4XSxbNDE4LDI2Ml0sWzI2Miw0MzFdLFs0MzEsNDE4XSxbMzA0LDQwOF0sWzQwOCw0MDldLFs0MDksMzA0XSxbMzEwLDQxNV0sWzQxNSw0MDddLFs0MDcsMzEwXSxbMjcwLDQwOV0sWzQwOSw0MTBdLFs0MTAsMjcwXSxbNDUwLDM0OF0sWzM0OCwzNDddLFszNDcsNDUwXSxbNDIyLDQzMF0sWzQzMCw0MzRdLFs0MzQsNDIyXSxbMzEzLDMxNF0sWzMxNCwxN10sWzE3LDMxM10sWzMwNiwzMDddLFszMDcsMzc1XSxbMzc1LDMwNl0sWzM4NywzODhdLFszODgsMjYwXSxbMjYwLDM4N10sWzI4Niw0MTRdLFs0MTQsMzk4XSxbMzk4LDI4Nl0sWzMzNSw0MDZdLFs0MDYsNDE4XSxbNDE4LDMzNV0sWzM2NCwzNjddLFszNjcsNDE2XSxbNDE2LDM2NF0sWzQyMywzNThdLFszNTgsMzI3XSxbMzI3LDQyM10sWzI1MSwyODRdLFsyODQsMjk4XSxbMjk4LDI1MV0sWzI4MSw1XSxbNSw0XSxbNCwyODFdLFszNzMsMzc0XSxbMzc0LDI1M10sWzI1MywzNzNdLFszMDcsMzIwXSxbMzIwLDMyMV0sWzMyMSwzMDddLFs0MjUsNDI3XSxbNDI3LDQxMV0sWzQxMSw0MjVdLFs0MjEsMzEzXSxbMzEzLDE4XSxbMTgsNDIxXSxbMzIxLDQwNV0sWzQwNSw0MDZdLFs0MDYsMzIxXSxbMzIwLDQwNF0sWzQwNCw0MDVdLFs0MDUsMzIwXSxbMzE1LDE2XSxbMTYsMTddLFsxNywzMTVdLFs0MjYsNDI1XSxbNDI1LDI2Nl0sWzI2Niw0MjZdLFszNzcsNDAwXSxbNDAwLDM2OV0sWzM2OSwzNzddLFszMjIsMzkxXSxbMzkxLDI2OV0sWzI2OSwzMjJdLFs0MTcsNDY1XSxbNDY1LDQ2NF0sWzQ2NCw0MTddLFszODYsMjU3XSxbMjU3LDI1OF0sWzI1OCwzODZdLFs0NjYsMjYwXSxbMjYwLDM4OF0sWzM4OCw0NjZdLFs0NTYsMzk5XSxbMzk5LDQxOV0sWzQxOSw0NTZdLFsyODQsMzMyXSxbMzMyLDMzM10sWzMzMywyODRdLFs0MTcsMjg1XSxbMjg1LDhdLFs4LDQxN10sWzM0NiwzNDBdLFszNDAsMjYxXSxbMjYxLDM0Nl0sWzQxMyw0NDFdLFs0NDEsMjg1XSxbMjg1LDQxM10sWzMyNyw0NjBdLFs0NjAsMzI4XSxbMzI4LDMyN10sWzM1NSwzNzFdLFszNzEsMzI5XSxbMzI5LDM1NV0sWzM5Miw0MzldLFs0MzksNDM4XSxbNDM4LDM5Ml0sWzM4MiwzNDFdLFszNDEsMjU2XSxbMjU2LDM4Ml0sWzQyOSw0MjBdLFs0MjAsMzYwXSxbMzYwLDQyOV0sWzM2NCwzOTRdLFszOTQsMzc5XSxbMzc5LDM2NF0sWzI3NywzNDNdLFszNDMsNDM3XSxbNDM3LDI3N10sWzQ0Myw0NDRdLFs0NDQsMjgzXSxbMjgzLDQ0M10sWzI3NSw0NDBdLFs0NDAsMzYzXSxbMzYzLDI3NV0sWzQzMSwyNjJdLFsyNjIsMzY5XSxbMzY5LDQzMV0sWzI5NywzMzhdLFszMzgsMzM3XSxbMzM3LDI5N10sWzI3MywzNzVdLFszNzUsMzIxXSxbMzIxLDI3M10sWzQ1MCw0NTFdLFs0NTEsMzQ5XSxbMzQ5LDQ1MF0sWzQ0NiwzNDJdLFszNDIsNDY3XSxbNDY3LDQ0Nl0sWzI5MywzMzRdLFszMzQsMjgyXSxbMjgyLDI5M10sWzQ1OCw0NjFdLFs0NjEsNDYyXSxbNDYyLDQ1OF0sWzI3NiwzNTNdLFszNTMsMzgzXSxbMzgzLDI3Nl0sWzMwOCwzMjRdLFszMjQsMzI1XSxbMzI1LDMwOF0sWzI3NiwzMDBdLFszMDAsMjkzXSxbMjkzLDI3Nl0sWzM3MiwzNDVdLFszNDUsNDQ3XSxbNDQ3LDM3Ml0sWzM1MiwzNDVdLFszNDUsMzQwXSxbMzQwLDM1Ml0sWzI3NCwxXSxbMSwxOV0sWzE5LDI3NF0sWzQ1NiwyNDhdLFsyNDgsMjgxXSxbMjgxLDQ1Nl0sWzQzNiw0MjddLFs0MjcsNDI1XSxbNDI1LDQzNl0sWzM4MSwyNTZdLFsyNTYsMjUyXSxbMjUyLDM4MV0sWzI2OSwzOTFdLFszOTEsMzkzXSxbMzkzLDI2OV0sWzIwMCwxOTldLFsxOTksNDI4XSxbNDI4LDIwMF0sWzI2NiwzMzBdLFszMzAsMzI5XSxbMzI5LDI2Nl0sWzI4NywyNzNdLFsyNzMsNDIyXSxbNDIyLDI4N10sWzI1MCw0NjJdLFs0NjIsMzI4XSxbMzI4LDI1MF0sWzI1OCwyODZdLFsyODYsMzg0XSxbMzg0LDI1OF0sWzI2NSwzNTNdLFszNTMsMzQyXSxbMzQyLDI2NV0sWzM4NywyNTldLFsyNTksMjU3XSxbMjU3LDM4N10sWzQyNCw0MzFdLFs0MzEsNDMwXSxbNDMwLDQyNF0sWzM0MiwzNTNdLFszNTMsMjc2XSxbMjc2LDM0Ml0sWzI3MywzMzVdLFszMzUsNDI0XSxbNDI0LDI3M10sWzI5MiwzMjVdLFszMjUsMzA3XSxbMzA3LDI5Ml0sWzM2Niw0NDddLFs0NDcsMzQ1XSxbMzQ1LDM2Nl0sWzI3MSwzMDNdLFszMDMsMzAyXSxbMzAyLDI3MV0sWzQyMywyNjZdLFsyNjYsMzcxXSxbMzcxLDQyM10sWzI5NCw0NTVdLFs0NTUsNDYwXSxbNDYwLDI5NF0sWzI3OSwyNzhdLFsyNzgsMjk0XSxbMjk0LDI3OV0sWzI3MSwyNzJdLFsyNzIsMzA0XSxbMzA0LDI3MV0sWzQzMiw0MzRdLFs0MzQsNDI3XSxbNDI3LDQzMl0sWzI3Miw0MDddLFs0MDcsNDA4XSxbNDA4LDI3Ml0sWzM5NCw0MzBdLFs0MzAsNDMxXSxbNDMxLDM5NF0sWzM5NSwzNjldLFszNjksNDAwXSxbNDAwLDM5NV0sWzMzNCwzMzNdLFszMzMsMjk5XSxbMjk5LDMzNF0sWzM1MSw0MTddLFs0MTcsMTY4XSxbMTY4LDM1MV0sWzM1MiwyODBdLFsyODAsNDExXSxbNDExLDM1Ml0sWzMyNSwzMTldLFszMTksMzIwXSxbMzIwLDMyNV0sWzI5NSwyOTZdLFsyOTYsMzM2XSxbMzM2LDI5NV0sWzMxOSw0MDNdLFs0MDMsNDA0XSxbNDA0LDMxOV0sWzMzMCwzNDhdLFszNDgsMzQ5XSxbMzQ5LDMzMF0sWzI5MywyOThdLFsyOTgsMzMzXSxbMzMzLDI5M10sWzMyMyw0NTRdLFs0NTQsNDQ3XSxbNDQ3LDMyM10sWzE1LDE2XSxbMTYsMzE1XSxbMzE1LDE1XSxbMzU4LDQyOV0sWzQyOSwyNzldLFsyNzksMzU4XSxbMTQsMTVdLFsxNSwzMTZdLFszMTYsMTRdLFsyODUsMzM2XSxbMzM2LDldLFs5LDI4NV0sWzMyOSwzNDldLFszNDksMzUwXSxbMzUwLDMyOV0sWzM3NCwzODBdLFszODAsMjUyXSxbMjUyLDM3NF0sWzMxOCw0MDJdLFs0MDIsNDAzXSxbNDAzLDMxOF0sWzYsMTk3XSxbMTk3LDQxOV0sWzQxOSw2XSxbMzE4LDMxOV0sWzMxOSwzMjVdLFszMjUsMzE4XSxbMzY3LDM2NF0sWzM2NCwzNjVdLFszNjUsMzY3XSxbNDM1LDM2N10sWzM2NywzOTddLFszOTcsNDM1XSxbMzQ0LDQzOF0sWzQzOCw0MzldLFs0MzksMzQ0XSxbMjcyLDI3MV0sWzI3MSwzMTFdLFszMTEsMjcyXSxbMTk1LDVdLFs1LDI4MV0sWzI4MSwxOTVdLFsyNzMsMjg3XSxbMjg3LDI5MV0sWzI5MSwyNzNdLFszOTYsNDI4XSxbNDI4LDE5OV0sWzE5OSwzOTZdLFszMTEsMjcxXSxbMjcxLDI2OF0sWzI2OCwzMTFdLFsyODMsNDQ0XSxbNDQ0LDQ0NV0sWzQ0NSwyODNdLFszNzMsMjU0XSxbMjU0LDMzOV0sWzMzOSwzNzNdLFsyODIsMzM0XSxbMzM0LDI5Nl0sWzI5NiwyODJdLFs0NDksMzQ3XSxbMzQ3LDM0Nl0sWzM0Niw0NDldLFsyNjQsNDQ3XSxbNDQ3LDQ1NF0sWzQ1NCwyNjRdLFszMzYsMjk2XSxbMjk2LDI5OV0sWzI5OSwzMzZdLFszMzgsMTBdLFsxMCwxNTFdLFsxNTEsMzM4XSxbMjc4LDQzOV0sWzQzOSw0NTVdLFs0NTUsMjc4XSxbMjkyLDQwN10sWzQwNyw0MTVdLFs0MTUsMjkyXSxbMzU4LDM3MV0sWzM3MSwzNTVdLFszNTUsMzU4XSxbMzQwLDM0NV0sWzM0NSwzNzJdLFszNzIsMzQwXSxbMzQ2LDM0N10sWzM0NywyODBdLFsyODAsMzQ2XSxbNDQyLDQ0M10sWzQ0MywyODJdLFsyODIsNDQyXSxbMTksOTRdLFs5NCwzNzBdLFszNzAsMTldLFs0NDEsNDQyXSxbNDQyLDI5NV0sWzI5NSw0NDFdLFsyNDgsNDE5XSxbNDE5LDE5N10sWzE5NywyNDhdLFsyNjMsMjU1XSxbMjU1LDM1OV0sWzM1OSwyNjNdLFs0NDAsMjc1XSxbMjc1LDI3NF0sWzI3NCw0NDBdLFszMDAsMzgzXSxbMzgzLDM2OF0sWzM2OCwzMDBdLFszNTEsNDEyXSxbNDEyLDQ2NV0sWzQ2NSwzNTFdLFsyNjMsNDY3XSxbNDY3LDQ2Nl0sWzQ2NiwyNjNdLFszMDEsMzY4XSxbMzY4LDM4OV0sWzM4OSwzMDFdLFszOTUsMzc4XSxbMzc4LDM3OV0sWzM3OSwzOTVdLFs0MTIsMzUxXSxbMzUxLDQxOV0sWzQxOSw0MTJdLFs0MzYsNDI2XSxbNDI2LDMyMl0sWzMyMiw0MzZdLFsyLDE2NF0sWzE2NCwzOTNdLFszOTMsMl0sWzM3MCw0NjJdLFs0NjIsNDYxXSxbNDYxLDM3MF0sWzE2NCwwXSxbMCwyNjddLFsyNjcsMTY0XSxbMzAyLDExXSxbMTEsMTJdLFsxMiwzMDJdLFsyNjgsMTJdLFsxMiwxM10sWzEzLDI2OF0sWzI5MywzMDBdLFszMDAsMzAxXSxbMzAxLDI5M10sWzQ0NiwyNjFdLFsyNjEsMzQwXSxbMzQwLDQ0Nl0sWzMzMCwyNjZdLFsyNjYsNDI1XSxbNDI1LDMzMF0sWzQyNiw0MjNdLFs0MjMsMzkxXSxbMzkxLDQyNl0sWzQyOSwzNTVdLFszNTUsNDM3XSxbNDM3LDQyOV0sWzM5MSwzMjddLFszMjcsMzI2XSxbMzI2LDM5MV0sWzQ0MCw0NTddLFs0NTcsNDM4XSxbNDM4LDQ0MF0sWzM0MSwzODJdLFszODIsMzYyXSxbMzYyLDM0MV0sWzQ1OSw0NTddLFs0NTcsNDYxXSxbNDYxLDQ1OV0sWzQzNCw0MzBdLFs0MzAsMzk0XSxbMzk0LDQzNF0sWzQxNCw0NjNdLFs0NjMsMzYyXSxbMzYyLDQxNF0sWzM5NiwzNjldLFszNjksMjYyXSxbMjYyLDM5Nl0sWzM1NCw0NjFdLFs0NjEsNDU3XSxbNDU3LDM1NF0sWzMxNiw0MDNdLFs0MDMsNDAyXSxbNDAyLDMxNl0sWzMxNSw0MDRdLFs0MDQsNDAzXSxbNDAzLDMxNV0sWzMxNCw0MDVdLFs0MDUsNDA0XSxbNDA0LDMxNF0sWzMxMyw0MDZdLFs0MDYsNDA1XSxbNDA1LDMxM10sWzQyMSw0MThdLFs0MTgsNDA2XSxbNDA2LDQyMV0sWzM2Niw0MDFdLFs0MDEsMzYxXSxbMzYxLDM2Nl0sWzMwNiw0MDhdLFs0MDgsNDA3XSxbNDA3LDMwNl0sWzI5MSw0MDldLFs0MDksNDA4XSxbNDA4LDI5MV0sWzI4Nyw0MTBdLFs0MTAsNDA5XSxbNDA5LDI4N10sWzQzMiw0MzZdLFs0MzYsNDEwXSxbNDEwLDQzMl0sWzQzNCw0MTZdLFs0MTYsNDExXSxbNDExLDQzNF0sWzI2NCwzNjhdLFszNjgsMzgzXSxbMzgzLDI2NF0sWzMwOSw0MzhdLFs0MzgsNDU3XSxbNDU3LDMwOV0sWzM1MiwzNzZdLFszNzYsNDAxXSxbNDAxLDM1Ml0sWzI3NCwyNzVdLFsyNzUsNF0sWzQsMjc0XSxbNDIxLDQyOF0sWzQyOCwyNjJdLFsyNjIsNDIxXSxbMjk0LDMyN10sWzMyNywzNThdLFszNTgsMjk0XSxbNDMzLDQxNl0sWzQxNiwzNjddLFszNjcsNDMzXSxbMjg5LDQ1NV0sWzQ1NSw0MzldLFs0MzksMjg5XSxbNDYyLDM3MF0sWzM3MCwzMjZdLFszMjYsNDYyXSxbMiwzMjZdLFszMjYsMzcwXSxbMzcwLDJdLFszMDUsNDYwXSxbNDYwLDQ1NV0sWzQ1NSwzMDVdLFsyNTQsNDQ5XSxbNDQ5LDQ0OF0sWzQ0OCwyNTRdLFsyNTUsMjYxXSxbMjYxLDQ0Nl0sWzQ0NiwyNTVdLFsyNTMsNDUwXSxbNDUwLDQ0OV0sWzQ0OSwyNTNdLFsyNTIsNDUxXSxbNDUxLDQ1MF0sWzQ1MCwyNTJdLFsyNTYsNDUyXSxbNDUyLDQ1MV0sWzQ1MSwyNTZdLFszNDEsNDUzXSxbNDUzLDQ1Ml0sWzQ1MiwzNDFdLFs0MTMsNDY0XSxbNDY0LDQ2M10sWzQ2Myw0MTNdLFs0NDEsNDEzXSxbNDEzLDQxNF0sWzQxNCw0NDFdLFsyNTgsNDQyXSxbNDQyLDQ0MV0sWzQ0MSwyNThdLFsyNTcsNDQzXSxbNDQzLDQ0Ml0sWzQ0MiwyNTddLFsyNTksNDQ0XSxbNDQ0LDQ0M10sWzQ0MywyNTldLFsyNjAsNDQ1XSxbNDQ1LDQ0NF0sWzQ0NCwyNjBdLFs0NjcsMzQyXSxbMzQyLDQ0NV0sWzQ0NSw0NjddLFs0NTksNDU4XSxbNDU4LDI1MF0sWzI1MCw0NTldLFsyODksMzkyXSxbMzkyLDI5MF0sWzI5MCwyODldLFsyOTAsMzI4XSxbMzI4LDQ2MF0sWzQ2MCwyOTBdLFszNzYsNDMzXSxbNDMzLDQzNV0sWzQzNSwzNzZdLFsyNTAsMjkwXSxbMjkwLDM5Ml0sWzM5MiwyNTBdLFs0MTEsNDE2XSxbNDE2LDQzM10sWzQzMyw0MTFdLFszNDEsNDYzXSxbNDYzLDQ2NF0sWzQ2NCwzNDFdLFs0NTMsNDY0XSxbNDY0LDQ2NV0sWzQ2NSw0NTNdLFszNTcsNDY1XSxbNDY1LDQxMl0sWzQxMiwzNTddLFszNDMsNDEyXSxbNDEyLDM5OV0sWzM5OSwzNDNdLFszNjAsMzYzXSxbMzYzLDQ0MF0sWzQ0MCwzNjBdLFs0MzcsMzk5XSxbMzk5LDQ1Nl0sWzQ1Niw0MzddLFs0MjAsNDU2XSxbNDU2LDM2M10sWzM2Myw0MjBdLFs0MDEsNDM1XSxbNDM1LDI4OF0sWzI4OCw0MDFdLFszNzIsMzgzXSxbMzgzLDM1M10sWzM1MywzNzJdLFszMzksMjU1XSxbMjU1LDI0OV0sWzI0OSwzMzldLFs0NDgsMjYxXSxbMjYxLDI1NV0sWzI1NSw0NDhdLFsxMzMsMjQzXSxbMjQzLDE5MF0sWzE5MCwxMzNdLFsxMzMsMTU1XSxbMTU1LDExMl0sWzExMiwxMzNdLFszMywyNDZdLFsyNDYsMjQ3XSxbMjQ3LDMzXSxbMzMsMTMwXSxbMTMwLDI1XSxbMjUsMzNdLFszOTgsMzg0XSxbMzg0LDI4Nl0sWzI4NiwzOThdLFszNjIsMzk4XSxbMzk4LDQxNF0sWzQxNCwzNjJdLFszNjIsNDYzXSxbNDYzLDM0MV0sWzM0MSwzNjJdLFsyNjMsMzU5XSxbMzU5LDQ2N10sWzQ2NywyNjNdLFsyNjMsMjQ5XSxbMjQ5LDI1NV0sWzI1NSwyNjNdLFs0NjYsNDY3XSxbNDY3LDI2MF0sWzI2MCw0NjZdLFs3NSw2MF0sWzYwLDE2Nl0sWzE2Niw3NV0sWzIzOCwyMzldLFsyMzksNzldLFs3OSwyMzhdLFsxNjIsMTI3XSxbMTI3LDEzOV0sWzEzOSwxNjJdLFs3MiwxMV0sWzExLDM3XSxbMzcsNzJdLFsxMjEsMjMyXSxbMjMyLDEyMF0sWzEyMCwxMjFdLFs3Myw3Ml0sWzcyLDM5XSxbMzksNzNdLFsxMTQsMTI4XSxbMTI4LDQ3XSxbNDcsMTE0XSxbMjMzLDIzMl0sWzIzMiwxMjhdLFsxMjgsMjMzXSxbMTAzLDEwNF0sWzEwNCw2N10sWzY3LDEwM10sWzE1MiwxNzVdLFsxNzUsMTQ4XSxbMTQ4LDE1Ml0sWzExOSwxMThdLFsxMTgsMTAxXSxbMTAxLDExOV0sWzc0LDczXSxbNzMsNDBdLFs0MCw3NF0sWzEwNyw5XSxbOSwxMDhdLFsxMDgsMTA3XSxbNDksNDhdLFs0OCwxMzFdLFsxMzEsNDldLFszMiwxOTRdLFsxOTQsMjExXSxbMjExLDMyXSxbMTg0LDc0XSxbNzQsMTg1XSxbMTg1LDE4NF0sWzE5MSw4MF0sWzgwLDE4M10sWzE4MywxOTFdLFsxODUsNDBdLFs0MCwxODZdLFsxODYsMTg1XSxbMTE5LDIzMF0sWzIzMCwxMThdLFsxMTgsMTE5XSxbMjEwLDIwMl0sWzIwMiwyMTRdLFsyMTQsMjEwXSxbODQsODNdLFs4MywxN10sWzE3LDg0XSxbNzcsNzZdLFs3NiwxNDZdLFsxNDYsNzddLFsxNjEsMTYwXSxbMTYwLDMwXSxbMzAsMTYxXSxbMTkwLDU2XSxbNTYsMTczXSxbMTczLDE5MF0sWzE4MiwxMDZdLFsxMDYsMTk0XSxbMTk0LDE4Ml0sWzEzOCwxMzVdLFsxMzUsMTkyXSxbMTkyLDEzOF0sWzEyOSwyMDNdLFsyMDMsOThdLFs5OCwxMjldLFs1NCwyMV0sWzIxLDY4XSxbNjgsNTRdLFs1LDUxXSxbNTEsNF0sWzQsNV0sWzE0NSwxNDRdLFsxNDQsMjNdLFsyMywxNDVdLFs5MCw3N10sWzc3LDkxXSxbOTEsOTBdLFsyMDcsMjA1XSxbMjA1LDE4N10sWzE4NywyMDddLFs4MywyMDFdLFsyMDEsMThdLFsxOCw4M10sWzE4MSw5MV0sWzkxLDE4Ml0sWzE4MiwxODFdLFsxODAsOTBdLFs5MCwxODFdLFsxODEsMTgwXSxbMTYsODVdLFs4NSwxN10sWzE3LDE2XSxbMjA1LDIwNl0sWzIwNiwzNl0sWzM2LDIwNV0sWzE3NiwxNDhdLFsxNDgsMTQwXSxbMTQwLDE3Nl0sWzE2NSw5Ml0sWzkyLDM5XSxbMzksMTY1XSxbMjQ1LDE5M10sWzE5MywyNDRdLFsyNDQsMjQ1XSxbMjcsMTU5XSxbMTU5LDI4XSxbMjgsMjddLFszMCwyNDddLFsyNDcsMTYxXSxbMTYxLDMwXSxbMTc0LDIzNl0sWzIzNiwxOTZdLFsxOTYsMTc0XSxbMTAzLDU0XSxbNTQsMTA0XSxbMTA0LDEwM10sWzU1LDE5M10sWzE5Myw4XSxbOCw1NV0sWzExMSwxMTddLFsxMTcsMzFdLFszMSwxMTFdLFsyMjEsMTg5XSxbMTg5LDU1XSxbNTUsMjIxXSxbMjQwLDk4XSxbOTgsOTldLFs5OSwyNDBdLFsxNDIsMTI2XSxbMTI2LDEwMF0sWzEwMCwxNDJdLFsyMTksMTY2XSxbMTY2LDIxOF0sWzIxOCwyMTldLFsxMTIsMTU1XSxbMTU1LDI2XSxbMjYsMTEyXSxbMTk4LDIwOV0sWzIwOSwxMzFdLFsxMzEsMTk4XSxbMTY5LDEzNV0sWzEzNSwxNTBdLFsxNTAsMTY5XSxbMTE0LDQ3XSxbNDcsMjE3XSxbMjE3LDExNF0sWzIyNCwyMjNdLFsyMjMsNTNdLFs1MywyMjRdLFsyMjAsNDVdLFs0NSwxMzRdLFsxMzQsMjIwXSxbMzIsMjExXSxbMjExLDE0MF0sWzE0MCwzMl0sWzEwOSw2N10sWzY3LDEwOF0sWzEwOCwxMDldLFsxNDYsNDNdLFs0Myw5MV0sWzkxLDE0Nl0sWzIzMSwyMzBdLFsyMzAsMTIwXSxbMTIwLDIzMV0sWzExMywyMjZdLFsyMjYsMjQ3XSxbMjQ3LDExM10sWzEwNSw2M10sWzYzLDUyXSxbNTIsMTA1XSxbMjQxLDIzOF0sWzIzOCwyNDJdLFsyNDIsMjQxXSxbMTI0LDQ2XSxbNDYsMTU2XSxbMTU2LDEyNF0sWzk1LDc4XSxbNzgsOTZdLFs5Niw5NV0sWzcwLDQ2XSxbNDYsNjNdLFs2Myw3MF0sWzExNiwxNDNdLFsxNDMsMjI3XSxbMjI3LDExNl0sWzExNiwxMjNdLFsxMjMsMTExXSxbMTExLDExNl0sWzEsNDRdLFs0NCwxOV0sWzE5LDFdLFszLDIzNl0sWzIzNiw1MV0sWzUxLDNdLFsyMDcsMjE2XSxbMjE2LDIwNV0sWzIwNSwyMDddLFsyNiwxNTRdLFsxNTQsMjJdLFsyMiwyNl0sWzE2NSwzOV0sWzM5LDE2N10sWzE2NywxNjVdLFsxOTksMjAwXSxbMjAwLDIwOF0sWzIwOCwxOTldLFsxMDEsMzZdLFszNiwxMDBdLFsxMDAsMTAxXSxbNDMsNTddLFs1NywyMDJdLFsyMDIsNDNdLFsyNDIsMjBdLFsyMCw5OV0sWzk5LDI0Ml0sWzU2LDI4XSxbMjgsMTU3XSxbMTU3LDU2XSxbMTI0LDM1XSxbMzUsMTEzXSxbMTEzLDEyNF0sWzI5LDE2MF0sWzE2MCwyN10sWzI3LDI5XSxbMjExLDIwNF0sWzIwNCwyMTBdLFsyMTAsMjExXSxbMTI0LDExM10sWzExMyw0Nl0sWzQ2LDEyNF0sWzEwNiw0M10sWzQzLDIwNF0sWzIwNCwxMDZdLFs5Niw2Ml0sWzYyLDc3XSxbNzcsOTZdLFsyMjcsMTM3XSxbMTM3LDExNl0sWzExNiwyMjddLFs3Myw0MV0sWzQxLDcyXSxbNzIsNzNdLFszNiwyMDNdLFsyMDMsMTQyXSxbMTQyLDM2XSxbMjM1LDY0XSxbNjQsMjQwXSxbMjQwLDIzNV0sWzQ4LDQ5XSxbNDksNjRdLFs2NCw0OF0sWzQyLDQxXSxbNDEsNzRdLFs3NCw0Ml0sWzIxNCwyMTJdLFsyMTIsMjA3XSxbMjA3LDIxNF0sWzE4Myw0Ml0sWzQyLDE4NF0sWzE4NCwxODNdLFsyMTAsMTY5XSxbMTY5LDIxMV0sWzIxMSwyMTBdLFsxNDAsMTcwXSxbMTcwLDE3Nl0sWzE3NiwxNDBdLFsxMDQsMTA1XSxbMTA1LDY5XSxbNjksMTA0XSxbMTkzLDEyMl0sWzEyMiwxNjhdLFsxNjgsMTkzXSxbNTAsMTIzXSxbMTIzLDE4N10sWzE4Nyw1MF0sWzg5LDk2XSxbOTYsOTBdLFs5MCw4OV0sWzY2LDY1XSxbNjUsMTA3XSxbMTA3LDY2XSxbMTc5LDg5XSxbODksMTgwXSxbMTgwLDE3OV0sWzExOSwxMDFdLFsxMDEsMTIwXSxbMTIwLDExOV0sWzY4LDYzXSxbNjMsMTA0XSxbMTA0LDY4XSxbMjM0LDkzXSxbOTMsMjI3XSxbMjI3LDIzNF0sWzE2LDE1XSxbMTUsODVdLFs4NSwxNl0sWzIwOSwxMjldLFsxMjksNDldLFs0OSwyMDldLFsxNSwxNF0sWzE0LDg2XSxbODYsMTVdLFsxMDcsNTVdLFs1NSw5XSxbOSwxMDddLFsxMjAsMTAwXSxbMTAwLDEyMV0sWzEyMSwxMjBdLFsxNTMsMTQ1XSxbMTQ1LDIyXSxbMjIsMTUzXSxbMTc4LDg4XSxbODgsMTc5XSxbMTc5LDE3OF0sWzE5Nyw2XSxbNiwxOTZdLFsxOTYsMTk3XSxbODksODhdLFs4OCw5Nl0sWzk2LDg5XSxbMTM1LDEzOF0sWzEzOCwxMzZdLFsxMzYsMTM1XSxbMTM4LDIxNV0sWzIxNSwxNzJdLFsxNzIsMTM4XSxbMjE4LDExNV0sWzExNSwyMTldLFsyMTksMjE4XSxbNDEsNDJdLFs0Miw4MV0sWzgxLDQxXSxbNSwxOTVdLFsxOTUsNTFdLFs1MSw1XSxbNTcsNDNdLFs0Myw2MV0sWzYxLDU3XSxbMjA4LDE3MV0sWzE3MSwxOTldLFsxOTksMjA4XSxbNDEsODFdLFs4MSwzOF0sWzM4LDQxXSxbMjI0LDUzXSxbNTMsMjI1XSxbMjI1LDIyNF0sWzI0LDE0NF0sWzE0NCwxMTBdLFsxMTAsMjRdLFsxMDUsNTJdLFs1Miw2Nl0sWzY2LDEwNV0sWzExOCwyMjldLFsyMjksMTE3XSxbMTE3LDExOF0sWzIyNywzNF0sWzM0LDIzNF0sWzIzNCwyMjddLFs2NiwxMDddLFsxMDcsNjldLFs2OSw2Nl0sWzEwLDEwOV0sWzEwOSwxNTFdLFsxNTEsMTBdLFsyMTksNDhdLFs0OCwyMzVdLFsyMzUsMjE5XSxbMTgzLDYyXSxbNjIsMTkxXSxbMTkxLDE4M10sWzE0MiwxMjldLFsxMjksMTI2XSxbMTI2LDE0Ml0sWzExNiwxMTFdLFsxMTEsMTQzXSxbMTQzLDExNl0sWzExOCwxMTddLFsxMTcsNTBdLFs1MCwxMThdLFsyMjMsMjIyXSxbMjIyLDUyXSxbNTIsMjIzXSxbOTQsMTldLFsxOSwxNDFdLFsxNDEsOTRdLFsyMjIsMjIxXSxbMjIxLDY1XSxbNjUsMjIyXSxbMTk2LDNdLFszLDE5N10sWzE5NywxOTZdLFs0NSwyMjBdLFsyMjAsNDRdLFs0NCw0NV0sWzE1Niw3MF0sWzcwLDEzOV0sWzEzOSwxNTZdLFsxODgsMTIyXSxbMTIyLDI0NV0sWzI0NSwxODhdLFsxMzksNzFdLFs3MSwxNjJdLFsxNjIsMTM5XSxbMTQ5LDE3MF0sWzE3MCwxNTBdLFsxNTAsMTQ5XSxbMTIyLDE4OF0sWzE4OCwxOTZdLFsxOTYsMTIyXSxbMjA2LDIxNl0sWzIxNiw5Ml0sWzkyLDIwNl0sWzE2NCwyXSxbMiwxNjddLFsxNjcsMTY0XSxbMjQyLDE0MV0sWzE0MSwyNDFdLFsyNDEsMjQyXSxbMCwxNjRdLFsxNjQsMzddLFszNywwXSxbMTEsNzJdLFs3MiwxMl0sWzEyLDExXSxbMTIsMzhdLFszOCwxM10sWzEzLDEyXSxbNzAsNjNdLFs2Myw3MV0sWzcxLDcwXSxbMzEsMjI2XSxbMjI2LDExMV0sWzExMSwzMV0sWzM2LDEwMV0sWzEwMSwyMDVdLFsyMDUsMzZdLFsyMDMsMjA2XSxbMjA2LDE2NV0sWzE2NSwyMDNdLFsxMjYsMjA5XSxbMjA5LDIxN10sWzIxNywxMjZdLFs5OCwxNjVdLFsxNjUsOTddLFs5Nyw5OF0sWzIzNywyMjBdLFsyMjAsMjE4XSxbMjE4LDIzN10sWzIzNywyMzldLFsyMzksMjQxXSxbMjQxLDIzN10sWzIxMCwyMTRdLFsyMTQsMTY5XSxbMTY5LDIxMF0sWzE0MCwxNzFdLFsxNzEsMzJdLFszMiwxNDBdLFsyNDEsMTI1XSxbMTI1LDIzN10sWzIzNywyNDFdLFsxNzksODZdLFs4NiwxNzhdLFsxNzgsMTc5XSxbMTgwLDg1XSxbODUsMTc5XSxbMTc5LDE4MF0sWzE4MSw4NF0sWzg0LDE4MF0sWzE4MCwxODFdLFsxODIsODNdLFs4MywxODFdLFsxODEsMTgyXSxbMTk0LDIwMV0sWzIwMSwxODJdLFsxODIsMTk0XSxbMTc3LDEzN10sWzEzNywxMzJdLFsxMzIsMTc3XSxbMTg0LDc2XSxbNzYsMTgzXSxbMTgzLDE4NF0sWzE4NSw2MV0sWzYxLDE4NF0sWzE4NCwxODVdLFsxODYsNTddLFs1NywxODVdLFsxODUsMTg2XSxbMjE2LDIxMl0sWzIxMiwxODZdLFsxODYsMjE2XSxbMTkyLDIxNF0sWzIxNCwxODddLFsxODcsMTkyXSxbMTM5LDM0XSxbMzQsMTU2XSxbMTU2LDEzOV0sWzIxOCw3OV0sWzc5LDIzN10sWzIzNywyMThdLFsxNDcsMTIzXSxbMTIzLDE3N10sWzE3NywxNDddLFs0NSw0NF0sWzQ0LDRdLFs0LDQ1XSxbMjA4LDIwMV0sWzIwMSwzMl0sWzMyLDIwOF0sWzk4LDY0XSxbNjQsMTI5XSxbMTI5LDk4XSxbMTkyLDIxM10sWzIxMywxMzhdLFsxMzgsMTkyXSxbMjM1LDU5XSxbNTksMjE5XSxbMjE5LDIzNV0sWzE0MSwyNDJdLFsyNDIsOTddLFs5NywxNDFdLFs5NywyXSxbMiwxNDFdLFsxNDEsOTddLFsyNDAsNzVdLFs3NSwyMzVdLFsyMzUsMjQwXSxbMjI5LDI0XSxbMjQsMjI4XSxbMjI4LDIyOV0sWzMxLDI1XSxbMjUsMjI2XSxbMjI2LDMxXSxbMjMwLDIzXSxbMjMsMjI5XSxbMjI5LDIzMF0sWzIzMSwyMl0sWzIyLDIzMF0sWzIzMCwyMzFdLFsyMzIsMjZdLFsyNiwyMzFdLFsyMzEsMjMyXSxbMjMzLDExMl0sWzExMiwyMzJdLFsyMzIsMjMzXSxbMjQ0LDE4OV0sWzE4OSwyNDNdLFsyNDMsMjQ0XSxbMTg5LDIyMV0sWzIyMSwxOTBdLFsxOTAsMTg5XSxbMjIyLDI4XSxbMjgsMjIxXSxbMjIxLDIyMl0sWzIyMywyN10sWzI3LDIyMl0sWzIyMiwyMjNdLFsyMjQsMjldLFsyOSwyMjNdLFsyMjMsMjI0XSxbMjI1LDMwXSxbMzAsMjI0XSxbMjI0LDIyNV0sWzExMywyNDddLFsyNDcsMjI1XSxbMjI1LDExM10sWzk5LDYwXSxbNjAsMjQwXSxbMjQwLDk5XSxbMjEzLDE0N10sWzE0NywyMTVdLFsyMTUsMjEzXSxbNjAsMjBdLFsyMCwxNjZdLFsxNjYsNjBdLFsxOTIsMTg3XSxbMTg3LDIxM10sWzIxMywxOTJdLFsyNDMsMTEyXSxbMTEyLDI0NF0sWzI0NCwyNDNdLFsyNDQsMjMzXSxbMjMzLDI0NV0sWzI0NSwyNDRdLFsyNDUsMTI4XSxbMTI4LDE4OF0sWzE4OCwyNDVdLFsxODgsMTE0XSxbMTE0LDE3NF0sWzE3NCwxODhdLFsxMzQsMTMxXSxbMTMxLDIyMF0sWzIyMCwxMzRdLFsxNzQsMjE3XSxbMjE3LDIzNl0sWzIzNiwxNzRdLFsyMzYsMTk4XSxbMTk4LDEzNF0sWzEzNCwyMzZdLFsyMTUsMTc3XSxbMTc3LDU4XSxbNTgsMjE1XSxbMTU2LDE0M10sWzE0MywxMjRdLFsxMjQsMTU2XSxbMjUsMTEwXSxbMTEwLDddLFs3LDI1XSxbMzEsMjI4XSxbMjI4LDI1XSxbMjUsMzFdLFsyNjQsMzU2XSxbMzU2LDM2OF0sWzM2OCwyNjRdLFswLDExXSxbMTEsMjY3XSxbMjY3LDBdLFs0NTEsNDUyXSxbNDUyLDM0OV0sWzM0OSw0NTFdLFsyNjcsMzAyXSxbMzAyLDI2OV0sWzI2OSwyNjddLFszNTAsMzU3XSxbMzU3LDI3N10sWzI3NywzNTBdLFszNTAsNDUyXSxbNDUyLDM1N10sWzM1NywzNTBdLFsyOTksMzMzXSxbMzMzLDI5N10sWzI5NywyOTldLFszOTYsMTc1XSxbMTc1LDM3N10sWzM3NywzOTZdLFsyODAsMzQ3XSxbMzQ3LDMzMF0sWzMzMCwyODBdLFsyNjksMzAzXSxbMzAzLDI3MF0sWzI3MCwyNjldLFsxNTEsOV0sWzksMzM3XSxbMzM3LDE1MV0sWzM0NCwyNzhdLFsyNzgsMzYwXSxbMzYwLDM0NF0sWzQyNCw0MThdLFs0MTgsNDMxXSxbNDMxLDQyNF0sWzI3MCwzMDRdLFszMDQsNDA5XSxbNDA5LDI3MF0sWzI3MiwzMTBdLFszMTAsNDA3XSxbNDA3LDI3Ml0sWzMyMiwyNzBdLFsyNzAsNDEwXSxbNDEwLDMyMl0sWzQ0OSw0NTBdLFs0NTAsMzQ3XSxbMzQ3LDQ0OV0sWzQzMiw0MjJdLFs0MjIsNDM0XSxbNDM0LDQzMl0sWzE4LDMxM10sWzMxMywxN10sWzE3LDE4XSxbMjkxLDMwNl0sWzMwNiwzNzVdLFszNzUsMjkxXSxbMjU5LDM4N10sWzM4NywyNjBdLFsyNjAsMjU5XSxbNDI0LDMzNV0sWzMzNSw0MThdLFs0MTgsNDI0XSxbNDM0LDM2NF0sWzM2NCw0MTZdLFs0MTYsNDM0XSxbMzkxLDQyM10sWzQyMywzMjddLFszMjcsMzkxXSxbMzAxLDI1MV0sWzI1MSwyOThdLFsyOTgsMzAxXSxbMjc1LDI4MV0sWzI4MSw0XSxbNCwyNzVdLFsyNTQsMzczXSxbMzczLDI1M10sWzI1MywyNTRdLFszNzUsMzA3XSxbMzA3LDMyMV0sWzMyMSwzNzVdLFsyODAsNDI1XSxbNDI1LDQxMV0sWzQxMSwyODBdLFsyMDAsNDIxXSxbNDIxLDE4XSxbMTgsMjAwXSxbMzM1LDMyMV0sWzMyMSw0MDZdLFs0MDYsMzM1XSxbMzIxLDMyMF0sWzMyMCw0MDVdLFs0MDUsMzIxXSxbMzE0LDMxNV0sWzMxNSwxN10sWzE3LDMxNF0sWzQyMyw0MjZdLFs0MjYsMjY2XSxbMjY2LDQyM10sWzM5NiwzNzddLFszNzcsMzY5XSxbMzY5LDM5Nl0sWzI3MCwzMjJdLFszMjIsMjY5XSxbMjY5LDI3MF0sWzQxMyw0MTddLFs0MTcsNDY0XSxbNDY0LDQxM10sWzM4NSwzODZdLFszODYsMjU4XSxbMjU4LDM4NV0sWzI0OCw0NTZdLFs0NTYsNDE5XSxbNDE5LDI0OF0sWzI5OCwyODRdLFsyODQsMzMzXSxbMzMzLDI5OF0sWzE2OCw0MTddLFs0MTcsOF0sWzgsMTY4XSxbNDQ4LDM0Nl0sWzM0NiwyNjFdLFsyNjEsNDQ4XSxbNDE3LDQxM10sWzQxMywyODVdLFsyODUsNDE3XSxbMzI2LDMyN10sWzMyNywzMjhdLFszMjgsMzI2XSxbMjc3LDM1NV0sWzM1NSwzMjldLFszMjksMjc3XSxbMzA5LDM5Ml0sWzM5Miw0MzhdLFs0MzgsMzA5XSxbMzgxLDM4Ml0sWzM4MiwyNTZdLFsyNTYsMzgxXSxbMjc5LDQyOV0sWzQyOSwzNjBdLFszNjAsMjc5XSxbMzY1LDM2NF0sWzM2NCwzNzldLFszNzksMzY1XSxbMzU1LDI3N10sWzI3Nyw0MzddLFs0MzcsMzU1XSxbMjgyLDQ0M10sWzQ0MywyODNdLFsyODMsMjgyXSxbMjgxLDI3NV0sWzI3NSwzNjNdLFszNjMsMjgxXSxbMzk1LDQzMV0sWzQzMSwzNjldLFszNjksMzk1XSxbMjk5LDI5N10sWzI5NywzMzddLFszMzcsMjk5XSxbMzM1LDI3M10sWzI3MywzMjFdLFszMjEsMzM1XSxbMzQ4LDQ1MF0sWzQ1MCwzNDldLFszNDksMzQ4XSxbMzU5LDQ0Nl0sWzQ0Niw0NjddLFs0NjcsMzU5XSxbMjgzLDI5M10sWzI5MywyODJdLFsyODIsMjgzXSxbMjUwLDQ1OF0sWzQ1OCw0NjJdLFs0NjIsMjUwXSxbMzAwLDI3Nl0sWzI3NiwzODNdLFszODMsMzAwXSxbMjkyLDMwOF0sWzMwOCwzMjVdLFszMjUsMjkyXSxbMjgzLDI3Nl0sWzI3NiwyOTNdLFsyOTMsMjgzXSxbMjY0LDM3Ml0sWzM3Miw0NDddLFs0NDcsMjY0XSxbMzQ2LDM1Ml0sWzM1MiwzNDBdLFszNDAsMzQ2XSxbMzU0LDI3NF0sWzI3NCwxOV0sWzE5LDM1NF0sWzM2Myw0NTZdLFs0NTYsMjgxXSxbMjgxLDM2M10sWzQyNiw0MzZdLFs0MzYsNDI1XSxbNDI1LDQyNl0sWzM4MCwzODFdLFszODEsMjUyXSxbMjUyLDM4MF0sWzI2NywyNjldLFsyNjksMzkzXSxbMzkzLDI2N10sWzQyMSwyMDBdLFsyMDAsNDI4XSxbNDI4LDQyMV0sWzM3MSwyNjZdLFsyNjYsMzI5XSxbMzI5LDM3MV0sWzQzMiwyODddLFsyODcsNDIyXSxbNDIyLDQzMl0sWzI5MCwyNTBdLFsyNTAsMzI4XSxbMzI4LDI5MF0sWzM4NSwyNThdLFsyNTgsMzg0XSxbMzg0LDM4NV0sWzQ0NiwyNjVdLFsyNjUsMzQyXSxbMzQyLDQ0Nl0sWzM4NiwzODddLFszODcsMjU3XSxbMjU3LDM4Nl0sWzQyMiw0MjRdLFs0MjQsNDMwXSxbNDMwLDQyMl0sWzQ0NSwzNDJdLFszNDIsMjc2XSxbMjc2LDQ0NV0sWzQyMiwyNzNdLFsyNzMsNDI0XSxbNDI0LDQyMl0sWzMwNiwyOTJdLFsyOTIsMzA3XSxbMzA3LDMwNl0sWzM1MiwzNjZdLFszNjYsMzQ1XSxbMzQ1LDM1Ml0sWzI2OCwyNzFdLFsyNzEsMzAyXSxbMzAyLDI2OF0sWzM1OCw0MjNdLFs0MjMsMzcxXSxbMzcxLDM1OF0sWzMyNywyOTRdLFsyOTQsNDYwXSxbNDYwLDMyN10sWzMzMSwyNzldLFsyNzksMjk0XSxbMjk0LDMzMV0sWzMwMywyNzFdLFsyNzEsMzA0XSxbMzA0LDMwM10sWzQzNiw0MzJdLFs0MzIsNDI3XSxbNDI3LDQzNl0sWzMwNCwyNzJdLFsyNzIsNDA4XSxbNDA4LDMwNF0sWzM5NSwzOTRdLFszOTQsNDMxXSxbNDMxLDM5NV0sWzM3OCwzOTVdLFszOTUsNDAwXSxbNDAwLDM3OF0sWzI5NiwzMzRdLFszMzQsMjk5XSxbMjk5LDI5Nl0sWzYsMzUxXSxbMzUxLDE2OF0sWzE2OCw2XSxbMzc2LDM1Ml0sWzM1Miw0MTFdLFs0MTEsMzc2XSxbMzA3LDMyNV0sWzMyNSwzMjBdLFszMjAsMzA3XSxbMjg1LDI5NV0sWzI5NSwzMzZdLFszMzYsMjg1XSxbMzIwLDMxOV0sWzMxOSw0MDRdLFs0MDQsMzIwXSxbMzI5LDMzMF0sWzMzMCwzNDldLFszNDksMzI5XSxbMzM0LDI5M10sWzI5MywzMzNdLFszMzMsMzM0XSxbMzY2LDMyM10sWzMyMyw0NDddLFs0NDcsMzY2XSxbMzE2LDE1XSxbMTUsMzE1XSxbMzE1LDMxNl0sWzMzMSwzNThdLFszNTgsMjc5XSxbMjc5LDMzMV0sWzMxNywxNF0sWzE0LDMxNl0sWzMxNiwzMTddLFs4LDI4NV0sWzI4NSw5XSxbOSw4XSxbMjc3LDMyOV0sWzMyOSwzNTBdLFszNTAsMjc3XSxbMjUzLDM3NF0sWzM3NCwyNTJdLFsyNTIsMjUzXSxbMzE5LDMxOF0sWzMxOCw0MDNdLFs0MDMsMzE5XSxbMzUxLDZdLFs2LDQxOV0sWzQxOSwzNTFdLFszMjQsMzE4XSxbMzE4LDMyNV0sWzMyNSwzMjRdLFszOTcsMzY3XSxbMzY3LDM2NV0sWzM2NSwzOTddLFsyODgsNDM1XSxbNDM1LDM5N10sWzM5NywyODhdLFsyNzgsMzQ0XSxbMzQ0LDQzOV0sWzQzOSwyNzhdLFszMTAsMjcyXSxbMjcyLDMxMV0sWzMxMSwzMTBdLFsyNDgsMTk1XSxbMTk1LDI4MV0sWzI4MSwyNDhdLFszNzUsMjczXSxbMjczLDI5MV0sWzI5MSwzNzVdLFsxNzUsMzk2XSxbMzk2LDE5OV0sWzE5OSwxNzVdLFszMTIsMzExXSxbMzExLDI2OF0sWzI2OCwzMTJdLFsyNzYsMjgzXSxbMjgzLDQ0NV0sWzQ0NSwyNzZdLFszOTAsMzczXSxbMzczLDMzOV0sWzMzOSwzOTBdLFsyOTUsMjgyXSxbMjgyLDI5Nl0sWzI5NiwyOTVdLFs0NDgsNDQ5XSxbNDQ5LDM0Nl0sWzM0Niw0NDhdLFszNTYsMjY0XSxbMjY0LDQ1NF0sWzQ1NCwzNTZdLFszMzcsMzM2XSxbMzM2LDI5OV0sWzI5OSwzMzddLFszMzcsMzM4XSxbMzM4LDE1MV0sWzE1MSwzMzddLFsyOTQsMjc4XSxbMjc4LDQ1NV0sWzQ1NSwyOTRdLFszMDgsMjkyXSxbMjkyLDQxNV0sWzQxNSwzMDhdLFs0MjksMzU4XSxbMzU4LDM1NV0sWzM1NSw0MjldLFsyNjUsMzQwXSxbMzQwLDM3Ml0sWzM3MiwyNjVdLFszNTIsMzQ2XSxbMzQ2LDI4MF0sWzI4MCwzNTJdLFsyOTUsNDQyXSxbNDQyLDI4Ml0sWzI4MiwyOTVdLFszNTQsMTldLFsxOSwzNzBdLFszNzAsMzU0XSxbMjg1LDQ0MV0sWzQ0MSwyOTVdLFsyOTUsMjg1XSxbMTk1LDI0OF0sWzI0OCwxOTddLFsxOTcsMTk1XSxbNDU3LDQ0MF0sWzQ0MCwyNzRdLFsyNzQsNDU3XSxbMzAxLDMwMF0sWzMwMCwzNjhdLFszNjgsMzAxXSxbNDE3LDM1MV0sWzM1MSw0NjVdLFs0NjUsNDE3XSxbMjUxLDMwMV0sWzMwMSwzODldLFszODksMjUxXSxbMzk0LDM5NV0sWzM5NSwzNzldLFszNzksMzk0XSxbMzk5LDQxMl0sWzQxMiw0MTldLFs0MTksMzk5XSxbNDEwLDQzNl0sWzQzNiwzMjJdLFszMjIsNDEwXSxbMzI2LDJdLFsyLDM5M10sWzM5MywzMjZdLFszNTQsMzcwXSxbMzcwLDQ2MV0sWzQ2MSwzNTRdLFszOTMsMTY0XSxbMTY0LDI2N10sWzI2NywzOTNdLFsyNjgsMzAyXSxbMzAyLDEyXSxbMTIsMjY4XSxbMzEyLDI2OF0sWzI2OCwxM10sWzEzLDMxMl0sWzI5OCwyOTNdLFsyOTMsMzAxXSxbMzAxLDI5OF0sWzI2NSw0NDZdLFs0NDYsMzQwXSxbMzQwLDI2NV0sWzI4MCwzMzBdLFszMzAsNDI1XSxbNDI1LDI4MF0sWzMyMiw0MjZdLFs0MjYsMzkxXSxbMzkxLDMyMl0sWzQyMCw0MjldLFs0MjksNDM3XSxbNDM3LDQyMF0sWzM5MywzOTFdLFszOTEsMzI2XSxbMzI2LDM5M10sWzM0NCw0NDBdLFs0NDAsNDM4XSxbNDM4LDM0NF0sWzQ1OCw0NTldLFs0NTksNDYxXSxbNDYxLDQ1OF0sWzM2NCw0MzRdLFs0MzQsMzk0XSxbMzk0LDM2NF0sWzQyOCwzOTZdLFszOTYsMjYyXSxbMjYyLDQyOF0sWzI3NCwzNTRdLFszNTQsNDU3XSxbNDU3LDI3NF0sWzMxNywzMTZdLFszMTYsNDAyXSxbNDAyLDMxN10sWzMxNiwzMTVdLFszMTUsNDAzXSxbNDAzLDMxNl0sWzMxNSwzMTRdLFszMTQsNDA0XSxbNDA0LDMxNV0sWzMxNCwzMTNdLFszMTMsNDA1XSxbNDA1LDMxNF0sWzMxMyw0MjFdLFs0MjEsNDA2XSxbNDA2LDMxM10sWzMyMywzNjZdLFszNjYsMzYxXSxbMzYxLDMyM10sWzI5MiwzMDZdLFszMDYsNDA3XSxbNDA3LDI5Ml0sWzMwNiwyOTFdLFsyOTEsNDA4XSxbNDA4LDMwNl0sWzI5MSwyODddLFsyODcsNDA5XSxbNDA5LDI5MV0sWzI4Nyw0MzJdLFs0MzIsNDEwXSxbNDEwLDI4N10sWzQyNyw0MzRdLFs0MzQsNDExXSxbNDExLDQyN10sWzM3MiwyNjRdLFsyNjQsMzgzXSxbMzgzLDM3Ml0sWzQ1OSwzMDldLFszMDksNDU3XSxbNDU3LDQ1OV0sWzM2NiwzNTJdLFszNTIsNDAxXSxbNDAxLDM2Nl0sWzEsMjc0XSxbMjc0LDRdLFs0LDFdLFs0MTgsNDIxXSxbNDIxLDI2Ml0sWzI2Miw0MThdLFszMzEsMjk0XSxbMjk0LDM1OF0sWzM1OCwzMzFdLFs0MzUsNDMzXSxbNDMzLDM2N10sWzM2Nyw0MzVdLFszOTIsMjg5XSxbMjg5LDQzOV0sWzQzOSwzOTJdLFszMjgsNDYyXSxbNDYyLDMyNl0sWzMyNiwzMjhdLFs5NCwyXSxbMiwzNzBdLFszNzAsOTRdLFsyODksMzA1XSxbMzA1LDQ1NV0sWzQ1NSwyODldLFszMzksMjU0XSxbMjU0LDQ0OF0sWzQ0OCwzMzldLFszNTksMjU1XSxbMjU1LDQ0Nl0sWzQ0NiwzNTldLFsyNTQsMjUzXSxbMjUzLDQ0OV0sWzQ0OSwyNTRdLFsyNTMsMjUyXSxbMjUyLDQ1MF0sWzQ1MCwyNTNdLFsyNTIsMjU2XSxbMjU2LDQ1MV0sWzQ1MSwyNTJdLFsyNTYsMzQxXSxbMzQxLDQ1Ml0sWzQ1MiwyNTZdLFs0MTQsNDEzXSxbNDEzLDQ2M10sWzQ2Myw0MTRdLFsyODYsNDQxXSxbNDQxLDQxNF0sWzQxNCwyODZdLFsyODYsMjU4XSxbMjU4LDQ0MV0sWzQ0MSwyODZdLFsyNTgsMjU3XSxbMjU3LDQ0Ml0sWzQ0MiwyNThdLFsyNTcsMjU5XSxbMjU5LDQ0M10sWzQ0MywyNTddLFsyNTksMjYwXSxbMjYwLDQ0NF0sWzQ0NCwyNTldLFsyNjAsNDY3XSxbNDY3LDQ0NV0sWzQ0NSwyNjBdLFszMDksNDU5XSxbNDU5LDI1MF0sWzI1MCwzMDldLFszMDUsMjg5XSxbMjg5LDI5MF0sWzI5MCwzMDVdLFszMDUsMjkwXSxbMjkwLDQ2MF0sWzQ2MCwzMDVdLFs0MDEsMzc2XSxbMzc2LDQzNV0sWzQzNSw0MDFdLFszMDksMjUwXSxbMjUwLDM5Ml0sWzM5MiwzMDldLFszNzYsNDExXSxbNDExLDQzM10sWzQzMywzNzZdLFs0NTMsMzQxXSxbMzQxLDQ2NF0sWzQ2NCw0NTNdLFszNTcsNDUzXSxbNDUzLDQ2NV0sWzQ2NSwzNTddLFszNDMsMzU3XSxbMzU3LDQxMl0sWzQxMiwzNDNdLFs0MzcsMzQzXSxbMzQzLDM5OV0sWzM5OSw0MzddLFszNDQsMzYwXSxbMzYwLDQ0MF0sWzQ0MCwzNDRdLFs0MjAsNDM3XSxbNDM3LDQ1Nl0sWzQ1Niw0MjBdLFszNjAsNDIwXSxbNDIwLDM2M10sWzM2MywzNjBdLFszNjEsNDAxXSxbNDAxLDI4OF0sWzI4OCwzNjFdLFsyNjUsMzcyXSxbMzcyLDM1M10sWzM1MywyNjVdLFszOTAsMzM5XSxbMzM5LDI0OV0sWzI0OSwzOTBdLFszMzksNDQ4XSxbNDQ4LDI1NV0sWzI1NSwzMzldKTtmdW5jdGlvbiBhaChoYSl7aGEuaj17ZmFjZUxhbmRtYXJrczpbXSxmYWNlQmxlbmRzaGFwZXM6W10sZmFjaWFsVHJhbnNmb3JtYXRpb25NYXRyaXhlczpbXX19dmFyIGhoPWNsYXNzIGV4dGVuZHMgJGF7Y29uc3RydWN0b3IoaGEsYWEpe3N1cGVyKG5ldyBYYShoYSxhYSksImltYWdlX2luIiwibm9ybV9yZWN0IiwhMSksdGhpcy5qPXtmYWNlTGFuZG1hcmtzOltdLGZhY2VCbGVuZHNoYXBlczpbXSxmYWNpYWxUcmFuc2Zvcm1hdGlvbk1hdHJpeGVzOltdfSx0aGlzLm91dHB1dEZhY2lhbFRyYW5zZm9ybWF0aW9uTWF0cml4ZXM9dGhpcy5vdXRwdXRGYWNlQmxlbmRzaGFwZXM9ITEsa24oaGE9dGhpcy5oPW5ldyBJaSwwLDEsYWE9bmV3IGJpKSx0aGlzLnY9bmV3IE9pLGtuKHRoaXMuaCwwLDMsdGhpcy52KSx0aGlzLnM9bmV3IHhpLGtuKHRoaXMuaCwwLDIsdGhpcy5zKSxDbih0aGlzLnMsNCwxKSxJbih0aGlzLnMsMiwuNSksSW4odGhpcy52LDIsLjUpLEluKHRoaXMuaCw0LC41KX1nZXQgYmFzZU9wdGlvbnMoKXtyZXR1cm4gVG4odGhpcy5oLGJpLDEpfXNldCBiYXNlT3B0aW9ucyhoYSl7a24odGhpcy5oLDAsMSxoYSl9byhoYSl7cmV0dXJuIm51bUZhY2VzImluIGhhJiZDbih0aGlzLnMsNCxoYS5udW1GYWNlcz8/MSksIm1pbkZhY2VEZXRlY3Rpb25Db25maWRlbmNlImluIGhhJiZJbih0aGlzLnMsMixoYS5taW5GYWNlRGV0ZWN0aW9uQ29uZmlkZW5jZT8/LjUpLCJtaW5UcmFja2luZ0NvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMuaCw0LGhhLm1pblRyYWNraW5nQ29uZmlkZW5jZT8/LjUpLCJtaW5GYWNlUHJlc2VuY2VDb25maWRlbmNlImluIGhhJiZJbih0aGlzLnYsMixoYS5taW5GYWNlUHJlc2VuY2VDb25maWRlbmNlPz8uNSksIm91dHB1dEZhY2VCbGVuZHNoYXBlcyJpbiBoYSYmKHRoaXMub3V0cHV0RmFjZUJsZW5kc2hhcGVzPSEhaGEub3V0cHV0RmFjZUJsZW5kc2hhcGVzKSwib3V0cHV0RmFjaWFsVHJhbnNmb3JtYXRpb25NYXRyaXhlcyJpbiBoYSYmKHRoaXMub3V0cHV0RmFjaWFsVHJhbnNmb3JtYXRpb25NYXRyaXhlcz0hIWhhLm91dHB1dEZhY2lhbFRyYW5zZm9ybWF0aW9uTWF0cml4ZXMpLHRoaXMubChoYSl9RihoYSxhYSl7cmV0dXJuIGFoKHRoaXMpLHphKHRoaXMsaGEsYWEpLHRoaXMuan1HKGhhLGFhLHhhKXtyZXR1cm4gYWgodGhpcyksS2EodGhpcyxoYSx4YSxhYSksdGhpcy5qfW0oKXt2YXIgaGE9bmV3IExzO3hzKGhhLCJpbWFnZV9pbiIpLHhzKGhhLCJub3JtX3JlY3QiKSxTcyhoYSwiZmFjZV9sYW5kbWFya3MiKTtjb25zdCBhYT1uZXcgaHM7RG4oYWEsTmksdGhpcy5oKTtjb25zdCB4YT1uZXcgdnM7bXMoeGEsIm1lZGlhcGlwZS50YXNrcy52aXNpb24uZmFjZV9sYW5kbWFya2VyLkZhY2VMYW5kbWFya2VyR3JhcGgiKSx5cyh4YSwiSU1BR0U6aW1hZ2VfaW4iKSx5cyh4YSwiTk9STV9SRUNUOm5vcm1fcmVjdCIpLF9zKHhhLCJOT1JNX0xBTkRNQVJLUzpmYWNlX2xhbmRtYXJrcyIpLHhhLm8oYWEpLGtzKGhhLHhhKSx0aGlzLmcuYXR0YWNoUHJvdG9WZWN0b3JMaXN0ZW5lcigiZmFjZV9sYW5kbWFya3MiLChiYSxTYSk9Pntmb3IoY29uc3QgVGEgb2YgYmEpYmE9ZWkoVGEpLHRoaXMuai5mYWNlTGFuZG1hcmtzLnB1c2goeG8oYmEpKTt6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJmYWNlX2xhbmRtYXJrcyIsYmE9Pnt6byh0aGlzLGJhKX0pLHRoaXMub3V0cHV0RmFjZUJsZW5kc2hhcGVzJiYoU3MoaGEsImJsZW5kc2hhcGVzIiksX3MoeGEsIkJMRU5EU0hBUEVTOmJsZW5kc2hhcGVzIiksdGhpcy5nLmF0dGFjaFByb3RvVmVjdG9yTGlzdGVuZXIoImJsZW5kc2hhcGVzIiwoYmEsU2EpPT57aWYodGhpcy5vdXRwdXRGYWNlQmxlbmRzaGFwZXMpZm9yKGNvbnN0IFRhIG9mIGJhKWJhPURzKFRhKSx0aGlzLmouZmFjZUJsZW5kc2hhcGVzLnB1c2goYm8oYmEuZygpPz9bXSkpO3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoImJsZW5kc2hhcGVzIixiYT0+e3pvKHRoaXMsYmEpfSkpLHRoaXMub3V0cHV0RmFjaWFsVHJhbnNmb3JtYXRpb25NYXRyaXhlcyYmKFNzKGhhLCJmYWNlX2dlb21ldHJ5IiksX3MoeGEsIkZBQ0VfR0VPTUVUUlk6ZmFjZV9nZW9tZXRyeSIpLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJmYWNlX2dlb21ldHJ5IiwoYmEsU2EpPT57aWYodGhpcy5vdXRwdXRGYWNpYWxUcmFuc2Zvcm1hdGlvbk1hdHJpeGVzKWZvcihjb25zdCBUYSBvZiBiYSkoYmE9VG4oTWkoVGEpLG5pLDIpKSYmdGhpcy5qLmZhY2lhbFRyYW5zZm9ybWF0aW9uTWF0cml4ZXMucHVzaCh7cm93czpNbihGbihiYSwxKSk/PzAsY29sdW1uczpNbihGbihiYSwyKSk/PzAsZGF0YTpjbihiYSwzLGZlKS5zbGljZSgpPz9bXX0pO3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoImZhY2VfZ2VvbWV0cnkiLGJhPT57em8odGhpcyxiYSl9KSksaGE9aGEuZygpLHRoaXMuc2V0R3JhcGgobmV3IFVpbnQ4QXJyYXkoaGEpLCEwKX19O2hoLnByb3RvdHlwZS5kZXRlY3RGb3JWaWRlbz1oaC5wcm90b3R5cGUuRyxoaC5wcm90b3R5cGUuZGV0ZWN0PWhoLnByb3RvdHlwZS5GLGhoLnByb3RvdHlwZS5zZXRPcHRpb25zPWhoLnByb3RvdHlwZS5vLGhoLmNyZWF0ZUZyb21Nb2RlbFBhdGg9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShoaCxoYSx7YmFzZU9wdGlvbnM6e21vZGVsQXNzZXRQYXRoOmFhfX0pfSxoaC5jcmVhdGVGcm9tTW9kZWxCdWZmZXI9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShoaCxoYSx7YmFzZU9wdGlvbnM6e21vZGVsQXNzZXRCdWZmZXI6YWF9fSl9LGhoLmNyZWF0ZUZyb21PcHRpb25zPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gSGEoaGgsaGEsYWEpfSxoaC5GQUNFX0xBTkRNQVJLU19MSVBTPUphLGhoLkZBQ0VfTEFORE1BUktTX0xFRlRfRVlFPVphLGhoLkZBQ0VfTEFORE1BUktTX0xFRlRfRVlFQlJPVz1RYSxoaC5GQUNFX0xBTkRNQVJLU19MRUZUX0lSSVM9dGgsaGguRkFDRV9MQU5ETUFSS1NfUklHSFRfRVlFPWVoLGhoLkZBQ0VfTEFORE1BUktTX1JJR0hUX0VZRUJST1c9bmgsaGguRkFDRV9MQU5ETUFSS1NfUklHSFRfSVJJUz1yaCxoaC5GQUNFX0xBTkRNQVJLU19GQUNFX09WQUw9c2gsaGguRkFDRV9MQU5ETUFSS1NfQ09OVE9VUlM9aWgsaGguRkFDRV9MQU5ETUFSS1NfVEVTU0VMQVRJT049b2g7dmFyIGNoPWNsYXNzIGV4dGVuZHMgJGF7Y29uc3RydWN0b3IoaGEsYWEpe3N1cGVyKG5ldyBYYShoYSxhYSksImltYWdlX2luIiwibm9ybV9yZWN0IiwhMCksa24oaGE9dGhpcy5qPW5ldyBVaSwwLDEsYWE9bmV3IGJpKX1nZXQgYmFzZU9wdGlvbnMoKXtyZXR1cm4gVG4odGhpcy5qLGJpLDEpfXNldCBiYXNlT3B0aW9ucyhoYSl7a24odGhpcy5qLDAsMSxoYSl9byhoYSl7cmV0dXJuIHN1cGVyLmwoaGEpfVBhKGhhLGFhLHhhKXtjb25zdCBiYT10eXBlb2YgYWEhPSJmdW5jdGlvbiI/YWE6e307aWYodGhpcy5oPXR5cGVvZiBhYT09ImZ1bmN0aW9uIj9hYTp4YSx6YSh0aGlzLGhhLGJhPz97fSksIXRoaXMuaClyZXR1cm4gdGhpcy5zfW0oKXt2YXIgaGE9bmV3IExzO3hzKGhhLCJpbWFnZV9pbiIpLHhzKGhhLCJub3JtX3JlY3QiKSxTcyhoYSwic3R5bGl6ZWRfaW1hZ2UiKTtjb25zdCBhYT1uZXcgaHM7RG4oYWEsQmksdGhpcy5qKTtjb25zdCB4YT1uZXcgdnM7bXMoeGEsIm1lZGlhcGlwZS50YXNrcy52aXNpb24uZmFjZV9zdHlsaXplci5GYWNlU3R5bGl6ZXJHcmFwaCIpLHlzKHhhLCJJTUFHRTppbWFnZV9pbiIpLHlzKHhhLCJOT1JNX1JFQ1Q6bm9ybV9yZWN0IiksX3MoeGEsIlNUWUxJWkVEX0lNQUdFOnN0eWxpemVkX2ltYWdlIikseGEubyhhYSksa3MoaGEseGEpLHRoaXMuZy5XKCJzdHlsaXplZF9pbWFnZSIsKGJhLFNhKT0+e3ZhciBUYT0hdGhpcy5oLHdhPWJhLmRhdGEsRWE9YmEud2lkdGg7Y29uc3Qga2E9RWEqKGJhPWJhLmhlaWdodCk7aWYod2EgaW5zdGFuY2VvZiBVaW50OEFycmF5KWlmKHdhLmxlbmd0aD09PTMqa2Epe2NvbnN0IEFhPW5ldyBVaW50OENsYW1wZWRBcnJheSg0KmthKTtmb3IobGV0IEZhPTA7RmE8a2E7KytGYSlBYVs0KkZhXT13YVszKkZhXSxBYVs0KkZhKzFdPXdhWzMqRmErMV0sQWFbNCpGYSsyXT13YVszKkZhKzJdLEFhWzQqRmErM109MjU1O3dhPW5ldyBJbWFnZURhdGEoQWEsRWEsYmEpfWVsc2V7aWYod2EubGVuZ3RoIT09NCprYSl0aHJvdyBFcnJvcigiVW5zdXBwb3J0ZWQgY2hhbm5lbCBjb3VudDogIit3YS5sZW5ndGgva2EpO3dhPW5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KHdhLmJ1ZmZlcix3YS5ieXRlT2Zmc2V0LHdhLmxlbmd0aCksRWEsYmEpfWVsc2UgaWYoISh3YSBpbnN0YW5jZW9mIFdlYkdMVGV4dHVyZSkpdGhyb3cgRXJyb3IoYFVuc3VwcG9ydGVkIGZvcm1hdDogJHt3YS5jb25zdHJ1Y3Rvci5uYW1lfWApO0VhPW5ldyBVYShbd2FdLCExLCExLHRoaXMuZy5pLmNhbnZhcyx0aGlzLk8sRWEsYmEpLHRoaXMucz1UYT1UYT9FYS5jbG9uZSgpOkVhLHRoaXMuaCYmdGhpcy5oKFRhKSx6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJzdHlsaXplZF9pbWFnZSIsYmE9Pnt0aGlzLnM9bnVsbCx0aGlzLmgmJnRoaXMuaChudWxsKSx6byh0aGlzLGJhKX0pLGhhPWhhLmcoKSx0aGlzLnNldEdyYXBoKG5ldyBVaW50OEFycmF5KGhhKSwhMCl9fTtjaC5wcm90b3R5cGUuc3R5bGl6ZT1jaC5wcm90b3R5cGUuUGEsY2gucHJvdG90eXBlLnNldE9wdGlvbnM9Y2gucHJvdG90eXBlLm8sY2guY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKGNoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LGNoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKGNoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sY2guY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShjaCxoYSxhYSl9O3ZhciB1aD1HYShbMCwxXSxbMSwyXSxbMiwzXSxbMyw0XSxbMCw1XSxbNSw2XSxbNiw3XSxbNyw4XSxbNSw5XSxbOSwxMF0sWzEwLDExXSxbMTEsMTJdLFs5LDEzXSxbMTMsMTRdLFsxNCwxNV0sWzE1LDE2XSxbMTMsMTddLFswLDE3XSxbMTcsMThdLFsxOCwxOV0sWzE5LDIwXSk7ZnVuY3Rpb24gbGgoaGEpe2hhLmdlc3R1cmVzPVtdLGhhLmxhbmRtYXJrcz1bXSxoYS53b3JsZExhbmRtYXJrcz1bXSxoYS5oYW5kZWRuZXNzPVtdfWZ1bmN0aW9uIGRoKGhhKXtyZXR1cm4gaGEuZ2VzdHVyZXMubGVuZ3RoPT09MD97Z2VzdHVyZXM6W10sbGFuZG1hcmtzOltdLHdvcmxkTGFuZG1hcmtzOltdLGhhbmRlZG5lc3M6W10saGFuZGVkbmVzc2VzOltdfTp7Z2VzdHVyZXM6aGEuZ2VzdHVyZXMsbGFuZG1hcmtzOmhhLmxhbmRtYXJrcyx3b3JsZExhbmRtYXJrczpoYS53b3JsZExhbmRtYXJrcyxoYW5kZWRuZXNzOmhhLmhhbmRlZG5lc3MsaGFuZGVkbmVzc2VzOmhhLmhhbmRlZG5lc3N9fWZ1bmN0aW9uIGZoKGhhLGFhPSEwKXtjb25zdCB4YT1bXTtmb3IoY29uc3QgU2Egb2YgaGEpe3ZhciBiYT1EcyhTYSk7aGE9W107Zm9yKGNvbnN0IFRhIG9mIGJhLmcoKSliYT1hYSYmRm4oVGEsMSkhPW51bGw/TW4oRm4oVGEsMSkpOi0xLGhhLnB1c2goe3Njb3JlOlBuKFRhLDIpPz8wLGluZGV4OmJhLGNhdGVnb3J5TmFtZTpSbihUYSwzKT8/IiI/PyIiLGRpc3BsYXlOYW1lOlJuKFRhLDQpPz8iIj8/IiJ9KTt4YS5wdXNoKGhhKX1yZXR1cm4geGF9dmFyIHBoPWNsYXNzIGV4dGVuZHMgJGF7Y29uc3RydWN0b3IoaGEsYWEpe3N1cGVyKG5ldyBYYShoYSxhYSksImltYWdlX2luIiwibm9ybV9yZWN0IiwhMSksdGhpcy5nZXN0dXJlcz1bXSx0aGlzLmxhbmRtYXJrcz1bXSx0aGlzLndvcmxkTGFuZG1hcmtzPVtdLHRoaXMuaGFuZGVkbmVzcz1bXSxrbihoYT10aGlzLmo9bmV3IEppLDAsMSxhYT1uZXcgYmkpLHRoaXMucz1uZXcgJGksa24odGhpcy5qLDAsMix0aGlzLnMpLHRoaXMuRD1uZXcgS2ksa24odGhpcy5zLDAsMyx0aGlzLkQpLHRoaXMudj1uZXcgV2ksa24odGhpcy5zLDAsMix0aGlzLnYpLHRoaXMuaD1uZXcgWGksa24odGhpcy5qLDAsMyx0aGlzLmgpLEluKHRoaXMudiwyLC41KSxJbih0aGlzLnMsNCwuNSksSW4odGhpcy5ELDIsLjUpfWdldCBiYXNlT3B0aW9ucygpe3JldHVybiBUbih0aGlzLmosYmksMSl9c2V0IGJhc2VPcHRpb25zKGhhKXtrbih0aGlzLmosMCwxLGhhKX1vKGhhKXt2YXIgU2EsVGEsd2EsRWE7aWYoQ24odGhpcy52LDMsaGEubnVtSGFuZHM/PzEpLCJtaW5IYW5kRGV0ZWN0aW9uQ29uZmlkZW5jZSJpbiBoYSYmSW4odGhpcy52LDIsaGEubWluSGFuZERldGVjdGlvbkNvbmZpZGVuY2U/Py41KSwibWluVHJhY2tpbmdDb25maWRlbmNlImluIGhhJiZJbih0aGlzLnMsNCxoYS5taW5UcmFja2luZ0NvbmZpZGVuY2U/Py41KSwibWluSGFuZFByZXNlbmNlQ29uZmlkZW5jZSJpbiBoYSYmSW4odGhpcy5ELDIsaGEubWluSGFuZFByZXNlbmNlQ29uZmlkZW5jZT8/LjUpLGhhLmNhbm5lZEdlc3R1cmVzQ2xhc3NpZmllck9wdGlvbnMpe3ZhciBhYT1uZXcgR2kseGE9YWEsYmE9QW8oaGEuY2FubmVkR2VzdHVyZXNDbGFzc2lmaWVyT3B0aW9ucywoU2E9VG4odGhpcy5oLEdpLDMpKT09bnVsbD92b2lkIDA6U2EuaCgpKTtrbih4YSwwLDIsYmEpLGtuKHRoaXMuaCwwLDMsYWEpfWVsc2UgaGEuY2FubmVkR2VzdHVyZXNDbGFzc2lmaWVyT3B0aW9ucz09PXZvaWQgMCYmKChUYT1Ubih0aGlzLmgsR2ksMykpPT1udWxsfHxUYS5nKCkpO3JldHVybiBoYS5jdXN0b21HZXN0dXJlc0NsYXNzaWZpZXJPcHRpb25zPyhrbih4YT1hYT1uZXcgR2ksMCwyLGJhPUFvKGhhLmN1c3RvbUdlc3R1cmVzQ2xhc3NpZmllck9wdGlvbnMsKHdhPVRuKHRoaXMuaCxHaSw0KSk9PW51bGw/dm9pZCAwOndhLmgoKSkpLGtuKHRoaXMuaCwwLDQsYWEpKTpoYS5jdXN0b21HZXN0dXJlc0NsYXNzaWZpZXJPcHRpb25zPT09dm9pZCAwJiYoKEVhPVRuKHRoaXMuaCxHaSw0KSk9PW51bGx8fEVhLmcoKSksdGhpcy5sKGhhKX1LYShoYSxhYSl7cmV0dXJuIGxoKHRoaXMpLHphKHRoaXMsaGEsYWEpLGRoKHRoaXMpfUxhKGhhLGFhLHhhKXtyZXR1cm4gbGgodGhpcyksS2EodGhpcyxoYSx4YSxhYSksZGgodGhpcyl9bSgpe3ZhciBoYT1uZXcgTHM7eHMoaGEsImltYWdlX2luIikseHMoaGEsIm5vcm1fcmVjdCIpLFNzKGhhLCJoYW5kX2dlc3R1cmVzIiksU3MoaGEsImhhbmRfbGFuZG1hcmtzIiksU3MoaGEsIndvcmxkX2hhbmRfbGFuZG1hcmtzIiksU3MoaGEsImhhbmRlZG5lc3MiKTtjb25zdCBhYT1uZXcgaHM7RG4oYWEsdG8sdGhpcy5qKTtjb25zdCB4YT1uZXcgdnM7bXMoeGEsIm1lZGlhcGlwZS50YXNrcy52aXNpb24uZ2VzdHVyZV9yZWNvZ25pemVyLkdlc3R1cmVSZWNvZ25pemVyR3JhcGgiKSx5cyh4YSwiSU1BR0U6aW1hZ2VfaW4iKSx5cyh4YSwiTk9STV9SRUNUOm5vcm1fcmVjdCIpLF9zKHhhLCJIQU5EX0dFU1RVUkVTOmhhbmRfZ2VzdHVyZXMiKSxfcyh4YSwiTEFORE1BUktTOmhhbmRfbGFuZG1hcmtzIiksX3MoeGEsIldPUkxEX0xBTkRNQVJLUzp3b3JsZF9oYW5kX2xhbmRtYXJrcyIpLF9zKHhhLCJIQU5ERURORVNTOmhhbmRlZG5lc3MiKSx4YS5vKGFhKSxrcyhoYSx4YSksdGhpcy5nLmF0dGFjaFByb3RvVmVjdG9yTGlzdGVuZXIoImhhbmRfbGFuZG1hcmtzIiwoYmEsU2EpPT57Zm9yKGNvbnN0IFRhIG9mIGJhKXtiYT1laShUYSk7Y29uc3Qgd2E9W107Zm9yKGNvbnN0IEVhIG9mIGJuKGJhLFpzLDEpKXdhLnB1c2goe3g6UG4oRWEsMSk/PzAseTpQbihFYSwyKT8/MCx6OlBuKEVhLDMpPz8wLHZpc2liaWxpdHk6UG4oRWEsNCk/PzB9KTt0aGlzLmxhbmRtYXJrcy5wdXNoKHdhKX16byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJoYW5kX2xhbmRtYXJrcyIsYmE9Pnt6byh0aGlzLGJhKX0pLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJ3b3JsZF9oYW5kX2xhbmRtYXJrcyIsKGJhLFNhKT0+e2Zvcihjb25zdCBUYSBvZiBiYSl7YmE9SnMoVGEpO2NvbnN0IHdhPVtdO2Zvcihjb25zdCBFYSBvZiBibihiYSxZcywxKSl3YS5wdXNoKHt4OlBuKEVhLDEpPz8wLHk6UG4oRWEsMik/PzAsejpQbihFYSwzKT8/MCx2aXNpYmlsaXR5OlBuKEVhLDQpPz8wfSk7dGhpcy53b3JsZExhbmRtYXJrcy5wdXNoKHdhKX16byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJ3b3JsZF9oYW5kX2xhbmRtYXJrcyIsYmE9Pnt6byh0aGlzLGJhKX0pLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJoYW5kX2dlc3R1cmVzIiwoYmEsU2EpPT57dGhpcy5nZXN0dXJlcy5wdXNoKC4uLmZoKGJhLCExKSksem8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiaGFuZF9nZXN0dXJlcyIsYmE9Pnt6byh0aGlzLGJhKX0pLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJoYW5kZWRuZXNzIiwoYmEsU2EpPT57dGhpcy5oYW5kZWRuZXNzLnB1c2goLi4uZmgoYmEpKSx6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJoYW5kZWRuZXNzIixiYT0+e3pvKHRoaXMsYmEpfSksaGE9aGEuZygpLHRoaXMuc2V0R3JhcGgobmV3IFVpbnQ4QXJyYXkoaGEpLCEwKX19O2Z1bmN0aW9uIGdoKGhhKXtyZXR1cm57bGFuZG1hcmtzOmhhLmxhbmRtYXJrcyx3b3JsZExhbmRtYXJrczpoYS53b3JsZExhbmRtYXJrcyxoYW5kZWRuZXNzZXM6aGEuaGFuZGVkbmVzcyxoYW5kZWRuZXNzOmhhLmhhbmRlZG5lc3N9fXBoLnByb3RvdHlwZS5yZWNvZ25pemVGb3JWaWRlbz1waC5wcm90b3R5cGUuTGEscGgucHJvdG90eXBlLnJlY29nbml6ZT1waC5wcm90b3R5cGUuS2EscGgucHJvdG90eXBlLnNldE9wdGlvbnM9cGgucHJvdG90eXBlLm8scGguY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKHBoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LHBoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKHBoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0scGguY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShwaCxoYSxhYSl9LHBoLkhBTkRfQ09OTkVDVElPTlM9dWg7dmFyIG1oPWNsYXNzIGV4dGVuZHMgJGF7Y29uc3RydWN0b3IoaGEsYWEpe3N1cGVyKG5ldyBYYShoYSxhYSksImltYWdlX2luIiwibm9ybV9yZWN0IiwhMSksdGhpcy5sYW5kbWFya3M9W10sdGhpcy53b3JsZExhbmRtYXJrcz1bXSx0aGlzLmhhbmRlZG5lc3M9W10sa24oaGE9dGhpcy5oPW5ldyAkaSwwLDEsYWE9bmV3IGJpKSx0aGlzLnM9bmV3IEtpLGtuKHRoaXMuaCwwLDMsdGhpcy5zKSx0aGlzLmo9bmV3IFdpLGtuKHRoaXMuaCwwLDIsdGhpcy5qKSxDbih0aGlzLmosMywxKSxJbih0aGlzLmosMiwuNSksSW4odGhpcy5zLDIsLjUpLEluKHRoaXMuaCw0LC41KX1nZXQgYmFzZU9wdGlvbnMoKXtyZXR1cm4gVG4odGhpcy5oLGJpLDEpfXNldCBiYXNlT3B0aW9ucyhoYSl7a24odGhpcy5oLDAsMSxoYSl9byhoYSl7cmV0dXJuIm51bUhhbmRzImluIGhhJiZDbih0aGlzLmosMyxoYS5udW1IYW5kcz8/MSksIm1pbkhhbmREZXRlY3Rpb25Db25maWRlbmNlImluIGhhJiZJbih0aGlzLmosMixoYS5taW5IYW5kRGV0ZWN0aW9uQ29uZmlkZW5jZT8/LjUpLCJtaW5UcmFja2luZ0NvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMuaCw0LGhhLm1pblRyYWNraW5nQ29uZmlkZW5jZT8/LjUpLCJtaW5IYW5kUHJlc2VuY2VDb25maWRlbmNlImluIGhhJiZJbih0aGlzLnMsMixoYS5taW5IYW5kUHJlc2VuY2VDb25maWRlbmNlPz8uNSksdGhpcy5sKGhhKX1GKGhhLGFhKXtyZXR1cm4gdGhpcy5sYW5kbWFya3M9W10sdGhpcy53b3JsZExhbmRtYXJrcz1bXSx0aGlzLmhhbmRlZG5lc3M9W10semEodGhpcyxoYSxhYSksZ2godGhpcyl9RyhoYSxhYSx4YSl7cmV0dXJuIHRoaXMubGFuZG1hcmtzPVtdLHRoaXMud29ybGRMYW5kbWFya3M9W10sdGhpcy5oYW5kZWRuZXNzPVtdLEthKHRoaXMsaGEseGEsYWEpLGdoKHRoaXMpfW0oKXt2YXIgaGE9bmV3IExzO3hzKGhhLCJpbWFnZV9pbiIpLHhzKGhhLCJub3JtX3JlY3QiKSxTcyhoYSwiaGFuZF9sYW5kbWFya3MiKSxTcyhoYSwid29ybGRfaGFuZF9sYW5kbWFya3MiKSxTcyhoYSwiaGFuZGVkbmVzcyIpO2NvbnN0IGFhPW5ldyBocztEbihhYSxRaSx0aGlzLmgpO2NvbnN0IHhhPW5ldyB2czttcyh4YSwibWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5oYW5kX2xhbmRtYXJrZXIuSGFuZExhbmRtYXJrZXJHcmFwaCIpLHlzKHhhLCJJTUFHRTppbWFnZV9pbiIpLHlzKHhhLCJOT1JNX1JFQ1Q6bm9ybV9yZWN0IiksX3MoeGEsIkxBTkRNQVJLUzpoYW5kX2xhbmRtYXJrcyIpLF9zKHhhLCJXT1JMRF9MQU5ETUFSS1M6d29ybGRfaGFuZF9sYW5kbWFya3MiKSxfcyh4YSwiSEFOREVETkVTUzpoYW5kZWRuZXNzIikseGEubyhhYSksa3MoaGEseGEpLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJoYW5kX2xhbmRtYXJrcyIsKGJhLFNhKT0+e2Zvcihjb25zdCBUYSBvZiBiYSliYT1laShUYSksdGhpcy5sYW5kbWFya3MucHVzaCh4byhiYSkpO3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoImhhbmRfbGFuZG1hcmtzIixiYT0+e3pvKHRoaXMsYmEpfSksdGhpcy5nLmF0dGFjaFByb3RvVmVjdG9yTGlzdGVuZXIoIndvcmxkX2hhbmRfbGFuZG1hcmtzIiwoYmEsU2EpPT57Zm9yKGNvbnN0IFRhIG9mIGJhKWJhPUpzKFRhKSx0aGlzLndvcmxkTGFuZG1hcmtzLnB1c2goU28oYmEpKTt6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJ3b3JsZF9oYW5kX2xhbmRtYXJrcyIsYmE9Pnt6byh0aGlzLGJhKX0pLHRoaXMuZy5hdHRhY2hQcm90b1ZlY3Rvckxpc3RlbmVyKCJoYW5kZWRuZXNzIiwoYmEsU2EpPT57dmFyIFRhPXRoaXMuaGFuZGVkbmVzcyx3YT1UYS5wdXNoO2NvbnN0IEVhPVtdO2Zvcihjb25zdCBrYSBvZiBiYSl7YmE9RHMoa2EpO2NvbnN0IEFhPVtdO2Zvcihjb25zdCBGYSBvZiBiYS5nKCkpQWEucHVzaCh7c2NvcmU6UG4oRmEsMik/PzAsaW5kZXg6TW4oRm4oRmEsMSkpPz8tMSxjYXRlZ29yeU5hbWU6Um4oRmEsMyk/PyIiPz8iIixkaXNwbGF5TmFtZTpSbihGYSw0KT8/IiI/PyIifSk7RWEucHVzaChBYSl9d2EuY2FsbChUYSwuLi5FYSksem8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiaGFuZGVkbmVzcyIsYmE9Pnt6byh0aGlzLGJhKX0pLGhhPWhhLmcoKSx0aGlzLnNldEdyYXBoKG5ldyBVaW50OEFycmF5KGhhKSwhMCl9fTttaC5wcm90b3R5cGUuZGV0ZWN0Rm9yVmlkZW89bWgucHJvdG90eXBlLkcsbWgucHJvdG90eXBlLmRldGVjdD1taC5wcm90b3R5cGUuRixtaC5wcm90b3R5cGUuc2V0T3B0aW9ucz1taC5wcm90b3R5cGUubyxtaC5jcmVhdGVGcm9tTW9kZWxQYXRoPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gSGEobWgsaGEse2Jhc2VPcHRpb25zOnttb2RlbEFzc2V0UGF0aDphYX19KX0sbWguY3JlYXRlRnJvbU1vZGVsQnVmZmVyPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gSGEobWgsaGEse2Jhc2VPcHRpb25zOnttb2RlbEFzc2V0QnVmZmVyOmFhfX0pfSxtaC5jcmVhdGVGcm9tT3B0aW9ucz1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKG1oLGhhLGFhKX0sbWguSEFORF9DT05ORUNUSU9OUz11aDt2YXIgeWg9R2EoWzAsMV0sWzEsMl0sWzIsM10sWzMsN10sWzAsNF0sWzQsNV0sWzUsNl0sWzYsOF0sWzksMTBdLFsxMSwxMl0sWzExLDEzXSxbMTMsMTVdLFsxNSwxN10sWzE1LDE5XSxbMTUsMjFdLFsxNywxOV0sWzEyLDE0XSxbMTQsMTZdLFsxNiwxOF0sWzE2LDIwXSxbMTYsMjJdLFsxOCwyMF0sWzExLDIzXSxbMTIsMjRdLFsyMywyNF0sWzIzLDI1XSxbMjQsMjZdLFsyNSwyN10sWzI2LDI4XSxbMjcsMjldLFsyOCwzMF0sWzI5LDMxXSxbMzAsMzJdLFsyNywzMV0sWzI4LDMyXSk7ZnVuY3Rpb24gX2goaGEpe2hhLmg9e2ZhY2VMYW5kbWFya3M6W10sZmFjZUJsZW5kc2hhcGVzOltdLHBvc2VMYW5kbWFya3M6W10scG9zZVdvcmxkTGFuZG1hcmtzOltdLHBvc2VTZWdtZW50YXRpb25NYXNrczpbXSxsZWZ0SGFuZExhbmRtYXJrczpbXSxsZWZ0SGFuZFdvcmxkTGFuZG1hcmtzOltdLHJpZ2h0SGFuZExhbmRtYXJrczpbXSxyaWdodEhhbmRXb3JsZExhbmRtYXJrczpbXX19ZnVuY3Rpb24gdmgoaGEpe3RyeXtpZighaGEuRClyZXR1cm4gaGEuaDtoYS5EKGhhLmgpfWZpbmFsbHl7JG8oaGEpfX1mdW5jdGlvbiBFaChoYSxhYSl7aGE9ZWkoaGEpLGFhLnB1c2goeG8oaGEpKX12YXIgd2g9Y2xhc3MgZXh0ZW5kcyAkYXtjb25zdHJ1Y3RvcihoYSxhYSl7c3VwZXIobmV3IFhhKGhhLGFhKSwiaW5wdXRfZnJhbWVzX2ltYWdlIixudWxsLCExKSx0aGlzLmg9e2ZhY2VMYW5kbWFya3M6W10sZmFjZUJsZW5kc2hhcGVzOltdLHBvc2VMYW5kbWFya3M6W10scG9zZVdvcmxkTGFuZG1hcmtzOltdLHBvc2VTZWdtZW50YXRpb25NYXNrczpbXSxsZWZ0SGFuZExhbmRtYXJrczpbXSxsZWZ0SGFuZFdvcmxkTGFuZG1hcmtzOltdLHJpZ2h0SGFuZExhbmRtYXJrczpbXSxyaWdodEhhbmRXb3JsZExhbmRtYXJrczpbXX0sdGhpcy5vdXRwdXRQb3NlU2VnbWVudGF0aW9uTWFza3M9dGhpcy5vdXRwdXRGYWNlQmxlbmRzaGFwZXM9ITEsa24oaGE9dGhpcy5qPW5ldyBhbywwLDEsYWE9bmV3IGJpKSx0aGlzLkk9bmV3IEtpLGtuKHRoaXMuaiwwLDIsdGhpcy5JKSx0aGlzLmFhPW5ldyBlbyxrbih0aGlzLmosMCwzLHRoaXMuYWEpLHRoaXMucz1uZXcgeGksa24odGhpcy5qLDAsNCx0aGlzLnMpLHRoaXMuUD1uZXcgT2ksa24odGhpcy5qLDAsNSx0aGlzLlApLHRoaXMudj1uZXcgcm8sa24odGhpcy5qLDAsNix0aGlzLnYpLHRoaXMuSj1uZXcgaW8sa24odGhpcy5qLDAsNyx0aGlzLkopLEluKHRoaXMucywyLC41KSxJbih0aGlzLnMsMywuMyksSW4odGhpcy5QLDIsLjUpLEluKHRoaXMudiwyLC41KSxJbih0aGlzLnYsMywuMyksSW4odGhpcy5KLDIsLjUpLEluKHRoaXMuSSwyLC41KX1nZXQgYmFzZU9wdGlvbnMoKXtyZXR1cm4gVG4odGhpcy5qLGJpLDEpfXNldCBiYXNlT3B0aW9ucyhoYSl7a24odGhpcy5qLDAsMSxoYSl9byhoYSl7cmV0dXJuIm1pbkZhY2VEZXRlY3Rpb25Db25maWRlbmNlImluIGhhJiZJbih0aGlzLnMsMixoYS5taW5GYWNlRGV0ZWN0aW9uQ29uZmlkZW5jZT8/LjUpLCJtaW5GYWNlU3VwcHJlc3Npb25UaHJlc2hvbGQiaW4gaGEmJkluKHRoaXMucywzLGhhLm1pbkZhY2VTdXBwcmVzc2lvblRocmVzaG9sZD8/LjMpLCJtaW5GYWNlUHJlc2VuY2VDb25maWRlbmNlImluIGhhJiZJbih0aGlzLlAsMixoYS5taW5GYWNlUHJlc2VuY2VDb25maWRlbmNlPz8uNSksIm91dHB1dEZhY2VCbGVuZHNoYXBlcyJpbiBoYSYmKHRoaXMub3V0cHV0RmFjZUJsZW5kc2hhcGVzPSEhaGEub3V0cHV0RmFjZUJsZW5kc2hhcGVzKSwibWluUG9zZURldGVjdGlvbkNvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMudiwyLGhhLm1pblBvc2VEZXRlY3Rpb25Db25maWRlbmNlPz8uNSksIm1pblBvc2VTdXBwcmVzc2lvblRocmVzaG9sZCJpbiBoYSYmSW4odGhpcy52LDMsaGEubWluUG9zZVN1cHByZXNzaW9uVGhyZXNob2xkPz8uMyksIm1pblBvc2VQcmVzZW5jZUNvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMuSiwyLGhhLm1pblBvc2VQcmVzZW5jZUNvbmZpZGVuY2U/Py41KSwib3V0cHV0UG9zZVNlZ21lbnRhdGlvbk1hc2tzImluIGhhJiYodGhpcy5vdXRwdXRQb3NlU2VnbWVudGF0aW9uTWFza3M9ISFoYS5vdXRwdXRQb3NlU2VnbWVudGF0aW9uTWFza3MpLCJtaW5IYW5kTGFuZG1hcmtzQ29uZmlkZW5jZSJpbiBoYSYmSW4odGhpcy5JLDIsaGEubWluSGFuZExhbmRtYXJrc0NvbmZpZGVuY2U/Py41KSx0aGlzLmwoaGEpfUYoaGEsYWEseGEpe2NvbnN0IGJhPXR5cGVvZiBhYSE9ImZ1bmN0aW9uIj9hYTp7fTtyZXR1cm4gdGhpcy5EPXR5cGVvZiBhYT09ImZ1bmN0aW9uIj9hYTp4YSxfaCh0aGlzKSx6YSh0aGlzLGhhLGJhKSx2aCh0aGlzKX1HKGhhLGFhLHhhLGJhKXtjb25zdCBTYT10eXBlb2YgeGEhPSJmdW5jdGlvbiI/eGE6e307cmV0dXJuIHRoaXMuRD10eXBlb2YgeGE9PSJmdW5jdGlvbiI/eGE6YmEsX2godGhpcyksS2EodGhpcyxoYSxTYSxhYSksdmgodGhpcyl9bSgpe3ZhciBoYT1uZXcgTHM7eHMoaGEsImlucHV0X2ZyYW1lc19pbWFnZSIpLFNzKGhhLCJwb3NlX2xhbmRtYXJrcyIpLFNzKGhhLCJwb3NlX3dvcmxkX2xhbmRtYXJrcyIpLFNzKGhhLCJmYWNlX2xhbmRtYXJrcyIpLFNzKGhhLCJsZWZ0X2hhbmRfbGFuZG1hcmtzIiksU3MoaGEsImxlZnRfaGFuZF93b3JsZF9sYW5kbWFya3MiKSxTcyhoYSwicmlnaHRfaGFuZF9sYW5kbWFya3MiKSxTcyhoYSwicmlnaHRfaGFuZF93b3JsZF9sYW5kbWFya3MiKTtjb25zdCBhYT1uZXcgaHMseGE9bmV3IEpyO2duKHhhLDEsa2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vbWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5ob2xpc3RpY19sYW5kbWFya2VyLnByb3RvLkhvbGlzdGljTGFuZG1hcmtlckdyYXBoT3B0aW9ucyIpLCIiKSxmdW5jdGlvbihTYSxUYSl7aWYoVGEhPW51bGwpaWYoQXJyYXkuaXNBcnJheShUYSkpcm4oU2EsMixZZShUYSxxZSx2b2lkIDAsdm9pZCAwLCExKSk7ZWxzZXtpZighKHR5cGVvZiBUYT09InN0cmluZyJ8fFRhIGluc3RhbmNlb2YgVXx8UihUYSkpKXRocm93IEVycm9yKCJpbnZhbGlkIHZhbHVlIGluIEFueS52YWx1ZSBmaWVsZDogIitUYSsiIGV4cGVjdGVkIGEgQnl0ZVN0cmluZywgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcsIGEgVWludDhBcnJheSBvciBhIGpzcGIgYXJyYXkiKTtnbihTYSwyLHNlKFRhLCExLCExKSxEKCkpfX0oeGEsdGhpcy5qLmcoKSk7Y29uc3QgYmE9bmV3IHZzO21zKGJhLCJtZWRpYXBpcGUudGFza3MudmlzaW9uLmhvbGlzdGljX2xhbmRtYXJrZXIuSG9saXN0aWNMYW5kbWFya2VyR3JhcGgiKSxMbihiYSw4LEpyLHhhKSx5cyhiYSwiSU1BR0U6aW5wdXRfZnJhbWVzX2ltYWdlIiksX3MoYmEsIlBPU0VfTEFORE1BUktTOnBvc2VfbGFuZG1hcmtzIiksX3MoYmEsIlBPU0VfV09STERfTEFORE1BUktTOnBvc2Vfd29ybGRfbGFuZG1hcmtzIiksX3MoYmEsIkZBQ0VfTEFORE1BUktTOmZhY2VfbGFuZG1hcmtzIiksX3MoYmEsIkxFRlRfSEFORF9MQU5ETUFSS1M6bGVmdF9oYW5kX2xhbmRtYXJrcyIpLF9zKGJhLCJMRUZUX0hBTkRfV09STERfTEFORE1BUktTOmxlZnRfaGFuZF93b3JsZF9sYW5kbWFya3MiKSxfcyhiYSwiUklHSFRfSEFORF9MQU5ETUFSS1M6cmlnaHRfaGFuZF9sYW5kbWFya3MiKSxfcyhiYSwiUklHSFRfSEFORF9XT1JMRF9MQU5ETUFSS1M6cmlnaHRfaGFuZF93b3JsZF9sYW5kbWFya3MiKSxiYS5vKGFhKSxrcyhoYSxiYSksS28odGhpcyxoYSksdGhpcy5nLmF0dGFjaFByb3RvTGlzdGVuZXIoInBvc2VfbGFuZG1hcmtzIiwoU2EsVGEpPT57RWgoU2EsdGhpcy5oLnBvc2VMYW5kbWFya3MpLHpvKHRoaXMsVGEpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoInBvc2VfbGFuZG1hcmtzIixTYT0+e3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaFByb3RvTGlzdGVuZXIoInBvc2Vfd29ybGRfbGFuZG1hcmtzIiwoU2EsVGEpPT57dmFyIHdhPXRoaXMuaC5wb3NlV29ybGRMYW5kbWFya3M7U2E9SnMoU2EpLHdhLnB1c2goU28oU2EpKSx6byh0aGlzLFRhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJwb3NlX3dvcmxkX2xhbmRtYXJrcyIsU2E9Pnt6byh0aGlzLFNhKX0pLHRoaXMub3V0cHV0UG9zZVNlZ21lbnRhdGlvbk1hc2tzJiYoX3MoYmEsIlBPU0VfU0VHTUVOVEFUSU9OX01BU0s6cG9zZV9zZWdtZW50YXRpb25fbWFzayIpLFlvKHRoaXMsInBvc2Vfc2VnbWVudGF0aW9uX21hc2siKSx0aGlzLmcuVygicG9zZV9zZWdtZW50YXRpb25fbWFzayIsKFNhLFRhKT0+e3RoaXMuaC5wb3NlU2VnbWVudGF0aW9uTWFza3M9W1lhKHRoaXMsU2EsITAsIXRoaXMuRCldLHpvKHRoaXMsVGEpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoInBvc2Vfc2VnbWVudGF0aW9uX21hc2siLFNhPT57dGhpcy5oLnBvc2VTZWdtZW50YXRpb25NYXNrcz1bXSx6byh0aGlzLFNhKX0pKSx0aGlzLmcuYXR0YWNoUHJvdG9MaXN0ZW5lcigiZmFjZV9sYW5kbWFya3MiLChTYSxUYSk9PntFaChTYSx0aGlzLmguZmFjZUxhbmRtYXJrcyksem8odGhpcyxUYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiZmFjZV9sYW5kbWFya3MiLFNhPT57em8odGhpcyxTYSl9KSx0aGlzLm91dHB1dEZhY2VCbGVuZHNoYXBlcyYmKFNzKGhhLCJleHRyYV9ibGVuZHNoYXBlcyIpLF9zKGJhLCJGQUNFX0JMRU5EU0hBUEVTOmV4dHJhX2JsZW5kc2hhcGVzIiksdGhpcy5nLmF0dGFjaFByb3RvTGlzdGVuZXIoImV4dHJhX2JsZW5kc2hhcGVzIiwoU2EsVGEpPT57dmFyIHdhPXRoaXMuaC5mYWNlQmxlbmRzaGFwZXM7dGhpcy5vdXRwdXRGYWNlQmxlbmRzaGFwZXMmJihTYT1EcyhTYSksd2EucHVzaChibyhTYS5nKCk/P1tdKSkpLHpvKHRoaXMsVGEpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoImV4dHJhX2JsZW5kc2hhcGVzIixTYT0+e3pvKHRoaXMsU2EpfSkpLHRoaXMuZy5hdHRhY2hQcm90b0xpc3RlbmVyKCJsZWZ0X2hhbmRfbGFuZG1hcmtzIiwoU2EsVGEpPT57RWgoU2EsdGhpcy5oLmxlZnRIYW5kTGFuZG1hcmtzKSx6byh0aGlzLFRhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJsZWZ0X2hhbmRfbGFuZG1hcmtzIixTYT0+e3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaFByb3RvTGlzdGVuZXIoImxlZnRfaGFuZF93b3JsZF9sYW5kbWFya3MiLChTYSxUYSk9Pnt2YXIgd2E9dGhpcy5oLmxlZnRIYW5kV29ybGRMYW5kbWFya3M7U2E9SnMoU2EpLHdhLnB1c2goU28oU2EpKSx6byh0aGlzLFRhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJsZWZ0X2hhbmRfd29ybGRfbGFuZG1hcmtzIixTYT0+e3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaFByb3RvTGlzdGVuZXIoInJpZ2h0X2hhbmRfbGFuZG1hcmtzIiwoU2EsVGEpPT57RWgoU2EsdGhpcy5oLnJpZ2h0SGFuZExhbmRtYXJrcyksem8odGhpcyxUYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigicmlnaHRfaGFuZF9sYW5kbWFya3MiLFNhPT57em8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoUHJvdG9MaXN0ZW5lcigicmlnaHRfaGFuZF93b3JsZF9sYW5kbWFya3MiLChTYSxUYSk9Pnt2YXIgd2E9dGhpcy5oLnJpZ2h0SGFuZFdvcmxkTGFuZG1hcmtzO1NhPUpzKFNhKSx3YS5wdXNoKFNvKFNhKSksem8odGhpcyxUYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigicmlnaHRfaGFuZF93b3JsZF9sYW5kbWFya3MiLFNhPT57em8odGhpcyxTYSl9KSxoYT1oYS5nKCksdGhpcy5zZXRHcmFwaChuZXcgVWludDhBcnJheShoYSksITApfX07d2gucHJvdG90eXBlLmRldGVjdEZvclZpZGVvPXdoLnByb3RvdHlwZS5HLHdoLnByb3RvdHlwZS5kZXRlY3Q9d2gucHJvdG90eXBlLkYsd2gucHJvdG90eXBlLnNldE9wdGlvbnM9d2gucHJvdG90eXBlLm8sd2guY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKHdoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LHdoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKHdoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sd2guY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYSh3aCxoYSxhYSl9LHdoLkhBTkRfQ09OTkVDVElPTlM9dWgsd2guUE9TRV9DT05ORUNUSU9OUz15aCx3aC5GQUNFX0xBTkRNQVJLU19MSVBTPUphLHdoLkZBQ0VfTEFORE1BUktTX0xFRlRfRVlFPVphLHdoLkZBQ0VfTEFORE1BUktTX0xFRlRfRVlFQlJPVz1RYSx3aC5GQUNFX0xBTkRNQVJLU19MRUZUX0lSSVM9dGgsd2guRkFDRV9MQU5ETUFSS1NfUklHSFRfRVlFPWVoLHdoLkZBQ0VfTEFORE1BUktTX1JJR0hUX0VZRUJST1c9bmgsd2guRkFDRV9MQU5ETUFSS1NfUklHSFRfSVJJUz1yaCx3aC5GQUNFX0xBTkRNQVJLU19GQUNFX09WQUw9c2gsd2guRkFDRV9MQU5ETUFSS1NfQ09OVE9VUlM9aWgsd2guRkFDRV9MQU5ETUFSS1NfVEVTU0VMQVRJT049b2g7dmFyIFRoPWNsYXNzIGV4dGVuZHMgJGF7Y29uc3RydWN0b3IoaGEsYWEpe3N1cGVyKG5ldyBYYShoYSxhYSksImlucHV0X2ltYWdlIiwibm9ybV9yZWN0IiwhMCksdGhpcy5qPXtjbGFzc2lmaWNhdGlvbnM6W119LGtuKGhhPXRoaXMuaD1uZXcgaG8sMCwxLGFhPW5ldyBiaSl9Z2V0IGJhc2VPcHRpb25zKCl7cmV0dXJuIFRuKHRoaXMuaCxiaSwxKX1zZXQgYmFzZU9wdGlvbnMoaGEpe2tuKHRoaXMuaCwwLDEsaGEpfW8oaGEpe3JldHVybiBrbih0aGlzLmgsMCwyLEFvKGhhLFRuKHRoaXMuaCxtaSwyKSkpLHRoaXMubChoYSl9dWEoaGEsYWEpe3JldHVybiB0aGlzLmo9e2NsYXNzaWZpY2F0aW9uczpbXX0semEodGhpcyxoYSxhYSksdGhpcy5qfXZhKGhhLGFhLHhhKXtyZXR1cm4gdGhpcy5qPXtjbGFzc2lmaWNhdGlvbnM6W119LEthKHRoaXMsaGEseGEsYWEpLHRoaXMuan1tKCl7dmFyIGhhPW5ldyBMczt4cyhoYSwiaW5wdXRfaW1hZ2UiKSx4cyhoYSwibm9ybV9yZWN0IiksU3MoaGEsImNsYXNzaWZpY2F0aW9ucyIpO2NvbnN0IGFhPW5ldyBocztEbihhYSxjbyx0aGlzLmgpO2NvbnN0IHhhPW5ldyB2czttcyh4YSwibWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5pbWFnZV9jbGFzc2lmaWVyLkltYWdlQ2xhc3NpZmllckdyYXBoIikseXMoeGEsIklNQUdFOmlucHV0X2ltYWdlIikseXMoeGEsIk5PUk1fUkVDVDpub3JtX3JlY3QiKSxfcyh4YSwiQ0xBU1NJRklDQVRJT05TOmNsYXNzaWZpY2F0aW9ucyIpLHhhLm8oYWEpLGtzKGhhLHhhKSx0aGlzLmcuYXR0YWNoUHJvdG9MaXN0ZW5lcigiY2xhc3NpZmljYXRpb25zIiwoYmEsU2EpPT57dGhpcy5qPWZ1bmN0aW9uKFRhKXtjb25zdCB3YT17Y2xhc3NpZmljYXRpb25zOmJuKFRhLGlpLDEpLm1hcChFYT0+e3ZhciBrYTtyZXR1cm4gYm8oKChrYT1UbihFYSxDcyw0KSk9PW51bGw/dm9pZCAwOmthLmcoKSk/P1tdLE1uKEZuKEVhLDIpKSxSbihFYSwzKT8/IiIpfSl9O3JldHVybiBBZShlbihUYSwyKSkhPW51bGwmJih3YS50aW1lc3RhbXBNcz1NbihBZShlbihUYSwyKSkpKSx3YX0oaGkoYmEpKSx6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJjbGFzc2lmaWNhdGlvbnMiLGJhPT57em8odGhpcyxiYSl9KSxoYT1oYS5nKCksdGhpcy5zZXRHcmFwaChuZXcgVWludDhBcnJheShoYSksITApfX07VGgucHJvdG90eXBlLmNsYXNzaWZ5Rm9yVmlkZW89VGgucHJvdG90eXBlLnZhLFRoLnByb3RvdHlwZS5jbGFzc2lmeT1UaC5wcm90b3R5cGUudWEsVGgucHJvdG90eXBlLnNldE9wdGlvbnM9VGgucHJvdG90eXBlLm8sVGguY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFRoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LFRoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFRoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sVGguY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShUaCxoYSxhYSl9O3ZhciBBaD1jbGFzcyBleHRlbmRzICRhe2NvbnN0cnVjdG9yKGhhLGFhKXtzdXBlcihuZXcgWGEoaGEsYWEpLCJpbWFnZV9pbiIsIm5vcm1fcmVjdCIsITApLHRoaXMuaD1uZXcgdW8sdGhpcy5lbWJlZGRpbmdzPXtlbWJlZGRpbmdzOltdfSxrbihoYT10aGlzLmgsMCwxLGFhPW5ldyBiaSl9Z2V0IGJhc2VPcHRpb25zKCl7cmV0dXJuIFRuKHRoaXMuaCxiaSwxKX1zZXQgYmFzZU9wdGlvbnMoaGEpe2tuKHRoaXMuaCwwLDEsaGEpfW8oaGEpe3ZhciBhYT10aGlzLmgseGE9VG4odGhpcy5oLF9pLDIpO3JldHVybiB4YT14YT94YS5jbG9uZSgpOm5ldyBfaSxoYS5sMk5vcm1hbGl6ZSE9PXZvaWQgMD9Pbih4YSwxLGhhLmwyTm9ybWFsaXplKToibDJOb3JtYWxpemUiaW4gaGEmJnJuKHhhLDEpLGhhLnF1YW50aXplIT09dm9pZCAwP09uKHhhLDIsaGEucXVhbnRpemUpOiJxdWFudGl6ZSJpbiBoYSYmcm4oeGEsMiksa24oYWEsMCwyLHhhKSx0aGlzLmwoaGEpfUJhKGhhLGFhKXtyZXR1cm4gemEodGhpcyxoYSxhYSksdGhpcy5lbWJlZGRpbmdzfUNhKGhhLGFhLHhhKXtyZXR1cm4gS2EodGhpcyxoYSx4YSxhYSksdGhpcy5lbWJlZGRpbmdzfW0oKXt2YXIgaGE9bmV3IExzO3hzKGhhLCJpbWFnZV9pbiIpLHhzKGhhLCJub3JtX3JlY3QiKSxTcyhoYSwiZW1iZWRkaW5nc19vdXQiKTtjb25zdCBhYT1uZXcgaHM7RG4oYWEsbG8sdGhpcy5oKTtjb25zdCB4YT1uZXcgdnM7bXMoeGEsIm1lZGlhcGlwZS50YXNrcy52aXNpb24uaW1hZ2VfZW1iZWRkZXIuSW1hZ2VFbWJlZGRlckdyYXBoIikseXMoeGEsIklNQUdFOmltYWdlX2luIikseXMoeGEsIk5PUk1fUkVDVDpub3JtX3JlY3QiKSxfcyh4YSwiRU1CRURESU5HUzplbWJlZGRpbmdzX291dCIpLHhhLm8oYWEpLGtzKGhhLHhhKSx0aGlzLmcuYXR0YWNoUHJvdG9MaXN0ZW5lcigiZW1iZWRkaW5nc19vdXQiLChiYSxTYSk9PntiYT1naShiYSksdGhpcy5lbWJlZGRpbmdzPWZ1bmN0aW9uKFRhKXtyZXR1cm57ZW1iZWRkaW5nczpibihUYSxsaSwxKS5tYXAod2E9Pnt2YXIga2EsQWE7Y29uc3QgRWE9e2hlYWRJbmRleDpNbihGbih3YSwzKSk/Py0xLGhlYWROYW1lOlJuKHdhLDQpPz8iIj8/IiJ9O2lmKHduKHdhLGNpLF9uKHdhLDEpKSE9PXZvaWQgMCl3YT1jbih3YT1Ubih3YSxjaSxfbih3YSwxKSksMSxmZSksRWEuZmxvYXRFbWJlZGRpbmc9d2Euc2xpY2UoKTtlbHNle2NvbnN0IEZhPW5ldyBVaW50OEFycmF5KDApO0VhLnF1YW50aXplZEVtYmVkZGluZz0oKEFhPShrYT1Ubih3YSx1aSxfbih3YSwyKSkpPT1udWxsP3ZvaWQgMDprYS5xYSgpKT09bnVsbD92b2lkIDA6QWEuaCgpKT8/RmF9cmV0dXJuIEVhfSksdGltZXN0YW1wTXM6TW4oQWUoZW4oVGEsMikpKX19KGJhKSx6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJlbWJlZGRpbmdzX291dCIsYmE9Pnt6byh0aGlzLGJhKX0pLGhhPWhhLmcoKSx0aGlzLnNldEdyYXBoKG5ldyBVaW50OEFycmF5KGhhKSwhMCl9fTtBaC5jb3NpbmVTaW1pbGFyaXR5PWZ1bmN0aW9uKGhhLGFhKXtpZihoYS5mbG9hdEVtYmVkZGluZyYmYWEuZmxvYXRFbWJlZGRpbmcpaGE9Rm8oaGEuZmxvYXRFbWJlZGRpbmcsYWEuZmxvYXRFbWJlZGRpbmcpO2Vsc2V7aWYoIWhhLnF1YW50aXplZEVtYmVkZGluZ3x8IWFhLnF1YW50aXplZEVtYmVkZGluZyl0aHJvdyBFcnJvcigiQ2Fubm90IGNvbXB1dGUgY29zaW5lIHNpbWlsYXJpdHkgYmV0d2VlbiBxdWFudGl6ZWQgYW5kIGZsb2F0IGVtYmVkZGluZ3MuIik7aGE9Rm8oTG8oaGEucXVhbnRpemVkRW1iZWRkaW5nKSxMbyhhYS5xdWFudGl6ZWRFbWJlZGRpbmcpKX1yZXR1cm4gaGF9LEFoLnByb3RvdHlwZS5lbWJlZEZvclZpZGVvPUFoLnByb3RvdHlwZS5DYSxBaC5wcm90b3R5cGUuZW1iZWQ9QWgucHJvdG90eXBlLkJhLEFoLnByb3RvdHlwZS5zZXRPcHRpb25zPUFoLnByb3RvdHlwZS5vLEFoLmNyZWF0ZUZyb21Nb2RlbFBhdGg9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShBaCxoYSx7YmFzZU9wdGlvbnM6e21vZGVsQXNzZXRQYXRoOmFhfX0pfSxBaC5jcmVhdGVGcm9tTW9kZWxCdWZmZXI9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShBaCxoYSx7YmFzZU9wdGlvbnM6e21vZGVsQXNzZXRCdWZmZXI6YWF9fSl9LEFoLmNyZWF0ZUZyb21PcHRpb25zPWZ1bmN0aW9uKGhhLGFhKXtyZXR1cm4gSGEoQWgsaGEsYWEpfTt2YXIgYmg9Y2xhc3N7Y29uc3RydWN0b3IoaGEsYWEseGEpe3RoaXMuY29uZmlkZW5jZU1hc2tzPWhhLHRoaXMuY2F0ZWdvcnlNYXNrPWFhLHRoaXMucXVhbGl0eVNjb3Jlcz14YX1jbG9zZSgpe3ZhciBoYSxhYTsoaGE9dGhpcy5jb25maWRlbmNlTWFza3MpPT1udWxsfHxoYS5mb3JFYWNoKHhhPT57eGEuY2xvc2UoKX0pLChhYT10aGlzLmNhdGVnb3J5TWFzayk9PW51bGx8fGFhLmNsb3NlKCl9fTtmdW5jdGlvbiBraChoYSl7aGEuY2F0ZWdvcnlNYXNrPXZvaWQgMCxoYS5jb25maWRlbmNlTWFza3M9dm9pZCAwLGhhLnF1YWxpdHlTY29yZXM9dm9pZCAwfWZ1bmN0aW9uIHhoKGhhKXt0cnl7Y29uc3QgYWE9bmV3IGJoKGhhLmNvbmZpZGVuY2VNYXNrcyxoYS5jYXRlZ29yeU1hc2ssaGEucXVhbGl0eVNjb3Jlcyk7aWYoIWhhLmopcmV0dXJuIGFhO2hhLmooYWEpfWZpbmFsbHl7JG8oaGEpfX1iaC5wcm90b3R5cGUuY2xvc2U9YmgucHJvdG90eXBlLmNsb3NlO3ZhciBTaD1jbGFzcyBleHRlbmRzICRhe2NvbnN0cnVjdG9yKGhhLGFhKXtzdXBlcihuZXcgWGEoaGEsYWEpLCJpbWFnZV9pbiIsIm5vcm1fcmVjdCIsITEpLHRoaXMucz1bXSx0aGlzLm91dHB1dENhdGVnb3J5TWFzaz0hMSx0aGlzLm91dHB1dENvbmZpZGVuY2VNYXNrcz0hMCx0aGlzLmg9bmV3IHlvLHRoaXMudj1uZXcgZm8sa24odGhpcy5oLDAsMyx0aGlzLnYpLGtuKGhhPXRoaXMuaCwwLDEsYWE9bmV3IGJpKX1nZXQgYmFzZU9wdGlvbnMoKXtyZXR1cm4gVG4odGhpcy5oLGJpLDEpfXNldCBiYXNlT3B0aW9ucyhoYSl7a24odGhpcy5oLDAsMSxoYSl9byhoYSl7cmV0dXJuIGhhLmRpc3BsYXlOYW1lc0xvY2FsZSE9PXZvaWQgMD9ybih0aGlzLmgsMixrZShoYS5kaXNwbGF5TmFtZXNMb2NhbGUpKToiZGlzcGxheU5hbWVzTG9jYWxlImluIGhhJiZybih0aGlzLmgsMiksIm91dHB1dENhdGVnb3J5TWFzayJpbiBoYSYmKHRoaXMub3V0cHV0Q2F0ZWdvcnlNYXNrPWhhLm91dHB1dENhdGVnb3J5TWFzaz8/ITEpLCJvdXRwdXRDb25maWRlbmNlTWFza3MiaW4gaGEmJih0aGlzLm91dHB1dENvbmZpZGVuY2VNYXNrcz1oYS5vdXRwdXRDb25maWRlbmNlTWFza3M/PyEwKSxzdXBlci5sKGhhKX1LKCl7KGZ1bmN0aW9uKGhhKXt2YXIgeGEsYmE7Y29uc3QgYWE9Ym4oaGEuZmEoKSx2cywxKS5maWx0ZXIoU2E9PihSbihTYSwxKT8/IiIpLmluY2x1ZGVzKCJtZWRpYXBpcGUudGFza3MuVGVuc29yc1RvU2VnbWVudGF0aW9uQ2FsY3VsYXRvciIpKTtpZihoYS5zPVtdLDE8YWEubGVuZ3RoKXRocm93IEVycm9yKCJUaGUgZ3JhcGggaGFzIG1vcmUgdGhhbiBvbmUgbWVkaWFwaXBlLnRhc2tzLlRlbnNvcnNUb1NlZ21lbnRhdGlvbkNhbGN1bGF0b3IuIik7YWEubGVuZ3RoPT09MSYmKCgoYmE9KHhhPVRuKGFhWzBdLGhzLDcpKT09bnVsbD92b2lkIDA6eGEubCgpKT09bnVsbD92b2lkIDA6YmEuZygpKT8/bmV3IE1hcCkuZm9yRWFjaCgoU2EsVGEpPT57aGEuc1tOdW1iZXIoVGEpXT1SbihTYSwxKT8/IiJ9KX0pKHRoaXMpfWdhKGhhLGFhLHhhKXtjb25zdCBiYT10eXBlb2YgYWEhPSJmdW5jdGlvbiI/YWE6e307cmV0dXJuIHRoaXMuaj10eXBlb2YgYWE9PSJmdW5jdGlvbiI/YWE6eGEsa2godGhpcyksemEodGhpcyxoYSxiYSkseGgodGhpcyl9TmEoaGEsYWEseGEsYmEpe2NvbnN0IFNhPXR5cGVvZiB4YSE9ImZ1bmN0aW9uIj94YTp7fTtyZXR1cm4gdGhpcy5qPXR5cGVvZiB4YT09ImZ1bmN0aW9uIj94YTpiYSxraCh0aGlzKSxLYSh0aGlzLGhhLFNhLGFhKSx4aCh0aGlzKX1GYSgpe3JldHVybiB0aGlzLnN9bSgpe3ZhciBoYT1uZXcgTHM7eHMoaGEsImltYWdlX2luIikseHMoaGEsIm5vcm1fcmVjdCIpO2NvbnN0IGFhPW5ldyBocztEbihhYSxfbyx0aGlzLmgpO2NvbnN0IHhhPW5ldyB2czttcyh4YSwibWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5pbWFnZV9zZWdtZW50ZXIuSW1hZ2VTZWdtZW50ZXJHcmFwaCIpLHlzKHhhLCJJTUFHRTppbWFnZV9pbiIpLHlzKHhhLCJOT1JNX1JFQ1Q6bm9ybV9yZWN0IikseGEubyhhYSksa3MoaGEseGEpLEtvKHRoaXMsaGEpLHRoaXMub3V0cHV0Q29uZmlkZW5jZU1hc2tzJiYoU3MoaGEsImNvbmZpZGVuY2VfbWFza3MiKSxfcyh4YSwiQ09ORklERU5DRV9NQVNLUzpjb25maWRlbmNlX21hc2tzIiksWW8odGhpcywiY29uZmlkZW5jZV9tYXNrcyIpLHRoaXMuZy5kYSgiY29uZmlkZW5jZV9tYXNrcyIsKGJhLFNhKT0+e3RoaXMuY29uZmlkZW5jZU1hc2tzPWJhLm1hcChUYT0+WWEodGhpcyxUYSwhMCwhdGhpcy5qKSksem8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiY29uZmlkZW5jZV9tYXNrcyIsYmE9Pnt0aGlzLmNvbmZpZGVuY2VNYXNrcz1bXSx6byh0aGlzLGJhKX0pKSx0aGlzLm91dHB1dENhdGVnb3J5TWFzayYmKFNzKGhhLCJjYXRlZ29yeV9tYXNrIiksX3MoeGEsIkNBVEVHT1JZX01BU0s6Y2F0ZWdvcnlfbWFzayIpLFlvKHRoaXMsImNhdGVnb3J5X21hc2siKSx0aGlzLmcuVygiY2F0ZWdvcnlfbWFzayIsKGJhLFNhKT0+e3RoaXMuY2F0ZWdvcnlNYXNrPVlhKHRoaXMsYmEsITEsIXRoaXMuaiksem8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiY2F0ZWdvcnlfbWFzayIsYmE9Pnt0aGlzLmNhdGVnb3J5TWFzaz12b2lkIDAsem8odGhpcyxiYSl9KSksU3MoaGEsInF1YWxpdHlfc2NvcmVzIiksX3MoeGEsIlFVQUxJVFlfU0NPUkVTOnF1YWxpdHlfc2NvcmVzIiksdGhpcy5nLmF0dGFjaEZsb2F0VmVjdG9yTGlzdGVuZXIoInF1YWxpdHlfc2NvcmVzIiwoYmEsU2EpPT57dGhpcy5xdWFsaXR5U2NvcmVzPWJhLHpvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoInF1YWxpdHlfc2NvcmVzIixiYT0+e3RoaXMuY2F0ZWdvcnlNYXNrPXZvaWQgMCx6byh0aGlzLGJhKX0pLGhhPWhhLmcoKSx0aGlzLnNldEdyYXBoKG5ldyBVaW50OEFycmF5KGhhKSwhMCl9fTtTaC5wcm90b3R5cGUuZ2V0TGFiZWxzPVNoLnByb3RvdHlwZS5GYSxTaC5wcm90b3R5cGUuc2VnbWVudEZvclZpZGVvPVNoLnByb3RvdHlwZS5OYSxTaC5wcm90b3R5cGUuc2VnbWVudD1TaC5wcm90b3R5cGUuZ2EsU2gucHJvdG90eXBlLnNldE9wdGlvbnM9U2gucHJvdG90eXBlLm8sU2guY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFNoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LFNoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFNoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sU2guY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShTaCxoYSxhYSl9O3ZhciBMaD1jbGFzc3tjb25zdHJ1Y3RvcihoYSxhYSx4YSl7dGhpcy5jb25maWRlbmNlTWFza3M9aGEsdGhpcy5jYXRlZ29yeU1hc2s9YWEsdGhpcy5xdWFsaXR5U2NvcmVzPXhhfWNsb3NlKCl7dmFyIGhhLGFhOyhoYT10aGlzLmNvbmZpZGVuY2VNYXNrcyk9PW51bGx8fGhhLmZvckVhY2goeGE9Pnt4YS5jbG9zZSgpfSksKGFhPXRoaXMuY2F0ZWdvcnlNYXNrKT09bnVsbHx8YWEuY2xvc2UoKX19O0xoLnByb3RvdHlwZS5jbG9zZT1MaC5wcm90b3R5cGUuY2xvc2U7dmFyIEZoPWNsYXNzIGV4dGVuZHMgTm57Y29uc3RydWN0b3IoaGEpe3N1cGVyKGhhKX19LFJoPVswLFByLC0yXSxNaD1bMCxrciwtMyxJcl0sUGg9WzAsa3IsLTMsSXIsa3IsLTFdLE9oPVswLFBoXSxDaD1bMCxPaCxSaF0sSWg9WzAsUGgsUmhdLERoPVswLFBoLFByLC0xXSxOaD1bMCxEaCxSaF0sVWg9WzAsa3IsLTMsSXIsUmgsLTFdLEJoPVswLGtyLC0zLElyLFdyXSxHaD1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKGhhKXtzdXBlcihoYSl9fSxqaD1bMCxrciwtMSxJcl0sVmg9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3Rvcigpe3N1cGVyKCl9fTtWaC5BPVsxXTt2YXIgWGg9Y2xhc3MgZXh0ZW5kcyBObntjb25zdHJ1Y3RvcihoYSl7c3VwZXIoaGEpfX0sSGg9WzEsMiwzLDQsNSw2LDcsOCw5LDEwLDE0LDE1XSxXaD1bMCxIaCxWcixQaCxWcixJaCxWcixPaCxWcixDaCxWcixqaCxWcixCaCxWcixNaCxWcixbMCxCcixrciwtMixJcixQcixJciwtMSwyLGtyLFJoXSxWcixEaCxWcixOaCxrcixSaCxCcixWcixVaCxWcixbMCxicixqaF1dLHpoPVswLEJyLFByLC0xLElyXSxLaD1jbGFzcyBleHRlbmRzIE5ue2NvbnN0cnVjdG9yKCl7c3VwZXIoKX19O0toLkE9WzFdLEtoLnByb3RvdHlwZS5nPXFyKFswLGJyLFdoLEJyLHpoXSk7dmFyIFloPWNsYXNzIGV4dGVuZHMgJGF7Y29uc3RydWN0b3IoaGEsYWEpe3N1cGVyKG5ldyBYYShoYSxhYSksImltYWdlX2luIiwibm9ybV9yZWN0X2luIiwhMSksdGhpcy5vdXRwdXRDYXRlZ29yeU1hc2s9ITEsdGhpcy5vdXRwdXRDb25maWRlbmNlTWFza3M9ITAsdGhpcy5oPW5ldyB5byx0aGlzLnM9bmV3IGZvLGtuKHRoaXMuaCwwLDMsdGhpcy5zKSxrbihoYT10aGlzLmgsMCwxLGFhPW5ldyBiaSl9Z2V0IGJhc2VPcHRpb25zKCl7cmV0dXJuIFRuKHRoaXMuaCxiaSwxKX1zZXQgYmFzZU9wdGlvbnMoaGEpe2tuKHRoaXMuaCwwLDEsaGEpfW8oaGEpe3JldHVybiJvdXRwdXRDYXRlZ29yeU1hc2siaW4gaGEmJih0aGlzLm91dHB1dENhdGVnb3J5TWFzaz1oYS5vdXRwdXRDYXRlZ29yeU1hc2s/PyExKSwib3V0cHV0Q29uZmlkZW5jZU1hc2tzImluIGhhJiYodGhpcy5vdXRwdXRDb25maWRlbmNlTWFza3M9aGEub3V0cHV0Q29uZmlkZW5jZU1hc2tzPz8hMCksc3VwZXIubChoYSl9Z2EoaGEsYWEseGEsYmEpe2NvbnN0IFNhPXR5cGVvZiB4YSE9ImZ1bmN0aW9uIj94YTp7fTt0aGlzLmo9dHlwZW9mIHhhPT0iZnVuY3Rpb24iP3hhOmJhLHRoaXMucXVhbGl0eVNjb3Jlcz10aGlzLmNhdGVnb3J5TWFzaz10aGlzLmNvbmZpZGVuY2VNYXNrcz12b2lkIDAseGE9dGhpcy5DKzEsYmE9bmV3IEtoO2NvbnN0IFRhPW5ldyBYaDt2YXIgd2E9bmV3IEZoO2lmKENuKHdhLDEsMjU1KSxrbihUYSwwLDEyLHdhKSxhYS5rZXlwb2ludCYmYWEuc2NyaWJibGUpdGhyb3cgRXJyb3IoIkNhbm5vdCBwcm92aWRlIGJvdGgga2V5cG9pbnQgYW5kIHNjcmliYmxlLiIpO2lmKGFhLmtleXBvaW50KXt2YXIgRWE9bmV3IEdoO09uKEVhLDMsITApLEluKEVhLDEsYWEua2V5cG9pbnQueCksSW4oRWEsMixhYS5rZXlwb2ludC55KSx4bihUYSw1LEhoLEVhKX1lbHNle2lmKCFhYS5zY3JpYmJsZSl0aHJvdyBFcnJvcigiTXVzdCBwcm92aWRlIGVpdGhlciBhIGtleXBvaW50IG9yIGEgc2NyaWJibGUuIik7Zm9yKEVhIG9mKHdhPW5ldyBWaCxhYS5zY3JpYmJsZSkpT24oYWE9bmV3IEdoLDMsITApLEluKGFhLDEsRWEueCksSW4oYWEsMixFYS55KSxMbih3YSwxLEdoLGFhKTt4bihUYSwxNSxIaCx3YSl9TG4oYmEsMSxYaCxUYSksdGhpcy5nLmFkZFByb3RvVG9TdHJlYW0oYmEuZygpLCJkcmlzaHRpLlJlbmRlckRhdGEiLCJyb2lfaW4iLHhhKSx6YSh0aGlzLGhhLFNhKTtlOnt0cnl7Y29uc3QgQWE9bmV3IExoKHRoaXMuY29uZmlkZW5jZU1hc2tzLHRoaXMuY2F0ZWdvcnlNYXNrLHRoaXMucXVhbGl0eVNjb3Jlcyk7aWYoIXRoaXMuail7dmFyIGthPUFhO2JyZWFrIGV9dGhpcy5qKEFhKX1maW5hbGx5eyRvKHRoaXMpfWthPXZvaWQgMH1yZXR1cm4ga2F9bSgpe3ZhciBoYT1uZXcgTHM7eHMoaGEsImltYWdlX2luIikseHMoaGEsInJvaV9pbiIpLHhzKGhhLCJub3JtX3JlY3RfaW4iKTtjb25zdCBhYT1uZXcgaHM7RG4oYWEsX28sdGhpcy5oKTtjb25zdCB4YT1uZXcgdnM7bXMoeGEsIm1lZGlhcGlwZS50YXNrcy52aXNpb24uaW50ZXJhY3RpdmVfc2VnbWVudGVyLkludGVyYWN0aXZlU2VnbWVudGVyR3JhcGgiKSx5cyh4YSwiSU1BR0U6aW1hZ2VfaW4iKSx5cyh4YSwiUk9JOnJvaV9pbiIpLHlzKHhhLCJOT1JNX1JFQ1Q6bm9ybV9yZWN0X2luIikseGEubyhhYSksa3MoaGEseGEpLEtvKHRoaXMsaGEpLHRoaXMub3V0cHV0Q29uZmlkZW5jZU1hc2tzJiYoU3MoaGEsImNvbmZpZGVuY2VfbWFza3MiKSxfcyh4YSwiQ09ORklERU5DRV9NQVNLUzpjb25maWRlbmNlX21hc2tzIiksWW8odGhpcywiY29uZmlkZW5jZV9tYXNrcyIpLHRoaXMuZy5kYSgiY29uZmlkZW5jZV9tYXNrcyIsKGJhLFNhKT0+e3RoaXMuY29uZmlkZW5jZU1hc2tzPWJhLm1hcChUYT0+WWEodGhpcyxUYSwhMCwhdGhpcy5qKSksem8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiY29uZmlkZW5jZV9tYXNrcyIsYmE9Pnt0aGlzLmNvbmZpZGVuY2VNYXNrcz1bXSx6byh0aGlzLGJhKX0pKSx0aGlzLm91dHB1dENhdGVnb3J5TWFzayYmKFNzKGhhLCJjYXRlZ29yeV9tYXNrIiksX3MoeGEsIkNBVEVHT1JZX01BU0s6Y2F0ZWdvcnlfbWFzayIpLFlvKHRoaXMsImNhdGVnb3J5X21hc2siKSx0aGlzLmcuVygiY2F0ZWdvcnlfbWFzayIsKGJhLFNhKT0+e3RoaXMuY2F0ZWdvcnlNYXNrPVlhKHRoaXMsYmEsITEsIXRoaXMuaiksem8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigiY2F0ZWdvcnlfbWFzayIsYmE9Pnt0aGlzLmNhdGVnb3J5TWFzaz12b2lkIDAsem8odGhpcyxiYSl9KSksU3MoaGEsInF1YWxpdHlfc2NvcmVzIiksX3MoeGEsIlFVQUxJVFlfU0NPUkVTOnF1YWxpdHlfc2NvcmVzIiksdGhpcy5nLmF0dGFjaEZsb2F0VmVjdG9yTGlzdGVuZXIoInF1YWxpdHlfc2NvcmVzIiwoYmEsU2EpPT57dGhpcy5xdWFsaXR5U2NvcmVzPWJhLHpvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoInF1YWxpdHlfc2NvcmVzIixiYT0+e3RoaXMuY2F0ZWdvcnlNYXNrPXZvaWQgMCx6byh0aGlzLGJhKX0pLGhhPWhhLmcoKSx0aGlzLnNldEdyYXBoKG5ldyBVaW50OEFycmF5KGhhKSwhMCl9fTtZaC5wcm90b3R5cGUuc2VnbWVudD1ZaC5wcm90b3R5cGUuZ2EsWWgucHJvdG90eXBlLnNldE9wdGlvbnM9WWgucHJvdG90eXBlLm8sWWguY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFloLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LFloLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFloLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sWWguY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShZaCxoYSxhYSl9O3ZhciAkaD1jbGFzcyBleHRlbmRzICRhe2NvbnN0cnVjdG9yKGhhLGFhKXtzdXBlcihuZXcgWGEoaGEsYWEpLCJpbnB1dF9mcmFtZV9ncHUiLCJub3JtX3JlY3QiLCExKSx0aGlzLmo9e2RldGVjdGlvbnM6W119LGtuKGhhPXRoaXMuaD1uZXcgdm8sMCwxLGFhPW5ldyBiaSl9Z2V0IGJhc2VPcHRpb25zKCl7cmV0dXJuIFRuKHRoaXMuaCxiaSwxKX1zZXQgYmFzZU9wdGlvbnMoaGEpe2tuKHRoaXMuaCwwLDEsaGEpfW8oaGEpe3JldHVybiBoYS5kaXNwbGF5TmFtZXNMb2NhbGUhPT12b2lkIDA/cm4odGhpcy5oLDIsa2UoaGEuZGlzcGxheU5hbWVzTG9jYWxlKSk6ImRpc3BsYXlOYW1lc0xvY2FsZSJpbiBoYSYmcm4odGhpcy5oLDIpLGhhLm1heFJlc3VsdHMhPT12b2lkIDA/Q24odGhpcy5oLDMsaGEubWF4UmVzdWx0cyk6Im1heFJlc3VsdHMiaW4gaGEmJnJuKHRoaXMuaCwzKSxoYS5zY29yZVRocmVzaG9sZCE9PXZvaWQgMD9Jbih0aGlzLmgsNCxoYS5zY29yZVRocmVzaG9sZCk6InNjb3JlVGhyZXNob2xkImluIGhhJiZybih0aGlzLmgsNCksaGEuY2F0ZWdvcnlBbGxvd2xpc3QhPT12b2lkIDA/cG4odGhpcy5oLDUsaGEuY2F0ZWdvcnlBbGxvd2xpc3QpOiJjYXRlZ29yeUFsbG93bGlzdCJpbiBoYSYmcm4odGhpcy5oLDUpLGhhLmNhdGVnb3J5RGVueWxpc3QhPT12b2lkIDA/cG4odGhpcy5oLDYsaGEuY2F0ZWdvcnlEZW55bGlzdCk6ImNhdGVnb3J5RGVueWxpc3QiaW4gaGEmJnJuKHRoaXMuaCw2KSx0aGlzLmwoaGEpfUYoaGEsYWEpe3JldHVybiB0aGlzLmo9e2RldGVjdGlvbnM6W119LHphKHRoaXMsaGEsYWEpLHRoaXMuan1HKGhhLGFhLHhhKXtyZXR1cm4gdGhpcy5qPXtkZXRlY3Rpb25zOltdfSxLYSh0aGlzLGhhLHhhLGFhKSx0aGlzLmp9bSgpe3ZhciBoYT1uZXcgTHM7eHMoaGEsImlucHV0X2ZyYW1lX2dwdSIpLHhzKGhhLCJub3JtX3JlY3QiKSxTcyhoYSwiZGV0ZWN0aW9ucyIpO2NvbnN0IGFhPW5ldyBocztEbihhYSxFbyx0aGlzLmgpO2NvbnN0IHhhPW5ldyB2czttcyh4YSwibWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5PYmplY3REZXRlY3RvckdyYXBoIikseXMoeGEsIklNQUdFOmlucHV0X2ZyYW1lX2dwdSIpLHlzKHhhLCJOT1JNX1JFQ1Q6bm9ybV9yZWN0IiksX3MoeGEsIkRFVEVDVElPTlM6ZGV0ZWN0aW9ucyIpLHhhLm8oYWEpLGtzKGhhLHhhKSx0aGlzLmcuYXR0YWNoUHJvdG9WZWN0b3JMaXN0ZW5lcigiZGV0ZWN0aW9ucyIsKGJhLFNhKT0+e2Zvcihjb25zdCBUYSBvZiBiYSliYT1LcyhUYSksdGhpcy5qLmRldGVjdGlvbnMucHVzaChrbyhiYSkpO3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoImRldGVjdGlvbnMiLGJhPT57em8odGhpcyxiYSl9KSxoYT1oYS5nKCksdGhpcy5zZXRHcmFwaChuZXcgVWludDhBcnJheShoYSksITApfX07JGgucHJvdG90eXBlLmRldGVjdEZvclZpZGVvPSRoLnByb3RvdHlwZS5HLCRoLnByb3RvdHlwZS5kZXRlY3Q9JGgucHJvdG90eXBlLkYsJGgucHJvdG90eXBlLnNldE9wdGlvbnM9JGgucHJvdG90eXBlLm8sJGguY3JlYXRlRnJvbU1vZGVsUGF0aD1hc3luYyBmdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKCRoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LCRoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKCRoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sJGguY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYSgkaCxoYSxhYSl9O3ZhciBxaD1jbGFzc3tjb25zdHJ1Y3RvcihoYSxhYSx4YSl7dGhpcy5sYW5kbWFya3M9aGEsdGhpcy53b3JsZExhbmRtYXJrcz1hYSx0aGlzLnNlZ21lbnRhdGlvbk1hc2tzPXhhfWNsb3NlKCl7dmFyIGhhOyhoYT10aGlzLnNlZ21lbnRhdGlvbk1hc2tzKT09bnVsbHx8aGEuZm9yRWFjaChhYT0+e2FhLmNsb3NlKCl9KX19O2Z1bmN0aW9uIEpoKGhhKXtoYS5sYW5kbWFya3M9W10saGEud29ybGRMYW5kbWFya3M9W10saGEuc2VnbWVudGF0aW9uTWFza3M9dm9pZCAwfWZ1bmN0aW9uIFpoKGhhKXt0cnl7Y29uc3QgYWE9bmV3IHFoKGhhLmxhbmRtYXJrcyxoYS53b3JsZExhbmRtYXJrcyxoYS5zZWdtZW50YXRpb25NYXNrcyk7aWYoIWhhLnMpcmV0dXJuIGFhO2hhLnMoYWEpfWZpbmFsbHl7JG8oaGEpfX1xaC5wcm90b3R5cGUuY2xvc2U9cWgucHJvdG90eXBlLmNsb3NlO3ZhciBRaD1jbGFzcyBleHRlbmRzICRhe2NvbnN0cnVjdG9yKGhhLGFhKXtzdXBlcihuZXcgWGEoaGEsYWEpLCJpbWFnZV9pbiIsIm5vcm1fcmVjdCIsITEpLHRoaXMubGFuZG1hcmtzPVtdLHRoaXMud29ybGRMYW5kbWFya3M9W10sdGhpcy5vdXRwdXRTZWdtZW50YXRpb25NYXNrcz0hMSxrbihoYT10aGlzLmg9bmV3IHdvLDAsMSxhYT1uZXcgYmkpLHRoaXMudj1uZXcgaW8sa24odGhpcy5oLDAsMyx0aGlzLnYpLHRoaXMuaj1uZXcgcm8sa24odGhpcy5oLDAsMix0aGlzLmopLENuKHRoaXMuaiw0LDEpLEluKHRoaXMuaiwyLC41KSxJbih0aGlzLnYsMiwuNSksSW4odGhpcy5oLDQsLjUpfWdldCBiYXNlT3B0aW9ucygpe3JldHVybiBUbih0aGlzLmgsYmksMSl9c2V0IGJhc2VPcHRpb25zKGhhKXtrbih0aGlzLmgsMCwxLGhhKX1vKGhhKXtyZXR1cm4ibnVtUG9zZXMiaW4gaGEmJkNuKHRoaXMuaiw0LGhhLm51bVBvc2VzPz8xKSwibWluUG9zZURldGVjdGlvbkNvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMuaiwyLGhhLm1pblBvc2VEZXRlY3Rpb25Db25maWRlbmNlPz8uNSksIm1pblRyYWNraW5nQ29uZmlkZW5jZSJpbiBoYSYmSW4odGhpcy5oLDQsaGEubWluVHJhY2tpbmdDb25maWRlbmNlPz8uNSksIm1pblBvc2VQcmVzZW5jZUNvbmZpZGVuY2UiaW4gaGEmJkluKHRoaXMudiwyLGhhLm1pblBvc2VQcmVzZW5jZUNvbmZpZGVuY2U/Py41KSwib3V0cHV0U2VnbWVudGF0aW9uTWFza3MiaW4gaGEmJih0aGlzLm91dHB1dFNlZ21lbnRhdGlvbk1hc2tzPWhhLm91dHB1dFNlZ21lbnRhdGlvbk1hc2tzPz8hMSksdGhpcy5sKGhhKX1GKGhhLGFhLHhhKXtjb25zdCBiYT10eXBlb2YgYWEhPSJmdW5jdGlvbiI/YWE6e307cmV0dXJuIHRoaXMucz10eXBlb2YgYWE9PSJmdW5jdGlvbiI/YWE6eGEsSmgodGhpcyksemEodGhpcyxoYSxiYSksWmgodGhpcyl9RyhoYSxhYSx4YSxiYSl7Y29uc3QgU2E9dHlwZW9mIHhhIT0iZnVuY3Rpb24iP3hhOnt9O3JldHVybiB0aGlzLnM9dHlwZW9mIHhhPT0iZnVuY3Rpb24iP3hhOmJhLEpoKHRoaXMpLEthKHRoaXMsaGEsU2EsYWEpLFpoKHRoaXMpfW0oKXt2YXIgaGE9bmV3IExzO3hzKGhhLCJpbWFnZV9pbiIpLHhzKGhhLCJub3JtX3JlY3QiKSxTcyhoYSwibm9ybWFsaXplZF9sYW5kbWFya3MiKSxTcyhoYSwid29ybGRfbGFuZG1hcmtzIiksU3MoaGEsInNlZ21lbnRhdGlvbl9tYXNrcyIpO2NvbnN0IGFhPW5ldyBocztEbihhYSxUbyx0aGlzLmgpO2NvbnN0IHhhPW5ldyB2czttcyh4YSwibWVkaWFwaXBlLnRhc2tzLnZpc2lvbi5wb3NlX2xhbmRtYXJrZXIuUG9zZUxhbmRtYXJrZXJHcmFwaCIpLHlzKHhhLCJJTUFHRTppbWFnZV9pbiIpLHlzKHhhLCJOT1JNX1JFQ1Q6bm9ybV9yZWN0IiksX3MoeGEsIk5PUk1fTEFORE1BUktTOm5vcm1hbGl6ZWRfbGFuZG1hcmtzIiksX3MoeGEsIldPUkxEX0xBTkRNQVJLUzp3b3JsZF9sYW5kbWFya3MiKSx4YS5vKGFhKSxrcyhoYSx4YSksS28odGhpcyxoYSksdGhpcy5nLmF0dGFjaFByb3RvVmVjdG9yTGlzdGVuZXIoIm5vcm1hbGl6ZWRfbGFuZG1hcmtzIiwoYmEsU2EpPT57dGhpcy5sYW5kbWFya3M9W107Zm9yKGNvbnN0IFRhIG9mIGJhKWJhPWVpKFRhKSx0aGlzLmxhbmRtYXJrcy5wdXNoKHhvKGJhKSk7em8odGhpcyxTYSl9KSx0aGlzLmcuYXR0YWNoRW1wdHlQYWNrZXRMaXN0ZW5lcigibm9ybWFsaXplZF9sYW5kbWFya3MiLGJhPT57dGhpcy5sYW5kbWFya3M9W10sem8odGhpcyxiYSl9KSx0aGlzLmcuYXR0YWNoUHJvdG9WZWN0b3JMaXN0ZW5lcigid29ybGRfbGFuZG1hcmtzIiwoYmEsU2EpPT57dGhpcy53b3JsZExhbmRtYXJrcz1bXTtmb3IoY29uc3QgVGEgb2YgYmEpYmE9SnMoVGEpLHRoaXMud29ybGRMYW5kbWFya3MucHVzaChTbyhiYSkpO3pvKHRoaXMsU2EpfSksdGhpcy5nLmF0dGFjaEVtcHR5UGFja2V0TGlzdGVuZXIoIndvcmxkX2xhbmRtYXJrcyIsYmE9Pnt0aGlzLndvcmxkTGFuZG1hcmtzPVtdLHpvKHRoaXMsYmEpfSksdGhpcy5vdXRwdXRTZWdtZW50YXRpb25NYXNrcyYmKF9zKHhhLCJTRUdNRU5UQVRJT05fTUFTSzpzZWdtZW50YXRpb25fbWFza3MiKSxZbyh0aGlzLCJzZWdtZW50YXRpb25fbWFza3MiKSx0aGlzLmcuZGEoInNlZ21lbnRhdGlvbl9tYXNrcyIsKGJhLFNhKT0+e3RoaXMuc2VnbWVudGF0aW9uTWFza3M9YmEubWFwKFRhPT5ZYSh0aGlzLFRhLCEwLCF0aGlzLnMpKSx6byh0aGlzLFNhKX0pLHRoaXMuZy5hdHRhY2hFbXB0eVBhY2tldExpc3RlbmVyKCJzZWdtZW50YXRpb25fbWFza3MiLGJhPT57dGhpcy5zZWdtZW50YXRpb25NYXNrcz1bXSx6byh0aGlzLGJhKX0pKSxoYT1oYS5nKCksdGhpcy5zZXRHcmFwaChuZXcgVWludDhBcnJheShoYSksITApfX07UWgucHJvdG90eXBlLmRldGVjdEZvclZpZGVvPVFoLnByb3RvdHlwZS5HLFFoLnByb3RvdHlwZS5kZXRlY3Q9UWgucHJvdG90eXBlLkYsUWgucHJvdG90eXBlLnNldE9wdGlvbnM9UWgucHJvdG90eXBlLm8sUWguY3JlYXRlRnJvbU1vZGVsUGF0aD1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFFoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6YWF9fSl9LFFoLmNyZWF0ZUZyb21Nb2RlbEJ1ZmZlcj1mdW5jdGlvbihoYSxhYSl7cmV0dXJuIEhhKFFoLGhhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldEJ1ZmZlcjphYX19KX0sUWguY3JlYXRlRnJvbU9wdGlvbnM9ZnVuY3Rpb24oaGEsYWEpe3JldHVybiBIYShRaCxoYSxhYSl9LFFoLlBPU0VfQ09OTkVDVElPTlM9eWg7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRVBTSUxPTl9GTE9BVDMyJDE9MWUtNyxFUFNJTE9OX0ZMT0FUMTYkMT0xZS00O2NsYXNzIERhdGFTdG9yYWdle2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLmJhY2tlbmQ9YWEsdGhpcy5kYXRhTW92ZXI9eGEsdGhpcy5kYXRhPW5ldyBXZWFrTWFwLHRoaXMuZGF0YUlkc0NvdW50PTB9Z2V0KGFhKXtyZXR1cm4gdGhpcy5kYXRhLmhhcyhhYSl8fHRoaXMuZGF0YU1vdmVyLm1vdmVEYXRhKHRoaXMuYmFja2VuZCxhYSksdGhpcy5kYXRhLmdldChhYSl9c2V0KGFhLHhhKXt0aGlzLmRhdGFJZHNDb3VudCsrLHRoaXMuZGF0YS5zZXQoYWEseGEpfWhhcyhhYSl7cmV0dXJuIHRoaXMuZGF0YS5oYXMoYWEpfWRlbGV0ZShhYSl7cmV0dXJuIHRoaXMuZGF0YUlkc0NvdW50LS0sdGhpcy5kYXRhLmRlbGV0ZShhYSl9bnVtRGF0YUlkcygpe3JldHVybiB0aGlzLmRhdGFJZHNDb3VudH19Y2xhc3MgS2VybmVsQmFja2VuZHtyZWZDb3VudChhYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkKCJyZWZDb3VudCIpfWluY1JlZihhYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkKCJpbmNSZWYiKX10aW1lckF2YWlsYWJsZSgpe3JldHVybiEwfXRpbWUoYWEpe3JldHVybiBub3RZZXRJbXBsZW1lbnRlZCgidGltZSIpfXJlYWQoYWEpe3JldHVybiBub3RZZXRJbXBsZW1lbnRlZCgicmVhZCIpfXJlYWRTeW5jKGFhKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQoInJlYWRTeW5jIil9cmVhZFRvR1BVKGFhLHhhKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQoInJlYWRUb0dQVSIpfW51bURhdGFJZHMoKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQoIm51bURhdGFJZHMiKX1kaXNwb3NlRGF0YShhYSx4YSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkKCJkaXNwb3NlRGF0YSIpfXdyaXRlKGFhLHhhLGJhKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQoIndyaXRlIil9bW92ZShhYSx4YSxiYSxTYSxUYSl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkKCJtb3ZlIil9Y3JlYXRlVGVuc29yRnJvbUdQVURhdGEoYWEseGEsYmEpe3JldHVybiBub3RZZXRJbXBsZW1lbnRlZCgiY3JlYXRlVGVuc29yRnJvbUdQVURhdGEiKX1tZW1vcnkoKXtyZXR1cm4gbm90WWV0SW1wbGVtZW50ZWQoIm1lbW9yeSIpfWZsb2F0UHJlY2lzaW9uKCl7cmV0dXJuIG5vdFlldEltcGxlbWVudGVkKCJmbG9hdFByZWNpc2lvbiIpfWVwc2lsb24oKXtyZXR1cm4gdGhpcy5mbG9hdFByZWNpc2lvbigpPT09MzI/RVBTSUxPTl9GTE9BVDMyJDE6RVBTSUxPTl9GTE9BVDE2JDF9ZGlzcG9zZSgpe3JldHVybiBub3RZZXRJbXBsZW1lbnRlZCgiZGlzcG9zZSIpfX1mdW5jdGlvbiBub3RZZXRJbXBsZW1lbnRlZChoYSl7dGhyb3cgbmV3IEVycm9yKGAnJHtoYX0nIG5vdCB5ZXQgaW1wbGVtZW50ZWQgb3Igbm90IGZvdW5kIGluIHRoZSByZWdpc3RyeS4gVGhpcyBrZXJuZWwgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgYnkgdGhlIHRmanMgYmFja2VuZCB5b3UgaGF2ZSBjaG9zZW5gKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjbGFtcChoYSxhYSx4YSl7cmV0dXJuIE1hdGgubWF4KGhhLE1hdGgubWluKGFhLHhhKSl9ZnVuY3Rpb24gbmVhcmVzdExhcmdlckV2ZW4oaGEpe3JldHVybiBoYSUyPT09MD9oYTpoYSsxfWZ1bmN0aW9uIHN3YXAoaGEsYWEseGEpe2NvbnN0IGJhPWhhW2FhXTtoYVthYV09aGFbeGFdLGhhW3hhXT1iYX1mdW5jdGlvbiBzdW0kMihoYSl7bGV0IGFhPTA7Zm9yKGxldCB4YT0wO3hhPGhhLmxlbmd0aDt4YSsrKWFhKz1oYVt4YV07cmV0dXJuIGFhfWZ1bmN0aW9uIGFzc2VydChoYSxhYSl7aWYoIWhhKXRocm93IG5ldyBFcnJvcih0eXBlb2YgYWE9PSJzdHJpbmciP2FhOmFhKCkpfWZ1bmN0aW9uIGFzc2VydFNoYXBlc01hdGNoKGhhLGFhLHhhPSIiKXthc3NlcnQoYXJyYXlzRXF1YWwoaGEsYWEpLCgpPT54YStgIFNoYXBlcyAke2hhfSBhbmQgJHthYX0gbXVzdCBtYXRjaGApfWZ1bmN0aW9uIHNpemVGcm9tU2hhcGUoaGEpe2lmKGhhLmxlbmd0aD09PTApcmV0dXJuIDE7bGV0IGFhPWhhWzBdO2ZvcihsZXQgeGE9MTt4YTxoYS5sZW5ndGg7eGErKylhYSo9aGFbeGFdO3JldHVybiBhYX1mdW5jdGlvbiBhcnJheXNFcXVhbChoYSxhYSl7aWYoaGE9PT1hYSlyZXR1cm4hMDtpZihoYT09bnVsbHx8YWE9PW51bGx8fGhhLmxlbmd0aCE9PWFhLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoO3hhKyspaWYoaGFbeGFdIT09YWFbeGFdKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIGlzSW50KGhhKXtyZXR1cm4gaGElMT09PTB9ZnVuY3Rpb24gc2l6ZVRvU3F1YXJpc2hTaGFwZShoYSl7Y29uc3QgYWE9TWF0aC5jZWlsKE1hdGguc3FydChoYSkpO3JldHVyblthYSxNYXRoLmNlaWwoaGEvYWEpXX1mdW5jdGlvbiByaWdodFBhZChoYSxhYSl7cmV0dXJuIGFhPD1oYS5sZW5ndGg/aGE6aGErIiAiLnJlcGVhdChhYS1oYS5sZW5ndGgpfWZ1bmN0aW9uIHJlcGVhdGVkVHJ5KGhhLGFhPVNhPT4wLHhhLGJhKXtyZXR1cm4gbmV3IFByb21pc2UoKFNhLFRhKT0+e2xldCB3YT0wO2NvbnN0IEVhPSgpPT57aWYoaGEoKSl7U2EoKTtyZXR1cm59d2ErKztjb25zdCBrYT1hYSh3YSk7aWYoeGEhPW51bGwmJndhPj14YSl7VGEoKTtyZXR1cm59YmEhPW51bGw/YmEoRWEsa2EpOnNldFRpbWVvdXQoRWEsa2EpfTtFYSgpfSl9ZnVuY3Rpb24gaW5mZXJGcm9tSW1wbGljaXRTaGFwZShoYSxhYSl7bGV0IHhhPTEsYmE9LTE7Zm9yKGxldCBUYT0wO1RhPGhhLmxlbmd0aDsrK1RhKWlmKGhhW1RhXT49MCl4YSo9aGFbVGFdO2Vsc2UgaWYoaGFbVGFdPT09LTEpe2lmKGJhIT09LTEpdGhyb3cgRXJyb3IoYFNoYXBlcyBjYW4gb25seSBoYXZlIDEgaW1wbGljaXQgc2l6ZS4gRm91bmQgLTEgYXQgZGltICR7YmF9IGFuZCBkaW0gJHtUYX1gKTtiYT1UYX1lbHNlIGlmKGhhW1RhXTwwKXRocm93IEVycm9yKGBTaGFwZXMgY2FuIG5vdCBiZSA8IDAuIEZvdW5kICR7aGFbVGFdfSBhdCBkaW0gJHtUYX1gKTtpZihiYT09PS0xKXtpZihhYT4wJiZhYSE9PXhhKXRocm93IEVycm9yKGBTaXplKCR7YWF9KSBtdXN0IG1hdGNoIHRoZSBwcm9kdWN0IG9mIHNoYXBlICR7aGF9YCk7cmV0dXJuIGhhfWlmKHhhPT09MCl0aHJvdyBFcnJvcihgQ2Fubm90IGluZmVyIHRoZSBtaXNzaW5nIHNpemUgaW4gWyR7aGF9XSB3aGVuIHRoZXJlIGFyZSAwIGVsZW1lbnRzYCk7aWYoYWEleGEhPT0wKXRocm93IEVycm9yKGBUaGUgaW1wbGljaXQgc2hhcGUgY2FuJ3QgYmUgYSBmcmFjdGlvbmFsIG51bWJlci4gR290ICR7YWF9IC8gJHt4YX1gKTtjb25zdCBTYT1oYS5zbGljZSgpO3JldHVybiBTYVtiYV09YWEveGEsU2F9ZnVuY3Rpb24gcGFyc2VBeGlzUGFyYW0oaGEsYWEpe2NvbnN0IHhhPWFhLmxlbmd0aDtyZXR1cm4gaGE9aGE9PW51bGw/YWEubWFwKChiYSxTYSk9PlNhKTpbXS5jb25jYXQoaGEpLGFzc2VydChoYS5ldmVyeShiYT0+YmE+PS14YSYmYmE8eGEpLCgpPT5gQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW4gcmFuZ2UgWy0ke3hhfSwgJHt4YX0pIGJ1dCBnb3QgYXhpcyAke2hhfWApLGFzc2VydChoYS5ldmVyeShiYT0+aXNJbnQoYmEpKSwoKT0+YEFsbCB2YWx1ZXMgaW4gYXhpcyBwYXJhbSBtdXN0IGJlIGludGVnZXJzIGJ1dCBnb3QgYXhpcyAke2hhfWApLGhhLm1hcChiYT0+YmE8MD94YStiYTpiYSl9ZnVuY3Rpb24gc3F1ZWV6ZVNoYXBlKGhhLGFhKXtjb25zdCB4YT1bXSxiYT1bXTtmb3IobGV0IFNhPTA7U2E8aGEubGVuZ3RoOysrU2EpaGFbU2FdIT09MSYmKHhhLnB1c2goaGFbU2FdKSxiYS5wdXNoKFNhKSk7cmV0dXJue25ld1NoYXBlOnhhLGtlcHREaW1zOmJhfX1mdW5jdGlvbiBnZXRUeXBlZEFycmF5RnJvbURUeXBlKGhhLGFhKXtyZXR1cm4gZ2V0QXJyYXlGcm9tRFR5cGUoaGEsYWEpfWZ1bmN0aW9uIGdldEFycmF5RnJvbURUeXBlKGhhLGFhKXtsZXQgeGE9bnVsbDtpZihoYT09bnVsbHx8aGE9PT0iZmxvYXQzMiIpeGE9bmV3IEZsb2F0MzJBcnJheShhYSk7ZWxzZSBpZihoYT09PSJpbnQzMiIpeGE9bmV3IEludDMyQXJyYXkoYWEpO2Vsc2UgaWYoaGE9PT0iYm9vbCIpeGE9bmV3IFVpbnQ4QXJyYXkoYWEpO2Vsc2UgaWYoaGE9PT0ic3RyaW5nIil4YT1uZXcgQXJyYXkoYWEpO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGEgdHlwZSAke2hhfWApO3JldHVybiB4YX1mdW5jdGlvbiBjaGVja0NvbnZlcnNpb25Gb3JFcnJvcnMoaGEsYWEpe2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7eGErKyl7Y29uc3QgYmE9aGFbeGFdO2lmKGlzTmFOKGJhKXx8IWlzRmluaXRlKGJhKSl0aHJvdyBFcnJvcihgQSB0ZW5zb3Igb2YgdHlwZSAke2FhfSBiZWluZyB1cGxvYWRlZCBjb250YWlucyAke2JhfS5gKX19ZnVuY3Rpb24gaXNWYWxpZER0eXBlKGhhKXtyZXR1cm4gaGE9PT0iYm9vbCJ8fGhhPT09ImNvbXBsZXg2NCJ8fGhhPT09ImZsb2F0MzIifHxoYT09PSJpbnQzMiJ8fGhhPT09InN0cmluZyJ9ZnVuY3Rpb24gaGFzRW5jb2RpbmdMb3NzKGhhLGFhKXtyZXR1cm4hKGFhPT09ImNvbXBsZXg2NCJ8fGFhPT09ImZsb2F0MzIiJiZoYSE9PSJjb21wbGV4NjQifHxhYT09PSJpbnQzMiImJmhhIT09ImZsb2F0MzIiJiZoYSE9PSJjb21wbGV4NjQifHxhYT09PSJib29sIiYmaGE9PT0iYm9vbCIpfWZ1bmN0aW9uIGJ5dGVzUGVyRWxlbWVudChoYSl7aWYoaGE9PT0iZmxvYXQzMiJ8fGhhPT09ImludDMyIilyZXR1cm4gNDtpZihoYT09PSJjb21wbGV4NjQiKXJldHVybiA4O2lmKGhhPT09ImJvb2wiKXJldHVybiAxO3Rocm93IG5ldyBFcnJvcihgVW5rbm93biBkdHlwZSAke2hhfWApfWZ1bmN0aW9uIGJ5dGVzRnJvbVN0cmluZ0FycmF5KGhhKXtpZihoYT09bnVsbClyZXR1cm4gMDtsZXQgYWE9MDtyZXR1cm4gaGEuZm9yRWFjaCh4YT0+YWErPXhhLmxlbmd0aCksYWF9ZnVuY3Rpb24gaXNTdHJpbmcoaGEpe3JldHVybiB0eXBlb2YgaGE9PSJzdHJpbmcifHxoYSBpbnN0YW5jZW9mIFN0cmluZ31mdW5jdGlvbiBpc0Jvb2xlYW4oaGEpe3JldHVybiB0eXBlb2YgaGE9PSJib29sZWFuIn1mdW5jdGlvbiBpc051bWJlcihoYSl7cmV0dXJuIHR5cGVvZiBoYT09Im51bWJlciJ9ZnVuY3Rpb24gaW5mZXJEdHlwZShoYSl7cmV0dXJuIEFycmF5LmlzQXJyYXkoaGEpP2luZmVyRHR5cGUoaGFbMF0pOmhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5PyJmbG9hdDMyIjpoYSBpbnN0YW5jZW9mIEludDMyQXJyYXl8fGhhIGluc3RhbmNlb2YgVWludDhBcnJheXx8aGEgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheT8iaW50MzIiOmlzTnVtYmVyKGhhKT8iZmxvYXQzMiI6aXNTdHJpbmcoaGEpPyJzdHJpbmciOmlzQm9vbGVhbihoYSk/ImJvb2wiOiJmbG9hdDMyIn1mdW5jdGlvbiBpc0Z1bmN0aW9uKGhhKXtyZXR1cm4hIShoYSYmaGEuY29uc3RydWN0b3ImJmhhLmNhbGwmJmhhLmFwcGx5KX1mdW5jdGlvbiBuZWFyZXN0RGl2aXNvcihoYSxhYSl7Zm9yKGxldCB4YT1hYTt4YTxoYTsrK3hhKWlmKGhhJXhhPT09MClyZXR1cm4geGE7cmV0dXJuIGhhfWZ1bmN0aW9uIGNvbXB1dGVTdHJpZGVzKGhhKXtjb25zdCBhYT1oYS5sZW5ndGg7aWYoYWE8MilyZXR1cm5bXTtjb25zdCB4YT1uZXcgQXJyYXkoYWEtMSk7eGFbYWEtMl09aGFbYWEtMV07Zm9yKGxldCBiYT1hYS0zO2JhPj0wOy0tYmEpeGFbYmFdPXhhW2JhKzFdKmhhW2JhKzFdO3JldHVybiB4YX1mdW5jdGlvbiBjcmVhdGVOZXN0ZWRBcnJheShoYSxhYSx4YSxiYT0hMSl7Y29uc3QgU2E9bmV3IEFycmF5O2lmKGFhLmxlbmd0aD09PTEpe2NvbnN0IFRhPWFhWzBdKihiYT8yOjEpO2ZvcihsZXQgd2E9MDt3YTxUYTt3YSsrKVNhW3dhXT14YVtoYSt3YV19ZWxzZXtjb25zdCBUYT1hYVswXSx3YT1hYS5zbGljZSgxKSxFYT13YS5yZWR1Y2UoKGthLEFhKT0+a2EqQWEpKihiYT8yOjEpO2ZvcihsZXQga2E9MDtrYTxUYTtrYSsrKVNhW2thXT1jcmVhdGVOZXN0ZWRBcnJheShoYStrYSpFYSx3YSx4YSxiYSl9cmV0dXJuIFNhfWZ1bmN0aW9uIHRvTmVzdGVkQXJyYXkoaGEsYWEseGE9ITEpe2lmKGhhLmxlbmd0aD09PTApcmV0dXJuIGFhWzBdO2NvbnN0IGJhPWhhLnJlZHVjZSgoU2EsVGEpPT5TYSpUYSkqKHhhPzI6MSk7aWYoYmE9PT0wKXJldHVybltdO2lmKGJhIT09YWEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgWyR7aGF9XSBkb2VzIG5vdCBtYXRjaCB0aGUgaW5wdXQgc2l6ZSAke2FhLmxlbmd0aH0ke3hhPyIgZm9yIGEgY29tcGxleCB0ZW5zb3IiOiIifS5gKTtyZXR1cm4gY3JlYXRlTmVzdGVkQXJyYXkoMCxoYSxhYSx4YSl9ZnVuY3Rpb24gbWFrZU9uZXNUeXBlZEFycmF5KGhhLGFhKXtjb25zdCB4YT1tYWtlWmVyb3NUeXBlZEFycmF5KGhhLGFhKTtmb3IobGV0IGJhPTA7YmE8eGEubGVuZ3RoO2JhKyspeGFbYmFdPTE7cmV0dXJuIHhhfWZ1bmN0aW9uIG1ha2VaZXJvc1R5cGVkQXJyYXkoaGEsYWEpe2lmKGFhPT1udWxsfHxhYT09PSJmbG9hdDMyInx8YWE9PT0iY29tcGxleDY0IilyZXR1cm4gbmV3IEZsb2F0MzJBcnJheShoYSk7aWYoYWE9PT0iaW50MzIiKXJldHVybiBuZXcgSW50MzJBcnJheShoYSk7aWYoYWE9PT0iYm9vbCIpcmV0dXJuIG5ldyBVaW50OEFycmF5KGhhKTt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YSB0eXBlICR7YWF9YCl9ZnVuY3Rpb24gYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyhoYSl7aGEuZm9yRWFjaChhYT0+e2Fzc2VydChOdW1iZXIuaXNJbnRlZ2VyKGFhKSYmYWE+PTAsKCk9PmBUZW5zb3IgbXVzdCBoYXZlIGEgc2hhcGUgY29tcHJpc2VkIG9mIHBvc2l0aXZlIGludGVnZXJzIGJ1dCBnb3Qgc2hhcGUgWyR7aGF9XS5gKX0pfWZ1bmN0aW9uIGxvY1RvSW5kZXgoaGEsYWEseGEpe2lmKGFhPT09MClyZXR1cm4gMDtpZihhYT09PTEpcmV0dXJuIGhhWzBdO2xldCBiYT1oYVtoYS5sZW5ndGgtMV07Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aC0xOysrU2EpYmErPXhhW1NhXSpoYVtTYV07cmV0dXJuIGJhfWZ1bmN0aW9uIGluZGV4VG9Mb2MoaGEsYWEseGEpe2lmKGFhPT09MClyZXR1cm5bXTtpZihhYT09PTEpcmV0dXJuW2hhXTtjb25zdCBiYT1uZXcgQXJyYXkoYWEpO2ZvcihsZXQgU2E9MDtTYTxiYS5sZW5ndGgtMTsrK1NhKWJhW1NhXT1NYXRoLmZsb29yKGhhL3hhW1NhXSksaGEtPWJhW1NhXSp4YVtTYV07cmV0dXJuIGJhW2JhLmxlbmd0aC0xXT1oYSxiYX1mdW5jdGlvbiBpc1Byb21pc2UoaGEpe3JldHVybiBoYSYmaGEudGhlbiYmdHlwZW9mIGhhLnRoZW49PSJmdW5jdGlvbiJ9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgVEVOU09SRkxPV0pTX0ZMQUdTX1BSRUZJWD0idGZqc2ZsYWdzIjtjbGFzcyBFbnZpcm9ubWVudHtjb25zdHJ1Y3RvcihhYSl7dGhpcy5nbG9iYWw9YWEsdGhpcy5mbGFncz17fSx0aGlzLmZsYWdSZWdpc3RyeT17fSx0aGlzLnVybEZsYWdzPXt9LHRoaXMuZ2V0UXVlcnlQYXJhbXM9Z2V0UXVlcnlQYXJhbXMsdGhpcy5wb3B1bGF0ZVVSTEZsYWdzKCl9c2V0UGxhdGZvcm0oYWEseGEpe3RoaXMucGxhdGZvcm0hPW51bGwmJihlbnYoKS5nZXRCb29sKCJJU19URVNUIil8fGVudigpLmdldEJvb2woIlBST0QiKXx8Y29uc29sZS53YXJuKGBQbGF0Zm9ybSAke3RoaXMucGxhdGZvcm1OYW1lfSBoYXMgYWxyZWFkeSBiZWVuIHNldC4gT3ZlcndyaXRpbmcgdGhlIHBsYXRmb3JtIHdpdGggJHthYX0uYCkpLHRoaXMucGxhdGZvcm1OYW1lPWFhLHRoaXMucGxhdGZvcm09eGF9cmVnaXN0ZXJGbGFnKGFhLHhhLGJhKXtpZih0aGlzLmZsYWdSZWdpc3RyeVthYV09e2V2YWx1YXRpb25Gbjp4YSxzZXRIb29rOmJhfSx0aGlzLnVybEZsYWdzW2FhXSE9bnVsbCl7Y29uc3QgU2E9dGhpcy51cmxGbGFnc1thYV07ZW52KCkuZ2V0Qm9vbCgiSVNfVEVTVCIpfHxlbnYoKS5nZXRCb29sKCJQUk9EIil8fGNvbnNvbGUud2FybihgU2V0dGluZyBmZWF0dXJlIG92ZXJyaWRlIGZyb20gVVJMICR7YWF9OiAke1NhfS5gKSx0aGlzLnNldChhYSxTYSl9fWFzeW5jIGdldEFzeW5jKGFhKXtyZXR1cm4gYWEgaW4gdGhpcy5mbGFncz90aGlzLmZsYWdzW2FhXToodGhpcy5mbGFnc1thYV09YXdhaXQgdGhpcy5ldmFsdWF0ZUZsYWcoYWEpLHRoaXMuZmxhZ3NbYWFdKX1nZXQoYWEpe2lmKGFhIGluIHRoaXMuZmxhZ3MpcmV0dXJuIHRoaXMuZmxhZ3NbYWFdO2NvbnN0IHhhPXRoaXMuZXZhbHVhdGVGbGFnKGFhKTtpZihpc1Byb21pc2UoeGEpKXRocm93IG5ldyBFcnJvcihgRmxhZyAke2FhfSBjYW5ub3QgYmUgc3luY2hyb25vdXNseSBldmFsdWF0ZWQuIFBsZWFzZSB1c2UgZ2V0QXN5bmMoKSBpbnN0ZWFkLmApO3JldHVybiB0aGlzLmZsYWdzW2FhXT14YSx0aGlzLmZsYWdzW2FhXX1nZXROdW1iZXIoYWEpe3JldHVybiB0aGlzLmdldChhYSl9Z2V0Qm9vbChhYSl7cmV0dXJuIHRoaXMuZ2V0KGFhKX1nZXRTdHJpbmcoYWEpe3JldHVybiB0aGlzLmdldChhYSl9Z2V0RmxhZ3MoKXtyZXR1cm4gdGhpcy5mbGFnc31nZXQgZmVhdHVyZXMoKXtyZXR1cm4gdGhpcy5mbGFnc31zZXQoYWEseGEpe2lmKHRoaXMuZmxhZ1JlZ2lzdHJ5W2FhXT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBzZXQgZmxhZyAke2FhfSBhcyBpdCBoYXMgbm90IGJlZW4gcmVnaXN0ZXJlZC5gKTt0aGlzLmZsYWdzW2FhXT14YSx0aGlzLmZsYWdSZWdpc3RyeVthYV0uc2V0SG9vayE9bnVsbCYmdGhpcy5mbGFnUmVnaXN0cnlbYWFdLnNldEhvb2soeGEpfWV2YWx1YXRlRmxhZyhhYSl7aWYodGhpcy5mbGFnUmVnaXN0cnlbYWFdPT1udWxsKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGV2YWx1YXRlIGZsYWcgJyR7YWF9Jzogbm8gZXZhbHVhdGlvbiBmdW5jdGlvbiBmb3VuZC5gKTtyZXR1cm4gdGhpcy5mbGFnUmVnaXN0cnlbYWFdLmV2YWx1YXRpb25GbigpfXNldEZsYWdzKGFhKXt0aGlzLmZsYWdzPU9iamVjdC5hc3NpZ24oe30sYWEpfXJlc2V0KCl7dGhpcy5mbGFncz17fSx0aGlzLnVybEZsYWdzPXt9LHRoaXMucG9wdWxhdGVVUkxGbGFncygpfXBvcHVsYXRlVVJMRmxhZ3MoKXtpZih0eXBlb2YgdGhpcy5nbG9iYWw+InUifHx0eXBlb2YgdGhpcy5nbG9iYWwubG9jYXRpb24+InUifHx0eXBlb2YgdGhpcy5nbG9iYWwubG9jYXRpb24uc2VhcmNoPiJ1IilyZXR1cm47Y29uc3QgYWE9dGhpcy5nZXRRdWVyeVBhcmFtcyh0aGlzLmdsb2JhbC5sb2NhdGlvbi5zZWFyY2gpO1RFTlNPUkZMT1dKU19GTEFHU19QUkVGSVggaW4gYWEmJmFhW1RFTlNPUkZMT1dKU19GTEFHU19QUkVGSVhdLnNwbGl0KCIsIikuZm9yRWFjaChiYT0+e2NvbnN0W1NhLFRhXT1iYS5zcGxpdCgiOiIpO3RoaXMudXJsRmxhZ3NbU2FdPXBhcnNlVmFsdWUoU2EsVGEpfSl9fWZ1bmN0aW9uIGdldFF1ZXJ5UGFyYW1zKGhhKXtjb25zdCBhYT17fTtyZXR1cm4gaGEucmVwbGFjZSgvWz8mXShbXj0/Jl0rKSg/Oj0oW14mXSopKT8vZywoeGEsLi4uYmEpPT4oZGVjb2RlUGFyYW0oYWEsYmFbMF0sYmFbMV0pLGJhLmpvaW4oIj0iKSkpLGFhfWZ1bmN0aW9uIGRlY29kZVBhcmFtKGhhLGFhLHhhKXtoYVtkZWNvZGVVUklDb21wb25lbnQoYWEpXT1kZWNvZGVVUklDb21wb25lbnQoeGF8fCIiKX1mdW5jdGlvbiBwYXJzZVZhbHVlKGhhLGFhKXtjb25zdCB4YT1hYS50b0xvd2VyQ2FzZSgpO3JldHVybiB4YT09PSJ0cnVlInx8eGE9PT0iZmFsc2UiP3hhPT09InRydWUiOmAkeyt4YX1gPT09eGE/K3hhOmFhfWZ1bmN0aW9uIGVudigpe3JldHVybiBFTlYkMn1sZXQgRU5WJDI9bnVsbDtmdW5jdGlvbiBzZXRFbnZpcm9ubWVudEdsb2JhbChoYSl7RU5WJDI9aGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovbGV0IGdsb2JhbE5hbWVTcGFjZTtmdW5jdGlvbiBnZXRHbG9iYWxOYW1lc3BhY2UoKXtpZihnbG9iYWxOYW1lU3BhY2U9PW51bGwpe2xldCBoYTtpZih0eXBlb2Ygd2luZG93PCJ1IiloYT13aW5kb3c7ZWxzZSBpZih0eXBlb2YgZ2xvYmFsPCJ1IiloYT1nbG9iYWw7ZWxzZSBpZih0eXBlb2YgcHJvY2VzczwidSIpaGE9cHJvY2VzcztlbHNlIGlmKHR5cGVvZiBzZWxmPCJ1IiloYT1zZWxmO2Vsc2UgdGhyb3cgbmV3IEVycm9yKCJDb3VsZCBub3QgZmluZCBhIGdsb2JhbCBvYmplY3QiKTtnbG9iYWxOYW1lU3BhY2U9aGF9cmV0dXJuIGdsb2JhbE5hbWVTcGFjZX1mdW5jdGlvbiBnZXRHbG9iYWxNYXAoKXtjb25zdCBoYT1nZXRHbG9iYWxOYW1lc3BhY2UoKTtyZXR1cm4gaGEuX3RmR2xvYmFscz09bnVsbCYmKGhhLl90Zkdsb2JhbHM9bmV3IE1hcCksaGEuX3RmR2xvYmFsc31mdW5jdGlvbiBnZXRHbG9iYWwoaGEsYWEpe2NvbnN0IHhhPWdldEdsb2JhbE1hcCgpO2lmKHhhLmhhcyhoYSkpcmV0dXJuIHhhLmdldChoYSk7e2NvbnN0IGJhPWFhKCk7cmV0dXJuIHhhLnNldChoYSxiYSkseGEuZ2V0KGhhKX19Y29uc3QgQWJzPSJBYnMiLEFjb3M9IkFjb3MiLEFjb3NoPSJBY29zaCIsQWRkPSJBZGQiLEFkZE49IkFkZE4iLEFsbD0iQWxsIixBbnk9IkFueSIsQXJnTWF4PSJBcmdNYXgiLEFyZ01pbj0iQXJnTWluIixBc2luPSJBc2luIixBc2luaD0iQXNpbmgiLEF0YW49IkF0YW4iLEF0YW5oPSJBdGFuaCIsQXRhbjI9IkF0YW4yIixBdmdQb29sPSJBdmdQb29sIixBdmdQb29sR3JhZD0iQXZnUG9vbEdyYWQiLEF2Z1Bvb2wzRD0iQXZnUG9vbDNEIixBdmdQb29sM0RHcmFkPSJBdmdQb29sM0RHcmFkIixCYXRjaE1hdE11bD0iQmF0Y2hNYXRNdWwiLEJhdGNoVG9TcGFjZU5EPSJCYXRjaFRvU3BhY2VORCIsQmluY291bnQ9IkJpbmNvdW50IixCaXR3aXNlQW5kPSJCaXR3aXNlQW5kIixCcm9hZGNhc3RBcmdzPSJCcm9hZGNhc3RBcmdzIixDYXN0PSJDYXN0IixDZWlsPSJDZWlsIixDbGlwQnlWYWx1ZT0iQ2xpcEJ5VmFsdWUiLENvbXBsZXg9IkNvbXBsZXgiLENvbXBsZXhBYnM9IkNvbXBsZXhBYnMiLENvbmNhdD0iQ29uY2F0IixDb252MkQ9IkNvbnYyRCIsQ29udjJEQmFja3Byb3BGaWx0ZXI9IkNvbnYyREJhY2twcm9wRmlsdGVyIixDb252MkRCYWNrcHJvcElucHV0PSJDb252MkRCYWNrcHJvcElucHV0IixDb252M0Q9IkNvbnYzRCIsQ29udjNEQmFja3Byb3BGaWx0ZXJWMj0iQ29udjNEQmFja3Byb3BGaWx0ZXJWMiIsQ29udjNEQmFja3Byb3BJbnB1dFYyPSJDb252M0RCYWNrcHJvcElucHV0VjIiLENvcz0iQ29zIixDb3NoPSJDb3NoIixDdW1wcm9kPSJDdW1wcm9kIixDdW1zdW09IkN1bXN1bSIsQ3JvcEFuZFJlc2l6ZT0iQ3JvcEFuZFJlc2l6ZSIsRGVuc2VCaW5jb3VudD0iRGVuc2VCaW5jb3VudCIsRGVwdGhUb1NwYWNlPSJEZXB0aFRvU3BhY2UiLERlcHRod2lzZUNvbnYyZE5hdGl2ZT0iRGVwdGh3aXNlQ29udjJkTmF0aXZlIixEZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlcj0iRGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BGaWx0ZXIiLERlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQ9IkRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQiLERpYWc9IkRpYWciLERpbGF0aW9uMkQ9IkRpbGF0aW9uMkQiLFJlYWxEaXY9IlJlYWxEaXYiLEVpbnN1bT0iRWluc3VtIixFbHU9IkVsdSIsRWx1R3JhZD0iRWx1R3JhZCIsRXJmPSJFcmYiLEVxdWFsPSJFcXVhbCIsRXhwPSJFeHAiLEV4cGFuZERpbXM9IkV4cGFuZERpbXMiLEV4cG0xPSJFeHBtMSIsRkZUPSJGRlQiLEZpbGw9IkZpbGwiLEZsaXBMZWZ0UmlnaHQ9IkZsaXBMZWZ0UmlnaHQiLEZsb29yPSJGbG9vciIsRmxvb3JEaXY9IkZsb29yRGl2IixGdXNlZEJhdGNoTm9ybT0iRnVzZWRCYXRjaE5vcm0iLEdhdGhlclYyPSJHYXRoZXJWMiIsR2F0aGVyTmQ9IkdhdGhlck5kIixHcmVhdGVyPSJHcmVhdGVyIixHcmVhdGVyRXF1YWw9IkdyZWF0ZXJFcXVhbCIsSWRlbnRpdHk9IklkZW50aXR5IixJRkZUPSJJRkZUIixJbWFnPSJJbWFnIixJc0Zpbml0ZT0iSXNGaW5pdGUiLElzSW5mPSJJc0luZiIsSXNOYW49IklzTmFuIixMZWFreVJlbHU9IkxlYWt5UmVsdSIsTGVzcz0iTGVzcyIsTGVzc0VxdWFsPSJMZXNzRXF1YWwiLExpblNwYWNlPSJMaW5TcGFjZSIsTG9nPSJMb2ciLExvZzFwPSJMb2cxcCIsTG9naWNhbEFuZD0iTG9naWNhbEFuZCIsTG9naWNhbE5vdD0iTG9naWNhbE5vdCIsTG9naWNhbE9yPSJMb2dpY2FsT3IiLExSTj0iTFJOIixMUk5HcmFkPSJMUk5HcmFkIixNYXg9Ik1heCIsTWF4aW11bT0iTWF4aW11bSIsTWF4UG9vbD0iTWF4UG9vbCIsTWF4UG9vbEdyYWQ9Ik1heFBvb2xHcmFkIixNYXhQb29sM0Q9Ik1heFBvb2wzRCIsTWF4UG9vbDNER3JhZD0iTWF4UG9vbDNER3JhZCIsTWF4UG9vbFdpdGhBcmdtYXg9Ik1heFBvb2xXaXRoQXJnbWF4IixNZWFuPSJNZWFuIixNaW49Ik1pbiIsTWluaW11bT0iTWluaW11bSIsTWlycm9yUGFkPSJNaXJyb3JQYWQiLE1vZD0iTW9kIixNdWx0aW5vbWlhbD0iTXVsdGlub21pYWwiLE11bHRpcGx5PSJNdWx0aXBseSIsTmVnPSJOZWciLE5vdEVxdWFsPSJOb3RFcXVhbCIsTm9uTWF4U3VwcHJlc3Npb25WMz0iTm9uTWF4U3VwcHJlc3Npb25WMyIsTm9uTWF4U3VwcHJlc3Npb25WND0iTm9uTWF4U3VwcHJlc3Npb25WNCIsTm9uTWF4U3VwcHJlc3Npb25WNT0iTm9uTWF4U3VwcHJlc3Npb25WNSIsT25lc0xpa2U9Ik9uZXNMaWtlIixPbmVIb3Q9Ik9uZUhvdCIsUGFjaz0iUGFjayIsUGFkVjI9IlBhZFYyIixQb3c9IlBvdyIsUHJlbHU9IlByZWx1IixQcm9kPSJQcm9kIixSYWdnZWRHYXRoZXI9IlJhZ2dlZEdhdGhlciIsUmFnZ2VkUmFuZ2U9IlJhZ2dlZFJhbmdlIixSYWdnZWRUZW5zb3JUb1RlbnNvcj0iUmFnZ2VkVGVuc29yVG9UZW5zb3IiLFJhbmdlPSJSYW5nZSIsUmVhbD0iUmVhbCIsUmVjaXByb2NhbD0iUmVjaXByb2NhbCIsUmVsdT0iUmVsdSIsUmVzaGFwZT0iUmVzaGFwZSIsUmVzaXplTmVhcmVzdE5laWdoYm9yPSJSZXNpemVOZWFyZXN0TmVpZ2hib3IiLFJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWQ9IlJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWQiLFJlc2l6ZUJpbGluZWFyPSJSZXNpemVCaWxpbmVhciIsUmVzaXplQmlsaW5lYXJHcmFkPSJSZXNpemVCaWxpbmVhckdyYWQiLFJlbHU2PSJSZWx1NiIsUmV2ZXJzZT0iUmV2ZXJzZSIsUm91bmQ9IlJvdW5kIixSc3FydD0iUnNxcnQiLFNjYXR0ZXJOZD0iU2NhdHRlck5kIixUZW5zb3JTY2F0dGVyVXBkYXRlPSJUZW5zb3JTY2F0dGVyVXBkYXRlIixTZWFyY2hTb3J0ZWQ9IlNlYXJjaFNvcnRlZCIsU2VsZWN0PSJTZWxlY3QiLFNlbHU9IlNlbHUiLFNsaWNlPSJTbGljZSIsU2luPSJTaW4iLFNpbmg9IlNpbmgiLFNpZ249IlNpZ24iLFNpZ21vaWQ9IlNpZ21vaWQiLFNvZnRwbHVzPSJTb2Z0cGx1cyIsU3FydD0iU3FydCIsU3VtPSJTdW0iLFNwYWNlVG9CYXRjaE5EPSJTcGFjZVRvQmF0Y2hORCIsU3BsaXRWPSJTcGxpdFYiLFNvZnRtYXg9IlNvZnRtYXgiLFNwYXJzZUZpbGxFbXB0eVJvd3M9IlNwYXJzZUZpbGxFbXB0eVJvd3MiLFNwYXJzZVJlc2hhcGU9IlNwYXJzZVJlc2hhcGUiLFNwYXJzZVNlZ21lbnRNZWFuPSJTcGFyc2VTZWdtZW50TWVhbiIsU3BhcnNlU2VnbWVudFN1bT0iU3BhcnNlU2VnbWVudFN1bSIsU3BhcnNlVG9EZW5zZT0iU3BhcnNlVG9EZW5zZSIsU3F1YXJlZERpZmZlcmVuY2U9IlNxdWFyZWREaWZmZXJlbmNlIixTcXVhcmU9IlNxdWFyZSIsU3RhdGljUmVnZXhSZXBsYWNlPSJTdGF0aWNSZWdleFJlcGxhY2UiLFN0cmlkZWRTbGljZT0iU3RyaWRlZFNsaWNlIixTdHJpbmdOR3JhbXM9IlN0cmluZ05HcmFtcyIsU3RyaW5nU3BsaXQ9IlN0cmluZ1NwbGl0IixTdHJpbmdUb0hhc2hCdWNrZXRGYXN0PSJTdHJpbmdUb0hhc2hCdWNrZXRGYXN0IixTdWI9IlN1YiIsVGFuPSJUYW4iLFRhbmg9IlRhbmgiLFRpbGU9IlRpbGUiLFRvcEs9IlRvcEsiLFRyYW5zZm9ybT0iVHJhbnNmb3JtIixUcmFuc3Bvc2U9IlRyYW5zcG9zZSIsVW5pcXVlPSJVbmlxdWUiLFVucGFjaz0iVW5wYWNrIixVbnNvcnRlZFNlZ21lbnRTdW09IlVuc29ydGVkU2VnbWVudFN1bSIsWmVyb3NMaWtlPSJaZXJvc0xpa2UiLFN0ZXA9IlN0ZXAiLEZyb21QaXhlbHM9IkZyb21QaXhlbHMiLFJvdGF0ZVdpdGhPZmZzZXQ9IlJvdGF0ZVdpdGhPZmZzZXQiLF9GdXNlZE1hdE11bD0iX0Z1c2VkTWF0TXVsIixGdXNlZENvbnYyRD0iRnVzZWRDb252MkQiLEZ1c2VkRGVwdGh3aXNlQ29udjJEPSJGdXNlZERlcHRod2lzZUNvbnYyRCI7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gd2FybiguLi5oYSl7ZW52KCkuZ2V0Qm9vbCgiSVNfVEVTVCIpfHxlbnYoKS5nZXRCb29sKCJQUk9EIil8fGNvbnNvbGUud2FybiguLi5oYSl9ZnVuY3Rpb24gbG9nJDEoLi4uaGEpe2VudigpLmdldEJvb2woIklTX1RFU1QiKXx8ZW52KCkuZ2V0Qm9vbCgiUFJPRCIpfHxjb25zb2xlLmxvZyguLi5oYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qga2VybmVsUmVnaXN0cnk9Z2V0R2xvYmFsKCJrZXJuZWxSZWdpc3RyeSIsKCk9Pm5ldyBNYXApLGdyYWRSZWdpc3RyeT1nZXRHbG9iYWwoImdyYWRSZWdpc3RyeSIsKCk9Pm5ldyBNYXApO2Z1bmN0aW9uIGdldEtlcm5lbChoYSxhYSl7Y29uc3QgeGE9bWFrZUtleShoYSxhYSk7cmV0dXJuIGtlcm5lbFJlZ2lzdHJ5LmdldCh4YSl9ZnVuY3Rpb24gZ2V0R3JhZGllbnQoaGEpe3JldHVybiBncmFkUmVnaXN0cnkuZ2V0KGhhKX1mdW5jdGlvbiBnZXRLZXJuZWxzRm9yQmFja2VuZChoYSl7Y29uc3QgYWE9a2VybmVsUmVnaXN0cnkuZW50cmllcygpLHhhPVtdO2Zvcig7Oyl7Y29uc3R7ZG9uZTpiYSx2YWx1ZTpTYX09YWEubmV4dCgpO2lmKGJhKWJyZWFrO2NvbnN0W1RhLHdhXT1TYSxbRWFdPVRhLnNwbGl0KCJfIik7RWE9PT1oYSYmeGEucHVzaCh3YSl9cmV0dXJuIHhhfWZ1bmN0aW9uIHJlZ2lzdGVyS2VybmVsKGhhKXtjb25zdHtrZXJuZWxOYW1lOmFhLGJhY2tlbmROYW1lOnhhfT1oYSxiYT1tYWtlS2V5KGFhLHhhKTtrZXJuZWxSZWdpc3RyeS5oYXMoYmEpJiZ3YXJuKGBUaGUga2VybmVsICcke2FhfScgZm9yIGJhY2tlbmQgJyR7eGF9JyBpcyBhbHJlYWR5IHJlZ2lzdGVyZWRgKSxrZXJuZWxSZWdpc3RyeS5zZXQoYmEsaGEpfWZ1bmN0aW9uIG1ha2VLZXkoaGEsYWEpe3JldHVybmAke2FhfV8ke2hhfWB9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaXNUeXBlZEFycmF5QnJvd3NlcihoYSl7cmV0dXJuIGhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5fHxoYSBpbnN0YW5jZW9mIEludDMyQXJyYXl8fGhhIGluc3RhbmNlb2YgVWludDhBcnJheXx8aGEgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMb25nPWxvbmckMXx8TG9uZ0V4cG9ydHM7ZnVuY3Rpb24gaGV4VG9Mb25nKGhhKXtyZXR1cm4gTG9uZy5mcm9tU3RyaW5nKGhhLCEwLDE2KX1jb25zdCBrMD1oZXhUb0xvbmcoImMzYTVjODVjOTdjYjMxMjciKSxrMT1oZXhUb0xvbmcoImI0OTJiNjZmYmU5OGYyNzMiKSxrMj1oZXhUb0xvbmcoIjlhZTE2YTNiMmY5MDQwNGYiKTtmdW5jdGlvbiBzaGlmdE1peChoYSl7cmV0dXJuIGhhLnhvcihoYS5zaHJ1KDQ3KSl9ZnVuY3Rpb24gZmV0Y2gkMShoYSxhYSx4YSl7Y29uc3QgYmE9aGEuc2xpY2UoYWEsYWEreGEpO3JldHVybiBMb25nLmZyb21CeXRlcyhBcnJheS5mcm9tKGJhKSwhMCwhMCl9ZnVuY3Rpb24gZmV0Y2g2NChoYSxhYSl7cmV0dXJuIGZldGNoJDEoaGEsYWEsOCl9ZnVuY3Rpb24gZmV0Y2gzMihoYSxhYSl7cmV0dXJuIGZldGNoJDEoaGEsYWEsNCl9ZnVuY3Rpb24gcm90YXRlNjQoaGEsYWEpe3JldHVybiBhYT09PTA/aGE6aGEuc2hydShhYSkub3IoaGEuc2hsKDY0LWFhKSl9ZnVuY3Rpb24gaGFzaExlbjE2KGhhLGFhLHhhPWhleFRvTG9uZygiOWRkZmVhMDhlYjM4MmQ2OSIpKXtsZXQgYmE9aGEueG9yKGFhKS5tdWwoeGEpO2JhPWJhLnhvcihiYS5zaHJ1KDQ3KSk7bGV0IFNhPWFhLnhvcihiYSkubXVsKHhhKTtyZXR1cm4gU2E9U2EueG9yKFNhLnNocnUoNDcpKSxTYT1TYS5tdWwoeGEpLFNhfWZ1bmN0aW9uIHdlYWtIYXNoTGVuMzJXaXRoU2VlZHMoaGEsYWEseGEsYmEsU2EsVGEpe1NhPVNhLmFkZChoYSksVGE9cm90YXRlNjQoVGEuYWRkKFNhKS5hZGQoYmEpLDIxKTtjb25zdCB3YT1TYTtyZXR1cm4gU2E9U2EuYWRkKGFhKSxTYT1TYS5hZGQoeGEpLFRhPVRhLmFkZChyb3RhdGU2NChTYSw0NCkpLFtTYS5hZGQoYmEpLFRhLmFkZCh3YSldfWZ1bmN0aW9uIHdlYWtIYXNoTGVuMzJXaXRoU2VlZHNTdHIoaGEsYWEseGEsYmEpe3JldHVybiB3ZWFrSGFzaExlbjMyV2l0aFNlZWRzKGZldGNoNjQoaGEsYWEpLGZldGNoNjQoaGEsYWErOCksZmV0Y2g2NChoYSxhYSsxNiksZmV0Y2g2NChoYSxhYSsyNCkseGEsYmEpfWZ1bmN0aW9uIGhhc2hMZW4wdG8xNihoYSxhYT1oYS5sZW5ndGgpe2lmKGFhPj04KXtjb25zdCB4YT1rMi5hZGQoYWEqMiksYmE9ZmV0Y2g2NChoYSwwKS5hZGQoazIpLFNhPWZldGNoNjQoaGEsYWEtOCksVGE9cm90YXRlNjQoU2EsMzcpLm11bCh4YSkuYWRkKGJhKSx3YT1yb3RhdGU2NChiYSwyNSkuYWRkKFNhKS5tdWwoeGEpO3JldHVybiBoYXNoTGVuMTYoVGEsd2EseGEpfWlmKGFhPj00KXtjb25zdCB4YT1rMi5hZGQoYWEqMiksYmE9ZmV0Y2gzMihoYSwwKTtyZXR1cm4gaGFzaExlbjE2KGJhLnNobCgzKS5hZGQoYWEpLGZldGNoMzIoaGEsYWEtNCkseGEpfWlmKGFhPjApe2NvbnN0IHhhPWhhWzBdLGJhPWhhW2FhPj4xXSxTYT1oYVthYS0xXSxUYT14YSsoYmE8PDgpLHdhPWFhKyhTYTw8Mik7cmV0dXJuIHNoaWZ0TWl4KGsyLm11bChUYSkueG9yKGswLm11bCh3YSkpKS5tdWwoazIpfXJldHVybiBrMn1mdW5jdGlvbiBoYXNoTGVuMTd0bzMyKGhhLGFhPWhhLmxlbmd0aCl7Y29uc3QgeGE9azIuYWRkKGFhKjIpLGJhPWZldGNoNjQoaGEsMCkubXVsKGsxKSxTYT1mZXRjaDY0KGhhLDgpLFRhPWZldGNoNjQoaGEsYWEtOCkubXVsKHhhKSx3YT1mZXRjaDY0KGhhLGFhLTE2KS5tdWwoazIpO3JldHVybiBoYXNoTGVuMTYocm90YXRlNjQoYmEuYWRkKFNhKSw0MykuYWRkKHJvdGF0ZTY0KFRhLDMwKSkuYWRkKHdhKSxiYS5hZGQocm90YXRlNjQoU2EuYWRkKGsyKSwxOCkpLmFkZChUYSkseGEpfWZ1bmN0aW9uIGhhc2hMZW4zM3RvNjQoaGEsYWE9aGEubGVuZ3RoKXtjb25zdCB4YT1rMi5hZGQoYWEqMiksYmE9ZmV0Y2g2NChoYSwwKS5tdWwoazIpLFNhPWZldGNoNjQoaGEsOCksVGE9ZmV0Y2g2NChoYSxhYS04KS5tdWwoeGEpLHdhPWZldGNoNjQoaGEsYWEtMTYpLm11bChrMiksRWE9cm90YXRlNjQoYmEuYWRkKFNhKSw0MykuYWRkKHJvdGF0ZTY0KFRhLDMwKSkuYWRkKHdhKSxrYT1oYXNoTGVuMTYoRWEsYmEuYWRkKHJvdGF0ZTY0KFNhLmFkZChrMiksMTgpKS5hZGQoVGEpLHhhKSxBYT1mZXRjaDY0KGhhLDE2KS5tdWwoeGEpLEZhPWZldGNoNjQoaGEsMjQpLExhPUVhLmFkZChmZXRjaDY0KGhhLGFhLTMyKSkubXVsKHhhKSxlbD1rYS5hZGQoZmV0Y2g2NChoYSxhYS0yNCkpLm11bCh4YSk7cmV0dXJuIGhhc2hMZW4xNihyb3RhdGU2NChBYS5hZGQoRmEpLDQzKS5hZGQocm90YXRlNjQoTGEsMzApKS5hZGQoZWwpLEFhLmFkZChyb3RhdGU2NChGYS5hZGQoYmEpLDE4KSkuYWRkKExhKSx4YSl9ZnVuY3Rpb24gZmluZ2VyUHJpbnQ2NChoYSxhYT1oYS5sZW5ndGgpe2NvbnN0IHhhPUxvbmcuZnJvbU51bWJlcig4MSwhMCk7aWYoYWE8PTMyKXJldHVybiBhYTw9MTY/aGFzaExlbjB0bzE2KGhhLGFhKTpoYXNoTGVuMTd0bzMyKGhhLGFhKTtpZihhYTw9NjQpcmV0dXJuIGhhc2hMZW4zM3RvNjQoaGEsYWEpO2xldCBiYT14YSxTYT14YS5tdWwoazEpLmFkZCgxMTMpLFRhPXNoaWZ0TWl4KFNhLm11bChrMikuYWRkKDExMykpLm11bChrMiksd2E9W0xvbmcuVVpFUk8sTG9uZy5VWkVST10sRWE9W0xvbmcuVVpFUk8sTG9uZy5VWkVST107YmE9YmEubXVsKGsyKS5hZGQoZmV0Y2g2NChoYSwwKSk7bGV0IGthPTA7Y29uc3QgQWE9KGFhLTE+PjYpKjY0LEZhPUFhKyhhYS0xJjYzKS02MztkbyBiYT1yb3RhdGU2NChiYS5hZGQoU2EpLmFkZCh3YVswXSkuYWRkKGZldGNoNjQoaGEsa2ErOCkpLDM3KS5tdWwoazEpLFNhPXJvdGF0ZTY0KFNhLmFkZCh3YVsxXSkuYWRkKGZldGNoNjQoaGEsa2ErNDgpKSw0MikubXVsKGsxKSxiYT1iYS54b3IoRWFbMV0pLFNhPVNhLmFkZCh3YVswXSkuYWRkKGZldGNoNjQoaGEsa2ErNDApKSxUYT1yb3RhdGU2NChUYS5hZGQoRWFbMF0pLDMzKS5tdWwoazEpLHdhPXdlYWtIYXNoTGVuMzJXaXRoU2VlZHNTdHIoaGEsa2Esd2FbMV0ubXVsKGsxKSxiYS5hZGQoRWFbMF0pKSxFYT13ZWFrSGFzaExlbjMyV2l0aFNlZWRzU3RyKGhhLGthKzMyLFRhLmFkZChFYVsxXSksU2EuYWRkKGZldGNoNjQoaGEsa2ErMTYpKSksW1RhLGJhXT1bYmEsVGFdLGthKz02NDt3aGlsZShrYSE9PUFhKTtjb25zdCBMYT1rMS5hZGQoVGEuYW5kKDI1NSkuc2hsKDEpKTtyZXR1cm4ga2E9RmEsRWFbMF09RWFbMF0uYWRkKGFhLTEmNjMpLHdhWzBdPXdhWzBdLmFkZChFYVswXSksRWFbMF09RWFbMF0uYWRkKHdhWzBdKSxiYT1yb3RhdGU2NChiYS5hZGQoU2EpLmFkZCh3YVswXSkuYWRkKGZldGNoNjQoaGEsa2ErOCkpLDM3KS5tdWwoTGEpLFNhPXJvdGF0ZTY0KFNhLmFkZCh3YVsxXSkuYWRkKGZldGNoNjQoaGEsa2ErNDgpKSw0MikubXVsKExhKSxiYT1iYS54b3IoRWFbMV0ubXVsKDkpKSxTYT1TYS5hZGQod2FbMF0ubXVsKDkpLmFkZChmZXRjaDY0KGhhLGthKzQwKSkpLFRhPXJvdGF0ZTY0KFRhLmFkZChFYVswXSksMzMpLm11bChMYSksd2E9d2Vha0hhc2hMZW4zMldpdGhTZWVkc1N0cihoYSxrYSx3YVsxXS5tdWwoTGEpLGJhLmFkZChFYVswXSkpLEVhPXdlYWtIYXNoTGVuMzJXaXRoU2VlZHNTdHIoaGEsa2ErMzIsVGEuYWRkKEVhWzFdKSxTYS5hZGQoZmV0Y2g2NChoYSxrYSsxNikpKSxbVGEsYmFdPVtiYSxUYV0saGFzaExlbjE2KGhhc2hMZW4xNih3YVswXSxFYVswXSxMYSkuYWRkKHNoaWZ0TWl4KFNhKS5tdWwoazApKS5hZGQoVGEpLGhhc2hMZW4xNih3YVsxXSxFYVsxXSxMYSkuYWRkKGJhKSxMYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY3JlYXRlU2NhbGFyVmFsdWUoaGEsYWEpe3JldHVybiBhYT09PSJzdHJpbmciP2VuY29kZVN0cmluZyhoYSk6dG9UeXBlZEFycmF5KFtoYV0sYWEpfWZ1bmN0aW9uIG5vQ29udmVyc2lvbk5lZWRlZChoYSxhYSl7cmV0dXJuIGhhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5JiZhYT09PSJmbG9hdDMyInx8aGEgaW5zdGFuY2VvZiBJbnQzMkFycmF5JiZhYT09PSJpbnQzMiJ8fGhhIGluc3RhbmNlb2YgVWludDhBcnJheSYmYWE9PT0iYm9vbCJ9ZnVuY3Rpb24gdG9UeXBlZEFycmF5KGhhLGFhKXtpZihhYT09PSJzdHJpbmciKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IGNvbnZlcnQgYSBzdHJpbmdbXSB0byBhIFR5cGVkQXJyYXkiKTtpZihBcnJheS5pc0FycmF5KGhhKSYmKGhhPWZsYXR0ZW4oaGEpKSxlbnYoKS5nZXRCb29sKCJERUJVRyIpJiZjaGVja0NvbnZlcnNpb25Gb3JFcnJvcnMoaGEsYWEpLG5vQ29udmVyc2lvbk5lZWRlZChoYSxhYSkpcmV0dXJuIGhhO2lmKGFhPT1udWxsfHxhYT09PSJmbG9hdDMyInx8YWE9PT0iY29tcGxleDY0IilyZXR1cm4gbmV3IEZsb2F0MzJBcnJheShoYSk7aWYoYWE9PT0iaW50MzIiKXJldHVybiBuZXcgSW50MzJBcnJheShoYSk7aWYoYWE9PT0iYm9vbCIpe2NvbnN0IHhhPW5ldyBVaW50OEFycmF5KGhhLmxlbmd0aCk7Zm9yKGxldCBiYT0wO2JhPHhhLmxlbmd0aDsrK2JhKU1hdGgucm91bmQoaGFbYmFdKSE9PTAmJih4YVtiYV09MSk7cmV0dXJuIHhhfWVsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGEgdHlwZSAke2FhfWApfWZ1bmN0aW9uIG5vdygpe3JldHVybiBlbnYoKS5wbGF0Zm9ybS5ub3coKX1mdW5jdGlvbiBlbmNvZGVTdHJpbmcoaGEsYWE9InV0Zi04Iil7cmV0dXJuIGFhPWFhfHwidXRmLTgiLGVudigpLnBsYXRmb3JtLmVuY29kZShoYSxhYSl9ZnVuY3Rpb24gZGVjb2RlU3RyaW5nKGhhLGFhPSJ1dGYtOCIpe3JldHVybiBhYT1hYXx8InV0Zi04IixlbnYoKS5wbGF0Zm9ybS5kZWNvZGUoaGEsYWEpfWZ1bmN0aW9uIGlzVHlwZWRBcnJheShoYSl7cmV0dXJuIGVudigpLnBsYXRmb3JtLmlzVHlwZWRBcnJheSE9bnVsbD9lbnYoKS5wbGF0Zm9ybS5pc1R5cGVkQXJyYXkoaGEpOmlzVHlwZWRBcnJheUJyb3dzZXIoaGEpfWZ1bmN0aW9uIGZsYXR0ZW4oaGEsYWE9W10seGE9ITEpe2lmKGFhPT1udWxsJiYoYWE9W10pLHR5cGVvZiBoYT09ImJvb2xlYW4ifHx0eXBlb2YgaGE9PSJudW1iZXIifHx0eXBlb2YgaGE9PSJzdHJpbmcifHxpc1Byb21pc2UoaGEpfHxoYT09bnVsbHx8aXNUeXBlZEFycmF5KGhhKSYmeGEpYWEucHVzaChoYSk7ZWxzZSBpZihBcnJheS5pc0FycmF5KGhhKXx8aXNUeXBlZEFycmF5KGhhKSlmb3IobGV0IGJhPTA7YmE8aGEubGVuZ3RoOysrYmEpZmxhdHRlbihoYVtiYV0sYWEseGEpO2Vsc2V7bGV0IGJhPS0xO2Zvcihjb25zdCBTYSBvZiBPYmplY3Qua2V5cyhoYSkpL14oWzEtOV0rWzAtOV0qfDApJC8udGVzdChTYSkmJihiYT1NYXRoLm1heChiYSxOdW1iZXIoU2EpKSk7Zm9yKGxldCBTYT0wO1NhPD1iYTtTYSsrKWZsYXR0ZW4oaGFbU2FdLGFhLHhhKX1yZXR1cm4gYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUHJvZmlsZXJ7Y29uc3RydWN0b3IoYWEseGEpe3RoaXMuYmFja2VuZFRpbWVyPWFhLHRoaXMubG9nZ2VyPXhhLHhhPT1udWxsJiYodGhpcy5sb2dnZXI9bmV3IExvZ2dlcil9cHJvZmlsZUtlcm5lbChhYSx4YSxiYSl7bGV0IFNhO2NvbnN0IFRhPSgpPT57U2E9YmEoKX07bGV0IHdhO2NvbnN0IEVhPW5vdygpO2lmKHRoaXMuYmFja2VuZFRpbWVyLnRpbWVyQXZhaWxhYmxlKCkpd2E9dGhpcy5iYWNrZW5kVGltZXIudGltZShUYSk7ZWxzZXtUYSgpO2Zvcihjb25zdCBBYSBvZiBTYSlBYS5kYXRhU3luYygpO3dhPVByb21pc2UucmVzb2x2ZSh7a2VybmVsTXM6bm93KCktRWF9KX1pZihlbnYoKS5nZXRCb29sKCJDSEVDS19DT01QVVRBVElPTl9GT1JfRVJST1JTIikpZm9yKGxldCBBYT0wO0FhPFNhLmxlbmd0aDtBYSsrKXtjb25zdCBGYT1TYVtBYV07RmEuZGF0YSgpLnRoZW4oTGE9PntjaGVja0NvbXB1dGF0aW9uRm9yRXJyb3JzKExhLEZhLmR0eXBlLGFhKX0pfXJldHVybntrZXJuZWxOYW1lOmFhLG91dHB1dHM6U2EsaW5wdXRzOnhhLHRpbWVNczp3YS50aGVuKEFhPT5BYS5rZXJuZWxNcyksZXh0cmFJbmZvOndhLnRoZW4oQWE9PkFhLmdldEV4dHJhUHJvZmlsZUluZm8hPW51bGw/QWEuZ2V0RXh0cmFQcm9maWxlSW5mbygpOiIiKX19bG9nS2VybmVsUHJvZmlsZShhYSl7Y29uc3R7a2VybmVsTmFtZTp4YSxvdXRwdXRzOmJhLHRpbWVNczpTYSxpbnB1dHM6VGEsZXh0cmFJbmZvOndhfT1hYTtiYS5mb3JFYWNoKEVhPT57UHJvbWlzZS5hbGwoW0VhLmRhdGEoKSxTYSx3YV0pLnRoZW4oa2E9Pnt0aGlzLmxvZ2dlci5sb2dLZXJuZWxQcm9maWxlKHhhLEVhLGthWzBdLGthWzFdLFRhLGthWzJdKX0pfSl9fWZ1bmN0aW9uIGNoZWNrQ29tcHV0YXRpb25Gb3JFcnJvcnMoaGEsYWEseGEpe2lmKGFhIT09ImZsb2F0MzIiKXJldHVybiExO2ZvcihsZXQgYmE9MDtiYTxoYS5sZW5ndGg7YmErKyl7Y29uc3QgU2E9aGFbYmFdO2lmKGlzTmFOKFNhKXx8IWlzRmluaXRlKFNhKSlyZXR1cm4gY29uc29sZS53YXJuKGBGb3VuZCAke1NhfSBpbiB0aGUgcmVzdWx0IG9mICcke3hhfSdgKSwhMH1yZXR1cm4hMX1jbGFzcyBMb2dnZXJ7bG9nS2VybmVsUHJvZmlsZShhYSx4YSxiYSxTYSxUYSx3YSl7Y29uc3QgRWE9dHlwZW9mIFNhPT0ibnVtYmVyIj9yaWdodFBhZChgJHtTYX1tc2AsOSk6U2EuZXJyb3Isa2E9cmlnaHRQYWQoYWEsMjUpLEFhPXhhLnJhbmssRmE9eGEuc2l6ZSxMYT1yaWdodFBhZCh4YS5zaGFwZS50b1N0cmluZygpLDE0KTtsZXQgZWw9IiI7Zm9yKGNvbnN0IHRsIGluIFRhKXtjb25zdCBubD1UYVt0bF07aWYobmwhPW51bGwpe2NvbnN0IHNsPW5sLnNoYXBlfHx4YS5zaGFwZSxybD1zbC5sZW5ndGg7ZWwrPWAke3RsfTogJHtybH1EICR7cmw+MD9zbDoiIn0gYH19Y29uc29sZS5sb2coYCVjJHtrYX0JJWMke0VhfQklYyR7QWF9RCAke0xhfQklYyR7RmF9CSVjJHtlbH0JJWMke3dhfWAsImZvbnQtd2VpZ2h0OmJvbGQiLCJjb2xvcjpyZWQiLCJjb2xvcjpibHVlIiwiY29sb3I6IG9yYW5nZSIsImNvbG9yOiBncmVlbiIsImNvbG9yOiBzdGVlbGJsdWUiKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0RmlsdGVyZWROb2Rlc1hUb1koaGEsYWEseGEpe2NvbnN0IGJhPXt9LFNhPXt9O2ZvcihsZXQga2E9MDtrYTxhYS5sZW5ndGg7a2ErKyliYVthYVtrYV0uaWRdPSEwO2ZvcihsZXQga2E9MDtrYTxoYS5sZW5ndGg7a2ErKyl7Y29uc3QgQWE9aGFba2FdLEZhPUFhLmlucHV0cztmb3IoY29uc3QgTGEgaW4gRmEpe2NvbnN0IGVsPUZhW0xhXTtsZXQgdGw9ITE7Zm9yKGxldCBubD0wO25sPGFhLmxlbmd0aDtubCsrKWlmKGJhW2VsLmlkXSl7QWEub3V0cHV0cy5mb3JFYWNoKHNsPT5iYVtzbC5pZF09ITApLHRsPSEwLFNhW0FhLmlkXT0hMDticmVha31pZih0bClicmVha319Y29uc3QgVGE9e307VGFbeGEuaWRdPSEwO2NvbnN0IHdhPXt9O2ZvcihsZXQga2E9aGEubGVuZ3RoLTE7a2E+PTA7a2EtLSl7Y29uc3QgQWE9aGFba2FdLEZhPUFhLmlucHV0cztmb3IobGV0IExhPTA7TGE8QWEub3V0cHV0cy5sZW5ndGg7TGErKylpZihUYVtBYS5vdXRwdXRzW0xhXS5pZF0pe2Zvcihjb25zdCBlbCBpbiBGYSlUYVtGYVtlbF0uaWRdPSEwLHdhW0FhLmlkXT0hMDticmVha319Y29uc3QgRWE9W107Zm9yKGxldCBrYT0wO2thPGhhLmxlbmd0aDtrYSsrKXtjb25zdCBBYT1oYVtrYV07aWYoU2FbQWEuaWRdJiZ3YVtBYS5pZF0pe2NvbnN0IEZhPXt9O2Zvcihjb25zdCBlbCBpbiBBYS5pbnB1dHMpe2NvbnN0IHRsPUFhLmlucHV0c1tlbF07YmFbdGwuaWRdJiYoRmFbZWxdPXRsKX1jb25zdCBMYT1PYmplY3QuYXNzaWduKHt9LEFhKTtMYS5pbnB1dHM9RmEsTGEub3V0cHV0cz1BYS5vdXRwdXRzLEVhLnB1c2goTGEpfX1yZXR1cm4gRWF9ZnVuY3Rpb24gYmFja3Byb3BhZ2F0ZUdyYWRpZW50cyhoYSxhYSx4YSxiYSl7Zm9yKGxldCBTYT1hYS5sZW5ndGgtMTtTYT49MDtTYS0tKXtjb25zdCBUYT1hYVtTYV0sd2E9W107aWYoVGEub3V0cHV0cy5mb3JFYWNoKGthPT57Y29uc3QgQWE9aGFba2EuaWRdO0FhIT1udWxsP3dhLnB1c2goQWEpOndhLnB1c2gobnVsbCl9KSxUYS5ncmFkaWVudD09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb21wdXRlIGdyYWRpZW50OiBncmFkaWVudCBmdW5jdGlvbiBub3QgZm91bmQgZm9yICR7VGEua2VybmVsTmFtZX0uYCk7Y29uc3QgRWE9VGEuZ3JhZGllbnQod2EpO2Zvcihjb25zdCBrYSBpbiBUYS5pbnB1dHMpe2lmKCEoa2EgaW4gRWEpKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGJhY2twcm9wIHRocm91Z2ggaW5wdXQgJHtrYX0uIEF2YWlsYWJsZSBncmFkaWVudHMgZm91bmQ6ICR7T2JqZWN0LmtleXMoRWEpfS5gKTtjb25zdCBBYT14YSgoKT0+RWFba2FdKCkpO2lmKEFhLmR0eXBlIT09ImZsb2F0MzIiKXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gZ3JhZGllbnQgZm9yIG9wICR7VGEua2VybmVsTmFtZX0uIFRoZSBncmFkaWVudCBvZiBpbnB1dCAke2thfSBtdXN0IGhhdmUgJ2Zsb2F0MzInIGR0eXBlLCBidXQgaGFzICcke0FhLmR0eXBlfSdgKTtjb25zdCBGYT1UYS5pbnB1dHNba2FdO2lmKCFhcnJheXNFcXVhbChBYS5zaGFwZSxGYS5zaGFwZSkpdGhyb3cgbmV3IEVycm9yKGBFcnJvciBpbiBncmFkaWVudCBmb3Igb3AgJHtUYS5rZXJuZWxOYW1lfS4gVGhlIGdyYWRpZW50IG9mIGlucHV0ICcke2thfScgaGFzIHNoYXBlICcke0FhLnNoYXBlfScsIHdoaWNoIGRvZXMgbm90IG1hdGNoIHRoZSBzaGFwZSBvZiB0aGUgaW5wdXQgJyR7RmEuc2hhcGV9J2ApO2lmKGhhW0ZhLmlkXT09bnVsbCloYVtGYS5pZF09QWE7ZWxzZXtjb25zdCBMYT1oYVtGYS5pZF07aGFbRmEuaWRdPWJhKExhLEFhKSxMYS5kaXNwb3NlKCl9fX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRk9STUFUX0xJTUlUX05VTV9WQUxTPTIwLEZPUk1BVF9OVU1fRklSU1RfTEFTVF9WQUxTPTMsRk9STUFUX05VTV9TSUdfRElHSVRTPTc7ZnVuY3Rpb24gdGVuc29yVG9TdHJpbmcoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWNvbXB1dGVTdHJpZGVzKGFhKSxUYT1jb21wdXRlTWF4U2l6ZVBlckNvbHVtbihoYSxhYSx4YSxTYSksd2E9YWEubGVuZ3RoLEVhPXN1YlRlbnNvclRvU3RyaW5nKGhhLGFhLHhhLFNhLFRhKSxrYT1bIlRlbnNvciJdO3JldHVybiBiYSYmKGthLnB1c2goYCAgZHR5cGU6ICR7eGF9YCksa2EucHVzaChgICByYW5rOiAke3dhfWApLGthLnB1c2goYCAgc2hhcGU6IFske2FhfV1gKSxrYS5wdXNoKCIgIHZhbHVlczoiKSksa2EucHVzaChFYS5tYXAoQWE9PiIgICAgIitBYSkuam9pbihgCmApKSxrYS5qb2luKGAKYCl9ZnVuY3Rpb24gY29tcHV0ZU1heFNpemVQZXJDb2x1bW4oaGEsYWEseGEsYmEpe2NvbnN0IFNhPXNpemVGcm9tU2hhcGUoYWEpLFRhPWJhW2JhLmxlbmd0aC0xXSx3YT1uZXcgQXJyYXkoVGEpLmZpbGwoMCksRWE9YWEubGVuZ3RoLGthPXhhPT09ImNvbXBsZXg2NCI/Y3JlYXRlQ29tcGxleFR1cGxlcyhoYSk6aGE7aWYoRWE+MSlmb3IobGV0IEFhPTA7QWE8U2EvVGE7QWErKyl7Y29uc3QgRmE9QWEqVGE7Zm9yKGxldCBMYT0wO0xhPFRhO0xhKyspd2FbTGFdPU1hdGgubWF4KHdhW0xhXSx2YWxUb1N0cmluZyhrYVtGYStMYV0sMCx4YSkubGVuZ3RoKX1yZXR1cm4gd2F9ZnVuY3Rpb24gdmFsVG9TdHJpbmcoaGEsYWEseGEpe2xldCBiYTtyZXR1cm4gQXJyYXkuaXNBcnJheShoYSk/YmE9YCR7cGFyc2VGbG9hdChoYVswXS50b0ZpeGVkKEZPUk1BVF9OVU1fU0lHX0RJR0lUUykpfSArICR7cGFyc2VGbG9hdChoYVsxXS50b0ZpeGVkKEZPUk1BVF9OVU1fU0lHX0RJR0lUUykpfWpgOmlzU3RyaW5nKGhhKT9iYT1gJyR7aGF9J2A6eGE9PT0iYm9vbCI/YmE9Ym9vbE51bVRvU3RyaW5nKGhhKTpiYT1wYXJzZUZsb2F0KGhhLnRvRml4ZWQoRk9STUFUX05VTV9TSUdfRElHSVRTKSkudG9TdHJpbmcoKSxyaWdodFBhZChiYSxhYSl9ZnVuY3Rpb24gYm9vbE51bVRvU3RyaW5nKGhhKXtyZXR1cm4gaGE9PT0wPyJmYWxzZSI6InRydWUifWZ1bmN0aW9uIHN1YlRlbnNvclRvU3RyaW5nKGhhLGFhLHhhLGJhLFNhLFRhPSEwKXtjb25zdCB3YT14YT09PSJjb21wbGV4NjQiPzI6MSxFYT1hYVswXSxrYT1hYS5sZW5ndGg7aWYoa2E9PT0wKXtpZih4YT09PSJjb21wbGV4NjQiKXtjb25zdCBzbD1jcmVhdGVDb21wbGV4VHVwbGVzKGhhKTtyZXR1cm5bdmFsVG9TdHJpbmcoc2xbMF0sMCx4YSldfXJldHVybiB4YT09PSJib29sIj9bYm9vbE51bVRvU3RyaW5nKGhhWzBdKV06W2hhWzBdLnRvU3RyaW5nKCldfWlmKGthPT09MSl7aWYoRWE+Rk9STUFUX0xJTUlUX05VTV9WQUxTKXtjb25zdCBybD1GT1JNQVRfTlVNX0ZJUlNUX0xBU1RfVkFMUyp3YTtsZXQgb2w9QXJyYXkuZnJvbShoYS5zbGljZSgwLHJsKSksYWw9QXJyYXkuZnJvbShoYS5zbGljZSgoRWEtRk9STUFUX05VTV9GSVJTVF9MQVNUX1ZBTFMpKndhLEVhKndhKSk7cmV0dXJuIHhhPT09ImNvbXBsZXg2NCImJihvbD1jcmVhdGVDb21wbGV4VHVwbGVzKG9sKSxhbD1jcmVhdGVDb21wbGV4VHVwbGVzKGFsKSksWyJbIitvbC5tYXAoKGxsLGlsKT0+dmFsVG9TdHJpbmcobGwsU2FbaWxdLHhhKSkuam9pbigiLCAiKSsiLCAuLi4sICIrYWwubWFwKChsbCxpbCk9PnZhbFRvU3RyaW5nKGxsLFNhW0VhLUZPUk1BVF9OVU1fRklSU1RfTEFTVF9WQUxTK2lsXSx4YSkpLmpvaW4oIiwgIikrIl0iXX1yZXR1cm5bIlsiKyh4YT09PSJjb21wbGV4NjQiP2NyZWF0ZUNvbXBsZXhUdXBsZXMoaGEpOkFycmF5LmZyb20oaGEpKS5tYXAoKHJsLG9sKT0+dmFsVG9TdHJpbmcocmwsU2Fbb2xdLHhhKSkuam9pbigiLCAiKSsiXSJdfWNvbnN0IEFhPWFhLnNsaWNlKDEpLEZhPWJhLnNsaWNlKDEpLExhPWJhWzBdKndhLGVsPVtdO2lmKEVhPkZPUk1BVF9MSU1JVF9OVU1fVkFMUyl7Zm9yKGxldCBzbD0wO3NsPEZPUk1BVF9OVU1fRklSU1RfTEFTVF9WQUxTO3NsKyspe2NvbnN0IHJsPXNsKkxhLG9sPXJsK0xhO2VsLnB1c2goLi4uc3ViVGVuc29yVG9TdHJpbmcoaGEuc2xpY2Uocmwsb2wpLEFhLHhhLEZhLFNhLCExKSl9ZWwucHVzaCgiLi4uIik7Zm9yKGxldCBzbD1FYS1GT1JNQVRfTlVNX0ZJUlNUX0xBU1RfVkFMUztzbDxFYTtzbCsrKXtjb25zdCBybD1zbCpMYSxvbD1ybCtMYTtlbC5wdXNoKC4uLnN1YlRlbnNvclRvU3RyaW5nKGhhLnNsaWNlKHJsLG9sKSxBYSx4YSxGYSxTYSxzbD09PUVhLTEpKX19ZWxzZSBmb3IobGV0IHNsPTA7c2w8RWE7c2wrKyl7Y29uc3Qgcmw9c2wqTGEsb2w9cmwrTGE7ZWwucHVzaCguLi5zdWJUZW5zb3JUb1N0cmluZyhoYS5zbGljZShybCxvbCksQWEseGEsRmEsU2Esc2w9PT1FYS0xKSl9Y29uc3QgdGw9a2E9PT0yPyIsIjoiIjtlbFswXT0iWyIrKEVhPjA/ZWxbMF0rdGw6IiIpO2ZvcihsZXQgc2w9MTtzbDxlbC5sZW5ndGgtMTtzbCsrKWVsW3NsXT0iICIrZWxbc2xdK3RsO2xldCBubD1gLApgO2ZvcihsZXQgc2w9MjtzbDxrYTtzbCsrKW5sKz1gCmA7cmV0dXJuIGVsW2VsLmxlbmd0aC0xXT0iICIrZWxbZWwubGVuZ3RoLTFdKyJdIisoVGE/IiI6bmwpLGVsfWZ1bmN0aW9uIGNyZWF0ZUNvbXBsZXhUdXBsZXMoaGEpe2NvbnN0IGFhPVtdO2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7eGErPTIpYWEucHVzaChbaGFbeGFdLGhhW3hhKzFdXSk7cmV0dXJuIGFhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFRlbnNvckJ1ZmZlcntjb25zdHJ1Y3RvcihhYSx4YSxiYSl7aWYodGhpcy5kdHlwZT14YSx0aGlzLnNoYXBlPWFhLnNsaWNlKCksdGhpcy5zaXplPXNpemVGcm9tU2hhcGUoYWEpLGJhIT1udWxsKXtjb25zdCBTYT1iYS5sZW5ndGg7YXNzZXJ0KFNhPT09dGhpcy5zaXplLCgpPT5gTGVuZ3RoIG9mIHZhbHVlcyAnJHtTYX0nIGRvZXMgbm90IG1hdGNoIHRoZSBzaXplIGluZmVycmVkIGJ5IHRoZSBzaGFwZSAnJHt0aGlzLnNpemV9Jy5gKX1pZih4YT09PSJjb21wbGV4NjQiKXRocm93IG5ldyBFcnJvcigiY29tcGxleDY0IGR0eXBlIFRlbnNvckJ1ZmZlcnMgYXJlIG5vdCBzdXBwb3J0ZWQuIFBsZWFzZSBjcmVhdGUgYSBUZW5zb3JCdWZmZXIgZm9yIHRoZSByZWFsIGFuZCBpbWFnaW5hcnkgcGFydHMgc2VwYXJhdGVseSBhbmQgY2FsbCB0Zi5jb21wbGV4KHJlYWwsIGltYWcpLiIpO3RoaXMudmFsdWVzPWJhfHxnZXRBcnJheUZyb21EVHlwZSh4YSx0aGlzLnNpemUpLHRoaXMuc3RyaWRlcz1jb21wdXRlU3RyaWRlcyhhYSl9c2V0KGFhLC4uLnhhKXt4YS5sZW5ndGg9PT0wJiYoeGE9WzBdKSxhc3NlcnQoeGEubGVuZ3RoPT09dGhpcy5yYW5rLCgpPT5gVGhlIG51bWJlciBvZiBwcm92aWRlZCBjb29yZGluYXRlcyAoJHt4YS5sZW5ndGh9KSBtdXN0IG1hdGNoIHRoZSByYW5rICgke3RoaXMucmFua30pYCk7Y29uc3QgYmE9dGhpcy5sb2NUb0luZGV4KHhhKTt0aGlzLnZhbHVlc1tiYV09YWF9Z2V0KC4uLmFhKXthYS5sZW5ndGg9PT0wJiYoYWE9WzBdKTtsZXQgeGE9MDtmb3IoY29uc3QgU2Egb2YgYWEpe2lmKFNhPDB8fFNhPj10aGlzLnNoYXBlW3hhXSl7Y29uc3QgVGE9YFJlcXVlc3RlZCBvdXQgb2YgcmFuZ2UgZWxlbWVudCBhdCAke2FhfS4gICBCdWZmZXIgc2hhcGU9JHt0aGlzLnNoYXBlfWA7dGhyb3cgbmV3IEVycm9yKFRhKX14YSsrfWxldCBiYT1hYVthYS5sZW5ndGgtMV07Zm9yKGxldCBTYT0wO1NhPGFhLmxlbmd0aC0xOysrU2EpYmErPXRoaXMuc3RyaWRlc1tTYV0qYWFbU2FdO3JldHVybiB0aGlzLnZhbHVlc1tiYV19bG9jVG9JbmRleChhYSl7aWYodGhpcy5yYW5rPT09MClyZXR1cm4gMDtpZih0aGlzLnJhbms9PT0xKXJldHVybiBhYVswXTtsZXQgeGE9YWFbYWEubGVuZ3RoLTFdO2ZvcihsZXQgYmE9MDtiYTxhYS5sZW5ndGgtMTsrK2JhKXhhKz10aGlzLnN0cmlkZXNbYmFdKmFhW2JhXTtyZXR1cm4geGF9aW5kZXhUb0xvYyhhYSl7aWYodGhpcy5yYW5rPT09MClyZXR1cm5bXTtpZih0aGlzLnJhbms9PT0xKXJldHVyblthYV07Y29uc3QgeGE9bmV3IEFycmF5KHRoaXMuc2hhcGUubGVuZ3RoKTtmb3IobGV0IGJhPTA7YmE8eGEubGVuZ3RoLTE7KytiYSl4YVtiYV09TWF0aC5mbG9vcihhYS90aGlzLnN0cmlkZXNbYmFdKSxhYS09eGFbYmFdKnRoaXMuc3RyaWRlc1tiYV07cmV0dXJuIHhhW3hhLmxlbmd0aC0xXT1hYSx4YX1nZXQgcmFuaygpe3JldHVybiB0aGlzLnNoYXBlLmxlbmd0aH10b1RlbnNvcigpe3JldHVybiB0cmFja2VyRm4oKS5tYWtlVGVuc29yKHRoaXMudmFsdWVzLHRoaXMuc2hhcGUsdGhpcy5kdHlwZSl9fWxldCB0cmFja2VyRm49bnVsbCxvcEhhbmRsZXIkMT1udWxsO2Z1bmN0aW9uIHNldFRlbnNvclRyYWNrZXIoaGEpe3RyYWNrZXJGbj1oYX1mdW5jdGlvbiBzZXRPcEhhbmRsZXIoaGEpe29wSGFuZGxlciQxPWhhfWNsYXNzIFRlbnNvcntjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy5rZXB0PSExLHRoaXMuaXNEaXNwb3NlZEludGVybmFsPSExLHRoaXMuc2hhcGU9YWEuc2xpY2UoKSx0aGlzLmR0eXBlPXhhfHwiZmxvYXQzMiIsdGhpcy5zaXplPXNpemVGcm9tU2hhcGUoYWEpLHRoaXMuc3RyaWRlcz1jb21wdXRlU3RyaWRlcyhhYSksdGhpcy5kYXRhSWQ9YmEsdGhpcy5pZD1TYSx0aGlzLnJhbmtUeXBlPXRoaXMucmFuazw1P3RoaXMucmFuay50b1N0cmluZygpOiJoaWdoZXIifWdldCByYW5rKCl7cmV0dXJuIHRoaXMuc2hhcGUubGVuZ3RofWFzeW5jIGJ1ZmZlcigpe2NvbnN0IGFhPWF3YWl0IHRoaXMuZGF0YSgpO3JldHVybiBvcEhhbmRsZXIkMS5idWZmZXIodGhpcy5zaGFwZSx0aGlzLmR0eXBlLGFhKX1idWZmZXJTeW5jKCl7cmV0dXJuIG9wSGFuZGxlciQxLmJ1ZmZlcih0aGlzLnNoYXBlLHRoaXMuZHR5cGUsdGhpcy5kYXRhU3luYygpKX1hc3luYyBhcnJheSgpe2NvbnN0IGFhPWF3YWl0IHRoaXMuZGF0YSgpO3JldHVybiB0b05lc3RlZEFycmF5KHRoaXMuc2hhcGUsYWEsdGhpcy5kdHlwZT09PSJjb21wbGV4NjQiKX1hcnJheVN5bmMoKXtyZXR1cm4gdG9OZXN0ZWRBcnJheSh0aGlzLnNoYXBlLHRoaXMuZGF0YVN5bmMoKSx0aGlzLmR0eXBlPT09ImNvbXBsZXg2NCIpfWFzeW5jIGRhdGEoKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpO2NvbnN0IGFhPXRyYWNrZXJGbigpLnJlYWQodGhpcy5kYXRhSWQpO2lmKHRoaXMuZHR5cGU9PT0ic3RyaW5nIil7Y29uc3QgeGE9YXdhaXQgYWE7dHJ5e3JldHVybiB4YS5tYXAoYmE9PmRlY29kZVN0cmluZyhiYSkpfWNhdGNoe3Rocm93IG5ldyBFcnJvcigiRmFpbGVkIHRvIGRlY29kZSB0aGUgc3RyaW5nIGJ5dGVzIGludG8gdXRmLTguIFRvIGdldCB0aGUgb3JpZ2luYWwgYnl0ZXMsIGNhbGwgdGVuc29yLmJ5dGVzKCkuIil9fXJldHVybiBhYX1kYXRhVG9HUFUoYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRyYWNrZXJGbigpLnJlYWRUb0dQVSh0aGlzLmRhdGFJZCxhYSl9ZGF0YVN5bmMoKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpO2NvbnN0IGFhPXRyYWNrZXJGbigpLnJlYWRTeW5jKHRoaXMuZGF0YUlkKTtpZih0aGlzLmR0eXBlPT09InN0cmluZyIpdHJ5e3JldHVybiBhYS5tYXAoeGE9PmRlY29kZVN0cmluZyh4YSkpfWNhdGNoe3Rocm93IG5ldyBFcnJvcigiRmFpbGVkIHRvIGRlY29kZSB0aGUgc3RyaW5nIGJ5dGVzIGludG8gdXRmLTguIFRvIGdldCB0aGUgb3JpZ2luYWwgYnl0ZXMsIGNhbGwgdGVuc29yLmJ5dGVzKCkuIil9cmV0dXJuIGFhfWFzeW5jIGJ5dGVzKCl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKTtjb25zdCBhYT1hd2FpdCB0cmFja2VyRm4oKS5yZWFkKHRoaXMuZGF0YUlkKTtyZXR1cm4gdGhpcy5kdHlwZT09PSJzdHJpbmciP2FhOm5ldyBVaW50OEFycmF5KGFhLmJ1ZmZlcil9ZGlzcG9zZSgpe3RoaXMuaXNEaXNwb3NlZHx8KHRoaXMua2VyYXNNYXNrJiZ0aGlzLmtlcmFzTWFzay5kaXNwb3NlKCksdHJhY2tlckZuKCkuZGlzcG9zZVRlbnNvcih0aGlzKSx0aGlzLmlzRGlzcG9zZWRJbnRlcm5hbD0hMCl9Z2V0IGlzRGlzcG9zZWQoKXtyZXR1cm4gdGhpcy5pc0Rpc3Bvc2VkSW50ZXJuYWx9dGhyb3dJZkRpc3Bvc2VkKCl7aWYodGhpcy5pc0Rpc3Bvc2VkKXRocm93IG5ldyBFcnJvcigiVGVuc29yIGlzIGRpc3Bvc2VkLiIpfXByaW50KGFhPSExKXtyZXR1cm4gb3BIYW5kbGVyJDEucHJpbnQodGhpcyxhYSl9Y2xvbmUoKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxvcEhhbmRsZXIkMS5jbG9uZSh0aGlzKX10b1N0cmluZyhhYT0hMSl7Y29uc3QgeGE9dGhpcy5kYXRhU3luYygpO3JldHVybiB0ZW5zb3JUb1N0cmluZyh4YSx0aGlzLnNoYXBlLHRoaXMuZHR5cGUsYWEpfWNhc3QoYWEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLG9wSGFuZGxlciQxLmNhc3QodGhpcyxhYSl9dmFyaWFibGUoYWE9ITAseGEsYmEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRyYWNrZXJGbigpLm1ha2VWYXJpYWJsZSh0aGlzLGFhLHhhLGJhKX19T2JqZWN0LmRlZmluZVByb3BlcnR5KFRlbnNvcixTeW1ib2wuaGFzSW5zdGFuY2Use3ZhbHVlOmhhPT4hIWhhJiZoYS5kYXRhIT1udWxsJiZoYS5kYXRhU3luYyE9bnVsbCYmaGEudGhyb3dJZkRpc3Bvc2VkIT1udWxsfSk7ZnVuY3Rpb24gZ2V0R2xvYmFsVGVuc29yQ2xhc3MoKXtyZXR1cm4gZ2V0R2xvYmFsKCJUZW5zb3IiLCgpPT5UZW5zb3IpfWdldEdsb2JhbFRlbnNvckNsYXNzKCk7Y2xhc3MgVmFyaWFibGUgZXh0ZW5kcyBUZW5zb3J7Y29uc3RydWN0b3IoYWEseGEsYmEsU2Epe3N1cGVyKGFhLnNoYXBlLGFhLmR0eXBlLGFhLmRhdGFJZCxTYSksdGhpcy50cmFpbmFibGU9eGEsdGhpcy5uYW1lPWJhfWFzc2lnbihhYSl7aWYoYWEuZHR5cGUhPT10aGlzLmR0eXBlKXRocm93IG5ldyBFcnJvcihgZHR5cGUgb2YgdGhlIG5ldyB2YWx1ZSAoJHthYS5kdHlwZX0pIGFuZCBwcmV2aW91cyB2YWx1ZSAoJHt0aGlzLmR0eXBlfSkgbXVzdCBtYXRjaGApO2lmKCFhcnJheXNFcXVhbChhYS5zaGFwZSx0aGlzLnNoYXBlKSl0aHJvdyBuZXcgRXJyb3IoYHNoYXBlIG9mIHRoZSBuZXcgdmFsdWUgKCR7YWEuc2hhcGV9KSBhbmQgcHJldmlvdXMgdmFsdWUgKCR7dGhpcy5zaGFwZX0pIG11c3QgbWF0Y2hgKTt0cmFja2VyRm4oKS5kaXNwb3NlVGVuc29yKHRoaXMpLHRoaXMuZGF0YUlkPWFhLmRhdGFJZCx0cmFja2VyRm4oKS5pbmNSZWYodGhpcyxudWxsKX1kaXNwb3NlKCl7dHJhY2tlckZuKCkuZGlzcG9zZVZhcmlhYmxlKHRoaXMpLHRoaXMuaXNEaXNwb3NlZEludGVybmFsPSEwfX1PYmplY3QuZGVmaW5lUHJvcGVydHkoVmFyaWFibGUsU3ltYm9sLmhhc0luc3RhbmNlLHt2YWx1ZTpoYT0+aGEgaW5zdGFuY2VvZiBUZW5zb3ImJmhhLmFzc2lnbiE9bnVsbCYmaGEuYXNzaWduIGluc3RhbmNlb2YgRnVuY3Rpb259KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi92YXIgUmFuazsoZnVuY3Rpb24oaGEpe2hhLlIwPSJSMCIsaGEuUjE9IlIxIixoYS5SMj0iUjIiLGhhLlIzPSJSMyIsaGEuUjQ9IlI0IixoYS5SNT0iUjUiLGhhLlI2PSJSNiJ9KShSYW5rfHwoUmFuaz17fSkpO3ZhciBVcGNhc3RJbnQzMkFuZE1hcDsoZnVuY3Rpb24oaGEpe2hhLmZsb2F0MzI9ImZsb2F0MzIiLGhhLmludDMyPSJpbnQzMiIsaGEuYm9vbD0iaW50MzIiLGhhLmNvbXBsZXg2ND0iY29tcGxleDY0In0pKFVwY2FzdEludDMyQW5kTWFwfHwoVXBjYXN0SW50MzJBbmRNYXA9e30pKTt2YXIgVXBjYXN0Qm9vbEFuZE1hcDsoZnVuY3Rpb24oaGEpe2hhLmZsb2F0MzI9ImZsb2F0MzIiLGhhLmludDMyPSJpbnQzMiIsaGEuYm9vbD0iYm9vbCIsaGEuY29tcGxleDY0PSJjb21wbGV4NjQifSkoVXBjYXN0Qm9vbEFuZE1hcHx8KFVwY2FzdEJvb2xBbmRNYXA9e30pKTt2YXIgVXBjYXN0RmxvYXQzMkFuZE1hcDsoZnVuY3Rpb24oaGEpe2hhLmZsb2F0MzI9ImZsb2F0MzIiLGhhLmludDMyPSJmbG9hdDMyIixoYS5ib29sPSJmbG9hdDMyIixoYS5jb21wbGV4NjQ9ImNvbXBsZXg2NCJ9KShVcGNhc3RGbG9hdDMyQW5kTWFwfHwoVXBjYXN0RmxvYXQzMkFuZE1hcD17fSkpO3ZhciBVcGNhc3RDb21wbGV4NjRBbmRNYXA7KGZ1bmN0aW9uKGhhKXtoYS5mbG9hdDMyPSJjb21wbGV4NjQiLGhhLmludDMyPSJjb21wbGV4NjQiLGhhLmJvb2w9ImNvbXBsZXg2NCIsaGEuY29tcGxleDY0PSJjb21wbGV4NjQifSkoVXBjYXN0Q29tcGxleDY0QW5kTWFwfHwoVXBjYXN0Q29tcGxleDY0QW5kTWFwPXt9KSk7Y29uc3QgdXBjYXN0VHlwZU1hcD17ZmxvYXQzMjpVcGNhc3RGbG9hdDMyQW5kTWFwLGludDMyOlVwY2FzdEludDMyQW5kTWFwLGJvb2w6VXBjYXN0Qm9vbEFuZE1hcCxjb21wbGV4NjQ6VXBjYXN0Q29tcGxleDY0QW5kTWFwfTtmdW5jdGlvbiB1cGNhc3RUeXBlKGhhLGFhKXtpZihoYT09PSJzdHJpbmcifHxhYT09PSJzdHJpbmciKXtpZihoYT09PSJzdHJpbmciJiZhYT09PSJzdHJpbmciKXJldHVybiJzdHJpbmciO3Rocm93IG5ldyBFcnJvcihgQ2FuIG5vdCB1cGNhc3QgJHtoYX0gd2l0aCAke2FhfWApfXJldHVybiB1cGNhc3RUeXBlTWFwW2hhXVthYV19ZnVuY3Rpb24gc3VtT3V0VHlwZShoYSl7cmV0dXJuIHVwY2FzdFR5cGUoaGEsImludDMyIil9ZnVuY3Rpb24gaXNXZWJHTERhdGEoaGEpe3JldHVybiBoYSE9bnVsbCYmdHlwZW9mIGhhPT0ib2JqZWN0IiYmInRleHR1cmUiaW4gaGEmJmhhLnRleHR1cmUgaW5zdGFuY2VvZiBXZWJHTFRleHR1cmV9ZnVuY3Rpb24gaXNXZWJHUFVEYXRhKGhhKXtyZXR1cm4gdHlwZW9mIEdQVUJ1ZmZlcjwidSImJmhhIT1udWxsJiZ0eXBlb2YgaGE9PSJvYmplY3QiJiYiYnVmZmVyImluIGhhJiZoYS5idWZmZXIgaW5zdGFuY2VvZiBHUFVCdWZmZXJ9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWFrZVR5cGVzTWF0Y2goaGEsYWEpe2lmKGhhLmR0eXBlPT09YWEuZHR5cGUpcmV0dXJuW2hhLGFhXTtjb25zdCB4YT11cGNhc3RUeXBlKGhhLmR0eXBlLGFhLmR0eXBlKTtyZXR1cm5baGEuY2FzdCh4YSksYWEuY2FzdCh4YSldfWZ1bmN0aW9uIGdldFRlbnNvcnNJbkNvbnRhaW5lcihoYSl7Y29uc3QgYWE9W107cmV0dXJuIHdhbGtUZW5zb3JDb250YWluZXIoaGEsYWEsbmV3IFNldCksYWF9ZnVuY3Rpb24gd2Fsa1RlbnNvckNvbnRhaW5lcihoYSxhYSx4YSl7aWYoaGE9PW51bGwpcmV0dXJuO2lmKGhhIGluc3RhbmNlb2YgVGVuc29yKXthYS5wdXNoKGhhKTtyZXR1cm59aWYoIWlzSXRlcmFibGUoaGEpKXJldHVybjtjb25zdCBiYT1oYTtmb3IoY29uc3QgU2EgaW4gYmEpe2NvbnN0IFRhPWJhW1NhXTt4YS5oYXMoVGEpfHwoeGEuYWRkKFRhKSx3YWxrVGVuc29yQ29udGFpbmVyKFRhLGFhLHhhKSl9fWZ1bmN0aW9uIGlzSXRlcmFibGUoaGEpe3JldHVybiBBcnJheS5pc0FycmF5KGhhKXx8dHlwZW9mIGhhPT0ib2JqZWN0In0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpc1JlZ2lzdGVyZWRLZXJuZWxJbnZvY2F0aW9uKGhhKXtyZXR1cm4gaGEua2VybmVsTmFtZSE9bnVsbH1jbGFzcyBFbmdpbmVTdGF0ZXtjb25zdHJ1Y3Rvcigpe3RoaXMucmVnaXN0ZXJlZFZhcmlhYmxlcz17fSx0aGlzLm5leHRUYXBlTm9kZUlkPTAsdGhpcy5udW1CeXRlcz0wLHRoaXMubnVtVGVuc29ycz0wLHRoaXMubnVtU3RyaW5nVGVuc29ycz0wLHRoaXMubnVtRGF0YUJ1ZmZlcnM9MCx0aGlzLmdyYWRpZW50RGVwdGg9MCx0aGlzLmtlcm5lbERlcHRoPTAsdGhpcy5zY29wZVN0YWNrPVtdLHRoaXMubnVtRGF0YU1vdmVzU3RhY2s9W10sdGhpcy5uZXh0U2NvcGVJZD0wLHRoaXMudGVuc29ySW5mbz1uZXcgV2Vha01hcCx0aGlzLnByb2ZpbGluZz0hMSx0aGlzLmFjdGl2ZVByb2ZpbGU9e25ld0J5dGVzOjAsbmV3VGVuc29yczowLHBlYWtCeXRlczowLGtlcm5lbHM6W10scmVzdWx0Om51bGwsZ2V0IGtlcm5lbE5hbWVzKCl7cmV0dXJuIEFycmF5LmZyb20obmV3IFNldCh0aGlzLmtlcm5lbHMubWFwKGFhPT5hYS5uYW1lKSkpfX19ZGlzcG9zZSgpe2Zvcihjb25zdCBhYSBpbiB0aGlzLnJlZ2lzdGVyZWRWYXJpYWJsZXMpdGhpcy5yZWdpc3RlcmVkVmFyaWFibGVzW2FhXS5kaXNwb3NlKCl9fWNsYXNzIEVuZ2luZXtjb25zdHJ1Y3RvcihhYSl7dGhpcy5FTlY9YWEsdGhpcy5yZWdpc3RyeT17fSx0aGlzLnJlZ2lzdHJ5RmFjdG9yeT17fSx0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdElkPTAsdGhpcy5zdGF0ZT1uZXcgRW5naW5lU3RhdGV9YXN5bmMgcmVhZHkoKXtpZih0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdCE9bnVsbClyZXR1cm4gdGhpcy5wZW5kaW5nQmFja2VuZEluaXQudGhlbigoKT0+e30pO2lmKHRoaXMuYmFja2VuZEluc3RhbmNlIT1udWxsKXJldHVybjtjb25zdCBhYT10aGlzLmdldFNvcnRlZEJhY2tlbmRzKCk7Zm9yKGxldCB4YT0wO3hhPGFhLmxlbmd0aDt4YSsrKXtjb25zdCBiYT1hYVt4YV07aWYoYXdhaXQgdGhpcy5pbml0aWFsaXplQmFja2VuZChiYSkuc3VjY2Vzcyl7YXdhaXQgdGhpcy5zZXRCYWNrZW5kKGJhKTtyZXR1cm59fXRocm93IG5ldyBFcnJvcigiQ291bGQgbm90IGluaXRpYWxpemUgYW55IGJhY2tlbmRzLCBhbGwgYmFja2VuZCBpbml0aWFsaXphdGlvbnMgZmFpbGVkLiIpfWdldCBiYWNrZW5kKCl7aWYodGhpcy5wZW5kaW5nQmFja2VuZEluaXQhPW51bGwpdGhyb3cgbmV3IEVycm9yKGBCYWNrZW5kICcke3RoaXMuYmFja2VuZE5hbWV9JyBoYXMgbm90IHlldCBiZWVuIGluaXRpYWxpemVkLiBNYWtlIHN1cmUgdG8gYXdhaXQgdGYucmVhZHkoKSBvciBhd2FpdCB0Zi5zZXRCYWNrZW5kKCkgYmVmb3JlIGNhbGxpbmcgb3RoZXIgbWV0aG9kc2ApO2lmKHRoaXMuYmFja2VuZEluc3RhbmNlPT1udWxsKXtjb25zdHtuYW1lOmFhLGFzeW5jSW5pdDp4YX09dGhpcy5pbml0aWFsaXplQmFja2VuZHNBbmRSZXR1cm5CZXN0KCk7aWYoeGEpdGhyb3cgbmV3IEVycm9yKGBUaGUgaGlnaGVzdCBwcmlvcml0eSBiYWNrZW5kICcke2FhfScgaGFzIG5vdCB5ZXQgYmVlbiBpbml0aWFsaXplZC4gTWFrZSBzdXJlIHRvIGF3YWl0IHRmLnJlYWR5KCkgb3IgYXdhaXQgdGYuc2V0QmFja2VuZCgpIGJlZm9yZSBjYWxsaW5nIG90aGVyIG1ldGhvZHNgKTt0aGlzLnNldEJhY2tlbmQoYWEpfXJldHVybiB0aGlzLmJhY2tlbmRJbnN0YW5jZX1iYWNrZW5kTmFtZXMoKXtyZXR1cm4gT2JqZWN0LmtleXModGhpcy5yZWdpc3RyeUZhY3RvcnkpfWZpbmRCYWNrZW5kKGFhKXtpZighKGFhIGluIHRoaXMucmVnaXN0cnkpKWlmKGFhIGluIHRoaXMucmVnaXN0cnlGYWN0b3J5KXtjb25zdHthc3luY0luaXQ6eGF9PXRoaXMuaW5pdGlhbGl6ZUJhY2tlbmQoYWEpO2lmKHhhKXJldHVybiBudWxsfWVsc2UgcmV0dXJuIG51bGw7cmV0dXJuIHRoaXMucmVnaXN0cnlbYWFdfWZpbmRCYWNrZW5kRmFjdG9yeShhYSl7cmV0dXJuIGFhIGluIHRoaXMucmVnaXN0cnlGYWN0b3J5P3RoaXMucmVnaXN0cnlGYWN0b3J5W2FhXS5mYWN0b3J5Om51bGx9cmVnaXN0ZXJCYWNrZW5kKGFhLHhhLGJhPTEpe3JldHVybiBhYSBpbiB0aGlzLnJlZ2lzdHJ5RmFjdG9yeT8od2FybihgJHthYX0gYmFja2VuZCB3YXMgYWxyZWFkeSByZWdpc3RlcmVkLiBSZXVzaW5nIGV4aXN0aW5nIGJhY2tlbmQgZmFjdG9yeS5gKSwhMSk6KHRoaXMucmVnaXN0cnlGYWN0b3J5W2FhXT17ZmFjdG9yeTp4YSxwcmlvcml0eTpiYX0sITApfWFzeW5jIHNldEJhY2tlbmQoYWEpe2lmKHRoaXMucmVnaXN0cnlGYWN0b3J5W2FhXT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYEJhY2tlbmQgbmFtZSAnJHthYX0nIG5vdCBmb3VuZCBpbiByZWdpc3RyeWApO2lmKHRoaXMuYmFja2VuZE5hbWU9YWEsdGhpcy5yZWdpc3RyeVthYV09PW51bGwpe3RoaXMuYmFja2VuZEluc3RhbmNlPW51bGw7Y29uc3R7c3VjY2Vzczp4YSxhc3luY0luaXQ6YmF9PXRoaXMuaW5pdGlhbGl6ZUJhY2tlbmQoYWEpO2lmKCEoYmE/YXdhaXQgeGE6eGEpKXJldHVybiExfXJldHVybiB0aGlzLmJhY2tlbmRJbnN0YW5jZT10aGlzLnJlZ2lzdHJ5W2FhXSx0aGlzLnNldHVwUmVnaXN0ZXJlZEtlcm5lbHMoKSx0aGlzLnByb2ZpbGVyPW5ldyBQcm9maWxlcih0aGlzLmJhY2tlbmRJbnN0YW5jZSksITB9c2V0dXBSZWdpc3RlcmVkS2VybmVscygpe2dldEtlcm5lbHNGb3JCYWNrZW5kKHRoaXMuYmFja2VuZE5hbWUpLmZvckVhY2goeGE9Pnt4YS5zZXR1cEZ1bmMhPW51bGwmJnhhLnNldHVwRnVuYyh0aGlzLmJhY2tlbmRJbnN0YW5jZSl9KX1kaXNwb3NlUmVnaXN0ZXJlZEtlcm5lbHMoYWEpe2dldEtlcm5lbHNGb3JCYWNrZW5kKGFhKS5mb3JFYWNoKGJhPT57YmEuZGlzcG9zZUZ1bmMhPW51bGwmJmJhLmRpc3Bvc2VGdW5jKHRoaXMucmVnaXN0cnlbYWFdKX0pfWluaXRpYWxpemVCYWNrZW5kKGFhKXtjb25zdCB4YT10aGlzLnJlZ2lzdHJ5RmFjdG9yeVthYV07aWYoeGE9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgaW5pdGlhbGl6ZSBiYWNrZW5kICR7YWF9LCBubyByZWdpc3RyYXRpb24gZm91bmQuYCk7dHJ5e2NvbnN0IGJhPXhhLmZhY3RvcnkoKTtpZihiYSYmIShiYSBpbnN0YW5jZW9mIEtlcm5lbEJhY2tlbmQpJiZ0eXBlb2YgYmEudGhlbj09ImZ1bmN0aW9uIil7Y29uc3QgU2E9Kyt0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdElkLFRhPWJhLnRoZW4od2E9PlNhPHRoaXMucGVuZGluZ0JhY2tlbmRJbml0SWQ/ITE6KHRoaXMucmVnaXN0cnlbYWFdPXdhLHRoaXMucGVuZGluZ0JhY2tlbmRJbml0PW51bGwsITApKS5jYXRjaCh3YT0+KFNhPHRoaXMucGVuZGluZ0JhY2tlbmRJbml0SWR8fCh0aGlzLnBlbmRpbmdCYWNrZW5kSW5pdD1udWxsLHdhcm4oYEluaXRpYWxpemF0aW9uIG9mIGJhY2tlbmQgJHthYX0gZmFpbGVkYCksd2Fybih3YS5zdGFja3x8d2EubWVzc2FnZSkpLCExKSk7cmV0dXJuIHRoaXMucGVuZGluZ0JhY2tlbmRJbml0PVRhLHtzdWNjZXNzOlRhLGFzeW5jSW5pdDohMH19ZWxzZSByZXR1cm4gdGhpcy5yZWdpc3RyeVthYV09YmEse3N1Y2Nlc3M6ITAsYXN5bmNJbml0OiExfX1jYXRjaChiYSl7cmV0dXJuIHdhcm4oYEluaXRpYWxpemF0aW9uIG9mIGJhY2tlbmQgJHthYX0gZmFpbGVkYCksd2FybihiYS5zdGFja3x8YmEubWVzc2FnZSkse3N1Y2Nlc3M6ITEsYXN5bmNJbml0OiExfX19cmVtb3ZlQmFja2VuZChhYSl7aWYoIShhYSBpbiB0aGlzLnJlZ2lzdHJ5RmFjdG9yeSkpdGhyb3cgbmV3IEVycm9yKGAke2FhfSBiYWNrZW5kIG5vdCBmb3VuZCBpbiByZWdpc3RyeWApO3RoaXMuYmFja2VuZE5hbWU9PT1hYSYmdGhpcy5wZW5kaW5nQmFja2VuZEluaXQhPW51bGwmJnRoaXMucGVuZGluZ0JhY2tlbmRJbml0SWQrKyxhYSBpbiB0aGlzLnJlZ2lzdHJ5JiYodGhpcy5kaXNwb3NlUmVnaXN0ZXJlZEtlcm5lbHMoYWEpLHRoaXMucmVnaXN0cnlbYWFdLmRpc3Bvc2UoKSxkZWxldGUgdGhpcy5yZWdpc3RyeVthYV0pLGRlbGV0ZSB0aGlzLnJlZ2lzdHJ5RmFjdG9yeVthYV0sdGhpcy5iYWNrZW5kTmFtZT09PWFhJiYodGhpcy5wZW5kaW5nQmFja2VuZEluaXQ9bnVsbCx0aGlzLmJhY2tlbmROYW1lPW51bGwsdGhpcy5iYWNrZW5kSW5zdGFuY2U9bnVsbCl9Z2V0U29ydGVkQmFja2VuZHMoKXtpZihPYmplY3Qua2V5cyh0aGlzLnJlZ2lzdHJ5RmFjdG9yeSkubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoIk5vIGJhY2tlbmQgZm91bmQgaW4gcmVnaXN0cnkuIik7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMucmVnaXN0cnlGYWN0b3J5KS5zb3J0KChhYSx4YSk9PnRoaXMucmVnaXN0cnlGYWN0b3J5W3hhXS5wcmlvcml0eS10aGlzLnJlZ2lzdHJ5RmFjdG9yeVthYV0ucHJpb3JpdHkpfWluaXRpYWxpemVCYWNrZW5kc0FuZFJldHVybkJlc3QoKXtjb25zdCBhYT10aGlzLmdldFNvcnRlZEJhY2tlbmRzKCk7Zm9yKGxldCB4YT0wO3hhPGFhLmxlbmd0aDt4YSsrKXtjb25zdCBiYT1hYVt4YV0se3N1Y2Nlc3M6U2EsYXN5bmNJbml0OlRhfT10aGlzLmluaXRpYWxpemVCYWNrZW5kKGJhKTtpZihUYXx8U2EpcmV0dXJue25hbWU6YmEsYXN5bmNJbml0OlRhfX10aHJvdyBuZXcgRXJyb3IoIkNvdWxkIG5vdCBpbml0aWFsaXplIGFueSBiYWNrZW5kcywgYWxsIGJhY2tlbmQgaW5pdGlhbGl6YXRpb25zIGZhaWxlZC4iKX1tb3ZlRGF0YShhYSx4YSl7Y29uc3QgYmE9dGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmdldCh4YSksU2E9YmEuYmFja2VuZCxUYT10aGlzLnJlYWRTeW5jKHhhKSx3YT1TYS5yZWZDb3VudCh4YSk7U2EuZGlzcG9zZURhdGEoeGEsITApLGJhLmJhY2tlbmQ9YWEsYWEubW92ZSh4YSxUYSxiYS5zaGFwZSxiYS5kdHlwZSx3YSksdGhpcy5zaG91bGRDaGVja0Zvck1lbUxlYWtzKCkmJnRoaXMuc3RhdGUubnVtRGF0YU1vdmVzU3RhY2tbdGhpcy5zdGF0ZS5udW1EYXRhTW92ZXNTdGFjay5sZW5ndGgtMV0rK310aWR5KGFhLHhhKXtsZXQgYmE9bnVsbDtpZih4YT09bnVsbCl7aWYodHlwZW9mIGFhIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiUGxlYXNlIHByb3ZpZGUgYSBmdW5jdGlvbiB0byB0aWR5KCkiKTt4YT1hYX1lbHNle2lmKHR5cGVvZiBhYSE9InN0cmluZyImJiEoYWEgaW5zdGFuY2VvZiBTdHJpbmcpKXRocm93IG5ldyBFcnJvcigiV2hlbiBjYWxsaW5nIHdpdGggdHdvIGFyZ3VtZW50cywgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRpZHkoKSBtdXN0IGJlIGEgc3RyaW5nIik7aWYodHlwZW9mIHhhIT0iZnVuY3Rpb24iKXRocm93IG5ldyBFcnJvcigiV2hlbiBjYWxsaW5nIHdpdGggdHdvIGFyZ3VtZW50cywgdGhlIDJuZCBhcmd1bWVudCB0byB0aWR5KCkgbXVzdCBiZSBhIGZ1bmN0aW9uIik7YmE9YWF9bGV0IFNhO3JldHVybiB0aGlzLnNjb3BlZFJ1bigoKT0+dGhpcy5zdGFydFNjb3BlKGJhKSwoKT0+dGhpcy5lbmRTY29wZShTYSksKCk9PihTYT14YSgpLFNhIGluc3RhbmNlb2YgUHJvbWlzZSYmY29uc29sZS5lcnJvcigiQ2Fubm90IHJldHVybiBhIFByb21pc2UgaW5zaWRlIG9mIHRpZHkuIiksU2EpKX1zY29wZWRSdW4oYWEseGEsYmEpe2FhKCk7dHJ5e2NvbnN0IFNhPWJhKCk7cmV0dXJuIHhhKCksU2F9Y2F0Y2goU2Epe3Rocm93IHhhKCksU2F9fW5leHRUZW5zb3JJZCgpe3JldHVybiBFbmdpbmUubmV4dFRlbnNvcklkKyt9bmV4dFZhcmlhYmxlSWQoKXtyZXR1cm4gRW5naW5lLm5leHRWYXJpYWJsZUlkKyt9Y2xvbmUoYWEpe2NvbnN0IHhhPUVOR0lORS5ydW5LZXJuZWwoSWRlbnRpdHkse3g6YWF9KSxiYT17eDphYX0sU2E9d2E9Pih7eDooKT0+e2NvbnN0IEVhPSJmbG9hdDMyIixrYT17eDp3YX0sQWE9e2R0eXBlOkVhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChDYXN0LGthLEFhKX19KSxUYT1bXTtyZXR1cm4gdGhpcy5hZGRUYXBlTm9kZSh0aGlzLnN0YXRlLmFjdGl2ZVNjb3BlLm5hbWUsYmEsW3hhXSxTYSxUYSx7fSkseGF9cnVuS2VybmVsKGFhLHhhLGJhKXtpZih0aGlzLmJhY2tlbmROYW1lPT1udWxsJiZ0aGlzLmJhY2tlbmQsIShnZXRLZXJuZWwoYWEsdGhpcy5iYWNrZW5kTmFtZSkhPW51bGwpKXRocm93IG5ldyBFcnJvcihgS2VybmVsICcke2FhfScgbm90IHJlZ2lzdGVyZWQgZm9yIGJhY2tlbmQgJyR7dGhpcy5iYWNrZW5kTmFtZX0nYCk7cmV0dXJuIHRoaXMucnVuS2VybmVsRnVuYyh7a2VybmVsTmFtZTphYSxpbnB1dHM6eGEsYXR0cnM6YmF9KX1zaG91bGRDaGVja0Zvck1lbUxlYWtzKCl7cmV0dXJuIHRoaXMuRU5WLmdldEJvb2woIklTX1RFU1QiKX1jaGVja0tlcm5lbEZvck1lbUxlYWsoYWEseGEsYmEpe2NvbnN0IFNhPXRoaXMuYmFja2VuZC5udW1EYXRhSWRzKCk7bGV0IFRhPTA7YmEuZm9yRWFjaChrYT0+e1RhKz1rYS5kdHlwZT09PSJjb21wbGV4NjQiPzM6MX0pO2NvbnN0IHdhPXRoaXMuc3RhdGUubnVtRGF0YU1vdmVzU3RhY2tbdGhpcy5zdGF0ZS5udW1EYXRhTW92ZXNTdGFjay5sZW5ndGgtMV0sRWE9U2EteGEtVGEtd2E7aWYoRWE+MCl0aHJvdyBuZXcgRXJyb3IoYEJhY2tlbmQgJyR7dGhpcy5iYWNrZW5kTmFtZX0nIGhhcyBhbiBpbnRlcm5hbCBtZW1vcnkgbGVhayAoJHtFYX0gZGF0YSBpZHMpIGFmdGVyIHJ1bm5pbmcgJyR7YWF9J2ApfXJ1bktlcm5lbEZ1bmMoYWEpe2xldCB4YSxiYT1bXTtjb25zdCBTYT10aGlzLmlzVGFwZU9uKCksVGE9dGhpcy5zdGF0ZS5udW1CeXRlcyx3YT10aGlzLnN0YXRlLm51bVRlbnNvcnM7dGhpcy5zaG91bGRDaGVja0Zvck1lbUxlYWtzKCkmJnRoaXMuc3RhdGUubnVtRGF0YU1vdmVzU3RhY2sucHVzaCgwKTtsZXQgRWE7dGhpcy5iYWNrZW5kTmFtZT09bnVsbCYmdGhpcy5iYWNrZW5kO2xldCBrYTtjb25zdCBBYT1pc1JlZ2lzdGVyZWRLZXJuZWxJbnZvY2F0aW9uKGFhKT9hYS5rZXJuZWxOYW1lOnRoaXMuc3RhdGUuYWN0aXZlU2NvcGUhPW51bGw/dGhpcy5zdGF0ZS5hY3RpdmVTY29wZS5uYW1lOiIiO2lmKGlzUmVnaXN0ZXJlZEtlcm5lbEludm9jYXRpb24oYWEpKXtjb25zdHtrZXJuZWxOYW1lOm5sLGlucHV0czpzbCxhdHRyczpybH09YWE7dGhpcy5iYWNrZW5kTmFtZT09bnVsbCYmdGhpcy5iYWNrZW5kO2NvbnN0IG9sPWdldEtlcm5lbChubCx0aGlzLmJhY2tlbmROYW1lKTthc3NlcnQob2whPW51bGwsKCk9PmBDYW5ub3QgZmluZCByZWdpc3RlcmVkIGtlcm5lbCAnJHtubH0nIGZvciBiYWNrZW5kICcke3RoaXMuYmFja2VuZE5hbWV9J2ApLEVhPSgpPT57Y29uc3QgYWw9dGhpcy5iYWNrZW5kLm51bURhdGFJZHMoKTtrYT1vbC5rZXJuZWxGdW5jKHtpbnB1dHM6c2wsYXR0cnM6cmwsYmFja2VuZDp0aGlzLmJhY2tlbmR9KTtjb25zdCBsbD1BcnJheS5pc0FycmF5KGthKT9rYTpba2FdO3RoaXMuc2hvdWxkQ2hlY2tGb3JNZW1MZWFrcygpJiZ0aGlzLmNoZWNrS2VybmVsRm9yTWVtTGVhayhubCxhbCxsbCk7Y29uc3QgaWw9bGwubWFwKGNsPT5jbC5yYW5rIT1udWxsP2NsOnRoaXMubWFrZVRlbnNvckZyb21UZW5zb3JJbmZvKGNsKSk7aWYoU2Epe2NvbnN0IGNsPXRoaXMuZ2V0VGVuc29yc0ZvckdyYWRpZW50KG5sLHNsLGlsKTtiYT10aGlzLnNhdmVUZW5zb3JzRm9yQmFja3dhcmRNb2RlKGNsKX1yZXR1cm4gaWx9fWVsc2V7Y29uc3R7Zm9yd2FyZEZ1bmM6bmx9PWFhLHNsPXJsPT57U2EmJihiYT1ybC5tYXAob2w9PnRoaXMua2VlcCh0aGlzLmNsb25lKG9sKSkpKX07RWE9KCk9Pntjb25zdCBybD10aGlzLmJhY2tlbmQubnVtRGF0YUlkcygpO2thPXRoaXMudGlkeSgoKT0+bmwodGhpcy5iYWNrZW5kLHNsKSk7Y29uc3Qgb2w9QXJyYXkuaXNBcnJheShrYSk/a2E6W2thXTtyZXR1cm4gdGhpcy5zaG91bGRDaGVja0Zvck1lbUxlYWtzKCkmJnRoaXMuY2hlY2tLZXJuZWxGb3JNZW1MZWFrKEFhLHJsLG9sKSxvbH19Y29uc3R7aW5wdXRzOkZhLGF0dHJzOkxhfT1hYSxlbD1pc1JlZ2lzdGVyZWRLZXJuZWxJbnZvY2F0aW9uKGFhKT9udWxsOmFhLmJhY2t3YXJkc0Z1bmM7bGV0IHRsO3JldHVybiB0aGlzLnNjb3BlZFJ1bigoKT0+dGhpcy5zdGF0ZS5rZXJuZWxEZXB0aCsrLCgpPT50aGlzLnN0YXRlLmtlcm5lbERlcHRoLS0sKCk9PnshdGhpcy5FTlYuZ2V0Qm9vbCgiREVCVUciKSYmIXRoaXMuc3RhdGUucHJvZmlsaW5nP3hhPUVhKCk6KHRsPXRoaXMucHJvZmlsZXIucHJvZmlsZUtlcm5lbChBYSxGYSwoKT0+RWEoKSksdGhpcy5FTlYuZ2V0Qm9vbCgiREVCVUciKSYmdGhpcy5wcm9maWxlci5sb2dLZXJuZWxQcm9maWxlKHRsKSx4YT10bC5vdXRwdXRzKX0pLFNhJiZ0aGlzLmFkZFRhcGVOb2RlKEFhLEZhLHhhLGVsLGJhLExhKSx0aGlzLnN0YXRlLnByb2ZpbGluZyYmdGhpcy5zdGF0ZS5hY3RpdmVQcm9maWxlLmtlcm5lbHMucHVzaCh7bmFtZTpBYSxieXRlc0FkZGVkOnRoaXMuc3RhdGUubnVtQnl0ZXMtVGEsdG90YWxCeXRlc1NuYXBzaG90OnRoaXMuc3RhdGUubnVtQnl0ZXMsdGVuc29yc0FkZGVkOnRoaXMuc3RhdGUubnVtVGVuc29ycy13YSx0b3RhbFRlbnNvcnNTbmFwc2hvdDp0aGlzLnN0YXRlLm51bVRlbnNvcnMsaW5wdXRTaGFwZXM6T2JqZWN0LmtleXMoRmEpLm1hcChubD0+RmFbbmxdIT1udWxsP0ZhW25sXS5zaGFwZTpudWxsKSxvdXRwdXRTaGFwZXM6eGEubWFwKG5sPT5ubC5zaGFwZSksa2VybmVsVGltZU1zOnRsLnRpbWVNcyxleHRyYUluZm86dGwuZXh0cmFJbmZvfSksQXJyYXkuaXNBcnJheShrYSk/eGE6eGFbMF19c2F2ZVRlbnNvcnNGb3JCYWNrd2FyZE1vZGUoYWEpe3JldHVybiBhYS5tYXAoYmE9PnRoaXMua2VlcCh0aGlzLmNsb25lKGJhKSkpfWdldFRlbnNvcnNGb3JHcmFkaWVudChhYSx4YSxiYSl7Y29uc3QgU2E9Z2V0R3JhZGllbnQoYWEpO2lmKFNhIT1udWxsKXtjb25zdCBUYT1TYS5pbnB1dHNUb1NhdmV8fFtdLHdhPVNhLm91dHB1dHNUb1NhdmV8fFtdO2xldCBFYTtTYS5zYXZlQWxsSW5wdXRzPyhhc3NlcnQoQXJyYXkuaXNBcnJheSh4YSksKCk9PiJzYXZlQWxsSW5wdXRzIGlzIHRydWUsIGV4cGVjdGVkIGlucHV0cyB0byBiZSBhbiBhcnJheS4iKSxFYT1PYmplY3Qua2V5cyh4YSkubWFwKEFhPT54YVtBYV0pKTpFYT1UYS5tYXAoQWE9PnhhW0FhXSk7Y29uc3Qga2E9YmEuZmlsdGVyKChBYSxGYSk9PndhW0ZhXSk7cmV0dXJuIEVhLmNvbmNhdChrYSl9cmV0dXJuW119bWFrZVRlbnNvcihhYSx4YSxiYSxTYSl7aWYoYWE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJWYWx1ZXMgcGFzc2VkIHRvIGVuZ2luZS5tYWtlVGVuc29yKCkgYXJlIG51bGwiKTtiYT1iYXx8ImZsb2F0MzIiLFNhPVNhfHx0aGlzLmJhY2tlbmQ7bGV0IFRhPWFhO2JhPT09InN0cmluZyImJmlzU3RyaW5nKGFhWzBdKSYmKFRhPWFhLm1hcChrYT0+ZW5jb2RlU3RyaW5nKGthKSkpO2NvbnN0IHdhPVNhLndyaXRlKFRhLHhhLGJhKSxFYT1uZXcgVGVuc29yKHhhLGJhLHdhLHRoaXMubmV4dFRlbnNvcklkKCkpO2lmKHRoaXMudHJhY2tUZW5zb3IoRWEsU2EpLGJhPT09InN0cmluZyIpe2NvbnN0IGthPXRoaXMuc3RhdGUudGVuc29ySW5mby5nZXQod2EpLEFhPWJ5dGVzRnJvbVN0cmluZ0FycmF5KFRhKTt0aGlzLnN0YXRlLm51bUJ5dGVzKz1BYS1rYS5ieXRlcyxrYS5ieXRlcz1BYX1yZXR1cm4gRWF9bWFrZVRlbnNvckZyb21EYXRhSWQoYWEseGEsYmEsU2Epe2JhPWJhfHwiZmxvYXQzMiI7Y29uc3QgVGE9e2RhdGFJZDphYSxzaGFwZTp4YSxkdHlwZTpiYX07cmV0dXJuIHRoaXMubWFrZVRlbnNvckZyb21UZW5zb3JJbmZvKFRhLFNhKX1tYWtlVGVuc29yRnJvbVRlbnNvckluZm8oYWEseGEpe2NvbnN0e2RhdGFJZDpiYSxzaGFwZTpTYSxkdHlwZTpUYX09YWEsd2E9bmV3IFRlbnNvcihTYSxUYSxiYSx0aGlzLm5leHRUZW5zb3JJZCgpKTtyZXR1cm4gdGhpcy50cmFja1RlbnNvcih3YSx4YSksd2F9bWFrZVZhcmlhYmxlKGFhLHhhPSEwLGJhLFNhKXtiYT1iYXx8dGhpcy5uZXh0VmFyaWFibGVJZCgpLnRvU3RyaW5nKCksU2EhPW51bGwmJlNhIT09YWEuZHR5cGUmJihhYT1hYS5jYXN0KFNhKSk7Y29uc3QgVGE9bmV3IFZhcmlhYmxlKGFhLHhhLGJhLHRoaXMubmV4dFRlbnNvcklkKCkpO2lmKHRoaXMuc3RhdGUucmVnaXN0ZXJlZFZhcmlhYmxlc1tUYS5uYW1lXSE9bnVsbCl0aHJvdyBuZXcgRXJyb3IoYFZhcmlhYmxlIHdpdGggbmFtZSAke1RhLm5hbWV9IHdhcyBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtyZXR1cm4gdGhpcy5zdGF0ZS5yZWdpc3RlcmVkVmFyaWFibGVzW1RhLm5hbWVdPVRhLHRoaXMuaW5jUmVmKFRhLHRoaXMuYmFja2VuZCksVGF9dHJhY2tUZW5zb3IoYWEseGEpe3RoaXMuc3RhdGUubnVtVGVuc29ycysrLGFhLmR0eXBlPT09InN0cmluZyImJnRoaXMuc3RhdGUubnVtU3RyaW5nVGVuc29ycysrO2xldCBiYT0wO2FhLmR0eXBlIT09ImNvbXBsZXg2NCImJmFhLmR0eXBlIT09InN0cmluZyImJihiYT1hYS5zaXplKmJ5dGVzUGVyRWxlbWVudChhYS5kdHlwZSkpLHRoaXMuc3RhdGUubnVtQnl0ZXMrPWJhLHRoaXMuc3RhdGUudGVuc29ySW5mby5oYXMoYWEuZGF0YUlkKXx8KHRoaXMuc3RhdGUubnVtRGF0YUJ1ZmZlcnMrKyx0aGlzLnN0YXRlLnRlbnNvckluZm8uc2V0KGFhLmRhdGFJZCx7YmFja2VuZDp4YXx8dGhpcy5iYWNrZW5kLGR0eXBlOmFhLmR0eXBlLHNoYXBlOmFhLnNoYXBlLGJ5dGVzOmJhfSkpLGFhIGluc3RhbmNlb2YgVmFyaWFibGV8fHRoaXMudHJhY2soYWEpfWluY1JlZihhYSx4YSl7dGhpcy50cmFja1RlbnNvcihhYSx4YSksdGhpcy5iYWNrZW5kLmluY1JlZihhYS5kYXRhSWQpfXJlbW92ZURhdGFJZChhYSx4YSl7dGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmhhcyhhYSkmJnRoaXMuc3RhdGUudGVuc29ySW5mby5nZXQoYWEpLmJhY2tlbmQ9PT14YSYmKHRoaXMuc3RhdGUudGVuc29ySW5mby5kZWxldGUoYWEpLHRoaXMuc3RhdGUubnVtRGF0YUJ1ZmZlcnMtLSl9ZGlzcG9zZVRlbnNvcihhYSl7aWYoIXRoaXMuc3RhdGUudGVuc29ySW5mby5oYXMoYWEuZGF0YUlkKSlyZXR1cm47Y29uc3QgeGE9dGhpcy5zdGF0ZS50ZW5zb3JJbmZvLmdldChhYS5kYXRhSWQpO2lmKHRoaXMuc3RhdGUubnVtVGVuc29ycy0tLGFhLmR0eXBlPT09InN0cmluZyImJih0aGlzLnN0YXRlLm51bVN0cmluZ1RlbnNvcnMtLSx0aGlzLnN0YXRlLm51bUJ5dGVzLT14YS5ieXRlcyksYWEuZHR5cGUhPT0iY29tcGxleDY0IiYmYWEuZHR5cGUhPT0ic3RyaW5nIil7Y29uc3QgYmE9YWEuc2l6ZSpieXRlc1BlckVsZW1lbnQoYWEuZHR5cGUpO3RoaXMuc3RhdGUubnVtQnl0ZXMtPWJhfXhhLmJhY2tlbmQuZGlzcG9zZURhdGEoYWEuZGF0YUlkKSYmdGhpcy5yZW1vdmVEYXRhSWQoYWEuZGF0YUlkLHhhLmJhY2tlbmQpfWRpc3Bvc2VWYXJpYWJsZXMoKXtmb3IoY29uc3QgYWEgaW4gdGhpcy5zdGF0ZS5yZWdpc3RlcmVkVmFyaWFibGVzKXtjb25zdCB4YT10aGlzLnN0YXRlLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYWFdO3RoaXMuZGlzcG9zZVZhcmlhYmxlKHhhKX19ZGlzcG9zZVZhcmlhYmxlKGFhKXt0aGlzLmRpc3Bvc2VUZW5zb3IoYWEpLHRoaXMuc3RhdGUucmVnaXN0ZXJlZFZhcmlhYmxlc1thYS5uYW1lXSE9bnVsbCYmZGVsZXRlIHRoaXMuc3RhdGUucmVnaXN0ZXJlZFZhcmlhYmxlc1thYS5uYW1lXX1tZW1vcnkoKXtjb25zdCBhYT10aGlzLmJhY2tlbmQubWVtb3J5KCk7cmV0dXJuIGFhLm51bVRlbnNvcnM9dGhpcy5zdGF0ZS5udW1UZW5zb3JzLGFhLm51bURhdGFCdWZmZXJzPXRoaXMuc3RhdGUubnVtRGF0YUJ1ZmZlcnMsYWEubnVtQnl0ZXM9dGhpcy5zdGF0ZS5udW1CeXRlcyx0aGlzLnN0YXRlLm51bVN0cmluZ1RlbnNvcnM+MCYmKGFhLnVucmVsaWFibGU9ITAsYWEucmVhc29ucz09bnVsbCYmKGFhLnJlYXNvbnM9W10pLGFhLnJlYXNvbnMucHVzaCgiTWVtb3J5IHVzYWdlIGJ5IHN0cmluZyB0ZW5zb3JzIGlzIGFwcHJveGltYXRlICgyIGJ5dGVzIHBlciBjaGFyYWN0ZXIpIikpLGFhfWFzeW5jIHByb2ZpbGUoYWEpe3RoaXMuc3RhdGUucHJvZmlsaW5nPSEwO2NvbnN0IHhhPXRoaXMuc3RhdGUubnVtQnl0ZXMsYmE9dGhpcy5zdGF0ZS5udW1UZW5zb3JzO3RoaXMuc3RhdGUuYWN0aXZlUHJvZmlsZS5rZXJuZWxzPVtdLHRoaXMuc3RhdGUuYWN0aXZlUHJvZmlsZS5yZXN1bHQ9YXdhaXQgYWEoKSx0aGlzLnN0YXRlLnByb2ZpbGluZz0hMSx0aGlzLnN0YXRlLmFjdGl2ZVByb2ZpbGUucGVha0J5dGVzPU1hdGgubWF4KC4uLnRoaXMuc3RhdGUuYWN0aXZlUHJvZmlsZS5rZXJuZWxzLm1hcChTYT0+U2EudG90YWxCeXRlc1NuYXBzaG90KSksdGhpcy5zdGF0ZS5hY3RpdmVQcm9maWxlLm5ld0J5dGVzPXRoaXMuc3RhdGUubnVtQnl0ZXMteGEsdGhpcy5zdGF0ZS5hY3RpdmVQcm9maWxlLm5ld1RlbnNvcnM9dGhpcy5zdGF0ZS5udW1UZW5zb3JzLWJhO2Zvcihjb25zdCBTYSBvZiB0aGlzLnN0YXRlLmFjdGl2ZVByb2ZpbGUua2VybmVscylTYS5rZXJuZWxUaW1lTXM9YXdhaXQgU2Eua2VybmVsVGltZU1zLFNhLmV4dHJhSW5mbz1hd2FpdCBTYS5leHRyYUluZm87cmV0dXJuIHRoaXMuc3RhdGUuYWN0aXZlUHJvZmlsZX1pc1RhcGVPbigpe3JldHVybiB0aGlzLnN0YXRlLmdyYWRpZW50RGVwdGg+MCYmdGhpcy5zdGF0ZS5rZXJuZWxEZXB0aD09PTB9YWRkVGFwZU5vZGUoYWEseGEsYmEsU2EsVGEsd2Epe2NvbnN0IEVhPXtpZDp0aGlzLnN0YXRlLm5leHRUYXBlTm9kZUlkKyssa2VybmVsTmFtZTphYSxpbnB1dHM6eGEsb3V0cHV0czpiYSxzYXZlZDpUYX0sa2E9Z2V0R3JhZGllbnQoYWEpO2thIT1udWxsJiYoU2E9a2EuZ3JhZEZ1bmMpLFNhIT1udWxsJiYoRWEuZ3JhZGllbnQ9QWE9PihBYT1BYS5tYXAoKEZhLExhKT0+e2lmKEZhPT1udWxsKXtjb25zdCBlbD1iYVtMYV0sdGw9bWFrZVplcm9zVHlwZWRBcnJheShlbC5zaXplLGVsLmR0eXBlKTtyZXR1cm4gdGhpcy5tYWtlVGVuc29yKHRsLGVsLnNoYXBlLGVsLmR0eXBlKX1yZXR1cm4gRmF9KSxTYShBYS5sZW5ndGg+MT9BYTpBYVswXSxUYSx3YSkpKSx0aGlzLnN0YXRlLmFjdGl2ZVRhcGUucHVzaChFYSl9a2VlcChhYSl7cmV0dXJuIGFhLmtlcHQ9ITAsYWF9c3RhcnRUYXBlKCl7dGhpcy5zdGF0ZS5ncmFkaWVudERlcHRoPT09MCYmKHRoaXMuc3RhdGUuYWN0aXZlVGFwZT1bXSksdGhpcy5zdGF0ZS5ncmFkaWVudERlcHRoKyt9ZW5kVGFwZSgpe3RoaXMuc3RhdGUuZ3JhZGllbnREZXB0aC0tfXN0YXJ0U2NvcGUoYWEpe2NvbnN0IHhhPXt0cmFjazpbXSxuYW1lOiJ1bm5hbWVkIHNjb3BlIixpZDp0aGlzLnN0YXRlLm5leHRTY29wZUlkKyt9O2FhJiYoeGEubmFtZT1hYSksdGhpcy5zdGF0ZS5zY29wZVN0YWNrLnB1c2goeGEpLHRoaXMuc3RhdGUuYWN0aXZlU2NvcGU9eGF9ZW5kU2NvcGUoYWEpe2NvbnN0IHhhPWdldFRlbnNvcnNJbkNvbnRhaW5lcihhYSksYmE9bmV3IFNldCh4YS5tYXAoVGE9PlRhLmlkKSk7Zm9yKGxldCBUYT0wO1RhPHRoaXMuc3RhdGUuYWN0aXZlU2NvcGUudHJhY2subGVuZ3RoO1RhKyspe2NvbnN0IHdhPXRoaXMuc3RhdGUuYWN0aXZlU2NvcGUudHJhY2tbVGFdOyF3YS5rZXB0JiYhYmEuaGFzKHdhLmlkKSYmd2EuZGlzcG9zZSgpfWNvbnN0IFNhPXRoaXMuc3RhdGUuc2NvcGVTdGFjay5wb3AoKTt0aGlzLnN0YXRlLmFjdGl2ZVNjb3BlPXRoaXMuc3RhdGUuc2NvcGVTdGFjay5sZW5ndGg9PT0wP251bGw6dGhpcy5zdGF0ZS5zY29wZVN0YWNrW3RoaXMuc3RhdGUuc2NvcGVTdGFjay5sZW5ndGgtMV0seGEuZm9yRWFjaChUYT0+eyFUYS5rZXB0JiZUYS5zY29wZUlkPT09U2EuaWQmJnRoaXMudHJhY2soVGEpfSl9Z3JhZGllbnRzKGFhLHhhLGJhLFNhPSExKXtpZihhc3NlcnQoeGEubGVuZ3RoPjAsKCk9PiJncmFkaWVudHMoKSByZWNlaXZlZCBhbiBlbXB0eSBsaXN0IG9mIHhzLiIpLGJhIT1udWxsJiZiYS5kdHlwZSE9PSJmbG9hdDMyIil0aHJvdyBuZXcgRXJyb3IoYGR5IG11c3QgaGF2ZSAnZmxvYXQzMicgZHR5cGUsIGJ1dCBoYXMgJyR7YmEuZHR5cGV9J2ApO2NvbnN0IFRhPXRoaXMuc2NvcGVkUnVuKCgpPT50aGlzLnN0YXJ0VGFwZSgpLCgpPT50aGlzLmVuZFRhcGUoKSwoKT0+dGhpcy50aWR5KCJmb3J3YXJkIixhYSkpO2Fzc2VydChUYSBpbnN0YW5jZW9mIFRlbnNvciwoKT0+IlRoZSByZXN1bHQgeSByZXR1cm5lZCBieSBmKCkgbXVzdCBiZSBhIHRlbnNvci4iKTtjb25zdCB3YT1nZXRGaWx0ZXJlZE5vZGVzWFRvWSh0aGlzLnN0YXRlLmFjdGl2ZVRhcGUseGEsVGEpO2lmKCFTYSYmd2EubGVuZ3RoPT09MCYmeGEubGVuZ3RoPjApdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgY29tcHV0ZSBncmFkaWVudCBvZiB5PWYoeCkgd2l0aCByZXNwZWN0IHRvIHguIE1ha2Ugc3VyZSB0aGF0IHRoZSBmIHlvdSBwYXNzZWQgZW5jbG9zZXMgYWxsIG9wZXJhdGlvbnMgdGhhdCBsZWFkIGZyb20geCB0byB5LiIpO3JldHVybiB0aGlzLnRpZHkoImJhY2t3YXJkIiwoKT0+e2NvbnN0IEVhPXt9O0VhW1RhLmlkXT1iYT8/b25lcyhUYS5zaGFwZSksYmFja3Byb3BhZ2F0ZUdyYWRpZW50cyhFYSx3YSxBYT0+dGhpcy50aWR5KEFhKSxhZGQkMSk7Y29uc3Qga2E9eGEubWFwKEFhPT5FYVtBYS5pZF0pO3JldHVybiB0aGlzLnN0YXRlLmdyYWRpZW50RGVwdGg9PT0wJiYodGhpcy5zdGF0ZS5hY3RpdmVUYXBlLmZvckVhY2goQWE9Pntmb3IoY29uc3QgRmEgb2YgQWEuc2F2ZWQpRmEuZGlzcG9zZSgpfSksdGhpcy5zdGF0ZS5hY3RpdmVUYXBlPW51bGwpLHt2YWx1ZTpUYSxncmFkczprYX19KX1jdXN0b21HcmFkKGFhKXtyZXR1cm4gYXNzZXJ0KGlzRnVuY3Rpb24oYWEpLCgpPT4iVGhlIGYgcGFzc2VkIGluIGN1c3RvbUdyYWQoZikgbXVzdCBiZSBhIGZ1bmN0aW9uLiIpLCguLi54YSk9Pnthc3NlcnQoeGEuZXZlcnkoRWE9PkVhIGluc3RhbmNlb2YgVGVuc29yKSwoKT0+IlRoZSBhcmdzIHBhc3NlZCBpbiBjdXN0b21HcmFkKGYpKHgxLCB4MiwuLi4pIG11c3QgYWxsIGJlIHRlbnNvcnMiKTtsZXQgYmE7Y29uc3QgU2E9e307eGEuZm9yRWFjaCgoRWEsa2EpPT57U2Fba2FdPUVhfSk7Y29uc3QgVGE9KEVhLGthKT0+KGJhPWFhKC4uLnhhLGthKSxhc3NlcnQoYmEudmFsdWUgaW5zdGFuY2VvZiBUZW5zb3IsKCk9PiJUaGUgZnVuY3Rpb24gZiBwYXNzZWQgaW4gY3VzdG9tR3JhZChmKSBtdXN0IHJldHVybiBhbiBvYmplY3Qgd2hlcmUgYG9iai52YWx1ZWAgaXMgYSB0ZW5zb3IiKSxhc3NlcnQoaXNGdW5jdGlvbihiYS5ncmFkRnVuYyksKCk9PiJUaGUgZnVuY3Rpb24gZiBwYXNzZWQgaW4gY3VzdG9tR3JhZChmKSBtdXN0IHJldHVybiBhbiBvYmplY3Qgd2hlcmUgYG9iai5ncmFkRnVuY2AgaXMgYSBmdW5jdGlvbi4iKSxiYS52YWx1ZSksd2E9KEVhLGthKT0+e2NvbnN0IEFhPWJhLmdyYWRGdW5jKEVhLGthKSxGYT1BcnJheS5pc0FycmF5KEFhKT9BYTpbQWFdO2Fzc2VydChGYS5sZW5ndGg9PT14YS5sZW5ndGgsKCk9PiJUaGUgZnVuY3Rpb24gZiBwYXNzZWQgaW4gY3VzdG9tR3JhZChmKSBtdXN0IHJldHVybiBhbiBvYmplY3Qgd2hlcmUgYG9iai5ncmFkRnVuY2AgaXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHNhbWUgbnVtYmVyIG9mIHRlbnNvcnMgYXMgaW5wdXRzIHBhc3NlZCB0byBmKC4uLikuIiksYXNzZXJ0KEZhLmV2ZXJ5KGVsPT5lbCBpbnN0YW5jZW9mIFRlbnNvciksKCk9PiJUaGUgZnVuY3Rpb24gZiBwYXNzZWQgaW4gY3VzdG9tR3JhZChmKSBtdXN0IHJldHVybiBhbiBvYmplY3Qgd2hlcmUgYG9iai5ncmFkRnVuY2AgaXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBsaXN0IG9mIG9ubHkgdGVuc29ycy4iKTtjb25zdCBMYT17fTtyZXR1cm4gRmEuZm9yRWFjaCgoZWwsdGwpPT57TGFbdGxdPSgpPT5lbH0pLExhfTtyZXR1cm4gdGhpcy5ydW5LZXJuZWxGdW5jKHtmb3J3YXJkRnVuYzpUYSxiYWNrd2FyZHNGdW5jOndhLGlucHV0czpTYX0pfX1yZWFkU3luYyhhYSl7cmV0dXJuIHRoaXMuc3RhdGUudGVuc29ySW5mby5nZXQoYWEpLmJhY2tlbmQucmVhZFN5bmMoYWEpfXJlYWQoYWEpe3JldHVybiB0aGlzLnN0YXRlLnRlbnNvckluZm8uZ2V0KGFhKS5iYWNrZW5kLnJlYWQoYWEpfXJlYWRUb0dQVShhYSx4YSl7cmV0dXJuIHRoaXMuc3RhdGUudGVuc29ySW5mby5nZXQoYWEpLmJhY2tlbmQucmVhZFRvR1BVKGFhLHhhKX1hc3luYyB0aW1lKGFhKXtjb25zdCB4YT1ub3coKSxiYT1hd2FpdCB0aGlzLmJhY2tlbmQudGltZShhYSk7cmV0dXJuIGJhLndhbGxNcz1ub3coKS14YSxiYX10cmFjayhhYSl7cmV0dXJuIHRoaXMuc3RhdGUuYWN0aXZlU2NvcGUhPW51bGwmJihhYS5zY29wZUlkPXRoaXMuc3RhdGUuYWN0aXZlU2NvcGUuaWQsdGhpcy5zdGF0ZS5hY3RpdmVTY29wZS50cmFjay5wdXNoKGFhKSksYWF9Z2V0IHJlZ2lzdGVyZWRWYXJpYWJsZXMoKXtyZXR1cm4gdGhpcy5zdGF0ZS5yZWdpc3RlcmVkVmFyaWFibGVzfXJlc2V0KCl7dGhpcy5wZW5kaW5nQmFja2VuZEluaXRJZCsrLHRoaXMuc3RhdGUuZGlzcG9zZSgpLHRoaXMuRU5WLnJlc2V0KCksdGhpcy5zdGF0ZT1uZXcgRW5naW5lU3RhdGU7Zm9yKGNvbnN0IGFhIGluIHRoaXMucmVnaXN0cnkpdGhpcy5kaXNwb3NlUmVnaXN0ZXJlZEtlcm5lbHMoYWEpLHRoaXMucmVnaXN0cnlbYWFdLmRpc3Bvc2UoKSxkZWxldGUgdGhpcy5yZWdpc3RyeVthYV07dGhpcy5iYWNrZW5kTmFtZT1udWxsLHRoaXMuYmFja2VuZEluc3RhbmNlPW51bGwsdGhpcy5wZW5kaW5nQmFja2VuZEluaXQ9bnVsbH19RW5naW5lLm5leHRUZW5zb3JJZD0wLEVuZ2luZS5uZXh0VmFyaWFibGVJZD0wO2Z1bmN0aW9uIG9uZXMoaGEpe2NvbnN0IGFhPW1ha2VPbmVzVHlwZWRBcnJheShzaXplRnJvbVNoYXBlKGhhKSwiZmxvYXQzMiIpO3JldHVybiBFTkdJTkUubWFrZVRlbnNvcihhYSxoYSwiZmxvYXQzMiIpfWZ1bmN0aW9uIGdldE9yTWFrZUVuZ2luZSgpe2NvbnN0IGhhPWdldEdsb2JhbE5hbWVzcGFjZSgpO2lmKGhhLl90ZmVuZ2luZT09bnVsbCl7Y29uc3QgYWE9bmV3IEVudmlyb25tZW50KGhhKTtoYS5fdGZlbmdpbmU9bmV3IEVuZ2luZShhYSl9cmV0dXJuIHNldEVudmlyb25tZW50R2xvYmFsKGhhLl90ZmVuZ2luZS5FTlYpLHNldFRlbnNvclRyYWNrZXIoKCk9PmhhLl90ZmVuZ2luZSksaGEuX3RmZW5naW5lfWNvbnN0IEVOR0lORT1nZXRPck1ha2VFbmdpbmUoKTtmdW5jdGlvbiBhZGQkMShoYSxhYSl7Y29uc3QgeGE9e2E6aGEsYjphYX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoQWRkLHhhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBfaXNOYXZpZ2F0b3JEZWZpbmVkKCl7cmV0dXJuIHR5cGVvZiBuYXZpZ2F0b3I8InUiJiZuYXZpZ2F0b3IhPW51bGx9ZnVuY3Rpb24gaXNNb2JpbGUoaGEpe2lmKGhhfHxfaXNOYXZpZ2F0b3JEZWZpbmVkKCkpe2lmKGhhfHwoaGE9bmF2aWdhdG9yKSxoYS5wcm9kdWN0PT09IlJlYWN0TmF0aXZlIilyZXR1cm4hMDtjb25zdCBhYT1oYS51c2VyQWdlbnR8fGhhLnZlbmRvcnx8KHR5cGVvZiB3aW5kb3c8InUiP3dpbmRvdy5vcGVyYToiIik7aWYoIWFhKXtjb25zdCB4YT1oYTtyZXR1cm4geGEudXNlckFnZW50RGF0YSYmeGEudXNlckFnZW50RGF0YS5tb2JpbGV9cmV0dXJuLyhhbmRyb2lkfGJiXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVwvfGJsYWNrYmVycnl8YmxhemVyfGNvbXBhbHxlbGFpbmV8ZmVubmVjfGhpcHRvcHxpZW1vYmlsZXxpcChob25lfG9kKXxpcmlzfGtpbmRsZXxsZ2UgfG1hZW1vfG1pZHB8bW1wfG1vYmlsZS4rZmlyZWZveHxuZXRmcm9udHxvcGVyYSBtKG9ifGluKWl8cGFsbSggb3MpP3xwaG9uZXxwKGl4aXxyZSlcL3xwbHVja2VyfHBvY2tldHxwc3B8c2VyaWVzKDR8NikwfHN5bWJpYW58dHJlb3x1cFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vL2kudGVzdChhYSl8fC8xMjA3fDYzMTB8NjU5MHwzZ3NvfDR0aHB8NTBbMS02XWl8Nzcwc3w4MDJzfGEgd2F8YWJhY3xhYyhlcnxvb3xzXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XC1tfHIgfHMgKXxhdmFufGJlKGNrfGxsfG5xKXxiaShsYnxyZCl8YmwoYWN8YXopfGJyKGV8dil3fGJ1bWJ8YndcLShufHUpfGM1NVwvfGNhcGl8Y2N3YXxjZG1cLXxjZWxsfGNodG18Y2xkY3xjbWRcLXxjbyhtcHxuZCl8Y3Jhd3xkYShpdHxsbHxuZyl8ZGJ0ZXxkY1wtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcLWQpfGVsKDQ5fGFpKXxlbShsMnx1bCl8ZXIoaWN8azApfGVzbDh8ZXooWzQtN10wfG9zfHdhfHplKXxmZXRjfGZseShcLXxfKXxnMSB1fGc1NjB8Z2VuZXxnZlwtNXxnXC1tb3xnbyhcLnd8b2QpfGdyKGFkfHVuKXxoYWllfGhjaXR8aGRcLShtfHB8dCl8aGVpXC18aGkocHR8dGEpfGhwKCBpfGlwKXxoc1wtY3xodChjKFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVwtKDIwfGdvfG1hKXxpMjMwfGlhYyggfFwtfFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFwvKXxrbG9ufGtwdCB8a3djXC18a3lvKGN8ayl8bGUobm98eGkpfGxnKCBnfFwvKGt8bHx1KXw1MHw1NHxcLVthLXddKXxsaWJ3fGx5bnh8bTFcLXd8bTNnYXxtNTBcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cLWNyfG1lKHJjfHJpKXxtaShvOHxvYXx0cyl8bW1lZnxtbygwMXwwMnxiaXxkZXxkb3x0KFwtfCB8b3x2KXx6eil8bXQoNTB8cDF8diApfG13YnB8bXl3YXxuMTBbMC0yXXxuMjBbMi0zXXxuMzAoMHwyKXxuNTAoMHwyfDUpfG43KDAoMHwxKXwxMCl8bmUoKGN8bSlcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XC0oWzEtOF18YykpfHBoaWx8cGlyZXxwbChheXx1Yyl8cG5cLTJ8cG8oY2t8cnR8c2UpfHByb3h8cHNpb3xwdFwtZ3xxYVwtYXxxYygwN3wxMnwyMXwzMnw2MHxcLVsyLTddfGlcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcL3xzYShnZXxtYXxtbXxtc3xueXx2YSl8c2MoMDF8aFwtfG9vfHBcLSl8c2RrXC98c2UoYyhcLXwwfDEpfDQ3fG1jfG5kfHJpKXxzZ2hcLXxzaGFyfHNpZShcLXxtKXxza1wtMHxzbCg0NXxpZCl8c20oYWx8YXJ8YjN8aXR8dDUpfHNvKGZ0fG55KXxzcCgwMXxoXC18dlwtfHYgKXxzeSgwMXxtYil8dDIoMTh8NTApfHQ2KDAwfDEwfDE4KXx0YShndHxsayl8dGNsXC18dGRnXC18dGVsKGl8bSl8dGltXC18dFwtbW98dG8ocGx8c2gpfHRzKDcwfG1cLXxtM3xtNSl8dHhcLTl8dXAoXC5ifGcxfHNpKXx1dHN0fHY0MDB8djc1MHx2ZXJpfHZpKHJnfHRlKXx2ayg0MHw1WzAtM118XC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFwtfCApfHdlYmN8d2hpdHx3aShnIHxuY3xudyl8d21sYnx3b251fHg3MDB8eWFzXC18eW91cnx6ZXRvfHp0ZVwtL2kudGVzdChhYS5zdWJzdHIoMCw0KSl9cmV0dXJuITF9ZnVuY3Rpb24gaXNCcm93c2VyKCl7cmV0dXJuIHR5cGVvZiB3aW5kb3c8InUiJiZ3aW5kb3cuZG9jdW1lbnQhPW51bGx8fHR5cGVvZiBXb3JrZXJHbG9iYWxTY29wZTwidSJ9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRU5WJDE9ZW52KCk7RU5WJDEucmVnaXN0ZXJGbGFnKCJERUJVRyIsKCk9PiExLGhhPT57aGEmJmNvbnNvbGUud2FybigiRGVidWdnaW5nIG1vZGUgaXMgT04uIFRoZSBvdXRwdXQgb2YgZXZlcnkgbWF0aCBjYWxsIHdpbGwgYmUgZG93bmxvYWRlZCB0byBDUFUgYW5kIGNoZWNrZWQgZm9yIE5hTnMuIFRoaXMgc2lnbmlmaWNhbnRseSBpbXBhY3RzIHBlcmZvcm1hbmNlLiIpfSksRU5WJDEucmVnaXN0ZXJGbGFnKCJJU19CUk9XU0VSIiwoKT0+aXNCcm93c2VyKCkpLEVOViQxLnJlZ2lzdGVyRmxhZygiSVNfTk9ERSIsKCk9PnR5cGVvZiBwcm9jZXNzPCJ1IiYmdHlwZW9mIHByb2Nlc3MudmVyc2lvbnM8InUiJiZ0eXBlb2YgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlPCJ1IiksRU5WJDEucmVnaXN0ZXJGbGFnKCJJU19DSFJPTUUiLCgpPT50eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yIT1udWxsJiZuYXZpZ2F0b3IudXNlckFnZW50IT1udWxsJiYvQ2hyb21lLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpJiYvR29vZ2xlIEluYy8udGVzdChuYXZpZ2F0b3IudmVuZG9yKSksRU5WJDEucmVnaXN0ZXJGbGFnKCJJU19TQUZBUkkiLCgpPT50eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yIT1udWxsJiZuYXZpZ2F0b3IudXNlckFnZW50IT1udWxsJiYvU2FmYXJpLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpJiYvQXBwbGUvLnRlc3QobmF2aWdhdG9yLnZlbmRvcikpLEVOViQxLnJlZ2lzdGVyRmxhZygiUFJPRCIsKCk9PiExKSxFTlYkMS5yZWdpc3RlckZsYWcoIlRFTlNPUkxJS0VfQ0hFQ0tfU0hBUEVfQ09OU0lTVEVOQ1kiLCgpPT5FTlYkMS5nZXRCb29sKCJERUJVRyIpKSxFTlYkMS5yZWdpc3RlckZsYWcoIkRFUFJFQ0FUSU9OX1dBUk5JTkdTX0VOQUJMRUQiLCgpPT4hMCksRU5WJDEucmVnaXN0ZXJGbGFnKCJJU19URVNUIiwoKT0+ITEpLEVOViQxLnJlZ2lzdGVyRmxhZygiQ0hFQ0tfQ09NUFVUQVRJT05fRk9SX0VSUk9SUyIsKCk9PkVOViQxLmdldEJvb2woIkRFQlVHIikpLEVOViQxLnJlZ2lzdGVyRmxhZygiV1JBUF9UT19JTUFHRUJJVE1BUCIsKCk9PiExKSxFTlYkMS5yZWdpc3RlckZsYWcoIkNBTlZBUzJEX1dJTExfUkVBRF9GUkVRVUVOVExZX0ZPUl9HUFUiLCgpPT4hMSksRU5WJDEucmVnaXN0ZXJGbGFnKCJVU0VfU0VUVElNRU9VVENVU1RPTSIsKCk9PiExKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpbmZlclNoYXBlKGhhLGFhKXtsZXQgeGE9aGE7aWYoaXNUeXBlZEFycmF5KGhhKSlyZXR1cm4gYWE9PT0ic3RyaW5nIj9bXTpbaGEubGVuZ3RoXTtpZihpc1dlYkdMRGF0YShoYSkpe2NvbnN0IFNhPWhhLmNoYW5uZWxzfHwiUkdCQSI7cmV0dXJuW2hhLmhlaWdodCxoYS53aWR0aCpTYS5sZW5ndGhdfWVsc2UgaWYoaXNXZWJHUFVEYXRhKGhhKSlyZXR1cm5baGEuYnVmZmVyLnNpemUvKGFhPT1udWxsPzQ6Ynl0ZXNQZXJFbGVtZW50KGFhKSldO2lmKCFBcnJheS5pc0FycmF5KGhhKSlyZXR1cm5bXTtjb25zdCBiYT1bXTtmb3IoO0FycmF5LmlzQXJyYXkoeGEpfHxpc1R5cGVkQXJyYXkoeGEpJiZhYSE9PSJzdHJpbmciOyliYS5wdXNoKHhhLmxlbmd0aCkseGE9eGFbMF07cmV0dXJuIEFycmF5LmlzQXJyYXkoaGEpJiZlbnYoKS5nZXRCb29sKCJURU5TT1JMSUtFX0NIRUNLX1NIQVBFX0NPTlNJU1RFTkNZIikmJmRlZXBBc3NlcnRTaGFwZUNvbnNpc3RlbmN5KGhhLGJhLFtdKSxiYX1mdW5jdGlvbiBkZWVwQXNzZXJ0U2hhcGVDb25zaXN0ZW5jeShoYSxhYSx4YSl7aWYoeGE9eGF8fFtdLCFBcnJheS5pc0FycmF5KGhhKSYmIWlzVHlwZWRBcnJheShoYSkpe2Fzc2VydChhYS5sZW5ndGg9PT0wLCgpPT5gRWxlbWVudCBhcnJbJHt4YS5qb2luKCJdWyIpfV0gaXMgYSBwcmltaXRpdmUsIGJ1dCBzaG91bGQgYmUgYW4gYXJyYXkvVHlwZWRBcnJheSBvZiAke2FhWzBdfSBlbGVtZW50c2ApO3JldHVybn1hc3NlcnQoYWEubGVuZ3RoPjAsKCk9PmBFbGVtZW50IGFyclske3hhLmpvaW4oIl1bIil9XSBzaG91bGQgYmUgYSBwcmltaXRpdmUsIGJ1dCBpcyBhbiBhcnJheSBvZiAke2hhLmxlbmd0aH0gZWxlbWVudHNgKSxhc3NlcnQoaGEubGVuZ3RoPT09YWFbMF0sKCk9PmBFbGVtZW50IGFyclske3hhLmpvaW4oIl1bIil9XSBzaG91bGQgaGF2ZSAke2FhWzBdfSBlbGVtZW50cywgYnV0IGhhcyAke2hhLmxlbmd0aH0gZWxlbWVudHNgKTtjb25zdCBiYT1hYS5zbGljZSgxKTtmb3IobGV0IFNhPTA7U2E8aGEubGVuZ3RoOysrU2EpZGVlcEFzc2VydFNoYXBlQ29uc2lzdGVuY3koaGFbU2FdLGJhLHhhLmNvbmNhdChTYSkpfWZ1bmN0aW9uIGFzc2VydER0eXBlKGhhLGFhLHhhLGJhKXtpZihoYSE9PSJzdHJpbmdfb3JfbnVtZXJpYyIpe2lmKGhhPT1udWxsKXRocm93IG5ldyBFcnJvcigiRXhwZWN0ZWQgZHR5cGUgY2Fubm90IGJlIG51bGwuIik7aWYoaGEhPT0ibnVtZXJpYyImJmhhIT09YWF8fGhhPT09Im51bWVyaWMiJiZhYT09PSJzdHJpbmciKXRocm93IG5ldyBFcnJvcihgQXJndW1lbnQgJyR7eGF9JyBwYXNzZWQgdG8gJyR7YmF9JyBtdXN0IGJlICR7aGF9IHRlbnNvciwgYnV0IGdvdCAke2FhfSB0ZW5zb3JgKX19ZnVuY3Rpb24gY29udmVydFRvVGVuc29yKGhhLGFhLHhhLGJhPSJudW1lcmljIil7aWYoaGEgaW5zdGFuY2VvZiBnZXRHbG9iYWxUZW5zb3JDbGFzcygpKXJldHVybiBhc3NlcnREdHlwZShiYSxoYS5kdHlwZSxhYSx4YSksaGE7bGV0IFNhPWluZmVyRHR5cGUoaGEpO2lmKFNhIT09InN0cmluZyImJlsiYm9vbCIsImludDMyIiwiZmxvYXQzMiJdLmluZGV4T2YoYmEpPj0wJiYoU2E9YmEpLGFzc2VydER0eXBlKGJhLFNhLGFhLHhhKSxoYT09bnVsbHx8IWlzVHlwZWRBcnJheShoYSkmJiFBcnJheS5pc0FycmF5KGhhKSYmdHlwZW9mIGhhIT0ibnVtYmVyIiYmdHlwZW9mIGhhIT0iYm9vbGVhbiImJnR5cGVvZiBoYSE9InN0cmluZyIpe2NvbnN0IGthPWhhPT1udWxsPyJudWxsIjpoYS5jb25zdHJ1Y3Rvci5uYW1lO3Rocm93IG5ldyBFcnJvcihgQXJndW1lbnQgJyR7YWF9JyBwYXNzZWQgdG8gJyR7eGF9JyBtdXN0IGJlIGEgVGVuc29yIG9yIFRlbnNvckxpa2UsIGJ1dCBnb3QgJyR7a2F9J2ApfWNvbnN0IFRhPWluZmVyU2hhcGUoaGEsU2EpOyFpc1R5cGVkQXJyYXkoaGEpJiYhQXJyYXkuaXNBcnJheShoYSkmJihoYT1baGFdKTtjb25zdCBFYT1TYSE9PSJzdHJpbmciP3RvVHlwZWRBcnJheShoYSxTYSk6ZmxhdHRlbihoYSxbXSwhMCk7cmV0dXJuIEVOR0lORS5tYWtlVGVuc29yKEVhLFRhLFNhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBPUF9TQ09QRV9TVUZGSVg9Il9fb3AiO2Z1bmN0aW9uIG9wKGhhKXtjb25zdCBhYT1PYmplY3Qua2V5cyhoYSk7aWYoYWEubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYFBsZWFzZSBwcm92aWRlIGFuIG9iamVjdCB3aXRoIGEgc2luZ2xlIGtleSAob3BlcmF0aW9uIG5hbWUpIG1hcHBpbmcgdG8gYSBmdW5jdGlvbi4gR290IGFuIG9iamVjdCB3aXRoICR7YWEubGVuZ3RofSBrZXlzLmApO2xldCB4YT1hYVswXTtjb25zdCBiYT1oYVt4YV07eGEuZW5kc1dpdGgoIl8iKSYmKHhhPXhhLnN1YnN0cmluZygwLHhhLmxlbmd0aC0xKSkseGE9eGErT1BfU0NPUEVfU1VGRklYO2NvbnN0IFNhPSguLi5UYSk9PntFTkdJTkUuc3RhcnRTY29wZSh4YSk7dHJ5e2NvbnN0IHdhPWJhKC4uLlRhKTtyZXR1cm4gaXNQcm9taXNlKHdhKSYmY29uc29sZS5lcnJvcigiQ2Fubm90IHJldHVybiBhIFByb21pc2UgaW5zaWRlIG9mIHRpZHkuIiksRU5HSU5FLmVuZFNjb3BlKHdhKSx3YX1jYXRjaCh3YSl7dGhyb3cgRU5HSU5FLmVuZFNjb3BlKG51bGwpLHdhfX07cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTYSwibmFtZSIse3ZhbHVlOnhhLGNvbmZpZ3VyYWJsZTohMH0pLFNhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbXBsZXhfKGhhLGFhKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IoaGEsInJlYWwiLCJjb21wbGV4IiksYmE9Y29udmVydFRvVGVuc29yKGFhLCJpbWFnIiwiY29tcGxleCIpO2Fzc2VydFNoYXBlc01hdGNoKHhhLnNoYXBlLGJhLnNoYXBlLGByZWFsIGFuZCBpbWFnIHNoYXBlcywgJHt4YS5zaGFwZX0gYW5kICR7YmEuc2hhcGV9LCBtdXN0IG1hdGNoIGluIGNhbGwgdG8gdGYuY29tcGxleCgpLmApO2NvbnN0IFNhPXtyZWFsOnhhLGltYWc6YmF9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKENvbXBsZXgsU2EpfWNvbnN0IGNvbXBsZXgkMT1vcCh7Y29tcGxleF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYWtlVGVuc29yKGhhLGFhLHhhLGJhKXtpZihiYT09bnVsbCliYT1pbmZlckR0eXBlKGhhKTtlbHNlIGlmKGJhPT09ImNvbXBsZXg2NCIpdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgY29uc3RydWN0IGEgY29tcGxleDY0IHRlbnNvciBkaXJlY3RseS4gUGxlYXNlIHVzZSB0Zi5jb21wbGV4KHJlYWwsIGltYWcpLiIpO2lmKGlzV2ViR1BVRGF0YShoYSl8fGlzV2ViR0xEYXRhKGhhKSl7aWYoYmEhPT0iZmxvYXQzMiImJmJhIT09ImludDMyIil0aHJvdyBuZXcgRXJyb3IoYENyZWF0aW5nIHRlbnNvciBmcm9tIEdQVSBkYXRhIG9ubHkgc3VwcG9ydHMgJ2Zsb2F0MzInfCdpbnQzMicgZHR5cGUsIHdoaWxlIHRoZSBkdHlwZSBpcyAke2JhfS5gKTtyZXR1cm4gRU5HSU5FLmJhY2tlbmQuY3JlYXRlVGVuc29yRnJvbUdQVURhdGEoaGEsYWF8fHhhLGJhKX1pZighaXNUeXBlZEFycmF5KGhhKSYmIUFycmF5LmlzQXJyYXkoaGEpJiZ0eXBlb2YgaGEhPSJudW1iZXIiJiZ0eXBlb2YgaGEhPSJib29sZWFuIiYmdHlwZW9mIGhhIT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoInZhbHVlcyBwYXNzZWQgdG8gdGVuc29yKHZhbHVlcykgbXVzdCBiZSBhIG51bWJlci9ib29sZWFuL3N0cmluZyBvciBhbiBhcnJheSBvZiBudW1iZXJzL2Jvb2xlYW5zL3N0cmluZ3MsIG9yIGEgVHlwZWRBcnJheSIpO2lmKGFhIT1udWxsKXthc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zKGFhKTtjb25zdCBTYT1zaXplRnJvbVNoYXBlKGFhKSxUYT1zaXplRnJvbVNoYXBlKHhhKTthc3NlcnQoU2E9PT1UYSwoKT0+YEJhc2VkIG9uIHRoZSBwcm92aWRlZCBzaGFwZSwgWyR7YWF9XSwgdGhlIHRlbnNvciBzaG91bGQgaGF2ZSAke1NhfSB2YWx1ZXMgYnV0IGhhcyAke1RhfWApO2ZvcihsZXQgd2E9MDt3YTx4YS5sZW5ndGg7Kyt3YSl7Y29uc3QgRWE9eGFbd2FdLGthPXdhPT09eGEubGVuZ3RoLTE/RWEhPT1zaXplRnJvbVNoYXBlKGFhLnNsaWNlKHdhKSk6ITA7YXNzZXJ0KHhhW3dhXT09PWFhW3dhXXx8IWthLCgpPT5gRXJyb3IgY3JlYXRpbmcgYSBuZXcgVGVuc29yLiBJbmZlcnJlZCBzaGFwZSAoJHt4YX0pIGRvZXMgbm90IG1hdGNoIHRoZSBwcm92aWRlZCBzaGFwZSAoJHthYX0pLiBgKX19cmV0dXJuIWlzVHlwZWRBcnJheShoYSkmJiFBcnJheS5pc0FycmF5KGhhKSYmKGhhPVtoYV0pLGFhPWFhfHx4YSxoYT1iYSE9PSJzdHJpbmciP3RvVHlwZWRBcnJheShoYSxiYSk6ZmxhdHRlbihoYSxbXSwhMCksRU5HSU5FLm1ha2VUZW5zb3IoaGEsYWEsYmEpfWNsYXNzIENvbXBvc2l0ZUFycmF5QnVmZmVye3N0YXRpYyBqb2luKGFhKXtyZXR1cm4gbmV3IENvbXBvc2l0ZUFycmF5QnVmZmVyKGFhKS5zbGljZSgpfWNvbnN0cnVjdG9yKGFhKXtpZih0aGlzLnNoYXJkcz1bXSx0aGlzLnByZXZpb3VzU2hhcmRJbmRleD0wLGFhPT1udWxsfHwoYWEgaW5zdGFuY2VvZiBBcnJheXx8KGFhPVthYV0pLGFhPWFhLm1hcChiYT0+aXNUeXBlZEFycmF5KGJhKT9iYS5idWZmZXI6YmEpLGFhLmxlbmd0aD09PTApKXJldHVybjt0aGlzLmJ1ZmZlclVuaWZvcm1TaXplPWFhWzBdLmJ5dGVMZW5ndGg7bGV0IHhhPTA7Zm9yKGxldCBiYT0wO2JhPGFhLmxlbmd0aDtiYSsrKXtjb25zdCBTYT1hYVtiYV07YmEhPT1hYS5sZW5ndGgtMSYmU2EuYnl0ZUxlbmd0aCE9PXRoaXMuYnVmZmVyVW5pZm9ybVNpemUmJih0aGlzLmJ1ZmZlclVuaWZvcm1TaXplPXZvaWQgMCk7Y29uc3QgVGE9eGErU2EuYnl0ZUxlbmd0aDt0aGlzLnNoYXJkcy5wdXNoKHtidWZmZXI6U2Esc3RhcnQ6eGEsZW5kOlRhfSkseGE9VGF9dGhpcy5zaGFyZHMubGVuZ3RoPT09MCYmKHRoaXMuYnl0ZUxlbmd0aD0wKSx0aGlzLmJ5dGVMZW5ndGg9dGhpcy5zaGFyZHNbdGhpcy5zaGFyZHMubGVuZ3RoLTFdLmVuZH1zbGljZShhYT0wLHhhPXRoaXMuYnl0ZUxlbmd0aCl7aWYodGhpcy5zaGFyZHMubGVuZ3RoPT09MClyZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO2lmKGFhPWlzTmFOKE51bWJlcihhYSkpPzA6YWEseGE9aXNOYU4oTnVtYmVyKHhhKSk/MDp4YSxhYT1NYXRoLm1heCgwLGFhKSx4YT1NYXRoLm1pbih0aGlzLmJ5dGVMZW5ndGgseGEpLHhhPD1hYSlyZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO2NvbnN0IGJhPXRoaXMuZmluZFNoYXJkRm9yQnl0ZShhYSk7aWYoYmE9PT0tMSl0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBmaW5kIHN0YXJ0IHNoYXJkIGZvciBieXRlICR7YWF9YCk7Y29uc3QgU2E9eGEtYWEsVGE9bmV3IEFycmF5QnVmZmVyKFNhKSx3YT1uZXcgVWludDhBcnJheShUYSk7bGV0IEVhPTA7Zm9yKGxldCBrYT1iYTtrYTx0aGlzLnNoYXJkcy5sZW5ndGg7a2ErKyl7Y29uc3QgQWE9dGhpcy5zaGFyZHNba2FdLExhPWFhK0VhLUFhLnN0YXJ0LGVsPUVhLG5sPU1hdGgubWluKHhhLEFhLmVuZCktQWEuc3RhcnQsc2w9bmV3IFVpbnQ4QXJyYXkoQWEuYnVmZmVyLExhLG5sLUxhKTtpZih3YS5zZXQoc2wsZWwpLEVhKz1zbC5sZW5ndGgseGE8QWEuZW5kKWJyZWFrfXJldHVybiBUYX1maW5kU2hhcmRGb3JCeXRlKGFhKXtpZih0aGlzLnNoYXJkcy5sZW5ndGg9PT0wfHxhYTwwfHxhYT49dGhpcy5ieXRlTGVuZ3RoKXJldHVybi0xO2lmKHRoaXMuYnVmZmVyVW5pZm9ybVNpemUhPW51bGwpcmV0dXJuIHRoaXMucHJldmlvdXNTaGFyZEluZGV4PU1hdGguZmxvb3IoYWEvdGhpcy5idWZmZXJVbmlmb3JtU2l6ZSksdGhpcy5wcmV2aW91c1NoYXJkSW5kZXg7ZnVuY3Rpb24geGEoU2Epe3JldHVybiBhYTxTYS5zdGFydD8tMTphYT49U2EuZW5kPzE6MH1pZih4YSh0aGlzLnNoYXJkc1t0aGlzLnByZXZpb3VzU2hhcmRJbmRleF0pPT09MClyZXR1cm4gdGhpcy5wcmV2aW91c1NoYXJkSW5kZXg7Y29uc3QgYmE9c2VhcmNoKHRoaXMuc2hhcmRzLHhhKTtyZXR1cm4gYmE9PT0tMT8tMToodGhpcy5wcmV2aW91c1NoYXJkSW5kZXg9YmEsdGhpcy5wcmV2aW91c1NoYXJkSW5kZXgpfX1mdW5jdGlvbiBzZWFyY2goaGEsYWEpe2xldCB4YT0wLGJhPWhhLmxlbmd0aDtmb3IoO3hhPD1iYTspe2NvbnN0IFNhPU1hdGguZmxvb3IoKGJhLXhhKS8yKSt4YSxUYT1hYShoYVtTYV0pO2lmKFRhPT09MClyZXR1cm4gU2E7VGE8MD9iYT1TYTp4YT1TYSsxfXJldHVybi0xfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGVuZ2luZSgpe3JldHVybiBFTkdJTkV9ZnVuY3Rpb24gdGlkeShoYSxhYSl7cmV0dXJuIEVOR0lORS50aWR5KGhhLGFhKX1mdW5jdGlvbiBkaXNwb3NlKGhhKXtnZXRUZW5zb3JzSW5Db250YWluZXIoaGEpLmZvckVhY2goeGE9PnhhLmRpc3Bvc2UoKSl9ZnVuY3Rpb24ga2VlcChoYSl7cmV0dXJuIEVOR0lORS5rZWVwKGhhKX1mdW5jdGlvbiByZWdpc3RlckJhY2tlbmQoaGEsYWEseGE9MSl7cmV0dXJuIEVOR0lORS5yZWdpc3RlckJhY2tlbmQoaGEsYWEseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHVzZU5vZGVCdWZmZXI9dHlwZW9mIEJ1ZmZlcjwidSImJih0eXBlb2YgQmxvYj4idSJ8fHR5cGVvZiBhdG9iPiJ1Inx8dHlwZW9mIGJ0b2E+InUiKTtmdW5jdGlvbiBzdHJpbmdCeXRlTGVuZ3RoKGhhKXtyZXR1cm4gdXNlTm9kZUJ1ZmZlcj9CdWZmZXIuYnl0ZUxlbmd0aChoYSwidXRmOCIpOm5ldyBCbG9iKFtoYV0pLnNpemV9ZnVuY3Rpb24gYXJyYXlCdWZmZXJUb0Jhc2U2NFN0cmluZyhoYSl7aWYodXNlTm9kZUJ1ZmZlcilyZXR1cm4gQnVmZmVyLmZyb20oaGEpLnRvU3RyaW5nKCJiYXNlNjQiKTtjb25zdCBhYT1uZXcgVWludDhBcnJheShoYSk7bGV0IHhhPSIiO2ZvcihsZXQgYmE9MCxTYT1hYS5sZW5ndGg7YmE8U2E7YmErKyl4YSs9U3RyaW5nLmZyb21DaGFyQ29kZShhYVtiYV0pO3JldHVybiBidG9hKHhhKX1mdW5jdGlvbiBiYXNlNjRTdHJpbmdUb0FycmF5QnVmZmVyKGhhKXtpZih1c2VOb2RlQnVmZmVyKXtjb25zdCBiYT1CdWZmZXIuZnJvbShoYSwiYmFzZTY0Iik7cmV0dXJuIGJhLmJ1ZmZlci5zbGljZShiYS5ieXRlT2Zmc2V0LGJhLmJ5dGVPZmZzZXQrYmEuYnl0ZUxlbmd0aCl9Y29uc3QgYWE9YXRvYihoYSkseGE9bmV3IFVpbnQ4QXJyYXkoYWEubGVuZ3RoKTtmb3IobGV0IGJhPTA7YmE8YWEubGVuZ3RoOysrYmEpeGEuc2V0KFthYS5jaGFyQ29kZUF0KGJhKV0sYmEpO3JldHVybiB4YS5idWZmZXJ9ZnVuY3Rpb24gZ2V0TW9kZWxKU09ORm9yTW9kZWxBcnRpZmFjdHMoaGEsYWEpe2NvbnN0IHhhPXttb2RlbFRvcG9sb2d5OmhhLm1vZGVsVG9wb2xvZ3ksZm9ybWF0OmhhLmZvcm1hdCxnZW5lcmF0ZWRCeTpoYS5nZW5lcmF0ZWRCeSxjb252ZXJ0ZWRCeTpoYS5jb252ZXJ0ZWRCeSx3ZWlnaHRzTWFuaWZlc3Q6YWF9O3JldHVybiBoYS5zaWduYXR1cmUhPW51bGwmJih4YS5zaWduYXR1cmU9aGEuc2lnbmF0dXJlKSxoYS51c2VyRGVmaW5lZE1ldGFkYXRhIT1udWxsJiYoeGEudXNlckRlZmluZWRNZXRhZGF0YT1oYS51c2VyRGVmaW5lZE1ldGFkYXRhKSxoYS5tb2RlbEluaXRpYWxpemVyIT1udWxsJiYoeGEubW9kZWxJbml0aWFsaXplcj1oYS5tb2RlbEluaXRpYWxpemVyKSxoYS5pbml0aWFsaXplclNpZ25hdHVyZSE9bnVsbCYmKHhhLmluaXRpYWxpemVyU2lnbmF0dXJlPWhhLmluaXRpYWxpemVyU2lnbmF0dXJlKSxoYS50cmFpbmluZ0NvbmZpZyE9bnVsbCYmKHhhLnRyYWluaW5nQ29uZmlnPWhhLnRyYWluaW5nQ29uZmlnKSx4YX1mdW5jdGlvbiBnZXRNb2RlbEFydGlmYWN0c0ZvckpTT05TeW5jKGhhLGFhLHhhKXtjb25zdCBiYT17bW9kZWxUb3BvbG9neTpoYS5tb2RlbFRvcG9sb2d5LGZvcm1hdDpoYS5mb3JtYXQsZ2VuZXJhdGVkQnk6aGEuZ2VuZXJhdGVkQnksY29udmVydGVkQnk6aGEuY29udmVydGVkQnl9O2lmKGhhLnRyYWluaW5nQ29uZmlnIT1udWxsJiYoYmEudHJhaW5pbmdDb25maWc9aGEudHJhaW5pbmdDb25maWcpLGhhLndlaWdodHNNYW5pZmVzdCE9bnVsbCl7aWYoIWFhKXRocm93IG5ldyBFcnJvcigibW9kZWxKU09OIGhhcyB3ZWlnaHRzTWFuaWZlc3QgYnV0IHdlaWdodFNwZWNzIGlzIG51bGwiKTtpZigheGEpdGhyb3cgbmV3IEVycm9yKCJtb2RlbEpTT04gaGFzIHdlaWdodHNNYW5pZmVzdCBidXQgd2VpZ2h0RGF0YSBpcyBudWxsIik7YmEud2VpZ2h0U3BlY3M9YWEsYmEud2VpZ2h0RGF0YT14YX1yZXR1cm4gaGEuc2lnbmF0dXJlIT1udWxsJiYoYmEuc2lnbmF0dXJlPWhhLnNpZ25hdHVyZSksaGEudXNlckRlZmluZWRNZXRhZGF0YSE9bnVsbCYmKGJhLnVzZXJEZWZpbmVkTWV0YWRhdGE9aGEudXNlckRlZmluZWRNZXRhZGF0YSksaGEubW9kZWxJbml0aWFsaXplciE9bnVsbCYmKGJhLm1vZGVsSW5pdGlhbGl6ZXI9aGEubW9kZWxJbml0aWFsaXplciksaGEuaW5pdGlhbGl6ZXJTaWduYXR1cmUhPW51bGwmJihiYS5pbml0aWFsaXplclNpZ25hdHVyZT1oYS5pbml0aWFsaXplclNpZ25hdHVyZSksYmF9YXN5bmMgZnVuY3Rpb24gZ2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OKGhhLGFhKXtsZXQgeGEsYmE7cmV0dXJuIGhhLndlaWdodHNNYW5pZmVzdCE9bnVsbCYmKFt4YSxiYV09YXdhaXQgYWEoaGEud2VpZ2h0c01hbmlmZXN0KSksZ2V0TW9kZWxBcnRpZmFjdHNGb3JKU09OU3luYyhoYSx4YSxiYSl9ZnVuY3Rpb24gZ2V0TW9kZWxBcnRpZmFjdHNJbmZvRm9ySlNPTihoYSl7aWYoaGEubW9kZWxUb3BvbG9neSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXRocm93IG5ldyBFcnJvcigiRXhwZWN0ZWQgSlNPTiBtb2RlbCB0b3BvbG9neSwgcmVjZWl2ZWQgQXJyYXlCdWZmZXIuIik7cmV0dXJue2RhdGVTYXZlZDpuZXcgRGF0ZSxtb2RlbFRvcG9sb2d5VHlwZToiSlNPTiIsbW9kZWxUb3BvbG9neUJ5dGVzOmhhLm1vZGVsVG9wb2xvZ3k9PW51bGw/MDpzdHJpbmdCeXRlTGVuZ3RoKEpTT04uc3RyaW5naWZ5KGhhLm1vZGVsVG9wb2xvZ3kpKSx3ZWlnaHRTcGVjc0J5dGVzOmhhLndlaWdodFNwZWNzPT1udWxsPzA6c3RyaW5nQnl0ZUxlbmd0aChKU09OLnN0cmluZ2lmeShoYS53ZWlnaHRTcGVjcykpLHdlaWdodERhdGFCeXRlczpoYS53ZWlnaHREYXRhPT1udWxsPzA6bmV3IENvbXBvc2l0ZUFycmF5QnVmZmVyKGhhLndlaWdodERhdGEpLmJ5dGVMZW5ndGh9fWZ1bmN0aW9uIGdldFdlaWdodFNwZWNzKGhhKXtjb25zdCBhYT1bXTtmb3IoY29uc3QgeGEgb2YgaGEpYWEucHVzaCguLi54YS53ZWlnaHRzKTtyZXR1cm4gYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgSU9Sb3V0ZXJSZWdpc3RyeXtjb25zdHJ1Y3Rvcigpe3RoaXMuc2F2ZVJvdXRlcnM9W10sdGhpcy5sb2FkUm91dGVycz1bXX1zdGF0aWMgZ2V0SW5zdGFuY2UoKXtyZXR1cm4gSU9Sb3V0ZXJSZWdpc3RyeS5pbnN0YW5jZT09bnVsbCYmKElPUm91dGVyUmVnaXN0cnkuaW5zdGFuY2U9bmV3IElPUm91dGVyUmVnaXN0cnkpLElPUm91dGVyUmVnaXN0cnkuaW5zdGFuY2V9c3RhdGljIHJlZ2lzdGVyU2F2ZVJvdXRlcihhYSl7SU9Sb3V0ZXJSZWdpc3RyeS5nZXRJbnN0YW5jZSgpLnNhdmVSb3V0ZXJzLnB1c2goYWEpfXN0YXRpYyByZWdpc3RlckxvYWRSb3V0ZXIoYWEpe0lPUm91dGVyUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKS5sb2FkUm91dGVycy5wdXNoKGFhKX1zdGF0aWMgZ2V0U2F2ZUhhbmRsZXJzKGFhKXtyZXR1cm4gSU9Sb3V0ZXJSZWdpc3RyeS5nZXRIYW5kbGVycyhhYSwic2F2ZSIpfXN0YXRpYyBnZXRMb2FkSGFuZGxlcnMoYWEseGEpe3JldHVybiBJT1JvdXRlclJlZ2lzdHJ5LmdldEhhbmRsZXJzKGFhLCJsb2FkIix4YSl9c3RhdGljIGdldEhhbmRsZXJzKGFhLHhhLGJhKXtjb25zdCBTYT1bXTtyZXR1cm4oeGE9PT0ibG9hZCI/SU9Sb3V0ZXJSZWdpc3RyeS5nZXRJbnN0YW5jZSgpLmxvYWRSb3V0ZXJzOklPUm91dGVyUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKS5zYXZlUm91dGVycykuZm9yRWFjaCh3YT0+e2NvbnN0IEVhPXdhKGFhLGJhKTtFYSE9PW51bGwmJlNhLnB1c2goRWEpfSksU2F9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IERBVEFCQVNFX05BTUU9InRlbnNvcmZsb3dqcyIsREFUQUJBU0VfVkVSU0lPTj0xLE1PREVMX1NUT1JFX05BTUU9Im1vZGVsc19zdG9yZSIsSU5GT19TVE9SRV9OQU1FPSJtb2RlbF9pbmZvX3N0b3JlIjtmdW5jdGlvbiBnZXRJbmRleGVkREJGYWN0b3J5KCl7aWYoIWVudigpLmdldEJvb2woIklTX0JST1dTRVIiKSl0aHJvdyBuZXcgRXJyb3IoIkZhaWxlZCB0byBvYnRhaW4gSW5kZXhlZERCIGZhY3RvcnkgYmVjYXVzZSB0aGUgY3VycmVudCBlbnZpcm9ubWVudGlzIG5vdCBhIHdlYiBicm93c2VyLiIpO2NvbnN0IGhhPXR5cGVvZiB3aW5kb3c+InUiP3NlbGY6d2luZG93LGFhPWhhLmluZGV4ZWREQnx8aGEubW96SW5kZXhlZERCfHxoYS53ZWJraXRJbmRleGVkREJ8fGhhLm1zSW5kZXhlZERCfHxoYS5zaGltSW5kZXhlZERCO2lmKGFhPT1udWxsKXRocm93IG5ldyBFcnJvcigiVGhlIGN1cnJlbnQgYnJvd3NlciBkb2VzIG5vdCBhcHBlYXIgdG8gc3VwcG9ydCBJbmRleGVkREIuIik7cmV0dXJuIGFhfWZ1bmN0aW9uIHNldFVwRGF0YWJhc2UoaGEpe2NvbnN0IGFhPWhhLnJlc3VsdDthYS5jcmVhdGVPYmplY3RTdG9yZShNT0RFTF9TVE9SRV9OQU1FLHtrZXlQYXRoOiJtb2RlbFBhdGgifSksYWEuY3JlYXRlT2JqZWN0U3RvcmUoSU5GT19TVE9SRV9OQU1FLHtrZXlQYXRoOiJtb2RlbFBhdGgifSl9Y2xhc3MgQnJvd3NlckluZGV4ZWREQntjb25zdHJ1Y3RvcihhYSl7aWYodGhpcy5pbmRleGVkREI9Z2V0SW5kZXhlZERCRmFjdG9yeSgpLGFhPT1udWxsfHwhYWEpdGhyb3cgbmV3IEVycm9yKCJGb3IgSW5kZXhlZERCLCBtb2RlbFBhdGggbXVzdCBub3QgYmUgbnVsbCwgdW5kZWZpbmVkIG9yIGVtcHR5LiIpO3RoaXMubW9kZWxQYXRoPWFhfWFzeW5jIHNhdmUoYWEpe2lmKGFhLm1vZGVsVG9wb2xvZ3kgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil0aHJvdyBuZXcgRXJyb3IoIkJyb3dzZXJMb2NhbFN0b3JhZ2Uuc2F2ZSgpIGRvZXMgbm90IHN1cHBvcnQgc2F2aW5nIG1vZGVsIHRvcG9sb2d5IGluIGJpbmFyeSBmb3JtYXRzIHlldC4iKTtyZXR1cm4gdGhpcy5kYXRhYmFzZUFjdGlvbih0aGlzLm1vZGVsUGF0aCxhYSl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLmRhdGFiYXNlQWN0aW9uKHRoaXMubW9kZWxQYXRoKX1kYXRhYmFzZUFjdGlvbihhYSx4YSl7cmV0dXJuIG5ldyBQcm9taXNlKChiYSxTYSk9Pntjb25zdCBUYT10aGlzLmluZGV4ZWREQi5vcGVuKERBVEFCQVNFX05BTUUsREFUQUJBU0VfVkVSU0lPTik7VGEub251cGdyYWRlbmVlZGVkPSgpPT5zZXRVcERhdGFiYXNlKFRhKSxUYS5vbnN1Y2Nlc3M9KCk9Pntjb25zdCB3YT1UYS5yZXN1bHQ7aWYoeGE9PW51bGwpe2NvbnN0IEVhPXdhLnRyYW5zYWN0aW9uKE1PREVMX1NUT1JFX05BTUUsInJlYWRvbmx5IiksQWE9RWEub2JqZWN0U3RvcmUoTU9ERUxfU1RPUkVfTkFNRSkuZ2V0KHRoaXMubW9kZWxQYXRoKTtBYS5vbnN1Y2Nlc3M9KCk9PntpZihBYS5yZXN1bHQ9PW51bGwpcmV0dXJuIHdhLmNsb3NlKCksU2EobmV3IEVycm9yKGBDYW5ub3QgZmluZCBtb2RlbCB3aXRoIHBhdGggJyR7dGhpcy5tb2RlbFBhdGh9JyBpbiBJbmRleGVkREIuYCkpO2JhKEFhLnJlc3VsdC5tb2RlbEFydGlmYWN0cyl9LEFhLm9uZXJyb3I9RmE9Pih3YS5jbG9zZSgpLFNhKEFhLmVycm9yKSksRWEub25jb21wbGV0ZT0oKT0+d2EuY2xvc2UoKX1lbHNle3hhLndlaWdodERhdGE9Q29tcG9zaXRlQXJyYXlCdWZmZXIuam9pbih4YS53ZWlnaHREYXRhKTtjb25zdCBFYT1nZXRNb2RlbEFydGlmYWN0c0luZm9Gb3JKU09OKHhhKSxrYT13YS50cmFuc2FjdGlvbihJTkZPX1NUT1JFX05BTUUsInJlYWR3cml0ZSIpO2xldCBBYT1rYS5vYmplY3RTdG9yZShJTkZPX1NUT1JFX05BTUUpLEZhO3RyeXtGYT1BYS5wdXQoe21vZGVsUGF0aDp0aGlzLm1vZGVsUGF0aCxtb2RlbEFydGlmYWN0c0luZm86RWF9KX1jYXRjaChlbCl7cmV0dXJuIFNhKGVsKX1sZXQgTGE7RmEub25zdWNjZXNzPSgpPT57TGE9d2EudHJhbnNhY3Rpb24oTU9ERUxfU1RPUkVfTkFNRSwicmVhZHdyaXRlIik7Y29uc3QgZWw9TGEub2JqZWN0U3RvcmUoTU9ERUxfU1RPUkVfTkFNRSk7bGV0IHRsO3RyeXt0bD1lbC5wdXQoe21vZGVsUGF0aDp0aGlzLm1vZGVsUGF0aCxtb2RlbEFydGlmYWN0czp4YSxtb2RlbEFydGlmYWN0c0luZm86RWF9KX1jYXRjaChubCl7cmV0dXJuIFNhKG5sKX10bC5vbnN1Y2Nlc3M9KCk9PmJhKHttb2RlbEFydGlmYWN0c0luZm86RWF9KSx0bC5vbmVycm9yPW5sPT57QWE9a2Eub2JqZWN0U3RvcmUoSU5GT19TVE9SRV9OQU1FKTtjb25zdCBzbD1BYS5kZWxldGUodGhpcy5tb2RlbFBhdGgpO3NsLm9uc3VjY2Vzcz0oKT0+KHdhLmNsb3NlKCksU2EodGwuZXJyb3IpKSxzbC5vbmVycm9yPXJsPT4od2EuY2xvc2UoKSxTYSh0bC5lcnJvcikpfX0sRmEub25lcnJvcj1lbD0+KHdhLmNsb3NlKCksU2EoRmEuZXJyb3IpKSxrYS5vbmNvbXBsZXRlPSgpPT57TGE9PW51bGw/d2EuY2xvc2UoKTpMYS5vbmNvbXBsZXRlPSgpPT53YS5jbG9zZSgpfX19LFRhLm9uZXJyb3I9d2E9PlNhKFRhLmVycm9yKX0pfX1Ccm93c2VySW5kZXhlZERCLlVSTF9TQ0hFTUU9ImluZGV4ZWRkYjovLyI7Y29uc3QgaW5kZXhlZERCUm91dGVyPWhhPT5lbnYoKS5nZXRCb29sKCJJU19CUk9XU0VSIikmJiFBcnJheS5pc0FycmF5KGhhKSYmaGEuc3RhcnRzV2l0aChCcm93c2VySW5kZXhlZERCLlVSTF9TQ0hFTUUpP2Jyb3dzZXJJbmRleGVkREIoaGEuc2xpY2UoQnJvd3NlckluZGV4ZWREQi5VUkxfU0NIRU1FLmxlbmd0aCkpOm51bGw7SU9Sb3V0ZXJSZWdpc3RyeS5yZWdpc3RlclNhdmVSb3V0ZXIoaW5kZXhlZERCUm91dGVyKSxJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyTG9hZFJvdXRlcihpbmRleGVkREJSb3V0ZXIpO2Z1bmN0aW9uIGJyb3dzZXJJbmRleGVkREIoaGEpe3JldHVybiBuZXcgQnJvd3NlckluZGV4ZWREQihoYSl9ZnVuY3Rpb24gbWF5YmVTdHJpcFNjaGVtZSQxKGhhKXtyZXR1cm4gaGEuc3RhcnRzV2l0aChCcm93c2VySW5kZXhlZERCLlVSTF9TQ0hFTUUpP2hhLnNsaWNlKEJyb3dzZXJJbmRleGVkREIuVVJMX1NDSEVNRS5sZW5ndGgpOmhhfWNsYXNzIEJyb3dzZXJJbmRleGVkREJNYW5hZ2Vye2NvbnN0cnVjdG9yKCl7dGhpcy5pbmRleGVkREI9Z2V0SW5kZXhlZERCRmFjdG9yeSgpfWFzeW5jIGxpc3RNb2RlbHMoKXtyZXR1cm4gbmV3IFByb21pc2UoKGFhLHhhKT0+e2NvbnN0IGJhPXRoaXMuaW5kZXhlZERCLm9wZW4oREFUQUJBU0VfTkFNRSxEQVRBQkFTRV9WRVJTSU9OKTtiYS5vbnVwZ3JhZGVuZWVkZWQ9KCk9PnNldFVwRGF0YWJhc2UoYmEpLGJhLm9uc3VjY2Vzcz0oKT0+e2NvbnN0IFNhPWJhLnJlc3VsdCxUYT1TYS50cmFuc2FjdGlvbihJTkZPX1NUT1JFX05BTUUsInJlYWRvbmx5IiksRWE9VGEub2JqZWN0U3RvcmUoSU5GT19TVE9SRV9OQU1FKS5nZXRBbGwoKTtFYS5vbnN1Y2Nlc3M9KCk9Pntjb25zdCBrYT17fTtmb3IoY29uc3QgQWEgb2YgRWEucmVzdWx0KWthW0FhLm1vZGVsUGF0aF09QWEubW9kZWxBcnRpZmFjdHNJbmZvO2FhKGthKX0sRWEub25lcnJvcj1rYT0+KFNhLmNsb3NlKCkseGEoRWEuZXJyb3IpKSxUYS5vbmNvbXBsZXRlPSgpPT5TYS5jbG9zZSgpfSxiYS5vbmVycm9yPVNhPT54YShiYS5lcnJvcil9KX1hc3luYyByZW1vdmVNb2RlbChhYSl7cmV0dXJuIGFhPW1heWJlU3RyaXBTY2hlbWUkMShhYSksbmV3IFByb21pc2UoKHhhLGJhKT0+e2NvbnN0IFNhPXRoaXMuaW5kZXhlZERCLm9wZW4oREFUQUJBU0VfTkFNRSxEQVRBQkFTRV9WRVJTSU9OKTtTYS5vbnVwZ3JhZGVuZWVkZWQ9KCk9PnNldFVwRGF0YWJhc2UoU2EpLFNhLm9uc3VjY2Vzcz0oKT0+e2NvbnN0IFRhPVNhLnJlc3VsdCx3YT1UYS50cmFuc2FjdGlvbihJTkZPX1NUT1JFX05BTUUsInJlYWR3cml0ZSIpLEVhPXdhLm9iamVjdFN0b3JlKElORk9fU1RPUkVfTkFNRSksa2E9RWEuZ2V0KGFhKTtsZXQgQWE7a2Eub25zdWNjZXNzPSgpPT57aWYoa2EucmVzdWx0PT1udWxsKXJldHVybiBUYS5jbG9zZSgpLGJhKG5ldyBFcnJvcihgQ2Fubm90IGZpbmQgbW9kZWwgd2l0aCBwYXRoICcke2FhfScgaW4gSW5kZXhlZERCLmApKTt7Y29uc3QgRmE9RWEuZGVsZXRlKGFhKSxMYT0oKT0+e0FhPVRhLnRyYW5zYWN0aW9uKE1PREVMX1NUT1JFX05BTUUsInJlYWR3cml0ZSIpO2NvbnN0IHRsPUFhLm9iamVjdFN0b3JlKE1PREVMX1NUT1JFX05BTUUpLmRlbGV0ZShhYSk7dGwub25zdWNjZXNzPSgpPT54YShrYS5yZXN1bHQubW9kZWxBcnRpZmFjdHNJbmZvKSx0bC5vbmVycm9yPW5sPT5iYShrYS5lcnJvcil9O0ZhLm9uc3VjY2Vzcz1MYSxGYS5vbmVycm9yPWVsPT4oTGEoKSxUYS5jbG9zZSgpLGJhKGthLmVycm9yKSl9fSxrYS5vbmVycm9yPUZhPT4oVGEuY2xvc2UoKSxiYShrYS5lcnJvcikpLHdhLm9uY29tcGxldGU9KCk9PntBYT09bnVsbD9UYS5jbG9zZSgpOkFhLm9uY29tcGxldGU9KCk9PlRhLmNsb3NlKCl9fSxTYS5vbmVycm9yPVRhPT5iYShTYS5lcnJvcil9KX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgUEFUSF9TRVBBUkFUT1I9Ii8iLFBBVEhfUFJFRklYPSJ0ZW5zb3JmbG93anNfbW9kZWxzIixJTkZPX1NVRkZJWD0iaW5mbyIsTU9ERUxfVE9QT0xPR1lfU1VGRklYPSJtb2RlbF90b3BvbG9neSIsV0VJR0hUX1NQRUNTX1NVRkZJWD0id2VpZ2h0X3NwZWNzIixXRUlHSFRfREFUQV9TVUZGSVg9IndlaWdodF9kYXRhIixNT0RFTF9NRVRBREFUQV9TVUZGSVg9Im1vZGVsX21ldGFkYXRhIjtmdW5jdGlvbiBnZXRNb2RlbEtleXMoaGEpe3JldHVybntpbmZvOltQQVRIX1BSRUZJWCxoYSxJTkZPX1NVRkZJWF0uam9pbihQQVRIX1NFUEFSQVRPUiksdG9wb2xvZ3k6W1BBVEhfUFJFRklYLGhhLE1PREVMX1RPUE9MT0dZX1NVRkZJWF0uam9pbihQQVRIX1NFUEFSQVRPUiksd2VpZ2h0U3BlY3M6W1BBVEhfUFJFRklYLGhhLFdFSUdIVF9TUEVDU19TVUZGSVhdLmpvaW4oUEFUSF9TRVBBUkFUT1IpLHdlaWdodERhdGE6W1BBVEhfUFJFRklYLGhhLFdFSUdIVF9EQVRBX1NVRkZJWF0uam9pbihQQVRIX1NFUEFSQVRPUiksbW9kZWxNZXRhZGF0YTpbUEFUSF9QUkVGSVgsaGEsTU9ERUxfTUVUQURBVEFfU1VGRklYXS5qb2luKFBBVEhfU0VQQVJBVE9SKX19ZnVuY3Rpb24gcmVtb3ZlSXRlbXMoaGEpe2Zvcihjb25zdCBhYSBvZiBPYmplY3QudmFsdWVzKGhhKSl3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYWEpfWZ1bmN0aW9uIGdldE1vZGVsUGF0aEZyb21LZXkoaGEpe2NvbnN0IGFhPWhhLnNwbGl0KFBBVEhfU0VQQVJBVE9SKTtpZihhYS5sZW5ndGg8Myl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQga2V5IGZvcm1hdDogJHtoYX1gKTtyZXR1cm4gYWEuc2xpY2UoMSxhYS5sZW5ndGgtMSkuam9pbihQQVRIX1NFUEFSQVRPUil9ZnVuY3Rpb24gbWF5YmVTdHJpcFNjaGVtZShoYSl7cmV0dXJuIGhhLnN0YXJ0c1dpdGgoQnJvd3NlckxvY2FsU3RvcmFnZS5VUkxfU0NIRU1FKT9oYS5zbGljZShCcm93c2VyTG9jYWxTdG9yYWdlLlVSTF9TQ0hFTUUubGVuZ3RoKTpoYX1jbGFzcyBCcm93c2VyTG9jYWxTdG9yYWdle2NvbnN0cnVjdG9yKGFhKXtpZighZW52KCkuZ2V0Qm9vbCgiSVNfQlJPV1NFUiIpfHx0eXBlb2Ygd2luZG93PiJ1Inx8dHlwZW9mIHdpbmRvdy5sb2NhbFN0b3JhZ2U+InUiKXRocm93IG5ldyBFcnJvcigiVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBsb2NhbCBzdG9yYWdlLiIpO2lmKHRoaXMuTFM9d2luZG93LmxvY2FsU3RvcmFnZSxhYT09bnVsbHx8IWFhKXRocm93IG5ldyBFcnJvcigiRm9yIGxvY2FsIHN0b3JhZ2UsIG1vZGVsUGF0aCBtdXN0IG5vdCBiZSBudWxsLCB1bmRlZmluZWQgb3IgZW1wdHkuIik7dGhpcy5tb2RlbFBhdGg9YWEsdGhpcy5rZXlzPWdldE1vZGVsS2V5cyh0aGlzLm1vZGVsUGF0aCl9YXN5bmMgc2F2ZShhYSl7aWYoYWEubW9kZWxUb3BvbG9neSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXRocm93IG5ldyBFcnJvcigiQnJvd3NlckxvY2FsU3RvcmFnZS5zYXZlKCkgZG9lcyBub3Qgc3VwcG9ydCBzYXZpbmcgbW9kZWwgdG9wb2xvZ3kgaW4gYmluYXJ5IGZvcm1hdHMgeWV0LiIpO3tjb25zdCB4YT1KU09OLnN0cmluZ2lmeShhYS5tb2RlbFRvcG9sb2d5KSxiYT1KU09OLnN0cmluZ2lmeShhYS53ZWlnaHRTcGVjcyksU2E9Z2V0TW9kZWxBcnRpZmFjdHNJbmZvRm9ySlNPTihhYSksVGE9Q29tcG9zaXRlQXJyYXlCdWZmZXIuam9pbihhYS53ZWlnaHREYXRhKTt0cnl7dGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy5pbmZvLEpTT04uc3RyaW5naWZ5KFNhKSksdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy50b3BvbG9neSx4YSksdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy53ZWlnaHRTcGVjcyxiYSksdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy53ZWlnaHREYXRhLGFycmF5QnVmZmVyVG9CYXNlNjRTdHJpbmcoVGEpKTtjb25zdCB3YT17Zm9ybWF0OmFhLmZvcm1hdCxnZW5lcmF0ZWRCeTphYS5nZW5lcmF0ZWRCeSxjb252ZXJ0ZWRCeTphYS5jb252ZXJ0ZWRCeSxzaWduYXR1cmU6YWEuc2lnbmF0dXJlIT1udWxsP2FhLnNpZ25hdHVyZTp2b2lkIDAsdXNlckRlZmluZWRNZXRhZGF0YTphYS51c2VyRGVmaW5lZE1ldGFkYXRhIT1udWxsP2FhLnVzZXJEZWZpbmVkTWV0YWRhdGE6dm9pZCAwLG1vZGVsSW5pdGlhbGl6ZXI6YWEubW9kZWxJbml0aWFsaXplciE9bnVsbD9hYS5tb2RlbEluaXRpYWxpemVyOnZvaWQgMCxpbml0aWFsaXplclNpZ25hdHVyZTphYS5pbml0aWFsaXplclNpZ25hdHVyZSE9bnVsbD9hYS5pbml0aWFsaXplclNpZ25hdHVyZTp2b2lkIDAsdHJhaW5pbmdDb25maWc6YWEudHJhaW5pbmdDb25maWchPW51bGw/YWEudHJhaW5pbmdDb25maWc6dm9pZCAwfTtyZXR1cm4gdGhpcy5MUy5zZXRJdGVtKHRoaXMua2V5cy5tb2RlbE1ldGFkYXRhLEpTT04uc3RyaW5naWZ5KHdhKSkse21vZGVsQXJ0aWZhY3RzSW5mbzpTYX19Y2F0Y2h7dGhyb3cgcmVtb3ZlSXRlbXModGhpcy5rZXlzKSxuZXcgRXJyb3IoYEZhaWxlZCB0byBzYXZlIG1vZGVsICcke3RoaXMubW9kZWxQYXRofScgdG8gbG9jYWwgc3RvcmFnZTogc2l6ZSBxdW90YSBiZWluZyBleGNlZWRlZCBpcyBhIHBvc3NpYmxlIGNhdXNlIG9mIHRoaXMgZmFpbHVyZTogbW9kZWxUb3BvbG9neUJ5dGVzPSR7U2EubW9kZWxUb3BvbG9neUJ5dGVzfSwgd2VpZ2h0U3BlY3NCeXRlcz0ke1NhLndlaWdodFNwZWNzQnl0ZXN9LCB3ZWlnaHREYXRhQnl0ZXM9JHtTYS53ZWlnaHREYXRhQnl0ZXN9LmApfX19YXN5bmMgbG9hZCgpe2NvbnN0IGFhPUpTT04ucGFyc2UodGhpcy5MUy5nZXRJdGVtKHRoaXMua2V5cy5pbmZvKSk7aWYoYWE9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBJbiBsb2NhbCBzdG9yYWdlLCB0aGVyZSBpcyBubyBtb2RlbCB3aXRoIG5hbWUgJyR7dGhpcy5tb2RlbFBhdGh9J2ApO2lmKGFhLm1vZGVsVG9wb2xvZ3lUeXBlIT09IkpTT04iKXRocm93IG5ldyBFcnJvcigiQnJvd3NlckxvY2FsU3RvcmFnZSBkb2VzIG5vdCBzdXBwb3J0IGxvYWRpbmcgbm9uLUpTT04gbW9kZWwgdG9wb2xvZ3kgeWV0LiIpO2NvbnN0IHhhPXt9LGJhPUpTT04ucGFyc2UodGhpcy5MUy5nZXRJdGVtKHRoaXMua2V5cy50b3BvbG9neSkpO2lmKGJhPT1udWxsKXRocm93IG5ldyBFcnJvcihgSW4gbG9jYWwgc3RvcmFnZSwgdGhlIHRvcG9sb2d5IG9mIG1vZGVsICcke3RoaXMubW9kZWxQYXRofScgaXMgbWlzc2luZy5gKTt4YS5tb2RlbFRvcG9sb2d5PWJhO2NvbnN0IFNhPUpTT04ucGFyc2UodGhpcy5MUy5nZXRJdGVtKHRoaXMua2V5cy53ZWlnaHRTcGVjcykpO2lmKFNhPT1udWxsKXRocm93IG5ldyBFcnJvcihgSW4gbG9jYWwgc3RvcmFnZSwgdGhlIHdlaWdodCBzcGVjcyBvZiBtb2RlbCAnJHt0aGlzLm1vZGVsUGF0aH0nIGFyZSBtaXNzaW5nLmApO3hhLndlaWdodFNwZWNzPVNhO2NvbnN0IFRhPXRoaXMuTFMuZ2V0SXRlbSh0aGlzLmtleXMubW9kZWxNZXRhZGF0YSk7aWYoVGEhPW51bGwpe2NvbnN0IEVhPUpTT04ucGFyc2UoVGEpO3hhLmZvcm1hdD1FYS5mb3JtYXQseGEuZ2VuZXJhdGVkQnk9RWEuZ2VuZXJhdGVkQnkseGEuY29udmVydGVkQnk9RWEuY29udmVydGVkQnksRWEuc2lnbmF0dXJlIT1udWxsJiYoeGEuc2lnbmF0dXJlPUVhLnNpZ25hdHVyZSksRWEudXNlckRlZmluZWRNZXRhZGF0YSE9bnVsbCYmKHhhLnVzZXJEZWZpbmVkTWV0YWRhdGE9RWEudXNlckRlZmluZWRNZXRhZGF0YSksRWEubW9kZWxJbml0aWFsaXplciE9bnVsbCYmKHhhLm1vZGVsSW5pdGlhbGl6ZXI9RWEubW9kZWxJbml0aWFsaXplciksRWEuaW5pdGlhbGl6ZXJTaWduYXR1cmUhPW51bGwmJih4YS5pbml0aWFsaXplclNpZ25hdHVyZT1FYS5pbml0aWFsaXplclNpZ25hdHVyZSksRWEudHJhaW5pbmdDb25maWchPW51bGwmJih4YS50cmFpbmluZ0NvbmZpZz1FYS50cmFpbmluZ0NvbmZpZyl9Y29uc3Qgd2E9dGhpcy5MUy5nZXRJdGVtKHRoaXMua2V5cy53ZWlnaHREYXRhKTtpZih3YT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYEluIGxvY2FsIHN0b3JhZ2UsIHRoZSBiaW5hcnkgd2VpZ2h0IHZhbHVlcyBvZiBtb2RlbCAnJHt0aGlzLm1vZGVsUGF0aH0nIGFyZSBtaXNzaW5nLmApO3JldHVybiB4YS53ZWlnaHREYXRhPWJhc2U2NFN0cmluZ1RvQXJyYXlCdWZmZXIod2EpLHhhfX1Ccm93c2VyTG9jYWxTdG9yYWdlLlVSTF9TQ0hFTUU9ImxvY2Fsc3RvcmFnZTovLyI7Y29uc3QgbG9jYWxTdG9yYWdlUm91dGVyPWhhPT5lbnYoKS5nZXRCb29sKCJJU19CUk9XU0VSIikmJiFBcnJheS5pc0FycmF5KGhhKSYmaGEuc3RhcnRzV2l0aChCcm93c2VyTG9jYWxTdG9yYWdlLlVSTF9TQ0hFTUUpP2Jyb3dzZXJMb2NhbFN0b3JhZ2UoaGEuc2xpY2UoQnJvd3NlckxvY2FsU3RvcmFnZS5VUkxfU0NIRU1FLmxlbmd0aCkpOm51bGw7SU9Sb3V0ZXJSZWdpc3RyeS5yZWdpc3RlclNhdmVSb3V0ZXIobG9jYWxTdG9yYWdlUm91dGVyKSxJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyTG9hZFJvdXRlcihsb2NhbFN0b3JhZ2VSb3V0ZXIpO2Z1bmN0aW9uIGJyb3dzZXJMb2NhbFN0b3JhZ2UoaGEpe3JldHVybiBuZXcgQnJvd3NlckxvY2FsU3RvcmFnZShoYSl9Y2xhc3MgQnJvd3NlckxvY2FsU3RvcmFnZU1hbmFnZXJ7Y29uc3RydWN0b3IoKXthc3NlcnQoZW52KCkuZ2V0Qm9vbCgiSVNfQlJPV1NFUiIpLCgpPT4iQ3VycmVudCBlbnZpcm9ubWVudCBpcyBub3QgYSB3ZWIgYnJvd3NlciIpLGFzc2VydCh0eXBlb2Ygd2luZG93PiJ1Inx8dHlwZW9mIHdpbmRvdy5sb2NhbFN0b3JhZ2U8InUiLCgpPT4iQ3VycmVudCBicm93c2VyIGRvZXMgbm90IGFwcGVhciB0byBzdXBwb3J0IGxvY2FsU3RvcmFnZSIpLHRoaXMuTFM9d2luZG93LmxvY2FsU3RvcmFnZX1hc3luYyBsaXN0TW9kZWxzKCl7Y29uc3QgYWE9e30seGE9UEFUSF9QUkVGSVgrUEFUSF9TRVBBUkFUT1IsYmE9UEFUSF9TRVBBUkFUT1IrSU5GT19TVUZGSVg7Zm9yKGxldCBTYT0wO1NhPHRoaXMuTFMubGVuZ3RoOysrU2Epe2NvbnN0IFRhPXRoaXMuTFMua2V5KFNhKTtpZihUYS5zdGFydHNXaXRoKHhhKSYmVGEuZW5kc1dpdGgoYmEpKXtjb25zdCB3YT1nZXRNb2RlbFBhdGhGcm9tS2V5KFRhKTthYVt3YV09SlNPTi5wYXJzZSh0aGlzLkxTLmdldEl0ZW0oVGEpKX19cmV0dXJuIGFhfWFzeW5jIHJlbW92ZU1vZGVsKGFhKXthYT1tYXliZVN0cmlwU2NoZW1lKGFhKTtjb25zdCB4YT1nZXRNb2RlbEtleXMoYWEpO2lmKHRoaXMuTFMuZ2V0SXRlbSh4YS5pbmZvKT09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIG1vZGVsIGF0IHBhdGggJyR7YWF9J2ApO2NvbnN0IGJhPUpTT04ucGFyc2UodGhpcy5MUy5nZXRJdGVtKHhhLmluZm8pKTtyZXR1cm4gcmVtb3ZlSXRlbXMoeGEpLGJhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBVUkxfU0NIRU1FX1NVRkZJWD0iOi8vIjtjbGFzcyBNb2RlbFN0b3JlTWFuYWdlclJlZ2lzdHJ5e2NvbnN0cnVjdG9yKCl7dGhpcy5tYW5hZ2Vycz17fX1zdGF0aWMgZ2V0SW5zdGFuY2UoKXtyZXR1cm4gTW9kZWxTdG9yZU1hbmFnZXJSZWdpc3RyeS5pbnN0YW5jZT09bnVsbCYmKE1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkuaW5zdGFuY2U9bmV3IE1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkpLE1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkuaW5zdGFuY2V9c3RhdGljIHJlZ2lzdGVyTWFuYWdlcihhYSx4YSl7YXNzZXJ0KGFhIT1udWxsLCgpPT4ic2NoZW1lIG11c3Qgbm90IGJlIHVuZGVmaW5lZCBvciBudWxsLiIpLGFhLmVuZHNXaXRoKFVSTF9TQ0hFTUVfU1VGRklYKSYmKGFhPWFhLnNsaWNlKDAsYWEuaW5kZXhPZihVUkxfU0NIRU1FX1NVRkZJWCkpKSxhc3NlcnQoYWEubGVuZ3RoPjAsKCk9PiJzY2hlbWUgbXVzdCBub3QgYmUgYW4gZW1wdHkgc3RyaW5nLiIpO2NvbnN0IGJhPU1vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKTthc3NlcnQoYmEubWFuYWdlcnNbYWFdPT1udWxsLCgpPT5gQSBtb2RlbCBzdG9yZSBtYW5hZ2VyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCBmb3Igc2NoZW1lICcke2FhfScuYCksYmEubWFuYWdlcnNbYWFdPXhhfXN0YXRpYyBnZXRNYW5hZ2VyKGFhKXtjb25zdCB4YT1Nb2RlbFN0b3JlTWFuYWdlclJlZ2lzdHJ5LmdldEluc3RhbmNlKCkubWFuYWdlcnNbYWFdO2lmKHhhPT1udWxsKXRocm93IG5ldyBFcnJvcihgQ2Fubm90IGZpbmQgbW9kZWwgbWFuYWdlciBmb3Igc2NoZW1lICcke2FhfSdgKTtyZXR1cm4geGF9c3RhdGljIGdldFNjaGVtZXMoKXtyZXR1cm4gT2JqZWN0LmtleXMoTW9kZWxTdG9yZU1hbmFnZXJSZWdpc3RyeS5nZXRJbnN0YW5jZSgpLm1hbmFnZXJzKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUGxhdGZvcm1Ccm93c2Vye2NvbnN0cnVjdG9yKCl7dGhpcy5tZXNzYWdlTmFtZT0ic2V0VGltZW91dEN1c3RvbSIsdGhpcy5mdW5jdGlvblJlZnM9W10sdGhpcy5oYW5kbGVkTWVzc2FnZUNvdW50PTAsdGhpcy5oYXNFdmVudExpc3RlbmVyPSExfWZldGNoKGFhLHhhKXtyZXR1cm4gZmV0Y2goYWEseGEpfW5vdygpe3JldHVybiBwZXJmb3JtYW5jZS5ub3coKX1lbmNvZGUoYWEseGEpe2lmKHhhIT09InV0Zi04IiYmeGEhPT0idXRmOCIpdGhyb3cgbmV3IEVycm9yKGBCcm93c2VyJ3MgZW5jb2RlciBvbmx5IHN1cHBvcnRzIHV0Zi04LCBidXQgZ290ICR7eGF9YCk7cmV0dXJuIHRoaXMudGV4dEVuY29kZXI9PW51bGwmJih0aGlzLnRleHRFbmNvZGVyPW5ldyBUZXh0RW5jb2RlciksdGhpcy50ZXh0RW5jb2Rlci5lbmNvZGUoYWEpfWRlY29kZShhYSx4YSl7cmV0dXJuIG5ldyBUZXh0RGVjb2Rlcih4YSkuZGVjb2RlKGFhKX1zZXRUaW1lb3V0Q3VzdG9tKGFhLHhhKXtpZih0eXBlb2Ygd2luZG93PiJ1Inx8IWVudigpLmdldEJvb2woIlVTRV9TRVRUSU1FT1VUQ1VTVE9NIikpe3NldFRpbWVvdXQoYWEseGEpO3JldHVybn10aGlzLmZ1bmN0aW9uUmVmcy5wdXNoKGFhKSxzZXRUaW1lb3V0KCgpPT57d2luZG93LnBvc3RNZXNzYWdlKHtuYW1lOnRoaXMubWVzc2FnZU5hbWUsaW5kZXg6dGhpcy5mdW5jdGlvblJlZnMubGVuZ3RoLTF9LCIqIil9LHhhKSx0aGlzLmhhc0V2ZW50TGlzdGVuZXJ8fCh0aGlzLmhhc0V2ZW50TGlzdGVuZXI9ITAsd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGJhPT57aWYoYmEuc291cmNlPT09d2luZG93JiZiYS5kYXRhLm5hbWU9PT10aGlzLm1lc3NhZ2VOYW1lKXtiYS5zdG9wUHJvcGFnYXRpb24oKTtjb25zdCBTYT10aGlzLmZ1bmN0aW9uUmVmc1tiYS5kYXRhLmluZGV4XTtTYSgpLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudCsrLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudD09PXRoaXMuZnVuY3Rpb25SZWZzLmxlbmd0aCYmKHRoaXMuZnVuY3Rpb25SZWZzPVtdLHRoaXMuaGFuZGxlZE1lc3NhZ2VDb3VudD0wKX19LCEwKSl9aXNUeXBlZEFycmF5KGFhKXtyZXR1cm4gaXNUeXBlZEFycmF5QnJvd3NlcihhYSl9fWlmKGVudigpLmdldCgiSVNfQlJPV1NFUiIpKXtlbnYoKS5zZXRQbGF0Zm9ybSgiYnJvd3NlciIsbmV3IFBsYXRmb3JtQnJvd3Nlcik7dHJ5e01vZGVsU3RvcmVNYW5hZ2VyUmVnaXN0cnkucmVnaXN0ZXJNYW5hZ2VyKEJyb3dzZXJMb2NhbFN0b3JhZ2UuVVJMX1NDSEVNRSxuZXcgQnJvd3NlckxvY2FsU3RvcmFnZU1hbmFnZXIpfWNhdGNoe310cnl7TW9kZWxTdG9yZU1hbmFnZXJSZWdpc3RyeS5yZWdpc3Rlck1hbmFnZXIoQnJvd3NlckluZGV4ZWREQi5VUkxfU0NIRU1FLG5ldyBCcm93c2VySW5kZXhlZERCTWFuYWdlcil9Y2F0Y2h7fX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBnZXROb2RlRmV0Y2g9e2ltcG9ydEZldGNoOigpPT5yZXF1aXJlKCJub2RlLWZldGNoIil9O2xldCBzeXN0ZW1GZXRjaDtjbGFzcyBQbGF0Zm9ybU5vZGV7Y29uc3RydWN0b3IoKXt0aGlzLnV0aWw9cmVxdWlyZSgidXRpbCIpLHRoaXMudGV4dEVuY29kZXI9bmV3IHRoaXMudXRpbC5UZXh0RW5jb2Rlcn1mZXRjaChhYSx4YSl7cmV0dXJuIGVudigpLmdsb2JhbC5mZXRjaCE9bnVsbD9lbnYoKS5nbG9iYWwuZmV0Y2goYWEseGEpOihzeXN0ZW1GZXRjaD09bnVsbCYmKHN5c3RlbUZldGNoPWdldE5vZGVGZXRjaC5pbXBvcnRGZXRjaCgpKSxzeXN0ZW1GZXRjaChhYSx4YSkpfW5vdygpe2NvbnN0IGFhPXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJuIGFhWzBdKjFlMythYVsxXS8xZTZ9ZW5jb2RlKGFhLHhhKXtpZih4YSE9PSJ1dGYtOCImJnhhIT09InV0ZjgiKXRocm93IG5ldyBFcnJvcihgTm9kZSBidWlsdC1pbiBlbmNvZGVyIG9ubHkgc3VwcG9ydHMgdXRmLTgsIGJ1dCBnb3QgJHt4YX1gKTtyZXR1cm4gdGhpcy50ZXh0RW5jb2Rlci5lbmNvZGUoYWEpfWRlY29kZShhYSx4YSl7cmV0dXJuIGFhLmxlbmd0aD09PTA/IiI6bmV3IHRoaXMudXRpbC5UZXh0RGVjb2Rlcih4YSkuZGVjb2RlKGFhKX1pc1R5cGVkQXJyYXkoYWEpe3JldHVybiB0aGlzLnV0aWwudHlwZXMuaXNGbG9hdDMyQXJyYXkoYWEpfHx0aGlzLnV0aWwudHlwZXMuaXNJbnQzMkFycmF5KGFhKXx8dGhpcy51dGlsLnR5cGVzLmlzVWludDhBcnJheShhYSl8fHRoaXMudXRpbC50eXBlcy5pc1VpbnQ4Q2xhbXBlZEFycmF5KGFhKX19ZW52KCkuZ2V0KCJJU19OT0RFIikmJiFlbnYoKS5nZXQoIklTX0JST1dTRVIiKSYmZW52KCkuc2V0UGxhdGZvcm0oIm5vZGUiLG5ldyBQbGF0Zm9ybU5vZGUpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJ1ZmZlcihoYSxhYT0iZmxvYXQzMiIseGEpe3JldHVybiBhYT1hYXx8ImZsb2F0MzIiLGFzc2VydE5vbk5lZ2F0aXZlSW50ZWdlckRpbWVuc2lvbnMoaGEpLG5ldyBUZW5zb3JCdWZmZXIoaGEsYWEseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNhc3RfKGhhLGFhKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IoaGEsIngiLCJjYXN0Iik7aWYoIWlzVmFsaWREdHlwZShhYSkpdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY2FzdCB0byB1bmtub3duIGR0eXBlICR7YWF9YCk7aWYoYWE9PT0ic3RyaW5nIiYmeGEuZHR5cGUhPT0ic3RyaW5nInx8YWEhPT0ic3RyaW5nIiYmeGEuZHR5cGU9PT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIk9ubHkgc3RyaW5ncyBjYW4gYmUgY2FzdGVkIHRvIHN0cmluZ3MiKTtjb25zdCBiYT17eDp4YX0sU2E9e2R0eXBlOmFhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChDYXN0LGJhLFNhKX1jb25zdCBjYXN0JDE9b3Aoe2Nhc3RffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2xvbmVfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IoaGEsIngiLCJjbG9uZSIsInN0cmluZ19vcl9udW1lcmljIil9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKElkZW50aXR5LHhhKX1jb25zdCBjbG9uZT1vcCh7Y2xvbmVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcHJpbnQoaGEsYWE9ITEpe2NvbnNvbGUubG9nKGhhLnRvU3RyaW5nKGFhKSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZ2V0T3JNYWtlRW5naW5lKCk7Y29uc3Qgb3BIYW5kbGVyPXtidWZmZXIsY2FzdDpjYXN0JDEsY2xvbmUscHJpbnR9O3NldE9wSGFuZGxlcihvcEhhbmRsZXIpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFkZF8oaGEsYWEpe2xldCB4YT1jb252ZXJ0VG9UZW5zb3IoaGEsImEiLCJhZGQiKSxiYT1jb252ZXJ0VG9UZW5zb3IoYWEsImIiLCJhZGQiKTtbeGEsYmFdPW1ha2VUeXBlc01hdGNoKHhhLGJhKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChBZGQsU2EpfWNvbnN0IGFkZD1vcCh7YWRkX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZsb29yRGl2XyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvcihoYSwiYSIsImZsb29yRGl2IiksYmE9Y29udmVydFRvVGVuc29yKGFhLCJiIiwiZmxvb3JEaXYiKTtbeGEsYmFdPW1ha2VUeXBlc01hdGNoKHhhLGJhKTtjb25zdCBTYT17YTp4YSxiOmJhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChGbG9vckRpdixTYSl9Y29uc3QgZmxvb3JEaXYkMT1vcCh7Zmxvb3JEaXZffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGl2XyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvcihoYSwiYSIsImRpdiIpLGJhPWNvbnZlcnRUb1RlbnNvcihhYSwiYiIsImRpdiIpO2lmKFt4YSxiYV09bWFrZVR5cGVzTWF0Y2goeGEsYmEpLHhhLmR0eXBlPT09ImludDMyIiYmYmEuZHR5cGU9PT0iaW50MzIiKXJldHVybiBmbG9vckRpdiQxKHhhLGJhKTtjb25zdCBTYT17YTp4YSxiOmJhfSxUYT17fTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChSZWFsRGl2LFNhLFRhKX1jb25zdCBkaXY9b3Aoe2Rpdl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtdWxfKGhhLGFhKXtsZXQgeGE9Y29udmVydFRvVGVuc29yKGhhLCJhIiwibXVsIiksYmE9Y29udmVydFRvVGVuc29yKGFhLCJiIiwibXVsIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoTXVsdGlwbHksU2EpfWNvbnN0IG11bD1vcCh7bXVsX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFic18oaGEpe2NvbnN0IGFhPWNvbnZlcnRUb1RlbnNvcihoYSwieCIsImFicyIpO2lmKGFhLmR0eXBlPT09ImNvbXBsZXg2NCIpe2NvbnN0IHhhPXt4OmFhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChDb21wbGV4QWJzLHhhKX1lbHNle2NvbnN0IHhhPXt4OmFhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChBYnMseGEpfX1jb25zdCBhYnMkMT1vcCh7YWJzX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbXB1dGVEaWxhdGlvbjJESW5mbyhoYSxhYSx4YSxiYSxTYT0iTkhXQyIsVGEpe2NvbnN0IHdhPWhhWzNdLEVhPVsuLi5hYSx3YV0sa2E9Y29udmVydENvbnYyRERhdGFGb3JtYXQoU2EpO3JldHVybiBjb21wdXRlQ29udjJESW5mbyhoYSxFYSx4YSxUYSxiYSxudWxsLG51bGwsa2EpfWZ1bmN0aW9uIGNvbXB1dGVQb29sMkRJbmZvKGhhLGFhLHhhLGJhLFNhLFRhLHdhPSJjaGFubmVsc0xhc3QiKXtjb25zdFtFYSxrYV09cGFyc2VUdXBsZVBhcmFtKGFhKTtsZXQgQWE7aWYod2E9PT0iY2hhbm5lbHNMYXN0IilBYT1bRWEsa2EsaGFbM10saGFbM11dO2Vsc2UgaWYod2E9PT0iY2hhbm5lbHNGaXJzdCIpQWE9W0VhLGthLGhhWzFdLGhhWzFdXTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhRm9ybWF0ICR7d2F9YCk7cmV0dXJuIGNvbXB1dGVDb252MkRJbmZvKGhhLEFhLHhhLGJhLFNhLFRhLCExLHdhKX1mdW5jdGlvbiBjb21wdXRlUG9vbDNESW5mbyhoYSxhYSx4YSxiYSxTYSxUYSx3YT0iTkRIV0MiKXtjb25zdFtFYSxrYSxBYV09cGFyc2UzVHVwbGVQYXJhbShhYSk7bGV0IEZhLExhO2lmKHdhPT09Ik5ESFdDIilMYT0iY2hhbm5lbHNMYXN0IixGYT1bRWEsa2EsQWEsaGFbNF0saGFbNF1dO2Vsc2UgaWYod2E9PT0iTkNESFciKUxhPSJjaGFubmVsc0ZpcnN0IixGYT1bRWEsa2EsQWEsaGFbMV0saGFbMV1dO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGFGb3JtYXQgJHt3YX1gKTtyZXR1cm4gY29tcHV0ZUNvbnYzREluZm8oaGEsRmEseGEsYmEsU2EsITEsTGEsVGEpfWZ1bmN0aW9uIGNvbXB1dGVDb252MkRJbmZvKGhhLGFhLHhhLGJhLFNhLFRhLHdhPSExLEVhPSJjaGFubmVsc0xhc3QiKXtsZXRba2EsQWEsRmEsTGFdPVstMSwtMSwtMSwtMV07aWYoRWE9PT0iY2hhbm5lbHNMYXN0Iilba2EsQWEsRmEsTGFdPWhhO2Vsc2UgaWYoRWE9PT0iY2hhbm5lbHNGaXJzdCIpW2thLExhLEFhLEZhXT1oYTtlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhRm9ybWF0ICR7RWF9YCk7Y29uc3RbZWwsdGwsLG5sXT1hYSxbc2wscmxdPXBhcnNlVHVwbGVQYXJhbSh4YSksW29sLGFsXT1wYXJzZVR1cGxlUGFyYW0oYmEpLGxsPWdldEVmZmVjdGl2ZUZpbHRlclNpemUoZWwsb2wpLGlsPWdldEVmZmVjdGl2ZUZpbHRlclNpemUodGwsYWwpLHtwYWRJbmZvOmNsLG91dEhlaWdodDp1bCxvdXRXaWR0aDpkbH09Z2V0UGFkQW5kT3V0SW5mbyhTYSxBYSxGYSxzbCxybCxsbCxpbCxUYSxFYSksaGw9d2E/bmwqTGE6bmw7bGV0IHBsO3JldHVybiBFYT09PSJjaGFubmVsc0ZpcnN0Ij9wbD1ba2EsaGwsdWwsZGxdOkVhPT09ImNoYW5uZWxzTGFzdCImJihwbD1ba2EsdWwsZGwsaGxdKSx7YmF0Y2hTaXplOmthLGRhdGFGb3JtYXQ6RWEsaW5IZWlnaHQ6QWEsaW5XaWR0aDpGYSxpbkNoYW5uZWxzOkxhLG91dEhlaWdodDp1bCxvdXRXaWR0aDpkbCxvdXRDaGFubmVsczpobCxwYWRJbmZvOmNsLHN0cmlkZUhlaWdodDpzbCxzdHJpZGVXaWR0aDpybCxmaWx0ZXJIZWlnaHQ6ZWwsZmlsdGVyV2lkdGg6dGwsZWZmZWN0aXZlRmlsdGVySGVpZ2h0OmxsLGVmZmVjdGl2ZUZpbHRlcldpZHRoOmlsLGRpbGF0aW9uSGVpZ2h0Om9sLGRpbGF0aW9uV2lkdGg6YWwsaW5TaGFwZTpoYSxvdXRTaGFwZTpwbCxmaWx0ZXJTaGFwZTphYX19ZnVuY3Rpb24gY29tcHV0ZUNvbnYzREluZm8oaGEsYWEseGEsYmEsU2EsVGE9ITEsd2E9ImNoYW5uZWxzTGFzdCIsRWEpe2xldFtrYSxBYSxGYSxMYSxlbF09Wy0xLC0xLC0xLC0xLC0xXTtpZih3YT09PSJjaGFubmVsc0xhc3QiKVtrYSxBYSxGYSxMYSxlbF09aGE7ZWxzZSBpZih3YT09PSJjaGFubmVsc0ZpcnN0Iilba2EsZWwsQWEsRmEsTGFdPWhhO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGFGb3JtYXQgJHt3YX1gKTtjb25zdFt0bCxubCxzbCwscmxdPWFhLFtvbCxhbCxsbF09cGFyc2UzVHVwbGVQYXJhbSh4YSksW2lsLGNsLHVsXT1wYXJzZTNUdXBsZVBhcmFtKGJhKSxkbD1nZXRFZmZlY3RpdmVGaWx0ZXJTaXplKHRsLGlsKSxobD1nZXRFZmZlY3RpdmVGaWx0ZXJTaXplKG5sLGNsKSxwbD1nZXRFZmZlY3RpdmVGaWx0ZXJTaXplKHNsLHVsKSx7cGFkSW5mbzpmbCxvdXREZXB0aDptbCxvdXRIZWlnaHQ6Z2wsb3V0V2lkdGg6JGx9PWdldDNEUGFkQW5kT3V0SW5mbyhTYSxBYSxGYSxMYSxvbCxhbCxsbCxkbCxobCxwbCxFYSkseGw9VGE/cmwqZWw6cmw7bGV0IHlsO3JldHVybiB3YT09PSJjaGFubmVsc0ZpcnN0Ij95bD1ba2EseGwsbWwsZ2wsJGxdOndhPT09ImNoYW5uZWxzTGFzdCImJih5bD1ba2EsbWwsZ2wsJGwseGxdKSx7YmF0Y2hTaXplOmthLGRhdGFGb3JtYXQ6d2EsaW5EZXB0aDpBYSxpbkhlaWdodDpGYSxpbldpZHRoOkxhLGluQ2hhbm5lbHM6ZWwsb3V0RGVwdGg6bWwsb3V0SGVpZ2h0OmdsLG91dFdpZHRoOiRsLG91dENoYW5uZWxzOnhsLHBhZEluZm86Zmwsc3RyaWRlRGVwdGg6b2wsc3RyaWRlSGVpZ2h0OmFsLHN0cmlkZVdpZHRoOmxsLGZpbHRlckRlcHRoOnRsLGZpbHRlckhlaWdodDpubCxmaWx0ZXJXaWR0aDpzbCxlZmZlY3RpdmVGaWx0ZXJEZXB0aDpkbCxlZmZlY3RpdmVGaWx0ZXJIZWlnaHQ6aGwsZWZmZWN0aXZlRmlsdGVyV2lkdGg6cGwsZGlsYXRpb25EZXB0aDppbCxkaWxhdGlvbkhlaWdodDpjbCxkaWxhdGlvbldpZHRoOnVsLGluU2hhcGU6aGEsb3V0U2hhcGU6eWwsZmlsdGVyU2hhcGU6YWF9fWZ1bmN0aW9uIGNvbXB1dGVPdXRwdXRTaGFwZTJEKGhhLGFhLHhhLGJhLFNhKXtiYT09bnVsbCYmKGJhPWNvbXB1dGVEZWZhdWx0UGFkKGhhLGFhLHhhKSk7Y29uc3QgVGE9aGFbMF0sd2E9aGFbMV0sRWE9cm91bmQkMSgoVGEtYWErMipiYSkveGErMSxTYSksa2E9cm91bmQkMSgod2EtYWErMipiYSkveGErMSxTYSk7cmV0dXJuW0VhLGthXX1mdW5jdGlvbiBjb21wdXRlT3V0cHV0U2hhcGU0RChoYSxhYSx4YSxiYSxTYSxUYSl7U2E9PW51bGwmJihTYT1jb21wdXRlRGVmYXVsdFBhZChoYSxhYVswXSxiYVswXSkpO2NvbnN0IHdhPVswLDAsMCx4YV07Zm9yKGxldCBFYT0wO0VhPDM7RWErKyloYVtFYV0rMipTYT49YWFbRWFdJiYod2FbRWFdPXJvdW5kJDEoKGhhW0VhXS1hYVtFYV0rMipTYSkvYmFbRWFdKzEsVGEpKTtyZXR1cm4gd2F9ZnVuY3Rpb24gY29tcHV0ZURlZmF1bHRQYWQoaGEsYWEseGEsYmE9MSl7Y29uc3QgU2E9Z2V0RWZmZWN0aXZlRmlsdGVyU2l6ZShhYSxiYSk7cmV0dXJuIE1hdGguZmxvb3IoKGhhWzBdKih4YS0xKS14YStTYSkvMil9ZnVuY3Rpb24gcGFyc2VUdXBsZVBhcmFtKGhhKXtyZXR1cm4gdHlwZW9mIGhhPT0ibnVtYmVyIj9baGEsaGEsaGFdOmhhLmxlbmd0aD09PTI/W2hhWzBdLGhhWzFdLDFdOmhhfWZ1bmN0aW9uIHBhcnNlM1R1cGxlUGFyYW0oaGEpe3JldHVybiB0eXBlb2YgaGE9PSJudW1iZXIiP1toYSxoYSxoYV06aGF9ZnVuY3Rpb24gZ2V0RWZmZWN0aXZlRmlsdGVyU2l6ZShoYSxhYSl7cmV0dXJuIGFhPD0xP2hhOmhhKyhoYS0xKSooYWEtMSl9ZnVuY3Rpb24gZ2V0UGFkQW5kT3V0SW5mbyhoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSl7bGV0IEFhLEZhLExhO2lmKHR5cGVvZiBoYT09Im51bWJlciIpe0FhPXt0b3A6aGEsYm90dG9tOmhhLGxlZnQ6aGEscmlnaHQ6aGEsdHlwZTpoYT09PTA/IlZBTElEIjoiTlVNQkVSIn07Y29uc3QgdGw9Y29tcHV0ZU91dHB1dFNoYXBlMkQoW2FhLHhhXSxUYSxiYSxoYSxFYSk7RmE9dGxbMF0sTGE9dGxbMV19ZWxzZSBpZihoYT09PSJzYW1lIil7RmE9TWF0aC5jZWlsKGFhL2JhKSxMYT1NYXRoLmNlaWwoeGEvU2EpO2NvbnN0IGVsPU1hdGgubWF4KDAsKEZhLTEpKmJhK1RhLWFhKSx0bD1NYXRoLm1heCgwLChMYS0xKSpTYSt3YS14YSksbmw9TWF0aC5mbG9vcihlbC8yKSxzbD1lbC1ubCxybD1NYXRoLmZsb29yKHRsLzIpLG9sPXRsLXJsO0FhPXt0b3A6bmwsYm90dG9tOnNsLGxlZnQ6cmwscmlnaHQ6b2wsdHlwZToiU0FNRSJ9fWVsc2UgaWYoaGE9PT0idmFsaWQiKUFhPXt0b3A6MCxib3R0b206MCxsZWZ0OjAscmlnaHQ6MCx0eXBlOiJWQUxJRCJ9LEZhPU1hdGguY2VpbCgoYWEtVGErMSkvYmEpLExhPU1hdGguY2VpbCgoeGEtd2ErMSkvU2EpO2Vsc2UgaWYodHlwZW9mIGhhPT0ib2JqZWN0Iil7Y29uc3QgZWw9a2E9PT0iY2hhbm5lbHNMYXN0Ij9oYVsxXVswXTpoYVsyXVswXSx0bD1rYT09PSJjaGFubmVsc0xhc3QiP2hhWzFdWzFdOmhhWzJdWzFdLG5sPWthPT09ImNoYW5uZWxzTGFzdCI/aGFbMl1bMF06aGFbM11bMF0sc2w9a2E9PT0iY2hhbm5lbHNMYXN0Ij9oYVsyXVsxXTpoYVszXVsxXTtBYT17dG9wOmVsLGJvdHRvbTp0bCxsZWZ0Om5sLHJpZ2h0OnNsLHR5cGU6ZWw9PT0wJiZ0bD09PTAmJm5sPT09MCYmc2w9PT0wPyJWQUxJRCI6IkVYUExJQ0lUIn0sRmE9cm91bmQkMSgoYWEtVGErZWwrdGwpL2JhKzEsRWEpLExhPXJvdW5kJDEoKHhhLXdhK25sK3NsKS9TYSsxLEVhKX1lbHNlIHRocm93IEVycm9yKGBVbmtub3duIHBhZGRpbmcgcGFyYW1ldGVyOiAke2hhfWApO3JldHVybntwYWRJbmZvOkFhLG91dEhlaWdodDpGYSxvdXRXaWR0aDpMYX19ZnVuY3Rpb24gZ2V0M0RQYWRBbmRPdXRJbmZvKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthLEFhLEZhKXtsZXQgTGEsZWwsdGwsbmw7aWYoaGE9PT0idmFsaWQiJiYoaGE9MCksdHlwZW9mIGhhPT0ibnVtYmVyIil7TGE9e3RvcDpoYSxib3R0b206aGEsbGVmdDpoYSxyaWdodDpoYSxmcm9udDpoYSxiYWNrOmhhLHR5cGU6aGE9PT0wPyJWQUxJRCI6Ik5VTUJFUiJ9O2NvbnN0IHJsPWNvbXB1dGVPdXRwdXRTaGFwZTREKFthYSx4YSxiYSwxXSxbRWEsa2EsQWFdLDEsW1NhLFRhLHdhXSxoYSxGYSk7ZWw9cmxbMF0sdGw9cmxbMV0sbmw9cmxbMl19ZWxzZSBpZihoYT09PSJzYW1lIil7ZWw9TWF0aC5jZWlsKGFhL1NhKSx0bD1NYXRoLmNlaWwoeGEvVGEpLG5sPU1hdGguY2VpbChiYS93YSk7Y29uc3Qgc2w9KGVsLTEpKlNhK0VhLWFhLHJsPSh0bC0xKSpUYStrYS14YSxvbD0obmwtMSkqd2ErQWEtYmEsYWw9TWF0aC5mbG9vcihzbC8yKSxsbD1zbC1hbCxpbD1NYXRoLmZsb29yKHJsLzIpLGNsPXJsLWlsLHVsPU1hdGguZmxvb3Iob2wvMiksZGw9b2wtdWw7TGE9e3RvcDppbCxib3R0b206Y2wsbGVmdDp1bCxyaWdodDpkbCxmcm9udDphbCxiYWNrOmxsLHR5cGU6IlNBTUUifX1lbHNlIHRocm93IEVycm9yKGBVbmtub3duIHBhZGRpbmcgcGFyYW1ldGVyOiAke2hhfWApO3JldHVybntwYWRJbmZvOkxhLG91dERlcHRoOmVsLG91dEhlaWdodDp0bCxvdXRXaWR0aDpubH19ZnVuY3Rpb24gcm91bmQkMShoYSxhYSl7aWYoIWFhKXJldHVybiBNYXRoLnRydW5jKGhhKTtzd2l0Y2goYWEpe2Nhc2Uicm91bmQiOnJldHVybiBNYXRoLnJvdW5kKGhhKTtjYXNlImNlaWwiOnJldHVybiBNYXRoLmNlaWwoaGEpO2Nhc2UiZmxvb3IiOnJldHVybiBNYXRoLmZsb29yKGhhKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgVW5rbm93biByb3VuZGluZ01vZGUgJHthYX1gKX19ZnVuY3Rpb24gdHVwbGVWYWx1ZXNBcmVPbmUoaGEpe2NvbnN0W2FhLHhhLGJhXT1wYXJzZVR1cGxlUGFyYW0oaGEpO3JldHVybiBhYT09PTEmJnhhPT09MSYmYmE9PT0xfWZ1bmN0aW9uIGVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZShoYSxhYSl7cmV0dXJuIHR1cGxlVmFsdWVzQXJlT25lKGhhKXx8dHVwbGVWYWx1ZXNBcmVPbmUoYWEpfWZ1bmN0aW9uIHN0cmlkZXNPckRpbGF0aW9uc0FyZVBvc2l0aXZlKGhhKXtyZXR1cm4gcGFyc2VUdXBsZVBhcmFtKGhhKS5ldmVyeShhYT0+YWE+MCl9ZnVuY3Rpb24gY29udmVydENvbnYyRERhdGFGb3JtYXQoaGEpe2lmKGhhPT09Ik5IV0MiKXJldHVybiJjaGFubmVsc0xhc3QiO2lmKGhhPT09Ik5DSFciKXJldHVybiJjaGFubmVsc0ZpcnN0Ijt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YUZvcm1hdCAke2hhfWApfWZ1bmN0aW9uIGNoZWNrUGFkT25EaW1Sb3VuZGluZ01vZGUoaGEsYWEseGEpe2lmKHhhIT1udWxsKXtpZih0eXBlb2YgYWE9PSJzdHJpbmciKXRocm93IEVycm9yKGBFcnJvciBpbiAke2hhfTogcGFkIG11c3QgYmUgYW4gaW50ZWdlciB3aGVuIHVzaW5nIGRpbVJvdW5kaW5nTW9kZSAke3hhfSBidXQgZ290IHBhZCAke2FhfS5gKTtpZih0eXBlb2YgYWE9PSJudW1iZXIiKWFzc2VydChpc0ludChhYSksKCk9PmBFcnJvciBpbiAke2hhfTogcGFkIG11c3QgYmUgYW4gaW50ZWdlciB3aGVuIHVzaW5nIGRpbVJvdW5kaW5nTW9kZSAke3hhfSBidXQgZ290IHBhZCAke2FhfS5gKTtlbHNlIGlmKHR5cGVvZiBhYT09Im9iamVjdCIpYWEuZm9yRWFjaChiYT0+e2JhLmZvckVhY2goU2E9Pnthc3NlcnQoaXNJbnQoU2EpLCgpPT5gRXJyb3IgaW4gJHtoYX06IHBhZCBtdXN0IGJlIGFuIGludGVnZXIgd2hlbiB1c2luZyBkaW1Sb3VuZGluZ01vZGUgJHt4YX0gYnV0IGdvdCBwYWQgJHtTYX0uYCl9KX0pO2Vsc2UgdGhyb3cgRXJyb3IoYEVycm9yIGluICR7aGF9OiBVbmtub3duIHBhZGRpbmcgcGFyYW1ldGVyOiAke2FhfWApfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNoYXBlXyhoYSxhYSl7Y29uc3QgYmE9e3g6Y29udmVydFRvVGVuc29yKGhhLCJ4IiwicmVzaGFwZSIsInN0cmluZ19vcl9udW1lcmljIil9LFNhPXtzaGFwZTphYX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoUmVzaGFwZSxiYSxTYSl9Y29uc3QgcmVzaGFwZSQxPW9wKHtyZXNoYXBlX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNpZ21vaWRfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IoaGEsIngiLCJzaWdtb2lkIiwiZmxvYXQzMiIpfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChTaWdtb2lkLHhhKX1jb25zdCBzaWdtb2lkJDE9b3Aoe3NpZ21vaWRffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYnJvYWRjYXN0VG9fKGhhLGFhKXtsZXQgeGE9Y29udmVydFRvVGVuc29yKGhhLCJicm9hZGNhc3RUbyIsIngiKTtjb25zdCBiYT14YS5zaGFwZTtpZihhc3NlcnROb25OZWdhdGl2ZUludGVnZXJEaW1lbnNpb25zKGFhKSxhYS5sZW5ndGg8eGEucmFuayl0aHJvdyBuZXcgRXJyb3IoYGJyb2FkY2FzdFRvKCk6IHNoYXBlLmxlbmd0aD0ke2FhLmxlbmd0aH0gPCBpbnB1dC5yYW5rPSR7eGEucmFua30uYCk7aWYoYWEubGVuZ3RoPnhhLnJhbmspe2NvbnN0IEFhPXhhLnNoYXBlLnNsaWNlKCk7Zm9yKDtBYS5sZW5ndGg8YWEubGVuZ3RoOylBYS51bnNoaWZ0KDEpO3hhPXJlc2hhcGUkMSh4YSxBYSl9Y29uc3QgU2E9eGEuc2hhcGUsVGE9QXJyYXkuZnJvbShhYSk7Zm9yKGxldCBBYT1hYS5sZW5ndGgtMTtBYT49MDtBYS0tKWlmKFNhW0FhXT09PWFhW0FhXSlUYVtBYV09MTtlbHNlIGlmKHhhLnNoYXBlW0FhXSE9PTEpdGhyb3cgbmV3IEVycm9yKGBicm9hZGNhc3RUbygpOiBbJHtiYX1dIGNhbm5vdCBiZSBicm9hZGNhc3QgdG8gWyR7YWF9XS5gKTtpZihUYS5tYXAoKEFhLEZhKT0+QWE+MT9GYTotMSkuZmlsdGVyKEFhPT5BYT49MCkubGVuZ3RoPT09MClyZXR1cm4gY2xvbmUoeGEpO2NvbnN0IEVhPXt4OnhhfSxrYT17cmVwczpUYX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoVGlsZSxFYSxrYSl9Y29uc3QgYnJvYWRjYXN0VG89b3Aoe2Jyb2FkY2FzdFRvX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZpbGwkMShoYSxhYSx4YSl7YXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyhoYSkseGE9eGF8fGluZmVyRHR5cGUoYWEpO2NvbnN0IGJhPXtzaGFwZTpoYSx2YWx1ZTphYSxkdHlwZTp4YX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoRmlsbCx7fSxiYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0QnJvYWRjYXN0RGltcyQxKGhhLGFhKXtjb25zdCB4YT1oYS5sZW5ndGgsYmE9W107Zm9yKGxldCBTYT0wO1NhPHhhO1NhKyspe2NvbnN0IFRhPXhhLTEtU2Esd2E9aGFbVGFdfHwxOyhhYVthYS5sZW5ndGgtMS1TYV18fDEpPjEmJndhPT09MSYmYmEudW5zaGlmdChUYSl9cmV0dXJuIGJhfWZ1bmN0aW9uIGdldFJlZHVjdGlvbkF4ZXMoaGEsYWEpe2NvbnN0IHhhPVtdO2ZvcihsZXQgYmE9MDtiYTxhYS5sZW5ndGg7YmErKyl7Y29uc3QgU2E9aGFbaGEubGVuZ3RoLWJhLTFdLFRhPWFhLmxlbmd0aC1iYS0xLHdhPWFhW1RhXTsoU2E9PW51bGx8fFNhPT09MSYmd2E+MSkmJnhhLnVuc2hpZnQoVGEpfXJldHVybiB4YX1mdW5jdGlvbiBhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZShoYSxhYSl7Y29uc3QgeGE9TWF0aC5tYXgoaGEubGVuZ3RoLGFhLmxlbmd0aCksYmE9bmV3IEFycmF5KHhhKTtmb3IobGV0IFNhPTA7U2E8eGE7U2ErKyl7bGV0IFRhPWhhW2hhLmxlbmd0aC1TYS0xXTtUYT09bnVsbCYmKFRhPTEpO2xldCB3YT1hYVthYS5sZW5ndGgtU2EtMV07aWYod2E9PW51bGwmJih3YT0xKSxUYT09PTEpYmFbeGEtU2EtMV09d2E7ZWxzZSBpZih3YT09PTEpYmFbeGEtU2EtMV09VGE7ZWxzZSBpZihUYSE9PXdhKXtjb25zdCBFYT1gT3BlcmFuZHMgY291bGQgbm90IGJlIGJyb2FkY2FzdCB0b2dldGhlciB3aXRoIHNoYXBlcyAke2hhfSBhbmQgJHthYX0uYDt0aHJvdyBFcnJvcihFYSl9ZWxzZSBiYVt4YS1TYS0xXT1UYX1yZXR1cm4gYmF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gemVyb3NMaWtlXyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yKGhhLCJ4IiwiemVyb3NMaWtlIil9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKFplcm9zTGlrZSx4YSl9Y29uc3QgemVyb3NMaWtlJDE9b3Aoe3plcm9zTGlrZV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBlbHVfKGhhKXtjb25zdCB4YT17eDpjb252ZXJ0VG9UZW5zb3IoaGEsIngiLCJlbHUiLCJmbG9hdDMyIil9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKEVsdSx4YSl9Y29uc3QgZWx1JDE9b3Aoe2VsdV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBheGVzQXJlSW5uZXJNb3N0RGltcyhoYSxhYSl7Zm9yKGxldCB4YT0wO3hhPGhhLmxlbmd0aDsrK3hhKWlmKGhhW2hhLmxlbmd0aC14YS0xXSE9PWFhLTEteGEpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gY29tYmluZUxvY2F0aW9ucyhoYSxhYSx4YSl7Y29uc3QgYmE9aGEubGVuZ3RoK2FhLmxlbmd0aCxTYT1bXTtsZXQgVGE9MCx3YT0wO2ZvcihsZXQgRWE9MDtFYTxiYTtFYSsrKXhhLmluZGV4T2YoRWEpPT09LTE/U2EucHVzaChoYVtUYSsrXSk6U2EucHVzaChhYVt3YSsrXSk7cmV0dXJuIFNhfWZ1bmN0aW9uIGNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoaGEsYWEpe2NvbnN0IHhhPVtdLGJhPWhhLmxlbmd0aDtmb3IobGV0IFRhPTA7VGE8YmE7VGErKylhYS5pbmRleE9mKFRhKT09PS0xJiZ4YS5wdXNoKGhhW1RhXSk7Y29uc3QgU2E9YWEubWFwKFRhPT5oYVtUYV0pO3JldHVyblt4YSxTYV19ZnVuY3Rpb24gZXhwYW5kU2hhcGVUb0tlZXBEaW0oaGEsYWEpe2NvbnN0IHhhPWFhLm1hcChiYT0+MSk7cmV0dXJuIGNvbWJpbmVMb2NhdGlvbnMoaGEseGEsYWEpfWZ1bmN0aW9uIGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zKGhhLGFhLHhhKXthc3NlcnQoYXhlc0FyZUlubmVyTW9zdERpbXMoYWEseGEpLCgpPT5gJHtoYX0gc3VwcG9ydHMgb25seSBpbm5lci1tb3N0IGF4ZXMgZm9yIG5vdy4gR290IGF4ZXMgJHthYX0gYW5kIHJhbmstJHt4YX0gaW5wdXQuYCl9ZnVuY3Rpb24gZ2V0QXhlc1Blcm11dGF0aW9uKGhhLGFhKXtpZihheGVzQXJlSW5uZXJNb3N0RGltcyhoYSxhYSkpcmV0dXJuIG51bGw7Y29uc3QgeGE9W107Zm9yKGxldCBiYT0wO2JhPGFhOysrYmEpaGEuaW5kZXhPZihiYSk9PT0tMSYmeGEucHVzaChiYSk7cmV0dXJuIGhhLmZvckVhY2goYmE9PnhhLnB1c2goYmEpKSx4YX1mdW5jdGlvbiBnZXRVbmRvQXhlc1Blcm11dGF0aW9uKGhhKXtyZXR1cm4gaGEubWFwKChhYSx4YSk9Plt4YSxhYV0pLnNvcnQoKGFhLHhhKT0+YWFbMV0teGFbMV0pLm1hcChhYT0+YWFbMF0pfWZ1bmN0aW9uIGdldElubmVyTW9zdEF4ZXMoaGEsYWEpe2NvbnN0IHhhPVtdO2ZvcihsZXQgYmE9YWEtaGE7YmE8YWE7KytiYSl4YS5wdXNoKGJhKTtyZXR1cm4geGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcG93XyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvcihoYSwiYmFzZSIsInBvdyIpLGJhPWNvbnZlcnRUb1RlbnNvcihhYSwiZXhwIiwicG93Iik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCh4YSxiYSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoUG93LFNhKX1jb25zdCBwb3ckMT1vcCh7cG93X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNjYWxhcihoYSxhYSl7aWYoKGlzVHlwZWRBcnJheShoYSkmJmFhIT09InN0cmluZyJ8fEFycmF5LmlzQXJyYXkoaGEpKSYmYWEhPT0iY29tcGxleDY0Iil0aHJvdyBuZXcgRXJyb3IoIkVycm9yIGNyZWF0aW5nIGEgbmV3IFNjYWxhcjogdmFsdWUgbXVzdCBiZSBhIHByaW1pdGl2ZSAobnVtYmVyfGJvb2xlYW58c3RyaW5nKSIpO2lmKGFhPT09InN0cmluZyImJmlzVHlwZWRBcnJheShoYSkmJiEoaGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSl0aHJvdyBuZXcgRXJyb3IoIldoZW4gbWFraW5nIGEgc2NhbGFyIGZyb20gZW5jb2RlZCBzdHJpbmcsIHRoZSB2YWx1ZSBtdXN0IGJlIGBVaW50OEFycmF5YC4iKTtyZXR1cm4gbWFrZVRlbnNvcihoYSxbXSxbXSxhYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3FydF8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvcihoYSwieCIsInNxcnQiLCJmbG9hdDMyIil9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKFNxcnQseGEpfWNvbnN0IHNxcnQkMT1vcCh7c3FydF99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcXVhcmVfKGhhKXtjb25zdCBhYT1jb252ZXJ0VG9UZW5zb3IoaGEsIngiLCJzcXVhcmUiKSx4YT17fTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbCgiU3F1YXJlIix7eDphYX0seGEpfWNvbnN0IHNxdWFyZSQxPW9wKHtzcXVhcmVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3VtXyhoYSxhYT1udWxsLHhhPSExKXtsZXQgYmE9Y29udmVydFRvVGVuc29yKGhhLCJ4Iiwic3VtIik7YmEuZHR5cGU9PT0iYm9vbCImJihiYT1jYXN0JDEoYmEsImludDMyIikpO2NvbnN0IFNhPXt4OmJhfSxUYT17YXhpczphYSxrZWVwRGltczp4YX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoU3VtLFNhLFRhKX1jb25zdCBzdW0kMT1vcCh7c3VtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxlYWt5UmVsdV8oaGEsYWE9LjIpe2NvbnN0IGJhPXt4OmNvbnZlcnRUb1RlbnNvcihoYSwieCIsImxlYWt5UmVsdSIpfSxTYT17YWxwaGE6YWF9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKExlYWt5UmVsdSxiYSxTYSl9Y29uc3QgbGVha3lSZWx1JDE9b3Aoe2xlYWt5UmVsdV99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB2YXJpYWJsZUdyYWRzKGhhLGFhKXthc3NlcnQoaXNGdW5jdGlvbihoYSksKCk9PiJUaGUgZiBwYXNzZWQgaW4gdmFyaWFibGVHcmFkcyhmKSBtdXN0IGJlIGEgZnVuY3Rpb24iKSxhc3NlcnQoYWE9PW51bGx8fEFycmF5LmlzQXJyYXkoYWEpJiZhYS5ldmVyeShBYT0+QWEgaW5zdGFuY2VvZiBWYXJpYWJsZSksKCk9PiJUaGUgdmFyTGlzdCBwYXNzZWQgaW4gdmFyaWFibGVHcmFkcyhmLCB2YXJMaXN0KSBtdXN0IGJlIGFuIGFycmF5IG9mIHZhcmlhYmxlcyIpO2NvbnN0IHhhPWFhIT1udWxsO2lmKCF4YSl7YWE9W107Zm9yKGNvbnN0IEFhIGluIEVOR0lORS5yZWdpc3RlcmVkVmFyaWFibGVzKWFhLnB1c2goRU5HSU5FLnJlZ2lzdGVyZWRWYXJpYWJsZXNbQWFdKX1jb25zdCBiYT14YT9hYS5maWx0ZXIoQWE9PiFBYS50cmFpbmFibGUpOm51bGwsU2E9YWEubGVuZ3RoO2FhPWFhLmZpbHRlcihBYT0+QWEudHJhaW5hYmxlKSxhc3NlcnQoYWEubGVuZ3RoPjAsKCk9PmB2YXJpYWJsZUdyYWRzKCkgZXhwZWN0cyBhdCBsZWFzdCBvbmUgb2YgdGhlIGlucHV0IHZhcmlhYmxlcyB0byBiZSB0cmFpbmFibGUsIGJ1dCBub25lIG9mIHRoZSAke1NhfSB2YXJpYWJsZXMgaXMgdHJhaW5hYmxlLmApO2NvbnN0IFRhPSEwLHt2YWx1ZTp3YSxncmFkczpFYX09RU5HSU5FLmdyYWRpZW50cyhoYSxhYSxudWxsLFRhKTthc3NlcnQoRWEuc29tZShBYT0+QWEhPW51bGwpLCgpPT4iQ2Fubm90IGZpbmQgYSBjb25uZWN0aW9uIGJldHdlZW4gYW55IHZhcmlhYmxlIGFuZCB0aGUgcmVzdWx0IG9mIHRoZSBsb3NzIGZ1bmN0aW9uIHk9Zih4KS4gUGxlYXNlIG1ha2Ugc3VyZSB0aGUgb3BlcmF0aW9ucyB0aGF0IHVzZSB2YXJpYWJsZXMgYXJlIGluc2lkZSB0aGUgZnVuY3Rpb24gZiBwYXNzZWQgdG8gbWluaW1pemUoKS4iKSxhc3NlcnQod2EucmFuaz09PTAsKCk9PmBUaGUgZiBwYXNzZWQgaW4gdmFyaWFibGVHcmFkcyhmKSBtdXN0IHJldHVybiBhIHNjYWxhciwgYnV0IGl0IHJldHVybmVkIGEgcmFuay0ke3dhLnJhbmt9IHRlbnNvcmApO2NvbnN0IGthPXt9O3JldHVybiBhYS5mb3JFYWNoKChBYSxGYSk9PntFYVtGYV0hPW51bGwmJihrYVtBYS5uYW1lXT1FYVtGYV0pfSksYmEhPW51bGwmJmJhLmZvckVhY2goQWE9PmthW0FhLm5hbWVdPW51bGwpLHt2YWx1ZTp3YSxncmFkczprYX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3ViXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvcihoYSwiYSIsInN1YiIpLGJhPWNvbnZlcnRUb1RlbnNvcihhYSwiYiIsInN1YiIpO1t4YSxiYV09bWFrZVR5cGVzTWF0Y2goeGEsYmEpO2NvbnN0IFNhPXthOnhhLGI6YmF9O3JldHVybiBFTkdJTkUucnVuS2VybmVsKFN1YixTYSl9Y29uc3Qgc3ViJDE9b3Aoe3N1Yl99KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhpbXVtXyhoYSxhYSl7bGV0IHhhPWNvbnZlcnRUb1RlbnNvcihoYSwiYSIsIm1heGltdW0iKSxiYT1jb252ZXJ0VG9UZW5zb3IoYWEsImIiLCJtYXhpbXVtIik7W3hhLGJhXT1tYWtlVHlwZXNNYXRjaCh4YSxiYSkseGEuZHR5cGU9PT0iYm9vbCImJih4YT1jYXN0JDEoeGEsImludDMyIiksYmE9Y2FzdCQxKGJhLCJpbnQzMiIpKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSh4YS5zaGFwZSxiYS5zaGFwZSk7Y29uc3QgU2E9e2E6eGEsYjpiYX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoTWF4aW11bSxTYSl9Y29uc3QgbWF4aW11bSQxPW9wKHttYXhpbXVtX30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHplcm9zKGhhLGFhPSJmbG9hdDMyIil7aWYoYXNzZXJ0Tm9uTmVnYXRpdmVJbnRlZ2VyRGltZW5zaW9ucyhoYSksYWE9PT0iY29tcGxleDY0Iil7Y29uc3QgYmE9emVyb3MoaGEsImZsb2F0MzIiKSxTYT16ZXJvcyhoYSwiZmxvYXQzMiIpO3JldHVybiBjb21wbGV4JDEoYmEsU2EpfWNvbnN0IHhhPW1ha2VaZXJvc1R5cGVkQXJyYXkoc2l6ZUZyb21TaGFwZShoYSksYWEpO3JldHVybiBFTkdJTkUubWFrZVRlbnNvcih4YSxoYSxhYSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcHJlbHVfKGhhLGFhKXtjb25zdCB4YT1jb252ZXJ0VG9UZW5zb3IoaGEsIngiLCJwcmVsdSIpLGJhPWNvbnZlcnRUb1RlbnNvcihhYSwiYWxwaGEiLCJwcmVsdSIpLFNhPXt4OnhhLGFscGhhOmJhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChQcmVsdSxTYSl9Y29uc3QgcHJlbHUkMT1vcCh7cHJlbHVffSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVsdV8oaGEpe2NvbnN0IHhhPXt4OmNvbnZlcnRUb1RlbnNvcihoYSwieCIsInJlbHUiKX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoUmVsdSx4YSl9Y29uc3QgcmVsdSQxPW9wKHtyZWx1X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJlbHU2XyhoYSl7Y29uc3QgeGE9e3g6Y29udmVydFRvVGVuc29yKGhhLCJ4IiwicmVsdTYiKX07cmV0dXJuIEVOR0lORS5ydW5LZXJuZWwoUmVsdTYseGEpfWNvbnN0IHJlbHU2JDE9b3Aoe3JlbHU2X30pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0ZXBfKGhhLGFhPTApe2NvbnN0IGJhPXt4OmNvbnZlcnRUb1RlbnNvcihoYSwieCIsInN0ZXAiKX0sU2E9e2FscGhhOmFhfTtyZXR1cm4gRU5HSU5FLnJ1bktlcm5lbChTdGVwLGJhLFNhKX1jb25zdCBzdGVwJDE9b3Aoe3N0ZXBffSk7ZnVuY3Rpb24gdmFsaWRhdGVVcGRhdGVTaGFwZShoYSxhYSx4YSl7Y29uc3QgYmE9YWEucmFuaz4xP2FhLnNoYXBlW2FhLnJhbmstMV06MSxTYT1hYS5yYW5rPjE/YWEucmFuay0xOjEsVGE9YE11c3QgaGF2ZSB1cGRhdGVzLnNoYXBlID0gaW5kaWNlcy5zaGFwZVs6YmF0Y2hEaW1dICsgc2hhcGVbc2xpY2VEaW06XSwgZ290IHVwZGF0ZXMuc2hhcGU6ICR7eGEuc2hhcGV9LCBpbmRpY2VzLnNoYXBlOiAke2FhLnNoYXBlfSwgc2hhcGU6ICR7aGF9LCBzbGljZURpbTogJHtiYX0sIGFuZCBiYXRjaERpbTogJHtTYX0uYDtpZih4YS5yYW5rPFNhKXRocm93IG5ldyBFcnJvcihUYStgIHVwZGF0ZS5yYW5rIDwgJHtTYX0uIGApO2lmKGhhLmxlbmd0aDxiYSsoeGEucmFuay1TYSkpdGhyb3cgbmV3IEVycm9yKFRhK2AgT3V0cHV0IHNoYXBlIGxlbmd0aCA8ICR7YmErKHhhLnJhbmstU2EpfWApO2lmKHhhLnJhbmshPT1TYStoYS5sZW5ndGgtYmEpdGhyb3cgbmV3IEVycm9yKFRhK2AgdXBkYXRlLnJhbmsgIT0gJHtTYStoYS5sZW5ndGgtYmF9YCk7Zm9yKGxldCB3YT0wO3dhPFNhOysrd2EpaWYoeGEuc2hhcGVbd2FdIT09YWEuc2hhcGVbd2FdKXRocm93IG5ldyBFcnJvcihUYStgIHVwZGF0ZXMuc2hhcGVbJHt3YX1dICgke3hhLnNoYXBlW3dhXX0pICE9IGluZGljZXMuc2hhcGVbJHt3YX1dICgke2FhLnNoYXBlW3dhXX0pLmApO2ZvcihsZXQgd2E9MDt3YTx4YS5yYW5rLVNhOysrd2EpaWYoeGEuc2hhcGVbd2ErU2FdIT09aGFbd2ErYmFdKXRocm93IG5ldyBFcnJvcihUYStgIHVwZGF0ZXMuc2hhcGVbJHt3YStTYX1dICgke3hhLnNoYXBlW3dhK1NhXX0pICE9IHNoYXBlWyR7d2ErU2F9XSAoJHtoYVt3YStTYV19KWApfWZ1bmN0aW9uIHZhbGlkYXRlSW5wdXQoaGEsYWEseGEpe2lmKGFhLnJhbms8MSl0aHJvdyBuZXcgRXJyb3IoYHRmLnNjYXR0ZXJORCgpIGV4cGVjdHMgdGhlIGluZGljZXMgdG8gYmUgcmFuayAxIG9yIGhpZ2hlciwgYnV0IHRoZSByYW5rIHdhcyAke2FhLnJhbmt9LmApO2lmKGhhLnJhbms8MSl0aHJvdyBuZXcgRXJyb3IoYHRmLnNjYXR0ZXJORCgpIGV4cGVjdHMgdGhlIHVwZGF0ZXMgdG8gYmUgcmFuayAxIG9yIGhpZ2hlciwgYnV0IHRoZSByYW5rIHdhcyAke2hhLnJhbmt9LmApO2lmKGFhLmR0eXBlIT09ImludDMyIil0aHJvdyBuZXcgRXJyb3IoYFRoZSBkdHlwZSBvZiAnaW5kaWNlcycgc2hvdWxkIGJlIGludDMyLCBidXQgZ290IGR0eXBlOiAke2FhLmR0eXBlfWApO2lmKHhhLmxlbmd0aDwxKXRocm93IG5ldyBFcnJvcihgT3V0cHV0IHJhbmsgbXVzdCBiZSBncmVhdGVyIG9yIGVxdWFsIHRvIDEsIGJ1dCBnb3Qgc2hhcGU6ICR7eGF9YCk7aWYoeGEubGVuZ3RoPT09MCl7aWYoYWEuc2l6ZT09PTApdGhyb3cgbmV3IEVycm9yKGBJbmRpY2VzIHNwZWNpZmllZCBmb3IgZW1wdHkgb3V0cHV0LiBpbmRpY2VzIHNoYXBlOiAke2FhLnNoYXBlfWApO2lmKGhhLnNpemU9PT0wKXRocm93IG5ldyBFcnJvcihgVXBkYXRlcyBzcGVjaWZpZWQgZm9yIGVtcHR5IG91dHB1dC4gdXBkYXRlcyBzaGFwZTogJHtoYS5zaGFwZX1gKX12YWxpZGF0ZVVwZGF0ZVNoYXBlKHhhLGFhLGhhKX1mdW5jdGlvbiBjYWxjdWxhdGVTaGFwZXMoaGEsYWEseGEpe2NvbnN0IGJhPWFhLnNoYXBlLmxlbmd0aCxTYT1iYT4xP2FhLnNoYXBlW2JhLTFdOjEsVGE9eGEubGVuZ3RoO2xldCB3YT0xO2ZvcihsZXQgTGE9U2E7TGE8VGE7KytMYSl3YSo9eGFbTGFdO2NvbnN0IEVhPVNhPDE/MTpTYSxrYT1zaXplRnJvbVNoYXBlKGFhLnNoYXBlKS9FYSxBYT1bLi4uY29tcHV0ZVN0cmlkZXMoeGEuc2xpY2UoMCxTYSkpLDFdLEZhPXNpemVGcm9tU2hhcGUoeGEpO3JldHVybntzbGljZVJhbms6U2EsbnVtVXBkYXRlczprYSxzbGljZVNpemU6d2Esc3RyaWRlczpBYSxvdXRwdXRTaXplOkZhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB3aGVyZUltcGwkMShoYSxhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBUYT0wO1RhPGFhLmxlbmd0aDtUYSsrKWFhW1RhXSYmeGEucHVzaChUYSk7Y29uc3QgYmE9YnVmZmVyKGhhLCJpbnQzMiIpLFNhPWJ1ZmZlcihbeGEubGVuZ3RoLGhhLmxlbmd0aF0sImludDMyIik7Zm9yKGxldCBUYT0wO1RhPHhhLmxlbmd0aDtUYSsrKXtjb25zdCB3YT1iYS5pbmRleFRvTG9jKHhhW1RhXSksRWE9VGEqaGEubGVuZ3RoO1NhLnZhbHVlcy5zZXQod2EsRWEpfXJldHVybiBTYS50b1RlbnNvcigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdldEZ1c2VkRHlBY3RpdmF0aW9uKGhhLGFhLHhhKXtpZih4YT09bnVsbHx8eGE9PT0ibGluZWFyIilyZXR1cm4gaGE7aWYoeGE9PT0icmVsdSIpcmV0dXJuIG11bChoYSxzdGVwJDEoYWEpKTt0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb21wdXRlIGdyYWRpZW50IGZvciBmdXNlZCBhY3RpdmF0aW9uICR7eGF9LmApfWZ1bmN0aW9uIGdldEZ1c2VkQmlhc0dyYWRpZW50KGhhLGFhKXtsZXQgeGE9YWE7Y29uc3QgYmE9Z2V0UmVkdWN0aW9uQXhlcyhoYS5zaGFwZSxhYS5zaGFwZSk7cmV0dXJuIGJhLmxlbmd0aD4wJiYoeGE9c3VtJDEoeGEsYmEpKSxyZXNoYXBlJDEoeGEsaGEuc2hhcGUpfWZ1bmN0aW9uIGFwcGx5QWN0aXZhdGlvbihoYSxhYSx4YSxiYSl7aWYoYWE9PT0ibGluZWFyIilyZXR1cm4gaGE7aWYoYWE9PT0icmVsdSIpcmV0dXJuIHJlbHUkMShoYSk7aWYoYWE9PT0iZWx1IilyZXR1cm4gZWx1JDEoaGEpO2lmKGFhPT09InJlbHU2IilyZXR1cm4gcmVsdTYkMShoYSk7aWYoYWE9PT0icHJlbHUiKXJldHVybiBwcmVsdSQxKGhhLHhhKTtpZihhYT09PSJsZWFreXJlbHUiKXJldHVybiBsZWFreVJlbHUkMShoYSxiYSk7aWYoYWE9PT0ic2lnbW9pZCIpcmV0dXJuIHNpZ21vaWQkMShoYSk7dGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGZ1c2VkIGFjdGl2YXRpb24gJHthYX0uYCl9Y29uc3Qgc2hvdWxkRnVzZT0oaGEsYWEpPT4hKGhhPjApfHxhYT09PSJsaW5lYXIiOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJpbmFyeUluc2VydChoYSxhYSx4YSl7Y29uc3QgYmE9YmluYXJ5U2VhcmNoKGhhLGFhLHhhKSxTYT1iYTwwPy0oYmErMSk6YmE7aGEuc3BsaWNlKFNhLDAsYWEpfWZ1bmN0aW9uIGJpbmFyeVNlYXJjaChoYSxhYSx4YSl7cmV0dXJuIGJpbmFyeVNlYXJjaF8oaGEsYWEseGF8fGRlZmF1bHRDb21wYXJhdG9yKX1mdW5jdGlvbiBkZWZhdWx0Q29tcGFyYXRvcihoYSxhYSl7cmV0dXJuIGhhPmFhPzE6aGE8YWE/LTE6MH1mdW5jdGlvbiBiaW5hcnlTZWFyY2hfKGhhLGFhLHhhKXtsZXQgYmE9MCxTYT1oYS5sZW5ndGgsVGE9MCx3YT0hMTtmb3IoO2JhPFNhOyl7VGE9YmErKFNhLWJhPj4+MSk7Y29uc3QgRWE9eGEoYWEsaGFbVGFdKTtFYT4wP2JhPVRhKzE6KFNhPVRhLHdhPSFFYSl9cmV0dXJuIHdhP2JhOi1iYS0xfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uVjNJbXBsJDEoaGEsYWEseGEsYmEsU2Epe3JldHVybiBub25NYXhTdXBwcmVzc2lvbkltcGxfKGhhLGFhLHhhLGJhLFNhLDApfWZ1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uVjRJbXBsJDEoaGEsYWEseGEsYmEsU2EsVGEpe3JldHVybiBub25NYXhTdXBwcmVzc2lvbkltcGxfKGhhLGFhLHhhLGJhLFNhLDAsITEsVGEsITApfWZ1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uVjVJbXBsJDEoaGEsYWEseGEsYmEsU2EsVGEpe3JldHVybiBub25NYXhTdXBwcmVzc2lvbkltcGxfKGhhLGFhLHhhLGJhLFNhLFRhLCEwKX1mdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvbkltcGxfKGhhLGFhLHhhLGJhLFNhLFRhLHdhPSExLEVhPSExLGthPSExKXtjb25zdCBBYT1bXTtmb3IobGV0IHJsPTA7cmw8YWEubGVuZ3RoO3JsKyspYWFbcmxdPlNhJiZBYS5wdXNoKHtzY29yZTphYVtybF0sYm94SW5kZXg6cmwsc3VwcHJlc3NCZWdpbkluZGV4OjB9KTtBYS5zb3J0KGFzY2VuZGluZ0NvbXBhcmF0b3IpO2NvbnN0IEZhPVRhPjA/LS41L1RhOjAsTGE9W10sZWw9W107Zm9yKDtMYS5sZW5ndGg8eGEmJkFhLmxlbmd0aD4wOyl7Y29uc3Qgcmw9QWEucG9wKCkse3Njb3JlOm9sLGJveEluZGV4OmFsLHN1cHByZXNzQmVnaW5JbmRleDpsbH09cmw7aWYob2w8U2EpYnJlYWs7bGV0IGlsPSExO2ZvcihsZXQgY2w9TGEubGVuZ3RoLTE7Y2w+PWxsOy0tY2wpe2NvbnN0IHVsPWludGVyc2VjdGlvbk92ZXJVbmlvbihoYSxhbCxMYVtjbF0pO2lmKHVsPj1iYSl7aWw9ITA7YnJlYWt9aWYocmwuc2NvcmU9cmwuc2NvcmUqc3VwcHJlc3NXZWlnaHQoYmEsRmEsdWwpLHJsLnNjb3JlPD1TYSlicmVha31ybC5zdXBwcmVzc0JlZ2luSW5kZXg9TGEubGVuZ3RoLGlsfHwocmwuc2NvcmU9PT1vbD8oTGEucHVzaChhbCksZWwucHVzaChybC5zY29yZSkpOnJsLnNjb3JlPlNhJiZiaW5hcnlJbnNlcnQoQWEscmwsYXNjZW5kaW5nQ29tcGFyYXRvcikpfWNvbnN0IHRsPUxhLmxlbmd0aCxubD14YS10bDtFYSYmbmw+MCYmKExhLnB1c2goLi4ubmV3IEFycmF5KG5sKS5maWxsKDApKSxlbC5wdXNoKC4uLm5ldyBBcnJheShubCkuZmlsbCgwKSkpO2NvbnN0IHNsPXtzZWxlY3RlZEluZGljZXM6TGF9O3JldHVybiB3YSYmKHNsLnNlbGVjdGVkU2NvcmVzPWVsKSxrYSYmKHNsLnZhbGlkT3V0cHV0cz10bCksc2x9ZnVuY3Rpb24gaW50ZXJzZWN0aW9uT3ZlclVuaW9uKGhhLGFhLHhhKXtjb25zdCBiYT1oYS5zdWJhcnJheShhYSo0LGFhKjQrNCksU2E9aGEuc3ViYXJyYXkoeGEqNCx4YSo0KzQpLFRhPU1hdGgubWluKGJhWzBdLGJhWzJdKSx3YT1NYXRoLm1pbihiYVsxXSxiYVszXSksRWE9TWF0aC5tYXgoYmFbMF0sYmFbMl0pLGthPU1hdGgubWF4KGJhWzFdLGJhWzNdKSxBYT1NYXRoLm1pbihTYVswXSxTYVsyXSksRmE9TWF0aC5taW4oU2FbMV0sU2FbM10pLExhPU1hdGgubWF4KFNhWzBdLFNhWzJdKSxlbD1NYXRoLm1heChTYVsxXSxTYVszXSksdGw9KEVhLVRhKSooa2Etd2EpLG5sPShMYS1BYSkqKGVsLUZhKTtpZih0bDw9MHx8bmw8PTApcmV0dXJuIDA7Y29uc3Qgc2w9TWF0aC5tYXgoVGEsQWEpLHJsPU1hdGgubWF4KHdhLEZhKSxvbD1NYXRoLm1pbihFYSxMYSksYWw9TWF0aC5taW4oa2EsZWwpLGxsPU1hdGgubWF4KG9sLXNsLDApKk1hdGgubWF4KGFsLXJsLDApO3JldHVybiBsbC8odGwrbmwtbGwpfWZ1bmN0aW9uIHN1cHByZXNzV2VpZ2h0KGhhLGFhLHhhKXtjb25zdCBiYT1NYXRoLmV4cChhYSp4YSp4YSk7cmV0dXJuIHhhPD1oYT9iYTowfWZ1bmN0aW9uIGFzY2VuZGluZ0NvbXBhcmF0b3IoaGEsYWEpe3JldHVybiBoYS5zY29yZS1hYS5zY29yZXx8aGEuc2NvcmU9PT1hYS5zY29yZSYmYWEuYm94SW5kZXgtaGEuYm94SW5kZXh9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgR0xPQkFMX0NVU1RPTV9PQkpFQ1Q9bmV3IE1hcCxHTE9CQUxfQ1VTVE9NX05BTUVTPW5ldyBNYXA7Y2xhc3MgU2VyaWFsaXphYmxle2dldENsYXNzTmFtZSgpe3JldHVybiB0aGlzLmNvbnN0cnVjdG9yLmNsYXNzTmFtZX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YSl9fWNsYXNzIFNlcmlhbGl6YXRpb25NYXB7Y29uc3RydWN0b3IoKXt0aGlzLmNsYXNzTmFtZU1hcD17fX1zdGF0aWMgZ2V0TWFwKCl7cmV0dXJuIFNlcmlhbGl6YXRpb25NYXAuaW5zdGFuY2U9PW51bGwmJihTZXJpYWxpemF0aW9uTWFwLmluc3RhbmNlPW5ldyBTZXJpYWxpemF0aW9uTWFwKSxTZXJpYWxpemF0aW9uTWFwLmluc3RhbmNlfXN0YXRpYyByZWdpc3RlcihhYSl7U2VyaWFsaXphdGlvbk1hcC5nZXRNYXAoKS5jbGFzc05hbWVNYXBbYWEuY2xhc3NOYW1lXT1bYWEsYWEuZnJvbUNvbmZpZ119fWZ1bmN0aW9uIHJlZ2lzdGVyQ2xhc3MoaGEsYWEseGEpe2Fzc2VydChoYS5jbGFzc05hbWUhPW51bGwsKCk9PiJDbGFzcyBiZWluZyByZWdpc3RlcmVkIGRvZXMgbm90IGhhdmUgdGhlIHN0YXRpYyBjbGFzc05hbWUgcHJvcGVydHkgZGVmaW5lZC4iKSxhc3NlcnQodHlwZW9mIGhhLmNsYXNzTmFtZT09InN0cmluZyIsKCk9PiJjbGFzc05hbWUgaXMgcmVxdWlyZWQgdG8gYmUgYSBzdHJpbmcsIGJ1dCBnb3QgdHlwZSAiK3R5cGVvZiBoYS5jbGFzc05hbWUpLGFzc2VydChoYS5jbGFzc05hbWUubGVuZ3RoPjAsKCk9PiJDbGFzcyBiZWluZyByZWdpc3RlcmVkIGhhcyBhbiBlbXB0eS1zdHJpbmcgYXMgaXRzIGNsYXNzTmFtZSwgd2hpY2ggaXMgZGlzYWxsb3dlZC4iKSx0eXBlb2YgYWE+InUiJiYoYWE9IkN1c3RvbSIpLHR5cGVvZiB4YT4idSImJih4YT1oYS5jbGFzc05hbWUpO2NvbnN0IGJhPXhhLFNhPWFhKyI+IitiYTtyZXR1cm4gU2VyaWFsaXphdGlvbk1hcC5yZWdpc3RlcihoYSksR0xPQkFMX0NVU1RPTV9PQkpFQ1Quc2V0KFNhLGhhKSxHTE9CQUxfQ1VTVE9NX05BTUVTLnNldChoYSxTYSksaGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgT3B0aW1pemVyIGV4dGVuZHMgU2VyaWFsaXphYmxle21pbmltaXplKGFhLHhhPSExLGJhKXtjb25zdHt2YWx1ZTpTYSxncmFkczpUYX09dGhpcy5jb21wdXRlR3JhZGllbnRzKGFhLGJhKTtpZihiYSE9bnVsbCl7Y29uc3Qgd2E9YmEubWFwKEVhPT4oe25hbWU6RWEubmFtZSx0ZW5zb3I6VGFbRWEubmFtZV19KSk7dGhpcy5hcHBseUdyYWRpZW50cyh3YSl9ZWxzZSB0aGlzLmFwcGx5R3JhZGllbnRzKFRhKTtyZXR1cm4gZGlzcG9zZShUYSkseGE/U2E6KFNhLmRpc3Bvc2UoKSxudWxsKX1nZXQgaXRlcmF0aW9ucygpe3JldHVybiB0aGlzLml0ZXJhdGlvbnNfPT1udWxsJiYodGhpcy5pdGVyYXRpb25zXz0wKSx0aGlzLml0ZXJhdGlvbnNffWluY3JlbWVudEl0ZXJhdGlvbnMoKXt0aGlzLml0ZXJhdGlvbnNfPXRoaXMuaXRlcmF0aW9ucysxfWNvbXB1dGVHcmFkaWVudHMoYWEseGEpe3JldHVybiB2YXJpYWJsZUdyYWRzKGFhLHhhKX1kaXNwb3NlKCl7dGhpcy5pdGVyYXRpb25zXyE9bnVsbCYmZGlzcG9zZSh0aGlzLml0ZXJhdGlvbnNfKX1hc3luYyBzYXZlSXRlcmF0aW9ucygpe3JldHVybiB0aGlzLml0ZXJhdGlvbnNfPT1udWxsJiYodGhpcy5pdGVyYXRpb25zXz0wKSx7bmFtZToiaXRlciIsdGVuc29yOnNjYWxhcih0aGlzLml0ZXJhdGlvbnNfLCJpbnQzMiIpfX1hc3luYyBnZXRXZWlnaHRzKCl7dGhyb3cgbmV3IEVycm9yKCJnZXRXZWlnaHRzKCkgaXMgbm90IGltcGxlbWVudGVkIGZvciB0aGlzIG9wdGltaXplciB5ZXQuIil9YXN5bmMgc2V0V2VpZ2h0cyhhYSl7dGhyb3cgbmV3IEVycm9yKGBzZXRXZWlnaHRzKCkgaXMgbm90IGltcGxlbWVudGVkIGZvciB0aGlzIG9wdGltaXplciBjbGFzcyAke3RoaXMuZ2V0Q2xhc3NOYW1lKCl9YCl9YXN5bmMgZXh0cmFjdEl0ZXJhdGlvbnMoYWEpe3JldHVybiB0aGlzLml0ZXJhdGlvbnNfPShhd2FpdCBhYVswXS50ZW5zb3IuZGF0YSgpKVswXSxhYS5zbGljZSgxKX19T2JqZWN0LmRlZmluZVByb3BlcnR5KE9wdGltaXplcixTeW1ib2wuaGFzSW5zdGFuY2Use3ZhbHVlOmhhPT5oYS5taW5pbWl6ZSE9bnVsbCYmaGEuY29tcHV0ZUdyYWRpZW50cyE9bnVsbCYmaGEuYXBwbHlHcmFkaWVudHMhPW51bGx9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBBZGFkZWx0YU9wdGltaXplciBleHRlbmRzIE9wdGltaXplcntzdGF0aWMgZ2V0IGNsYXNzTmFtZSgpe3JldHVybiJBZGFkZWx0YSJ9Y29uc3RydWN0b3IoYWEseGEsYmE9bnVsbCl7c3VwZXIoKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLnJobz14YSx0aGlzLmVwc2lsb249YmEsdGhpcy5hY2N1bXVsYXRlZEdyYWRzPVtdLHRoaXMuYWNjdW11bGF0ZWRVcGRhdGVzPVtdLGJhPT1udWxsJiYodGhpcy5lcHNpbG9uPUVOR0lORS5iYWNrZW5kLmVwc2lsb24oKSl9YXBwbHlHcmFkaWVudHMoYWEpeyhBcnJheS5pc0FycmF5KGFhKT9hYS5tYXAoYmE9PmJhLm5hbWUpOk9iamVjdC5rZXlzKGFhKSkuZm9yRWFjaCgoYmEsU2EpPT57Y29uc3QgVGE9RU5HSU5FLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYmFdLHdhPSExO3RoaXMuYWNjdW11bGF0ZWRHcmFkc1tTYV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkR3JhZHNbU2FdPXtvcmlnaW5hbE5hbWU6YCR7YmF9L2FjY3VtX2dyYWRgLHZhcmlhYmxlOnRpZHkoKCk9Pnplcm9zTGlrZSQxKFRhKS52YXJpYWJsZSh3YSkpfSksdGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXNbU2FdPT1udWxsJiYodGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXNbU2FdPXtvcmlnaW5hbE5hbWU6YCR7YmF9L2FjY3VtX3ZhcmAsdmFyaWFibGU6dGlkeSgoKT0+emVyb3NMaWtlJDEoVGEpLnZhcmlhYmxlKHdhKSl9KTtjb25zdCBFYT1BcnJheS5pc0FycmF5KGFhKT9hYVtTYV0udGVuc29yOmFhW2JhXTtpZihFYT09bnVsbClyZXR1cm47Y29uc3Qga2E9dGhpcy5hY2N1bXVsYXRlZEdyYWRzW1NhXS52YXJpYWJsZSxBYT10aGlzLmFjY3VtdWxhdGVkVXBkYXRlc1tTYV0udmFyaWFibGU7dGlkeSgoKT0+e2NvbnN0IEZhPWFkZChtdWwoa2EsdGhpcy5yaG8pLG11bChzcXVhcmUkMShFYSksMS10aGlzLnJobykpLExhPW11bChkaXYoc3FydCQxKGFkZChBYSx0aGlzLmVwc2lsb24pKSxzcXJ0JDEoYWRkKGthLHRoaXMuZXBzaWxvbikpKSxFYSksZWw9YWRkKG11bChBYSx0aGlzLnJobyksbXVsKHNxdWFyZSQxKExhKSwxLXRoaXMucmhvKSk7a2EuYXNzaWduKEZhKSxBYS5hc3NpZ24oZWwpO2NvbnN0IHRsPWFkZChtdWwoTGEsLXRoaXMubGVhcm5pbmdSYXRlKSxUYSk7VGEuYXNzaWduKHRsKX0pfSksdGhpcy5pbmNyZW1lbnRJdGVyYXRpb25zKCl9ZGlzcG9zZSgpe3RoaXMuYWNjdW11bGF0ZWRVcGRhdGVzIT1udWxsJiYoZGlzcG9zZSh0aGlzLmFjY3VtdWxhdGVkR3JhZHMubWFwKGFhPT5hYS52YXJpYWJsZSkpLGRpc3Bvc2UodGhpcy5hY2N1bXVsYXRlZFVwZGF0ZXMubWFwKGFhPT5hYS52YXJpYWJsZSkpKX1hc3luYyBnZXRXZWlnaHRzKCl7Y29uc3QgYWE9Wy4uLnRoaXMuYWNjdW11bGF0ZWRHcmFkcywuLi50aGlzLmFjY3VtdWxhdGVkVXBkYXRlc107cmV0dXJuW2F3YWl0IHRoaXMuc2F2ZUl0ZXJhdGlvbnMoKV0uY29uY2F0KGFhLm1hcCh4YT0+KHtuYW1lOnhhLm9yaWdpbmFsTmFtZSx0ZW5zb3I6eGEudmFyaWFibGV9KSkpfWFzeW5jIHNldFdlaWdodHMoYWEpe2FhPWF3YWl0IHRoaXMuZXh0cmFjdEl0ZXJhdGlvbnMoYWEpO2NvbnN0IHhhPWFhLmxlbmd0aC8yLGJhPSExO3RoaXMuYWNjdW11bGF0ZWRHcmFkcz1hYS5zbGljZSgwLHhhKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKSx0aGlzLmFjY3VtdWxhdGVkVXBkYXRlcz1hYS5zbGljZSh4YSx4YSoyKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlLHJobzp0aGlzLnJobyxlcHNpbG9uOnRoaXMuZXBzaWxvbn19c3RhdGljIGZyb21Db25maWcoYWEseGEpe3JldHVybiBuZXcgYWEoeGEubGVhcm5pbmdSYXRlLHhhLnJobyx4YS5lcHNpbG9uKX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgQWRhZ3JhZE9wdGltaXplciBleHRlbmRzIE9wdGltaXplcntzdGF0aWMgZ2V0IGNsYXNzTmFtZSgpe3JldHVybiJBZGFncmFkIn1jb25zdHJ1Y3RvcihhYSx4YT0uMSl7c3VwZXIoKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLmluaXRpYWxBY2N1bXVsYXRvclZhbHVlPXhhLHRoaXMuYWNjdW11bGF0ZWRHcmFkcz1bXX1hcHBseUdyYWRpZW50cyhhYSl7KEFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpKS5mb3JFYWNoKChiYSxTYSk9Pntjb25zdCBUYT1FTkdJTkUucmVnaXN0ZXJlZFZhcmlhYmxlc1tiYV07dGhpcy5hY2N1bXVsYXRlZEdyYWRzW1NhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRHcmFkc1tTYV09e29yaWdpbmFsTmFtZTpgJHtiYX0vYWNjdW11bGF0b3JgLHZhcmlhYmxlOnRpZHkoKCk9PmZpbGwkMShUYS5zaGFwZSx0aGlzLmluaXRpYWxBY2N1bXVsYXRvclZhbHVlKS52YXJpYWJsZSghMSkpfSk7Y29uc3Qgd2E9QXJyYXkuaXNBcnJheShhYSk/YWFbU2FdLnRlbnNvcjphYVtiYV07aWYod2E9PW51bGwpcmV0dXJuO2NvbnN0IEVhPXRoaXMuYWNjdW11bGF0ZWRHcmFkc1tTYV0udmFyaWFibGU7dGlkeSgoKT0+e2NvbnN0IGthPWFkZChFYSxzcXVhcmUkMSh3YSkpO0VhLmFzc2lnbihrYSk7Y29uc3QgQWE9YWRkKG11bChkaXYod2Esc3FydCQxKGFkZChrYSxFTkdJTkUuYmFja2VuZC5lcHNpbG9uKCkpKSksLXRoaXMubGVhcm5pbmdSYXRlKSxUYSk7VGEuYXNzaWduKEFhKX0pfSksdGhpcy5pbmNyZW1lbnRJdGVyYXRpb25zKCl9ZGlzcG9zZSgpe3RoaXMuYWNjdW11bGF0ZWRHcmFkcyE9bnVsbCYmZGlzcG9zZSh0aGlzLmFjY3VtdWxhdGVkR3JhZHMubWFwKGFhPT5hYS52YXJpYWJsZSkpfWFzeW5jIGdldFdlaWdodHMoKXtyZXR1cm5bYXdhaXQgdGhpcy5zYXZlSXRlcmF0aW9ucygpXS5jb25jYXQodGhpcy5hY2N1bXVsYXRlZEdyYWRzLm1hcChhYT0+KHtuYW1lOmFhLm9yaWdpbmFsTmFtZSx0ZW5zb3I6YWEudmFyaWFibGV9KSkpfWFzeW5jIHNldFdlaWdodHMoYWEpe2FhPWF3YWl0IHRoaXMuZXh0cmFjdEl0ZXJhdGlvbnMoYWEpO2NvbnN0IHhhPSExO3RoaXMuYWNjdW11bGF0ZWRHcmFkcz1hYS5tYXAoYmE9Pih7b3JpZ2luYWxOYW1lOmJhLm5hbWUsdmFyaWFibGU6YmEudGVuc29yLnZhcmlhYmxlKHhhKX0pKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlLGluaXRpYWxBY2N1bXVsYXRvclZhbHVlOnRoaXMuaW5pdGlhbEFjY3VtdWxhdG9yVmFsdWV9fXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtyZXR1cm4gbmV3IGFhKHhhLmxlYXJuaW5nUmF0ZSx4YS5pbml0aWFsQWNjdW11bGF0b3JWYWx1ZSl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEFkYW1PcHRpbWl6ZXIgZXh0ZW5kcyBPcHRpbWl6ZXJ7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iQWRhbSJ9Y29uc3RydWN0b3IoYWEseGEsYmEsU2E9bnVsbCl7c3VwZXIoKSx0aGlzLmxlYXJuaW5nUmF0ZT1hYSx0aGlzLmJldGExPXhhLHRoaXMuYmV0YTI9YmEsdGhpcy5lcHNpbG9uPVNhLHRoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudD1bXSx0aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50PVtdLHRpZHkoKCk9Pnt0aGlzLmFjY0JldGExPXNjYWxhcih4YSkudmFyaWFibGUoKSx0aGlzLmFjY0JldGEyPXNjYWxhcihiYSkudmFyaWFibGUoKX0pLFNhPT1udWxsJiYodGhpcy5lcHNpbG9uPUVOR0lORS5iYWNrZW5kLmVwc2lsb24oKSl9YXBwbHlHcmFkaWVudHMoYWEpe2NvbnN0IHhhPUFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpO3RpZHkoKCk9Pntjb25zdCBiYT1zdWIkMSgxLHRoaXMuYWNjQmV0YTEpLFNhPXN1YiQxKDEsdGhpcy5hY2NCZXRhMik7eGEuZm9yRWFjaCgoVGEsd2EpPT57Y29uc3QgRWE9RU5HSU5FLnJlZ2lzdGVyZWRWYXJpYWJsZXNbVGFdLGthPSExO3RoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudFt3YV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnRbd2FdPXtvcmlnaW5hbE5hbWU6YCR7VGF9L21gLHZhcmlhYmxlOnRpZHkoKCk9Pnplcm9zTGlrZSQxKEVhKS52YXJpYWJsZShrYSkpfSksdGhpcy5hY2N1bXVsYXRlZFNlY29uZE1vbWVudFt3YV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkU2Vjb25kTW9tZW50W3dhXT17b3JpZ2luYWxOYW1lOmAke1RhfS92YCx2YXJpYWJsZTp0aWR5KCgpPT56ZXJvc0xpa2UkMShFYSkudmFyaWFibGUoa2EpKX0pO2NvbnN0IEFhPUFycmF5LmlzQXJyYXkoYWEpP2FhW3dhXS50ZW5zb3I6YWFbVGFdO2lmKEFhPT1udWxsKXJldHVybjtjb25zdCBGYT10aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnRbd2FdLnZhcmlhYmxlLExhPXRoaXMuYWNjdW11bGF0ZWRTZWNvbmRNb21lbnRbd2FdLnZhcmlhYmxlLGVsPWFkZChtdWwoRmEsdGhpcy5iZXRhMSksbXVsKEFhLDEtdGhpcy5iZXRhMSkpLHRsPWFkZChtdWwoTGEsdGhpcy5iZXRhMiksbXVsKHNxdWFyZSQxKEFhKSwxLXRoaXMuYmV0YTIpKSxubD1kaXYoZWwsYmEpLHNsPWRpdih0bCxTYSk7RmEuYXNzaWduKGVsKSxMYS5hc3NpZ24odGwpO2NvbnN0IHJsPWFkZChtdWwoZGl2KG5sLGFkZChzcXJ0JDEoc2wpLHRoaXMuZXBzaWxvbikpLC10aGlzLmxlYXJuaW5nUmF0ZSksRWEpO0VhLmFzc2lnbihybCl9KSx0aGlzLmFjY0JldGExLmFzc2lnbihtdWwodGhpcy5hY2NCZXRhMSx0aGlzLmJldGExKSksdGhpcy5hY2NCZXRhMi5hc3NpZ24obXVsKHRoaXMuYWNjQmV0YTIsdGhpcy5iZXRhMikpfSksdGhpcy5pbmNyZW1lbnRJdGVyYXRpb25zKCl9ZGlzcG9zZSgpe3RoaXMuYWNjQmV0YTEuZGlzcG9zZSgpLHRoaXMuYWNjQmV0YTIuZGlzcG9zZSgpLHRoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudCE9bnVsbCYmZGlzcG9zZSh0aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnQubWFwKGFhPT5hYS52YXJpYWJsZSkpLHRoaXMuYWNjdW11bGF0ZWRTZWNvbmRNb21lbnQhPW51bGwmJmRpc3Bvc2UodGhpcy5hY2N1bXVsYXRlZFNlY29uZE1vbWVudC5tYXAoYWE9PmFhLnZhcmlhYmxlKSl9YXN5bmMgZ2V0V2VpZ2h0cygpe2NvbnN0IGFhPVsuLi50aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnQsLi4udGhpcy5hY2N1bXVsYXRlZFNlY29uZE1vbWVudF07cmV0dXJuW2F3YWl0IHRoaXMuc2F2ZUl0ZXJhdGlvbnMoKV0uY29uY2F0KGFhLm1hcCh4YT0+KHtuYW1lOnhhLm9yaWdpbmFsTmFtZSx0ZW5zb3I6eGEudmFyaWFibGV9KSkpfWFzeW5jIHNldFdlaWdodHMoYWEpe2FhPWF3YWl0IHRoaXMuZXh0cmFjdEl0ZXJhdGlvbnMoYWEpLHRpZHkoKCk9Pnt0aGlzLmFjY0JldGExLmFzc2lnbihwb3ckMSh0aGlzLmJldGExLHRoaXMuaXRlcmF0aW9uc18rMSkpLHRoaXMuYWNjQmV0YTIuYXNzaWduKHBvdyQxKHRoaXMuYmV0YTIsdGhpcy5pdGVyYXRpb25zXysxKSl9KTtjb25zdCB4YT1hYS5sZW5ndGgvMixiYT0hMTt0aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnQ9YWEuc2xpY2UoMCx4YSkubWFwKFNhPT4oe29yaWdpbmFsTmFtZTpTYS5uYW1lLHZhcmlhYmxlOlNhLnRlbnNvci52YXJpYWJsZShiYSl9KSksdGhpcy5hY2N1bXVsYXRlZFNlY29uZE1vbWVudD1hYS5zbGljZSh4YSx4YSoyKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlLGJldGExOnRoaXMuYmV0YTEsYmV0YTI6dGhpcy5iZXRhMixlcHNpbG9uOnRoaXMuZXBzaWxvbn19c3RhdGljIGZyb21Db25maWcoYWEseGEpe3JldHVybiBuZXcgYWEoeGEubGVhcm5pbmdSYXRlLHhhLmJldGExLHhhLmJldGEyLHhhLmVwc2lsb24pfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBBZGFtYXhPcHRpbWl6ZXIgZXh0ZW5kcyBPcHRpbWl6ZXJ7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iQWRhbWF4In1jb25zdHJ1Y3RvcihhYSx4YSxiYSxTYT1udWxsLFRhPTApe3N1cGVyKCksdGhpcy5sZWFybmluZ1JhdGU9YWEsdGhpcy5iZXRhMT14YSx0aGlzLmJldGEyPWJhLHRoaXMuZXBzaWxvbj1TYSx0aGlzLmRlY2F5PVRhLHRoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudD1bXSx0aGlzLmFjY3VtdWxhdGVkV2VpZ2h0ZWRJbmZOb3JtPVtdLHRpZHkoKCk9Pnt0aGlzLml0ZXJhdGlvbj1zY2FsYXIoMCkudmFyaWFibGUoKSx0aGlzLmFjY0JldGExPXNjYWxhcih4YSkudmFyaWFibGUoKX0pLFNhPT1udWxsJiYodGhpcy5lcHNpbG9uPUVOR0lORS5iYWNrZW5kLmVwc2lsb24oKSl9YXBwbHlHcmFkaWVudHMoYWEpe2NvbnN0IHhhPUFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpO3RpZHkoKCk9Pntjb25zdCBiYT1zdWIkMSgxLHRoaXMuYWNjQmV0YTEpLFNhPWRpdigtdGhpcy5sZWFybmluZ1JhdGUsYWRkKG11bCh0aGlzLml0ZXJhdGlvbix0aGlzLmRlY2F5KSwxKSk7eGEuZm9yRWFjaCgoVGEsd2EpPT57Y29uc3QgRWE9RU5HSU5FLnJlZ2lzdGVyZWRWYXJpYWJsZXNbVGFdLGthPSExO3RoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudFt3YV09PW51bGwmJih0aGlzLmFjY3VtdWxhdGVkRmlyc3RNb21lbnRbd2FdPXtvcmlnaW5hbE5hbWU6YCR7VGF9L21gLHZhcmlhYmxlOnplcm9zTGlrZSQxKEVhKS52YXJpYWJsZShrYSl9KSx0aGlzLmFjY3VtdWxhdGVkV2VpZ2h0ZWRJbmZOb3JtW3dhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRXZWlnaHRlZEluZk5vcm1bd2FdPXtvcmlnaW5hbE5hbWU6YCR7VGF9L3ZgLHZhcmlhYmxlOnplcm9zTGlrZSQxKEVhKS52YXJpYWJsZShrYSl9KTtjb25zdCBBYT1BcnJheS5pc0FycmF5KGFhKT9hYVt3YV0udGVuc29yOmFhW1RhXTtpZihBYT09bnVsbClyZXR1cm47Y29uc3QgRmE9dGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50W3dhXS52YXJpYWJsZSxMYT10aGlzLmFjY3VtdWxhdGVkV2VpZ2h0ZWRJbmZOb3JtW3dhXS52YXJpYWJsZSxlbD1hZGQobXVsKEZhLHRoaXMuYmV0YTEpLG11bChBYSwxLXRoaXMuYmV0YTEpKSx0bD1tdWwoTGEsdGhpcy5iZXRhMiksbmw9YWJzJDEoQWEpLHNsPW1heGltdW0kMSh0bCxubCk7RmEuYXNzaWduKGVsKSxMYS5hc3NpZ24oc2wpO2NvbnN0IHJsPWFkZChtdWwoZGl2KFNhLGJhKSxkaXYoZWwsYWRkKHNsLHRoaXMuZXBzaWxvbikpKSxFYSk7RWEuYXNzaWduKHJsKX0pLHRoaXMuaXRlcmF0aW9uLmFzc2lnbihhZGQodGhpcy5pdGVyYXRpb24sMSkpLHRoaXMuYWNjQmV0YTEuYXNzaWduKG11bCh0aGlzLmFjY0JldGExLHRoaXMuYmV0YTEpKX0pLHRoaXMuaW5jcmVtZW50SXRlcmF0aW9ucygpfWRpc3Bvc2UoKXt0aGlzLmFjY0JldGExLmRpc3Bvc2UoKSx0aGlzLml0ZXJhdGlvbi5kaXNwb3NlKCksdGhpcy5hY2N1bXVsYXRlZEZpcnN0TW9tZW50IT1udWxsJiZkaXNwb3NlKHRoaXMuYWNjdW11bGF0ZWRGaXJzdE1vbWVudC5tYXAoYWE9PmFhLnZhcmlhYmxlKSksdGhpcy5hY2N1bXVsYXRlZFdlaWdodGVkSW5mTm9ybSE9bnVsbCYmZGlzcG9zZSh0aGlzLmFjY3VtdWxhdGVkV2VpZ2h0ZWRJbmZOb3JtLm1hcChhYT0+YWEudmFyaWFibGUpKX1hc3luYyBnZXRXZWlnaHRzKCl7dGhyb3cgbmV3IEVycm9yKCJnZXRXZWlnaHRzKCkgaXMgbm90IGltcGxlbWVudGVkIGZvciBBZGFtYXggeWV0LiIpfWFzeW5jIHNldFdlaWdodHMoYWEpe3Rocm93IG5ldyBFcnJvcigic2V0V2VpZ2h0cygpIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgQWRhbWF4IHlldC4iKX1nZXRDb25maWcoKXtyZXR1cm57bGVhcm5pbmdSYXRlOnRoaXMubGVhcm5pbmdSYXRlLGJldGExOnRoaXMuYmV0YTEsYmV0YTI6dGhpcy5iZXRhMixlcHNpbG9uOnRoaXMuZXBzaWxvbixkZWNheTp0aGlzLmRlY2F5fX1zdGF0aWMgZnJvbUNvbmZpZyhhYSx4YSl7cmV0dXJuIG5ldyBhYSh4YS5sZWFybmluZ1JhdGUseGEuYmV0YTEseGEuYmV0YTIseGEuZXBzaWxvbix4YS5kZWNheSl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFNHRE9wdGltaXplciBleHRlbmRzIE9wdGltaXplcntzdGF0aWMgZ2V0IGNsYXNzTmFtZSgpe3JldHVybiJTR0QifWNvbnN0cnVjdG9yKGFhKXtzdXBlcigpLHRoaXMubGVhcm5pbmdSYXRlPWFhLHRoaXMuc2V0TGVhcm5pbmdSYXRlKGFhKX1hcHBseUdyYWRpZW50cyhhYSl7KEFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpKS5mb3JFYWNoKChiYSxTYSk9Pntjb25zdCBUYT1BcnJheS5pc0FycmF5KGFhKT9hYVtTYV0udGVuc29yOmFhW2JhXTtpZihUYT09bnVsbClyZXR1cm47Y29uc3Qgd2E9RU5HSU5FLnJlZ2lzdGVyZWRWYXJpYWJsZXNbYmFdO3RpZHkoKCk9Pntjb25zdCBFYT1hZGQobXVsKHRoaXMuYyxUYSksd2EpO3dhLmFzc2lnbihFYSl9KX0pLHRoaXMuaW5jcmVtZW50SXRlcmF0aW9ucygpfXNldExlYXJuaW5nUmF0ZShhYSl7dGhpcy5sZWFybmluZ1JhdGU9YWEsdGhpcy5jIT1udWxsJiZ0aGlzLmMuZGlzcG9zZSgpLHRoaXMuYz1rZWVwKHNjYWxhcigtYWEpKX1kaXNwb3NlKCl7dGhpcy5jLmRpc3Bvc2UoKX1hc3luYyBnZXRXZWlnaHRzKCl7cmV0dXJuW2F3YWl0IHRoaXMuc2F2ZUl0ZXJhdGlvbnMoKV19YXN5bmMgc2V0V2VpZ2h0cyhhYSl7aWYoYWE9YXdhaXQgdGhpcy5leHRyYWN0SXRlcmF0aW9ucyhhYSksYWEubGVuZ3RoIT09MCl0aHJvdyBuZXcgRXJyb3IoIlNHRCBvcHRpbWl6ZXIgZG9lcyBub3QgaGF2ZSBzZXR0YWJsZSB3ZWlnaHRzLiIpfWdldENvbmZpZygpe3JldHVybntsZWFybmluZ1JhdGU6dGhpcy5sZWFybmluZ1JhdGV9fXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtyZXR1cm4gbmV3IGFhKHhhLmxlYXJuaW5nUmF0ZSl9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIE1vbWVudHVtT3B0aW1pemVyIGV4dGVuZHMgU0dET3B0aW1pemVye3N0YXRpYyBnZXQgY2xhc3NOYW1lKCl7cmV0dXJuIk1vbWVudHVtIn1jb25zdHJ1Y3RvcihhYSx4YSxiYT0hMSl7c3VwZXIoYWEpLHRoaXMubGVhcm5pbmdSYXRlPWFhLHRoaXMubW9tZW50dW09eGEsdGhpcy51c2VOZXN0ZXJvdj1iYSx0aGlzLmFjY3VtdWxhdGlvbnM9W10sdGhpcy5tPXNjYWxhcih0aGlzLm1vbWVudHVtKX1hcHBseUdyYWRpZW50cyhhYSl7KEFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpKS5mb3JFYWNoKChiYSxTYSk9Pntjb25zdCBUYT1FTkdJTkUucmVnaXN0ZXJlZFZhcmlhYmxlc1tiYV07dGhpcy5hY2N1bXVsYXRpb25zW1NhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0aW9uc1tTYV09e29yaWdpbmFsTmFtZTpgJHtiYX0vbW9tZW50dW1gLHZhcmlhYmxlOnRpZHkoKCk9Pnplcm9zTGlrZSQxKFRhKS52YXJpYWJsZSghMSkpfSk7Y29uc3Qgd2E9dGhpcy5hY2N1bXVsYXRpb25zW1NhXS52YXJpYWJsZSxFYT1BcnJheS5pc0FycmF5KGFhKT9hYVtTYV0udGVuc29yOmFhW2JhXTtFYSE9bnVsbCYmdGlkeSgoKT0+e2xldCBrYTtjb25zdCBBYT1hZGQobXVsKHRoaXMubSx3YSksRWEpO3RoaXMudXNlTmVzdGVyb3Y/a2E9YWRkKG11bCh0aGlzLmMsYWRkKEVhLG11bChBYSx0aGlzLm0pKSksVGEpOmthPWFkZChtdWwodGhpcy5jLEFhKSxUYSksd2EuYXNzaWduKEFhKSxUYS5hc3NpZ24oa2EpfSl9KSx0aGlzLmluY3JlbWVudEl0ZXJhdGlvbnMoKX1kaXNwb3NlKCl7dGhpcy5tLmRpc3Bvc2UoKSx0aGlzLmFjY3VtdWxhdGlvbnMhPW51bGwmJmRpc3Bvc2UodGhpcy5hY2N1bXVsYXRpb25zLm1hcChhYT0+YWEudmFyaWFibGUpKX1zZXRNb21lbnR1bShhYSl7dGhpcy5tb21lbnR1bT1hYX1hc3luYyBnZXRXZWlnaHRzKCl7cmV0dXJuW2F3YWl0IHRoaXMuc2F2ZUl0ZXJhdGlvbnMoKV0uY29uY2F0KHRoaXMuYWNjdW11bGF0aW9ucy5tYXAoYWE9Pih7bmFtZTphYS5vcmlnaW5hbE5hbWUsdGVuc29yOmFhLnZhcmlhYmxlfSkpKX1hc3luYyBzZXRXZWlnaHRzKGFhKXthYT1hd2FpdCB0aGlzLmV4dHJhY3RJdGVyYXRpb25zKGFhKTtjb25zdCB4YT0hMTt0aGlzLmFjY3VtdWxhdGlvbnM9YWEubWFwKGJhPT4oe29yaWdpbmFsTmFtZTpiYS5uYW1lLHZhcmlhYmxlOmJhLnRlbnNvci52YXJpYWJsZSh4YSl9KSl9Z2V0Q29uZmlnKCl7cmV0dXJue2xlYXJuaW5nUmF0ZTp0aGlzLmxlYXJuaW5nUmF0ZSxtb21lbnR1bTp0aGlzLm1vbWVudHVtLHVzZU5lc3Rlcm92OnRoaXMudXNlTmVzdGVyb3Z9fXN0YXRpYyBmcm9tQ29uZmlnKGFhLHhhKXtyZXR1cm4gbmV3IGFhKHhhLmxlYXJuaW5nUmF0ZSx4YS5tb21lbnR1bSx4YS51c2VOZXN0ZXJvdil9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFJNU1Byb3BPcHRpbWl6ZXIgZXh0ZW5kcyBPcHRpbWl6ZXJ7c3RhdGljIGdldCBjbGFzc05hbWUoKXtyZXR1cm4iUk1TUHJvcCJ9Y29uc3RydWN0b3IoYWEseGE9LjksYmE9MCxTYT1udWxsLFRhPSExKXtpZihzdXBlcigpLHRoaXMubGVhcm5pbmdSYXRlPWFhLHRoaXMuZGVjYXk9eGEsdGhpcy5tb21lbnR1bT1iYSx0aGlzLmVwc2lsb249U2EsdGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzPVtdLHRoaXMuYWNjdW11bGF0ZWRNb21lbnRzPVtdLHRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHM9W10sdGhpcy5jZW50ZXJlZD1UYSxTYT09bnVsbCYmKHRoaXMuZXBzaWxvbj1FTkdJTkUuYmFja2VuZC5lcHNpbG9uKCkpLGFhPT1udWxsKXRocm93IG5ldyBFcnJvcigibGVhcm5pbmdSYXRlIGZvciBSTVNQcm9wT3B0aW1pemVyIG11c3QgYmUgZGVmaW5lZC4iKX1hcHBseUdyYWRpZW50cyhhYSl7KEFycmF5LmlzQXJyYXkoYWEpP2FhLm1hcChiYT0+YmEubmFtZSk6T2JqZWN0LmtleXMoYWEpKS5mb3JFYWNoKChiYSxTYSk9Pntjb25zdCBUYT1FTkdJTkUucmVnaXN0ZXJlZFZhcmlhYmxlc1tiYV0sd2E9ITE7dGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzW1NhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRNZWFuU3F1YXJlc1tTYV09e29yaWdpbmFsTmFtZTpgJHtiYX0vcm1zYCx2YXJpYWJsZTp0aWR5KCgpPT56ZXJvc0xpa2UkMShUYSkudmFyaWFibGUod2EpKX0pLHRoaXMuYWNjdW11bGF0ZWRNb21lbnRzW1NhXT09bnVsbCYmKHRoaXMuYWNjdW11bGF0ZWRNb21lbnRzW1NhXT17b3JpZ2luYWxOYW1lOmAke2JhfS9tb21lbnR1bWAsdmFyaWFibGU6dGlkeSgoKT0+emVyb3NMaWtlJDEoVGEpLnZhcmlhYmxlKHdhKSl9KSx0aGlzLmFjY3VtdWxhdGVkTWVhbkdyYWRzW1NhXT09bnVsbCYmdGhpcy5jZW50ZXJlZCYmKHRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHNbU2FdPXtvcmlnaW5hbE5hbWU6YCR7YmF9L21nYCx2YXJpYWJsZTp0aWR5KCgpPT56ZXJvc0xpa2UkMShUYSkudmFyaWFibGUod2EpKX0pO2NvbnN0IEVhPUFycmF5LmlzQXJyYXkoYWEpP2FhW1NhXS50ZW5zb3I6YWFbYmFdO2lmKEVhPT1udWxsKXJldHVybjtjb25zdCBrYT10aGlzLmFjY3VtdWxhdGVkTWVhblNxdWFyZXNbU2FdLnZhcmlhYmxlLEFhPXRoaXMuYWNjdW11bGF0ZWRNb21lbnRzW1NhXS52YXJpYWJsZTt0aWR5KCgpPT57Y29uc3QgRmE9YWRkKG11bChrYSx0aGlzLmRlY2F5KSxtdWwoc3F1YXJlJDEoRWEpLDEtdGhpcy5kZWNheSkpO2lmKHRoaXMuY2VudGVyZWQpe2NvbnN0IExhPXRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHNbU2FdLnZhcmlhYmxlLGVsPWFkZChtdWwoTGEsdGhpcy5kZWNheSksbXVsKEVhLDEtdGhpcy5kZWNheSkpLHRsPWRpdihtdWwoRWEsdGhpcy5sZWFybmluZ1JhdGUpLHNxcnQkMShzdWIkMShGYSxhZGQoc3F1YXJlJDEoZWwpLHRoaXMuZXBzaWxvbikpKSksbmw9YWRkKG11bChBYSx0aGlzLm1vbWVudHVtKSx0bCk7a2EuYXNzaWduKEZhKSxMYS5hc3NpZ24oZWwpLEFhLmFzc2lnbihubCk7Y29uc3Qgc2w9c3ViJDEoVGEsbmwpO1RhLmFzc2lnbihzbCl9ZWxzZXtjb25zdCBMYT1hZGQobXVsKGthLHRoaXMuZGVjYXkpLG11bChzcXVhcmUkMShFYSksMS10aGlzLmRlY2F5KSksZWw9YWRkKG11bChBYSx0aGlzLm1vbWVudHVtKSxkaXYobXVsKEVhLHRoaXMubGVhcm5pbmdSYXRlKSxzcXJ0JDEoYWRkKExhLHRoaXMuZXBzaWxvbikpKSk7a2EuYXNzaWduKExhKSxBYS5hc3NpZ24oZWwpO2NvbnN0IHRsPXN1YiQxKFRhLGVsKTtUYS5hc3NpZ24odGwpfX0pfSksdGhpcy5pbmNyZW1lbnRJdGVyYXRpb25zKCl9ZGlzcG9zZSgpe3RoaXMuYWNjdW11bGF0ZWRNZWFuU3F1YXJlcyE9bnVsbCYmZGlzcG9zZSh0aGlzLmFjY3VtdWxhdGVkTWVhblNxdWFyZXMubWFwKGFhPT5hYS52YXJpYWJsZSkpLHRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHMhPW51bGwmJnRoaXMuY2VudGVyZWQmJmRpc3Bvc2UodGhpcy5hY2N1bXVsYXRlZE1lYW5HcmFkcy5tYXAoYWE9PmFhLnZhcmlhYmxlKSksdGhpcy5hY2N1bXVsYXRlZE1vbWVudHMhPW51bGwmJmRpc3Bvc2UodGhpcy5hY2N1bXVsYXRlZE1vbWVudHMubWFwKGFhPT5hYS52YXJpYWJsZSkpfWFzeW5jIGdldFdlaWdodHMoKXtjb25zdCBhYT1bLi4udGhpcy5hY2N1bXVsYXRlZE1lYW5TcXVhcmVzLC4uLnRoaXMuYWNjdW11bGF0ZWRNb21lbnRzXTtyZXR1cm4gdGhpcy5jZW50ZXJlZCYmYWEucHVzaCguLi50aGlzLmFjY3VtdWxhdGVkTWVhbkdyYWRzKSxbYXdhaXQgdGhpcy5zYXZlSXRlcmF0aW9ucygpXS5jb25jYXQoYWEubWFwKHhhPT4oe25hbWU6eGEub3JpZ2luYWxOYW1lLHRlbnNvcjp4YS52YXJpYWJsZX0pKSl9YXN5bmMgc2V0V2VpZ2h0cyhhYSl7YWE9YXdhaXQgdGhpcy5leHRyYWN0SXRlcmF0aW9ucyhhYSk7Y29uc3QgeGE9dGhpcy5jZW50ZXJlZD9hYS5sZW5ndGgvMzphYS5sZW5ndGgvMixiYT0hMTt0aGlzLmFjY3VtdWxhdGVkTWVhblNxdWFyZXM9YWEuc2xpY2UoMCx4YSkubWFwKFNhPT4oe29yaWdpbmFsTmFtZTpTYS5uYW1lLHZhcmlhYmxlOlNhLnRlbnNvci52YXJpYWJsZShiYSl9KSksdGhpcy5hY2N1bXVsYXRlZE1vbWVudHM9YWEuc2xpY2UoeGEseGEqMikubWFwKFNhPT4oe29yaWdpbmFsTmFtZTpTYS5uYW1lLHZhcmlhYmxlOlNhLnRlbnNvci52YXJpYWJsZShiYSl9KSksdGhpcy5jZW50ZXJlZCYmKHRoaXMuYWNjdW11bGF0ZWRNZWFuR3JhZHM9YWEuc2xpY2UoeGEqMix4YSozKS5tYXAoU2E9Pih7b3JpZ2luYWxOYW1lOlNhLm5hbWUsdmFyaWFibGU6U2EudGVuc29yLnZhcmlhYmxlKGJhKX0pKSl9Z2V0Q29uZmlnKCl7cmV0dXJue2xlYXJuaW5nUmF0ZTp0aGlzLmxlYXJuaW5nUmF0ZSxkZWNheTp0aGlzLmRlY2F5LG1vbWVudHVtOnRoaXMubW9tZW50dW0sZXBzaWxvbjp0aGlzLmVwc2lsb24sY2VudGVyZWQ6dGhpcy5jZW50ZXJlZH19c3RhdGljIGZyb21Db25maWcoYWEseGEpe3JldHVybiBuZXcgYWEoeGEubGVhcm5pbmdSYXRlLHhhLmRlY2F5LHhhLm1vbWVudHVtLHhhLmVwc2lsb24seGEuY2VudGVyZWQpfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBPUFRJTUlaRVJTPVtBZGFkZWx0YU9wdGltaXplcixBZGFncmFkT3B0aW1pemVyLEFkYW1PcHRpbWl6ZXIsQWRhbWF4T3B0aW1pemVyLE1vbWVudHVtT3B0aW1pemVyLFJNU1Byb3BPcHRpbWl6ZXIsU0dET3B0aW1pemVyXTtmdW5jdGlvbiByZWdpc3Rlck9wdGltaXplcnMoKXtmb3IoY29uc3QgaGEgb2YgT1BUSU1JWkVSUylyZWdpc3RlckNsYXNzKGhhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBERUZBVUxUX0ZJTEVfTkFNRV9QUkVGSVg9Im1vZGVsIixERUZBVUxUX0pTT05fRVhURU5TSU9OX05BTUU9Ii5qc29uIixERUZBVUxUX1dFSUdIVF9EQVRBX0VYVEVOU0lPTl9OQU1FPSIud2VpZ2h0cy5iaW4iO2Z1bmN0aW9uIGRlZmVyKGhhKXtyZXR1cm4gbmV3IFByb21pc2UoYWE9PnNldFRpbWVvdXQoYWEpKS50aGVuKGhhKX1jbGFzcyBCcm93c2VyRG93bmxvYWRze2NvbnN0cnVjdG9yKGFhKXtpZighZW52KCkuZ2V0Qm9vbCgiSVNfQlJPV1NFUiIpKXRocm93IG5ldyBFcnJvcigiYnJvd3NlckRvd25sb2FkcygpIGNhbm5vdCBwcm9jZWVkIGJlY2F1c2UgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgaXMgbm90IGEgYnJvd3Nlci4iKTthYS5zdGFydHNXaXRoKEJyb3dzZXJEb3dubG9hZHMuVVJMX1NDSEVNRSkmJihhYT1hYS5zbGljZShCcm93c2VyRG93bmxvYWRzLlVSTF9TQ0hFTUUubGVuZ3RoKSksKGFhPT1udWxsfHxhYS5sZW5ndGg9PT0wKSYmKGFhPURFRkFVTFRfRklMRV9OQU1FX1BSRUZJWCksdGhpcy5tb2RlbEpzb25GaWxlTmFtZT1hYStERUZBVUxUX0pTT05fRVhURU5TSU9OX05BTUUsdGhpcy53ZWlnaHREYXRhRmlsZU5hbWU9YWErREVGQVVMVF9XRUlHSFRfREFUQV9FWFRFTlNJT05fTkFNRX1hc3luYyBzYXZlKGFhKXtpZih0eXBlb2YgZG9jdW1lbnQ+InUiKXRocm93IG5ldyBFcnJvcigiQnJvd3NlciBkb3dubG9hZHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudCBzaW5jZSBgZG9jdW1lbnRgIGlzIG5vdCBwcmVzZW50Iik7Y29uc3QgeGE9Q29tcG9zaXRlQXJyYXlCdWZmZXIuam9pbihhYS53ZWlnaHREYXRhKSxiYT13aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbeGFdLHt0eXBlOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0ifSkpO2lmKGFhLm1vZGVsVG9wb2xvZ3kgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil0aHJvdyBuZXcgRXJyb3IoIkJyb3dzZXJEb3dubG9hZHMuc2F2ZSgpIGRvZXMgbm90IHN1cHBvcnQgc2F2aW5nIG1vZGVsIHRvcG9sb2d5IGluIGJpbmFyeSBmb3JtYXRzIHlldC4iKTt7Y29uc3QgU2E9W3twYXRoczpbIi4vIit0aGlzLndlaWdodERhdGFGaWxlTmFtZV0sd2VpZ2h0czphYS53ZWlnaHRTcGVjc31dLFRhPWdldE1vZGVsSlNPTkZvck1vZGVsQXJ0aWZhY3RzKGFhLFNhKSx3YT13aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbSlNPTi5zdHJpbmdpZnkoVGEpXSx7dHlwZToiYXBwbGljYXRpb24vanNvbiJ9KSksRWE9dGhpcy5tb2RlbEpzb25BbmNob3I9PW51bGw/ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOnRoaXMubW9kZWxKc29uQW5jaG9yO2lmKEVhLmRvd25sb2FkPXRoaXMubW9kZWxKc29uRmlsZU5hbWUsRWEuaHJlZj13YSxhd2FpdCBkZWZlcigoKT0+RWEuZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudCgiY2xpY2siKSkpLGFhLndlaWdodERhdGEhPW51bGwpe2NvbnN0IGthPXRoaXMud2VpZ2h0RGF0YUFuY2hvcj09bnVsbD9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik6dGhpcy53ZWlnaHREYXRhQW5jaG9yO2thLmRvd25sb2FkPXRoaXMud2VpZ2h0RGF0YUZpbGVOYW1lLGthLmhyZWY9YmEsYXdhaXQgZGVmZXIoKCk9PmthLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoImNsaWNrIikpKX1yZXR1cm57bW9kZWxBcnRpZmFjdHNJbmZvOmdldE1vZGVsQXJ0aWZhY3RzSW5mb0ZvckpTT04oYWEpfX19fUJyb3dzZXJEb3dubG9hZHMuVVJMX1NDSEVNRT0iZG93bmxvYWRzOi8vIjtjb25zdCBicm93c2VyRG93bmxvYWRzUm91dGVyPWhhPT5lbnYoKS5nZXRCb29sKCJJU19CUk9XU0VSIikmJiFBcnJheS5pc0FycmF5KGhhKSYmaGEuc3RhcnRzV2l0aChCcm93c2VyRG93bmxvYWRzLlVSTF9TQ0hFTUUpP2Jyb3dzZXJEb3dubG9hZHMoaGEuc2xpY2UoQnJvd3NlckRvd25sb2Fkcy5VUkxfU0NIRU1FLmxlbmd0aCkpOm51bGw7SU9Sb3V0ZXJSZWdpc3RyeS5yZWdpc3RlclNhdmVSb3V0ZXIoYnJvd3NlckRvd25sb2Fkc1JvdXRlcik7ZnVuY3Rpb24gYnJvd3NlckRvd25sb2FkcyhoYT0ibW9kZWwiKXtyZXR1cm4gbmV3IEJyb3dzZXJEb3dubG9hZHMoaGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1vbml0b3JQcm9taXNlc1Byb2dyZXNzKGhhLGFhLHhhLGJhKXt3YShoYSkseGE9eGE/PzAsYmE9YmE/PzEsRWEoeGEsYmEpO2xldCBTYT0wO2NvbnN0IFRhPWthPT4oa2EudGhlbihBYT0+e2NvbnN0IEZhPXhhKyArK1NhL2hhLmxlbmd0aCooYmEteGEpO3JldHVybiBhYShGYSksQWF9KSxrYSk7ZnVuY3Rpb24gd2Eoa2Epe2Fzc2VydChrYSE9bnVsbCYmQXJyYXkuaXNBcnJheShrYSkmJmthLmxlbmd0aD4wLCgpPT4icHJvbWlzZXMgbXVzdCBiZSBhIG5vbmUgZW1wdHkgYXJyYXkiKX1mdW5jdGlvbiBFYShrYSxBYSl7YXNzZXJ0KGthPj0wJiZrYTw9MSwoKT0+YFByb2dyZXNzIGZyYWN0aW9uIG11c3QgYmUgaW4gcmFuZ2UgWzAsIDFdLCBidXQgZ290IHN0YXJ0RnJhY3Rpb24gJHtrYX1gKSxhc3NlcnQoQWE+PTAmJkFhPD0xLCgpPT5gUHJvZ3Jlc3MgZnJhY3Rpb24gbXVzdCBiZSBpbiByYW5nZSBbMCwgMV0sIGJ1dCBnb3QgZW5kRnJhY3Rpb24gJHtBYX1gKSxhc3NlcnQoQWE+PWthLCgpPT5gc3RhcnRGcmFjdGlvbiBtdXN0IGJlIG5vIG1vcmUgdGhhbiBlbmRGcmFjdGlvbiwgYnV0IGdvdCBzdGFydEZyYWN0aW9uICR7a2F9IGFuZCBlbmRGcmFjdGlvbiAke0FhfWApfXJldHVybiBQcm9taXNlLmFsbChoYS5tYXAoVGEpKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9hc3luYyBmdW5jdGlvbiBsb2FkV2VpZ2h0c0FzQXJyYXlCdWZmZXIkMShoYSxhYSl7YWE9PW51bGwmJihhYT17fSk7Y29uc3QgeGE9YWEuZmV0Y2hGdW5jPT1udWxsP2VudigpLnBsYXRmb3JtLmZldGNoOmFhLmZldGNoRnVuYyxiYT1oYS5tYXAoTGE9PnhhKExhLGFhLnJlcXVlc3RJbml0LHtpc0JpbmFyeTohMH0pKSxFYT0oYWEub25Qcm9ncmVzcz09bnVsbD9hd2FpdCBQcm9taXNlLmFsbChiYSk6YXdhaXQgbW9uaXRvclByb21pc2VzUHJvZ3Jlc3MoYmEsYWEub25Qcm9ncmVzcywwLC41KSkubWFwKExhPT5MYS5hcnJheUJ1ZmZlcigpKTtyZXR1cm4gYWEub25Qcm9ncmVzcz09bnVsbD9hd2FpdCBQcm9taXNlLmFsbChFYSk6YXdhaXQgbW9uaXRvclByb21pc2VzUHJvZ3Jlc3MoRWEsYWEub25Qcm9ncmVzcywuNSwxKX1mdW5jdGlvbiBzdHJlYW1XZWlnaHRzKGhhLGFhKXt2YXIgeGE7Y29uc3QgYmE9YWEuZmV0Y2hGdW5jPT1udWxsP2VudigpLnBsYXRmb3JtLmZldGNoOmFhLmZldGNoRnVuYztsZXQgU2E9MCxUYTtyZXR1cm4oeGE9YWEub25Qcm9ncmVzcyk9PT1udWxsfHx4YT09PXZvaWQgMHx8eGEuY2FsbChhYSwwKSxuZXcgUmVhZGFibGVTdHJlYW0oe3B1bGw6YXN5bmMgd2E9Pntmb3IodmFyIEVhO1NhPGhhLmxlbmd0aDspe1RhfHwoVGE9KGF3YWl0IGJhKGhhW1NhXSxhYS5yZXF1ZXN0SW5pdCx7aXNCaW5hcnk6ITB9KSkuYm9keS5nZXRSZWFkZXIoKSk7Y29uc3R7ZG9uZTprYSx2YWx1ZTpBYX09YXdhaXQgVGEucmVhZCgpO2lmKGthKXtTYSsrLFRhPXZvaWQgMCwoRWE9YWEub25Qcm9ncmVzcyk9PT1udWxsfHxFYT09PXZvaWQgMHx8RWEuY2FsbChhYSxTYS9oYS5sZW5ndGgpO2NvbnRpbnVlfXdhLmVucXVldWUoQWEpO3JldHVybn13YS5jbG9zZSgpfX0pfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE9DVEVUX1NUUkVBTV9NSU1FX1RZUEU9ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsSlNPTl9UWVBFPSJhcHBsaWNhdGlvbi9qc29uIjtjbGFzcyBIVFRQUmVxdWVzdHtjb25zdHJ1Y3RvcihhYSx4YSl7aWYodGhpcy5ERUZBVUxUX01FVEhPRD0iUE9TVCIseGE9PW51bGwmJih4YT17fSksdGhpcy53ZWlnaHRQYXRoUHJlZml4PXhhLndlaWdodFBhdGhQcmVmaXgsdGhpcy53ZWlnaHRVcmxDb252ZXJ0ZXI9eGEud2VpZ2h0VXJsQ29udmVydGVyLHhhLmZldGNoRnVuYyE9bnVsbD8oYXNzZXJ0KHR5cGVvZiB4YS5mZXRjaEZ1bmM9PSJmdW5jdGlvbiIsKCk9PiJNdXN0IHBhc3MgYSBmdW5jdGlvbiB0aGF0IG1hdGNoZXMgdGhlIHNpZ25hdHVyZSBvZiBgZmV0Y2hgIChzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ZldGNoX0FQSSkiKSx0aGlzLmZldGNoPXhhLmZldGNoRnVuYyk6dGhpcy5mZXRjaD1lbnYoKS5wbGF0Zm9ybS5mZXRjaCxhc3NlcnQoYWEhPW51bGwmJmFhLmxlbmd0aD4wLCgpPT4iVVJMIHBhdGggZm9yIGh0dHAgbXVzdCBub3QgYmUgbnVsbCwgdW5kZWZpbmVkIG9yIGVtcHR5LiIpLEFycmF5LmlzQXJyYXkoYWEpJiZhc3NlcnQoYWEubGVuZ3RoPT09MiwoKT0+YFVSTCBwYXRocyBmb3IgaHR0cCBtdXN0IGhhdmUgYSBsZW5ndGggb2YgMiwgKGFjdHVhbCBsZW5ndGggaXMgJHthYS5sZW5ndGh9KS5gKSx0aGlzLnBhdGg9YWEseGEucmVxdWVzdEluaXQhPW51bGwmJnhhLnJlcXVlc3RJbml0LmJvZHkhPW51bGwpdGhyb3cgbmV3IEVycm9yKCJyZXF1ZXN0SW5pdCBpcyBleHBlY3RlZCB0byBoYXZlIG5vIHByZS1leGlzdGluZyBib2R5LCBidXQgaGFzIG9uZS4iKTt0aGlzLnJlcXVlc3RJbml0PXhhLnJlcXVlc3RJbml0fHx7fSx0aGlzLmxvYWRPcHRpb25zPXhhfWFzeW5jIHNhdmUoYWEpe2lmKGFhLm1vZGVsVG9wb2xvZ3kgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil0aHJvdyBuZXcgRXJyb3IoIkJyb3dzZXJIVFRQUmVxdWVzdC5zYXZlKCkgZG9lcyBub3Qgc3VwcG9ydCBzYXZpbmcgbW9kZWwgdG9wb2xvZ3kgaW4gYmluYXJ5IGZvcm1hdHMgeWV0LiIpO2NvbnN0IHhhPU9iamVjdC5hc3NpZ24oe21ldGhvZDp0aGlzLkRFRkFVTFRfTUVUSE9EfSx0aGlzLnJlcXVlc3RJbml0KTt4YS5ib2R5PW5ldyBGb3JtRGF0YTtjb25zdCBiYT1be3BhdGhzOlsiLi9tb2RlbC53ZWlnaHRzLmJpbiJdLHdlaWdodHM6YWEud2VpZ2h0U3BlY3N9XSxTYT1nZXRNb2RlbEpTT05Gb3JNb2RlbEFydGlmYWN0cyhhYSxiYSk7aWYoeGEuYm9keS5hcHBlbmQoIm1vZGVsLmpzb24iLG5ldyBCbG9iKFtKU09OLnN0cmluZ2lmeShTYSldLHt0eXBlOkpTT05fVFlQRX0pLCJtb2RlbC5qc29uIiksYWEud2VpZ2h0RGF0YSE9bnVsbCl7Y29uc3Qgd2E9Q29tcG9zaXRlQXJyYXlCdWZmZXIuam9pbihhYS53ZWlnaHREYXRhKTt4YS5ib2R5LmFwcGVuZCgibW9kZWwud2VpZ2h0cy5iaW4iLG5ldyBCbG9iKFt3YV0se3R5cGU6T0NURVRfU1RSRUFNX01JTUVfVFlQRX0pLCJtb2RlbC53ZWlnaHRzLmJpbiIpfWNvbnN0IFRhPWF3YWl0IHRoaXMuZmV0Y2godGhpcy5wYXRoLHhhKTtpZihUYS5vaylyZXR1cm57bW9kZWxBcnRpZmFjdHNJbmZvOmdldE1vZGVsQXJ0aWZhY3RzSW5mb0ZvckpTT04oYWEpLHJlc3BvbnNlczpbVGFdfTt0aHJvdyBuZXcgRXJyb3IoYEJyb3dzZXJIVFRQUmVxdWVzdC5zYXZlKCkgZmFpbGVkIGR1ZSB0byBIVFRQIHJlc3BvbnNlIHN0YXR1cyAke1RhLnN0YXR1c30uYCl9YXN5bmMgbG9hZE1vZGVsSlNPTigpe2NvbnN0IGFhPWF3YWl0IHRoaXMuZmV0Y2godGhpcy5wYXRoLHRoaXMucmVxdWVzdEluaXQpO2lmKCFhYS5vayl0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3QgdG8gJHt0aGlzLnBhdGh9IGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlICR7YWEuc3RhdHVzfS4gUGxlYXNlIHZlcmlmeSB0aGlzIFVSTCBwb2ludHMgdG8gdGhlIG1vZGVsIEpTT04gb2YgdGhlIG1vZGVsIHRvIGxvYWQuYCk7bGV0IHhhO3RyeXt4YT1hd2FpdCBhYS5qc29uKCl9Y2F0Y2h7bGV0IHdhPWBGYWlsZWQgdG8gcGFyc2UgbW9kZWwgSlNPTiBvZiByZXNwb25zZSBmcm9tICR7dGhpcy5wYXRofS5gO3Rocm93IHRoaXMucGF0aC5lbmRzV2l0aCgiLnBiIik/d2ErPSIgWW91ciBwYXRoIGNvbnRhaW5zIGEgLnBiIGZpbGUgZXh0ZW5zaW9uLiBTdXBwb3J0IGZvciAucGIgbW9kZWxzIGhhdmUgYmVlbiByZW1vdmVkIGluIFRlbnNvckZsb3cuanMgMS4wIGluIGZhdm9yIG9mIC5qc29uIG1vZGVscy4gWW91IGNhbiByZS1jb252ZXJ0IHlvdXIgUHl0aG9uIFRlbnNvckZsb3cgbW9kZWwgdXNpbmcgdGhlIFRlbnNvckZsb3cuanMgMS4wIGNvbnZlcnNpb24gc2NyaXB0cyBvciB5b3UgY2FuIGNvbnZlcnQgeW91ci5wYiBtb2RlbHMgd2l0aCB0aGUgJ3BiMmpzb24nTlBNIHNjcmlwdCBpbiB0aGUgdGVuc29yZmxvdy90ZmpzLWNvbnZlcnRlciByZXBvc2l0b3J5LiI6d2ErPSIgUGxlYXNlIG1ha2Ugc3VyZSB0aGUgc2VydmVyIGlzIHNlcnZpbmcgdmFsaWQgSlNPTiBmb3IgdGhpcyByZXF1ZXN0LiIsbmV3IEVycm9yKHdhKX1jb25zdCBiYT14YS5tb2RlbFRvcG9sb2d5LFNhPXhhLndlaWdodHNNYW5pZmVzdDtpZihiYT09bnVsbCYmU2E9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBUaGUgSlNPTiBmcm9tIEhUVFAgcGF0aCAke3RoaXMucGF0aH0gY29udGFpbnMgbmVpdGhlciBtb2RlbCB0b3BvbG9neSBvciBtYW5pZmVzdCBmb3Igd2VpZ2h0cy5gKTtyZXR1cm4geGF9YXN5bmMgbG9hZCgpe2lmKHRoaXMubG9hZE9wdGlvbnMuc3RyZWFtV2VpZ2h0cylyZXR1cm4gdGhpcy5sb2FkU3RyZWFtKCk7Y29uc3QgYWE9YXdhaXQgdGhpcy5sb2FkTW9kZWxKU09OKCk7cmV0dXJuIGdldE1vZGVsQXJ0aWZhY3RzRm9ySlNPTihhYSx4YT0+dGhpcy5sb2FkV2VpZ2h0cyh4YSkpfWFzeW5jIGxvYWRTdHJlYW0oKXtjb25zdCBhYT1hd2FpdCB0aGlzLmxvYWRNb2RlbEpTT04oKSx4YT1hd2FpdCB0aGlzLmdldFdlaWdodFVybHMoYWEud2VpZ2h0c01hbmlmZXN0KSxiYT1nZXRXZWlnaHRTcGVjcyhhYS53ZWlnaHRzTWFuaWZlc3QpLFNhPSgpPT5zdHJlYW1XZWlnaHRzKHhhLHRoaXMubG9hZE9wdGlvbnMpO3JldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sYWEpLHt3ZWlnaHRTcGVjczpiYSxnZXRXZWlnaHRTdHJlYW06U2F9KX1hc3luYyBnZXRXZWlnaHRVcmxzKGFhKXtjb25zdCB4YT1BcnJheS5pc0FycmF5KHRoaXMucGF0aCk/dGhpcy5wYXRoWzFdOnRoaXMucGF0aCxbYmEsU2FdPXBhcnNlVXJsKHhhKSxUYT10aGlzLndlaWdodFBhdGhQcmVmaXh8fGJhLHdhPVtdLEVhPVtdO2Zvcihjb25zdCBrYSBvZiBhYSlmb3IoY29uc3QgQWEgb2Yga2EucGF0aHMpdGhpcy53ZWlnaHRVcmxDb252ZXJ0ZXIhPW51bGw/RWEucHVzaCh0aGlzLndlaWdodFVybENvbnZlcnRlcihBYSkpOndhLnB1c2goVGErQWErU2EpO3JldHVybiB0aGlzLndlaWdodFVybENvbnZlcnRlciYmd2EucHVzaCguLi5hd2FpdCBQcm9taXNlLmFsbChFYSkpLHdhfWFzeW5jIGxvYWRXZWlnaHRzKGFhKXtjb25zdCB4YT1hd2FpdCB0aGlzLmdldFdlaWdodFVybHMoYWEpLGJhPWdldFdlaWdodFNwZWNzKGFhKSxTYT1hd2FpdCBsb2FkV2VpZ2h0c0FzQXJyYXlCdWZmZXIkMSh4YSx0aGlzLmxvYWRPcHRpb25zKTtyZXR1cm5bYmEsU2FdfX1IVFRQUmVxdWVzdC5VUkxfU0NIRU1FX1JFR0VYPS9eaHR0cHM/OlwvXC8vO2Z1bmN0aW9uIHBhcnNlVXJsKGhhKXtjb25zdCBhYT1oYS5sYXN0SW5kZXhPZigiLyIpLHhhPWhhLmxhc3RJbmRleE9mKCI/IiksYmE9aGEuc3Vic3RyaW5nKDAsYWEpLFNhPXhhPmFhP2hhLnN1YnN0cmluZyh4YSk6IiI7cmV0dXJuW2JhKyIvIixTYV19ZnVuY3Rpb24gaXNIVFRQU2NoZW1lKGhhKXtyZXR1cm4gaGEubWF0Y2goSFRUUFJlcXVlc3QuVVJMX1NDSEVNRV9SRUdFWCkhPW51bGx9Y29uc3QgaHR0cFJvdXRlcj0oaGEsYWEpPT57aWYodHlwZW9mIGZldGNoPiJ1IiYmKGFhPT1udWxsfHxhYS5mZXRjaEZ1bmM9PW51bGwpKXJldHVybiBudWxsO3tsZXQgeGE9ITA7aWYoQXJyYXkuaXNBcnJheShoYSk/eGE9aGEuZXZlcnkoYmE9PmlzSFRUUFNjaGVtZShiYSkpOnhhPWlzSFRUUFNjaGVtZShoYSkseGEpcmV0dXJuIGh0dHAoaGEsYWEpfXJldHVybiBudWxsfTtJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyU2F2ZVJvdXRlcihodHRwUm91dGVyKSxJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyTG9hZFJvdXRlcihodHRwUm91dGVyKTtmdW5jdGlvbiBodHRwKGhhLGFhKXtyZXR1cm4gbmV3IEhUVFBSZXF1ZXN0KGhhLGFhKX1mdW5jdGlvbiBwcmVwYXJlQW5kVmFsaWRhdGUoaGEsYWEpe2NvbnN0IHhhPWhhLnNoYXBlLmxlbmd0aCxiYT1hYS5zaGFwZS5sZW5ndGg7aWYoeGE8MSl0aHJvdyBuZXcgRXJyb3IoYHRmLmdhdGhlck5EKCkgZXhwZWN0cyB0aGUgaW5wdXQgdG8gYmUgcmFuayAxIG9yIGhpZ2hlciwgYnV0IHRoZSByYW5rIHdhcyAke3hhfS5gKTtpZihiYTwxKXRocm93IG5ldyBFcnJvcihgdGYuZ2F0aGVyTkQoKSBleHBlY3RzIHRoZSBpbmRpY2VzIHRvIGJlIHJhbmsgMSBvciBoaWdoZXIsIGJ1dCB0aGUgcmFuayB3YXMgJHtiYX0uYCk7aWYoYWEuZHR5cGUhPT0iaW50MzIiKXRocm93IG5ldyBFcnJvcihgdGYuZ2F0aGVyTkQoKSBleHBlY3RzIHRoZSBpbmRpY2VzIHRvIGJlIGludDMyIHR5cGUsIGJ1dCB0aGUgZHR5cGUgd2FzICR7YWEuZHR5cGV9LmApO2lmKGFhLnNoYXBlW2JhLTFdPnhhKXRocm93IG5ldyBFcnJvcihgaW5kZXggaW5uZXJtb3N0IGRpbWVuc2lvbiBsZW5ndGggbXVzdCBiZSA8PSB0ZW5zb3IgcmFuazsgc2F3OiAke2FhLnNoYXBlW2JhLTFdfSB2cy4gJHt4YX1gKTtpZihzaXplRnJvbVNoYXBlKGhhLnNoYXBlKT09PTApdGhyb3cgbmV3IEVycm9yKGBSZXF1ZXN0ZWQgbW9yZSB0aGFuIDAgZW50cmllcywgYnV0IGlucHV0IGlzIGVtcHR5LiBJbnB1dCBzaGFwZTogJHtoYS5zaGFwZX0uYCk7Y29uc3QgU2E9YWEuc2hhcGUsVGE9U2FbU2EubGVuZ3RoLTFdO2xldCB3YT0xO2ZvcihsZXQgTGE9MDtMYTxTYS5sZW5ndGgtMTsrK0xhKXdhKj1TYVtMYV07Y29uc3QgRWE9aGEuc2hhcGUsa2E9U2Euc2xpY2UoKTtrYS5wb3AoKTtsZXQgQWE9MTtmb3IobGV0IExhPVRhO0xhPHhhOysrTGEpQWEqPUVhW0xhXSxrYS5wdXNoKEVhW0xhXSk7Y29uc3QgRmE9Wy4uLmNvbXB1dGVTdHJpZGVzKGhhLnNoYXBlKS5tYXAoTGE9PkxhL0FhKSwxXS5zbGljZSgwLFRhKTtyZXR1cm5ba2Esd2EsQWEsRmFdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE5FV19BWElTPS0yLFNIUklOS19BWElTPS0xO2Z1bmN0aW9uIGFzc2VydFBhcmFtc1ZhbGlkKGhhLGFhLHhhKXtjb25zdCBiYT1oYS5zaGFwZS5sZW5ndGg7YXNzZXJ0KGJhPT09YWEubGVuZ3RoLCgpPT5gRXJyb3IgaW4gc2xpY2Uke2JhfUQ6IExlbmd0aCBvZiBiZWdpbiAke2FhfSBtdXN0IG1hdGNoIHRoZSByYW5rIG9mIHRoZSBhcnJheSAoJHtiYX0pLmApLGFzc2VydChiYT09PXhhLmxlbmd0aCwoKT0+YEVycm9yIGluIHNsaWNlJHtiYX1EOiBMZW5ndGggb2Ygc2l6ZSAke3hhfSBtdXN0IG1hdGNoIHRoZSByYW5rIG9mIHRoZSBhcnJheSAoJHtiYX0pLmApO2ZvcihsZXQgU2E9MDtTYTxiYTsrK1NhKWFzc2VydChhYVtTYV0reGFbU2FdPD1oYS5zaGFwZVtTYV0sKCk9PmBFcnJvciBpbiBzbGljZSR7YmF9RDogYmVnaW5bJHtTYX1dICsgc2l6ZVske1NhfV0gKCR7YWFbU2FdK3hhW1NhXX0pIHdvdWxkIG92ZXJmbG93IGlucHV0LnNoYXBlWyR7U2F9XSAoJHtoYS5zaGFwZVtTYV19KWApfWZ1bmN0aW9uIG1hc2tUb0F4ZXMoaGEpe2NvbnN0IGFhPVtdO2xldCB4YT0wO2Zvcig7aGE+MDspaGEmMSYmYWEucHVzaCh4YSksaGEvPTIseGErKztyZXR1cm4gYWF9ZnVuY3Rpb24gY29tcHV0ZU91dFNoYXBlJDIoaGEsYWEseGEpe2NvbnN0IGJhPVtdO2ZvcihsZXQgU2E9MDtTYTxoYS5sZW5ndGg7U2ErKyliYVtTYV09TWF0aC5jZWlsKChhYVtTYV0taGFbU2FdKS94YVtTYV0pO3JldHVybiBiYX1mdW5jdGlvbiBzdHJpZGVzV2l0aEVsaWRlZERpbXMoaGEsYWEseGEsYmEpe2NvbnN0IFNhPVsuLi5oYV07Zm9yKGxldCBUYT1TYS5sZW5ndGg7VGE8YmEubGVuZ3RoO1RhKyspU2EucHVzaCgxKTtmb3IobGV0IFRhPTA7VGE8eGE7VGErKylUYT09PTA/U2FbYWFdPTE6KFNhLnNwbGljZShhYSwwLDEpLFNhLnBvcCgpKTtyZXR1cm4gU2F9ZnVuY3Rpb24gdW5ub3JtYWxpemVBeGlzKGhhLGFhLHhhKXtyZXR1cm4geGE8PWhhP3hhOnhhLShhYS0xKX1mdW5jdGlvbiBnZXRFbGlkZWRBeGVzKGhhLGFhKXtjb25zdCB4YT1bXTtmb3IobGV0IGJhPTA7YmE8aGE7YmErKyl4YS5wdXNoKGFhK2JhKTtyZXR1cm4geGF9ZnVuY3Rpb24gZ2V0Tm9ybWFsaXplZEF4ZXMoaGEsYWEseGEsYmEsU2EsVGEsd2EsRWEsa2Epe2NvbnN0IEFhPWhhLmxlbmd0aDtsZXQgRmE9bmV3IEFycmF5KEFhKSxMYT1uZXcgQXJyYXkoQWEpLGVsPW5ldyBBcnJheShBYSk7aWYoYWEubGVuZ3RoJiZ4YT4wKXtjb25zdCB0bD1hYVswXSxubD14YSsxO0ZhPXN0YXJ0SW5kaWNlc1dpdGhFbGlkZWREaW1zKHdhLHRsLG5sLGJhLGhhKSxMYT1zdG9wSW5kaWNlc1dpdGhFbGlkZWREaW1zKEVhLHRsLG5sLFNhLGhhKSxlbD1zdHJpZGVzV2l0aEVsaWRlZERpbXMoVGEsdGwsbmwsaGEpfWVsc2UgZm9yKGxldCB0bD0wO3RsPEFhO3RsKyspRmFbdGxdPXN0YXJ0Rm9yQXhpcyh3YSxiYSxUYSxoYSx0bCxrYSksTGFbdGxdPXN0b3BGb3JBeGlzKEVhLFNhLFRhLGhhLHRsLGthKSxlbFt0bF09c3RyaWRlc0ZvckF4aXMoVGEsdGwsa2EpO3JldHVybntiZWdpbjpGYSxlbmQ6TGEsc3RyaWRlczplbH19ZnVuY3Rpb24gc3RhcnRJbmRpY2VzV2l0aEVsaWRlZERpbXMoaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPVsuLi5TYV0sd2E9Z2V0RWxpZGVkQXhlcyh4YSxhYSk7Zm9yKGxldCBFYT0wO0VhPFRhLmxlbmd0aDtFYSsrKWlmKHdhLmluZGV4T2YoRWEpPi0xKVRhW0VhXT0wO2Vsc2V7Y29uc3Qga2E9dW5ub3JtYWxpemVBeGlzKGFhLHhhLEVhKTtsZXQgQWE9YmFba2FdO2hhJjE8PGthJiYoQWE9MCksVGFbRWFdPUFhfXJldHVybiBUYX1mdW5jdGlvbiBzdG9wSW5kaWNlc1dpdGhFbGlkZWREaW1zKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1bLi4uU2FdLHdhPWdldEVsaWRlZEF4ZXMoeGEsYWEpO2ZvcihsZXQgRWE9MDtFYTxUYS5sZW5ndGg7RWErKylpZih3YS5pbmRleE9mKEVhKT4tMSlUYVtFYV09TnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7ZWxzZXtjb25zdCBrYT11bm5vcm1hbGl6ZUF4aXMoYWEseGEsRWEpO2xldCBBYT1iYVtrYV07aGEmMTw8a2EmJihBYT1OdW1iZXIuTUFYX1NBRkVfSU5URUdFUiksVGFbRWFdPUFhfWZvcihsZXQgRWE9MDtFYTxUYS5sZW5ndGg7RWErKyl7Y29uc3Qga2E9U2FbRWFdO1RhW0VhXTwwJiYoVGFbRWFdKz1rYSksVGFbRWFdPWNsYW1wKDAsVGFbRWFdLFNhW0VhXSl9cmV0dXJuIFRhfWZ1bmN0aW9uIHN0cmlkZXNGb3JBeGlzKGhhLGFhLHhhKXtsZXQgYmE9aGFbYWFdO3JldHVybih4YSYxPDxhYXx8YmE9PW51bGwpJiYoYmE9MSksYmF9ZnVuY3Rpb24gc3RhcnRGb3JBeGlzKGhhLGFhLHhhLGJhLFNhLFRhKXtsZXQgd2E9YWFbU2FdO2NvbnN0IEVhPXhhW1NhXXx8MTsoaGEmMTw8U2F8fFRhJjE8PFNhfHx3YT09bnVsbCkmJihFYT4wP3dhPU51bWJlci5NSU5fU0FGRV9JTlRFR0VSOndhPU51bWJlci5NQVhfU0FGRV9JTlRFR0VSKTtjb25zdCBrYT1iYVtTYV07cmV0dXJuIHdhPDAmJih3YSs9a2EpLHdhPWNsYW1wKDAsd2Esa2EtMSksd2F9ZnVuY3Rpb24gc3RvcEZvckF4aXMoaGEsYWEseGEsYmEsU2EsVGEpe2xldCB3YT1hYVtTYV07Y29uc3QgRWE9eGFbU2FdfHwxOyhoYSYxPDxTYXx8VGEmMTw8U2F8fHdhPT1udWxsKSYmKEVhPjA/d2E9TnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI6d2E9TnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIpO2NvbnN0IGthPWJhW1NhXTtyZXR1cm4gd2E8MCYmKHdhKz1rYSksRWE+MD93YT1jbGFtcCgwLHdhLGthKTp3YT1jbGFtcCgtMSx3YSxrYS0xKSx3YX1mdW5jdGlvbiBpc1NsaWNlQ29udGlub3VzKGhhLGFhLHhhKXtsZXQgYmE9eGEubGVuZ3RoO2ZvcihsZXQgU2E9MDtTYTx4YS5sZW5ndGg7U2ErKylpZih4YVtTYV0+MSl7YmE9U2E7YnJlYWt9Zm9yKGxldCBTYT1iYSsxO1NhPHhhLmxlbmd0aDtTYSsrKWlmKGFhW1NhXT4wfHx4YVtTYV0hPT1oYVtTYV0pcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gY29tcHV0ZUZsYXRPZmZzZXQoaGEsYWEpe2xldCB4YT1oYS5sZW5ndGg+MD9oYVtoYS5sZW5ndGgtMV06MTtmb3IobGV0IGJhPTA7YmE8aGEubGVuZ3RoLTE7YmErKyl4YSs9aGFbYmFdKmFhW2JhXTtyZXR1cm4geGF9ZnVuY3Rpb24gcGFyc2VTbGljZVBhcmFtcyhoYSxhYSx4YSl7bGV0IGJhO2NvbnN0IFNhPWhhLnNoYXBlLmxlbmd0aDt0eXBlb2YgYWE9PSJudW1iZXIiP2JhPVthYSwuLi5uZXcgQXJyYXkoU2EtMSkuZmlsbCgwKV06YWEubGVuZ3RoPFNhP2JhPWFhLmNvbmNhdChuZXcgQXJyYXkoU2EtYWEubGVuZ3RoKS5maWxsKDApKTpiYT1hYS5zbGljZSgpLGJhLmZvckVhY2god2E9Pnthc3NlcnQod2EhPT0tMSwoKT0+InNsaWNlKCkgZG9lcyBub3Qgc3VwcG9ydCBuZWdhdGl2ZSBiZWdpbiBpbmRleGluZy4iKX0pO2xldCBUYTtyZXR1cm4geGE9PW51bGw/VGE9bmV3IEFycmF5KFNhKS5maWxsKC0xKTp0eXBlb2YgeGE9PSJudW1iZXIiP1RhPVt4YSwuLi5uZXcgQXJyYXkoU2EtMSkuZmlsbCgtMSldOnhhLmxlbmd0aDxTYT9UYT14YS5jb25jYXQobmV3IEFycmF5KFNhLXhhLmxlbmd0aCkuZmlsbCgtMSkpOlRhPXhhLFRhPVRhLm1hcCgod2EsRWEpPT53YT49MD93YTooYXNzZXJ0KHdhPT09LTEsKCk9PmBOZWdhdGl2ZSBzaXplIHZhbHVlcyBzaG91bGQgYmUgZXhhY3RseSAtMSBidXQgZ290ICR7d2F9IGZvciB0aGUgc2xpY2UoKSBzaXplIGF0IGluZGV4ICR7RWF9LmApLGhhLnNoYXBlW0VhXS1iYVtFYV0pKSxbYmEsVGFdfWZ1bmN0aW9uIHNsaWNlSW5mbyhoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSl7bGV0IEFhO2lmKGJhPT1udWxsPyhBYT1uZXcgQXJyYXkoYWEubGVuZ3RoKSxBYS5maWxsKDEpKTpBYT1iYSx3YSE9bnVsbCYmd2Emd2EtMSl0aHJvdyBuZXcgRXJyb3IoIk11bHRpcGxlIGVsbGlwc2VzIGluIHNsaWNlIGlzIG5vdCBhbGxvd2VkLiIpO2xldCBGYT0hMTtjb25zdCBMYT17ZGltczpBYS5sZW5ndGgsbnVtQWRkQXhpc0FmdGVyRWxsaXBzaXM6MCxiZWdpbjphYS5zbGljZSgpLGVuZDp4YS5zbGljZSgpLHN0cmlkZXM6QWEuc2xpY2UoKSxiZWdpbk1hc2s6U2EsZW5kTWFzazpUYSxlbGxpcHNpc01hc2s6d2EsbmV3QXhpc01hc2s6RWEsc2hyaW5rQXhpc01hc2s6a2F9O2ZvcihsZXQgbGw9MDtsbDxMYS5kaW1zO2xsKyspRmEmJjE8PGxsJkVhJiZMYS5udW1BZGRBeGlzQWZ0ZXJFbGxpcHNpcysrLDE8PGxsJndhJiYoRmE9ITApO0ZhfHwoTGEuZWxsaXBzaXNNYXNrfD0xPDxMYS5kaW1zLExhLmRpbXMrKyk7Y29uc3QgZWw9e2RpbXM6aGEubGVuZ3RoLGJlZ2luTWFzazowLGVuZE1hc2s6MCxiZWdpblZhbGlkOiExLGVuZFZhbGlkOiExfTtidWlsZERlbnNlU3BlYyhMYSxlbCk7bGV0IHRsPSEwLG5sPSEwLHNsPSEwO2NvbnN0IHJsPVtdLG9sPVtdO2ZvcihsZXQgbGw9MDtsbDxoYS5sZW5ndGg7KytsbCl7aWYoZWwuc3RyaWRlc1tsbF09PT0wKXRocm93IEVycm9yKGBzdHJpZGVzWyR7bGx9XSBtdXN0IGJlIG5vbi16ZXJvYCk7Y29uc3QgaWw9ISEoZWwuc2hyaW5rQXhpc01hc2smMTw8bGwpLGNsPWhhW2xsXTtpZihjbD09PS0xKXtybC5wdXNoKGlsPzE6LTEpO2NvbnRpbnVlfWNvbnN0IHVsPVtlbC5iZWdpbk1hc2smMTw8bGwsZWwuZW5kTWFzayYxPDxsbF0sZGw9W2VsLnN0cmlkZXNbbGxdPjA/MDotMSxlbC5zdHJpZGVzW2xsXT4wP2NsOmNsLTFdO2lmKGlsJiZlbC5zdHJpZGVzW2xsXTw9MCl0aHJvdyBFcnJvcigib25seSBzdHJpZGUgMSBhbGxvd2VkIG9uIG5vbi1yYW5nZSBpbmRleGluZy4iKTtzbD1zbCYmZWwuc3RyaWRlc1tsbF09PT0xO2NvbnN0IGhsPSEhKGVsLmJlZ2luTWFzayYxPDxsbCYmZWwuZW5kTWFzayYxPDxsbCk7aWYoZWwuYmVnaW5WYWxpZCYmZWwuZW5kVmFsaWQpe2lmKGlsKXtjb25zdCBnbD1lbC5iZWdpbltsbF08MD9jbCtlbC5iZWdpbltsbF06ZWwuYmVnaW5bbGxdO2lmKGVsLmJlZ2luW2xsXT1nbCxlbC5lbmRbbGxdPWVsLmJlZ2luW2xsXSsxLGdsPDB8fGdsPj1jbCl0aHJvdyBFcnJvcihgc2xpY2UgaW5kZXggJHtlbC5iZWdpbltsbF19IG9mIGRpbWVuc2lvbiAke2xsfSBvdXQgb2YgYm91bmRzLmApfWVsc2UgZWwuYmVnaW5bbGxdPWNhbm9uaWNhbChlbC5iZWdpbltsbF0sMCxlbC5zdHJpZGVzW2xsXSxjbCx1bCxkbCksZWwuZW5kW2xsXT1jYW5vbmljYWwoZWwuZW5kW2xsXSwxLGVsLnN0cmlkZXNbbGxdLGNsLHVsLGRsKTtjb25zdCBtbD1lbC5zdHJpZGVzW2xsXT09PTEmJmVsLmJlZ2luW2xsXT09PTAmJmVsLmVuZFtsbF09PT1jbDt0bD10bCYmbWwsbmw9bmwmJihsbD09PTAmJmVsLnN0cmlkZXNbbGxdPT09MXx8bWwpfWVsc2UgdGw9dGwmJmVsLnN0cmlkZXNbbGxdPT09MSYmaGwsbmw9bmwmJihsbD09PTAmJmVsLnN0cmlkZXNbbGxdPT09MXx8aGwpO2xldCBwbCxmbD0hMTtpZihlbC5iZWdpblZhbGlkJiZlbC5lbmRWYWxpZD8ocGw9ZWwuZW5kW2xsXS1lbC5iZWdpbltsbF0sZmw9ITApOmlsPyhwbD0xLGZsPSEwKTpobCYmY2w+PTAmJihlbC5zdHJpZGVzW2xsXTwwP3BsPS1jbDpwbD1jbCxmbD0hMCksZmwpe2xldCBtbDtwbD09PTB8fHBsPDAhPWVsLnN0cmlkZXNbbGxdPDA/bWw9MDptbD1NYXRoLnRydW5jKHBsL2VsLnN0cmlkZXNbbGxdKSsocGwlZWwuc3RyaWRlc1tsbF0hPT0wPzE6MCkscmwucHVzaChtbCl9ZWxzZSBybC5wdXNoKC0xKX1mb3IobGV0IGxsPTA7bGw8ZWwuZmluYWxTaGFwZUdhdGhlckluZGljZXMubGVuZ3RoOysrbGwpe2NvbnN0IGlsPWVsLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzW2xsXTtpbD49MD9vbC5wdXNoKHJsW2lsXSk6aWw9PT1ORVdfQVhJUyYmb2wucHVzaCgxKX1yZXR1cm57ZmluYWxTaGFwZVNwYXJzZTpvbC5maWx0ZXIoKGxsLGlsKT0+ZWwuZmluYWxTaGFwZUdhdGhlckluZGljZXNbaWxdIT09TkVXX0FYSVMpLGZpbmFsU2hhcGU6b2wsaXNJZGVudGl0eTp0bCxzbGljZURpbTA6bmwsaXNTaW1wbGVTbGljZTpzbCxiZWdpbjplbC5iZWdpbixlbmQ6ZWwuZW5kLHN0cmlkZXM6ZWwuc3RyaWRlc319ZnVuY3Rpb24gYnVpbGREZW5zZVNwZWMoaGEsYWEpe2FhLmJlZ2luTWFzaz0wLGFhLmVuZE1hc2s9MCxhYS5zaHJpbmtBeGlzTWFzaz0wO2xldCB4YT0wO2FhLmJlZ2luVmFsaWQ9aGEuYmVnaW4hPW51bGwsYWEuZW5kVmFsaWQ9aGEuZW5kIT1udWxsLGFhLmJlZ2luPW5ldyBBcnJheShhYS5kaW1zKSxhYS5lbmQ9bmV3IEFycmF5KGFhLmRpbXMpLGFhLnN0cmlkZXM9bmV3IEFycmF5KGFhLmRpbXMpLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzPVtdLGFhLmZpbmFsU2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlPVtdLGFhLmlucHV0U2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlPW5ldyBBcnJheShhYS5kaW1zKTtmb3IobGV0IGJhPTA7YmE8aGEuZGltcztiYSsrKWlmKDE8PGJhJmhhLmVsbGlwc2lzTWFzayl7Y29uc3QgU2E9TWF0aC5taW4oYWEuZGltcy0oaGEuZGltcy1iYSkrMStoYS5udW1BZGRBeGlzQWZ0ZXJFbGxpcHNpcyxhYS5kaW1zKTtmb3IoO3hhPFNhO3hhKyspYWEuYmVnaW5beGFdPTAsYWEuZW5kW3hhXT0wLGFhLnN0cmlkZXNbeGFdPTEsYWEuYmVnaW5NYXNrfD0xPDx4YSxhYS5lbmRNYXNrfD0xPDx4YSxhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlcy5wdXNoKHhhKSxhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlc1NwYXJzZS5wdXNoKC0xKSxhYS5pbnB1dFNoYXBlR2F0aGVySW5kaWNlc1NwYXJzZVt4YV09YmF9ZWxzZSBpZigxPDxiYSZoYS5uZXdBeGlzTWFzaylhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlcy5wdXNoKE5FV19BWElTKSxhYS5maW5hbFNoYXBlR2F0aGVySW5kaWNlc1NwYXJzZS5wdXNoKC0xKTtlbHNle2lmKHhhPT09YWEuYmVnaW4ubGVuZ3RoKXRocm93IEVycm9yKGBJbmRleCBvdXQgb2YgcmFuZ2UgdXNpbmcgaW5wdXQgZGltICR7eGF9OyBpbnB1dCBoYXMgb25seSAke2FhLmRpbXN9IGRpbXMsICR7YWEuYmVnaW4ubGVuZ3RofS5gKTtoYS5iZWdpbiE9bnVsbCYmKGFhLmJlZ2luW3hhXT1oYS5iZWdpbltiYV0pLGhhLmVuZCE9bnVsbCYmKGFhLmVuZFt4YV09aGEuZW5kW2JhXSksYWEuc3RyaWRlc1t4YV09aGEuc3RyaWRlc1tiYV0saGEuYmVnaW5NYXNrJjE8PGJhJiYoYWEuYmVnaW5NYXNrfD0xPDx4YSksaGEuZW5kTWFzayYxPDxiYSYmKGFhLmVuZE1hc2t8PTE8PHhhKSxoYS5zaHJpbmtBeGlzTWFzayYxPDxiYT8oYWEuZmluYWxTaGFwZUdhdGhlckluZGljZXMucHVzaChTSFJJTktfQVhJUyksYWEuZmluYWxTaGFwZUdhdGhlckluZGljZXNTcGFyc2UucHVzaCgtMSksYWEuc2hyaW5rQXhpc01hc2t8PTE8PHhhKTooYWEuZmluYWxTaGFwZUdhdGhlckluZGljZXMucHVzaCh4YSksYWEuZmluYWxTaGFwZUdhdGhlckluZGljZXNTcGFyc2UucHVzaChiYSkpLGFhLmlucHV0U2hhcGVHYXRoZXJJbmRpY2VzU3BhcnNlW3hhXT1iYSx4YSsrfX1mdW5jdGlvbiBjYW5vbmljYWwoaGEsYWEseGEsYmEsU2EsVGEpe2lmKFNhW2FhXSlyZXR1cm4geGE+MD9UYVthYV06VGFbYWErMSYxXTt7Y29uc3Qgd2E9aGE8MD9iYStoYTpoYTtyZXR1cm4gd2E8VGFbMF0/VGFbMF06d2E+VGFbMV0/VGFbMV06d2F9fXZhciBzbGljZV91dGlsPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFzc2VydFBhcmFtc1ZhbGlkLGNvbXB1dGVGbGF0T2Zmc2V0LGNvbXB1dGVPdXRTaGFwZTpjb21wdXRlT3V0U2hhcGUkMixnZXROb3JtYWxpemVkQXhlcyxpc1NsaWNlQ29udGlub3VzLG1hc2tUb0F4ZXMscGFyc2VTbGljZVBhcmFtcyxzbGljZUluZm8sc3RhcnRGb3JBeGlzLHN0YXJ0SW5kaWNlc1dpdGhFbGlkZWREaW1zLHN0b3BGb3JBeGlzLHN0b3BJbmRpY2VzV2l0aEVsaWRlZERpbXMsc3RyaWRlc0ZvckF4aXMsc3RyaWRlc1dpdGhFbGlkZWREaW1zfSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZGVsYXlDYWxsYmFjaz10eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lPCJ1Ij9yZXF1ZXN0QW5pbWF0aW9uRnJhbWU6dHlwZW9mIHNldEltbWVkaWF0ZTwidSI/c2V0SW1tZWRpYXRlOmhhPT5oYSgpO2Z1bmN0aW9uIG5leHRGcmFtZSgpe3JldHVybiBuZXcgUHJvbWlzZShoYT0+ZGVsYXlDYWxsYmFjaygoKT0+aGEoKSkpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFzc2VydFBhcmFtc0NvbnNpc3RlbnQoaGEsYWEpe2NvbnN0IHhhPWhhWzBdLmxlbmd0aDtoYS5mb3JFYWNoKChTYSxUYSk9Pnthc3NlcnQoU2EubGVuZ3RoPT09eGEsKCk9PmBFcnJvciBpbiBjb25jYXQke3hhfUQ6IHJhbmsgb2YgdGVuc29yc1ske1RhfV0gbXVzdCBiZSB0aGUgc2FtZSBhcyB0aGUgcmFuayBvZiB0aGUgcmVzdCAoJHt4YX0pYCl9KSxhc3NlcnQoYWE+PTAmJmFhPHhhLCgpPT5gRXJyb3IgaW4gY29uY2F0JHt4YX1EOiBheGlzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAke3hhLTF9LmApO2NvbnN0IGJhPWhhWzBdO2hhLmZvckVhY2goKFNhLFRhKT0+e2ZvcihsZXQgd2E9MDt3YTx4YTt3YSsrKWFzc2VydCh3YT09PWFhfHxTYVt3YV09PT1iYVt3YV0sKCk9PmBFcnJvciBpbiBjb25jYXQke3hhfUQ6IFNoYXBlIG9mIHRlbnNvcnNbJHtUYX1dICgke1NhfSkgZG9lcyBub3QgbWF0Y2ggdGhlIHNoYXBlIG9mIHRoZSByZXN0ICgke2JhfSkgYWxvbmcgdGhlIG5vbi1jb25jYXRlbmF0ZWQgYXhpcyAke1RhfS5gKX0pfWZ1bmN0aW9uIGNvbXB1dGVPdXRTaGFwZSQxKGhhLGFhKXtjb25zdCB4YT1oYVswXS5zbGljZSgpO2ZvcihsZXQgYmE9MTtiYTxoYS5sZW5ndGg7YmErKyl4YVthYV0rPWhhW2JhXVthYV07cmV0dXJuIHhhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBSb3dQYXJ0aXRpb25UeXBlJDE7KGZ1bmN0aW9uKGhhKXtoYVtoYS5GSVJTVF9ESU1fU0laRT0wXT0iRklSU1RfRElNX1NJWkUiLGhhW2hhLlZBTFVFX1JPV0lEUz0xXT0iVkFMVUVfUk9XSURTIixoYVtoYS5ST1dfTEVOR1RIUz0yXT0iUk9XX0xFTkdUSFMiLGhhW2hhLlJPV19TUExJVFM9M109IlJPV19TUExJVFMiLGhhW2hhLlJPV19MSU1JVFM9NF09IlJPV19MSU1JVFMiLGhhW2hhLlJPV19TVEFSVFM9NV09IlJPV19TVEFSVFMifSkoUm93UGFydGl0aW9uVHlwZSQxfHwoUm93UGFydGl0aW9uVHlwZSQxPXt9KSk7ZnVuY3Rpb24gY29tYmluZVJhZ2dlZFRlbnNvclRvVGVuc29yU2hhcGVzKGhhLGFhLHhhKXtsZXQgYmE9bmV3IEFycmF5O2lmKHhhPT1udWxsJiZhYT09bnVsbClyZXR1cm4gYmE7aWYoYWE9PW51bGwpZm9yKDtiYS5sZW5ndGg8aGEreGEubGVuZ3RoOyliYS5wdXNoKC0xKTtlbHNlIGJhPWFhLnNsaWNlKCk7aWYoeGE9PW51bGwpcmV0dXJuIGJhO2lmKGhhK3hhLmxlbmd0aCE9PWJhLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYHJ0IGlucHV0LnNoYXBlIGFuZCBzaGFwZT0ke2FhfSBhcmUgaW5jb21wYXRpYmxlOiBydCBpbnB1dC5yYW5rID0gJHtoYSt4YS5sZW5ndGh9LCBidXQgc2hhcGUucmFuayA9ICR7YmEubGVuZ3RofWApO2ZvcihsZXQgU2E9MTtTYTx4YS5sZW5ndGg7KytTYSl7Y29uc3QgVGE9eGFbU2FdLHdhPWJhW2JhLmxlbmd0aC14YS5sZW5ndGgrU2FdLEVhPWJhW3dhXTtpZihUYT49MClpZihFYT49MCl7aWYoRWEhPT1UYSl0aHJvdyBuZXcgRXJyb3IoYHJ0IGlucHV0LnNoYXBlIGFuZCBzaGFwZT0ke2FhfSBhcmUgaW5jb21wYXRpYmxlOiBydCBpbnB1dC5zaGFwZVske1NhK2hhfV0gPSAke1RhfSBidXQgc2hhcGVbJHtTYStoYX1dID0gJHtFYX1gKX1lbHNlIGJhW3dhXT1UYX1yZXR1cm4gYmF9ZnVuY3Rpb24gZ2V0Um93UGFydGl0aW9uVHlwZXNIZWxwZXIoaGEpe2NvbnN0IGFhPXtGSVJTVF9ESU1fU0laRTpSb3dQYXJ0aXRpb25UeXBlJDEuRklSU1RfRElNX1NJWkUsVkFMVUVfUk9XSURTOlJvd1BhcnRpdGlvblR5cGUkMS5WQUxVRV9ST1dJRFMsUk9XX0xFTkdUSFM6Um93UGFydGl0aW9uVHlwZSQxLlJPV19MRU5HVEhTLFJPV19TUExJVFM6Um93UGFydGl0aW9uVHlwZSQxLlJPV19TUExJVFMsUk9XX0xJTUlUUzpSb3dQYXJ0aXRpb25UeXBlJDEuUk9XX0xJTUlUUyxST1dfU1RBUlRTOlJvd1BhcnRpdGlvblR5cGUkMS5ST1dfU1RBUlRTfSx4YT1bXTtmb3IoY29uc3QgYmEgb2YgaGEpaWYoYmEgaW4gYWEpeGEucHVzaChhYVtiYV0pO2Vsc2UgYnJlYWs7cmV0dXJuIHhhfWZ1bmN0aW9uIGdldFJhZ2dlZFJhbmsoaGEpe3JldHVybiBoYS5sZW5ndGg9PT0wPzA6aGFbMF09PT1Sb3dQYXJ0aXRpb25UeXBlJDEuRklSU1RfRElNX1NJWkU/aGEubGVuZ3RoLTE6aGEubGVuZ3RofWZ1bmN0aW9uIHZhbGlkYXRlRGVmYXVsdFZhbHVlU2hhcGUoaGEsYWEpe2lmKGhhPT1udWxsfHxhYT09bnVsbClyZXR1cm47Y29uc3QgeGE9aGEubGVuZ3RoLGJhPWFhLmxlbmd0aDtpZih4YT49YmEpdGhyb3cgbmV3IEVycm9yKGBkZWZhdWx0VmFsdWUuc2hhcGU9JHtoYX0gYW5kIHJhZ2dlZCB0ZW5zb3IgZmxhdFZhbHVlcy5zaGFwZT0ke2FhfSwgYXJlIGluY29tcGF0aWJsZTogZGVmYXVsdFZhbHVlLnJhbmsgPSAke3hhfSBtdXN0IGJlIGxlc3MgdGhhbiByYWdnZWQgdGVuc29yIGlucHV0IGZsYXRWYWx1ZXMucmFuayA9ICR7YmF9KWApO2ZvcihsZXQgU2E9MDtTYTxNYXRoLm1pbih4YSxiYS0xKTsrK1NhKXtjb25zdCBUYT1oYVtTYV0sd2E9YWFbU2ErMV07aWYoVGE+PTAmJndhPj0wJiZUYSE9PTEmJlRhIT09d2EpdGhyb3cgbmV3IEVycm9yKGBkZWZhdWx0VmFsdWUuc2hhcGU9JHtoYX0sIGFuZCByYWdnZWQgdGVuc29yIGlucHV0IGZsYXRWYWx1ZXMuc2hhcGU9JHthYX0gYXJlIGluY29tcGF0aWJsZTogZGVmYXVsdFZhbHVlLnNoYXBlWyR7U2EtaGEubGVuZ3RofV0gPSAke1RhfSBidXQgcmFnZ2VkIHRlbnNvciBpbnB1dC5mbGF0VmFsdWVzLnNoYXBlWyR7U2EtaGEubGVuZ3RofV0gPSAke3dhfWApfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBQQVJBTExFTElaRV9USFJFU0hPTEQ9MzA7ZnVuY3Rpb24gY29tcHV0ZU9wdGltYWxXaW5kb3dTaXplKGhhKXtyZXR1cm4gaGE8PVBBUkFMTEVMSVpFX1RIUkVTSE9MRD9oYTpuZWFyZXN0RGl2aXNvcihoYSxNYXRoLmZsb29yKE1hdGguc3FydChoYSkpKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRJbWFnZUNlbnRlcihoYSxhYSx4YSl7Y29uc3QgYmE9eGEqKHR5cGVvZiBoYT09Im51bWJlciI/aGE6aGFbMF0pLFNhPWFhKih0eXBlb2YgaGE9PSJudW1iZXIiP2hhOmhhWzFdKTtyZXR1cm5bYmEsU2FdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdldFJlc2hhcGVkKGhhLGFhLHhhLGJhPSEwKXtsZXQgU2E9W107aWYoYmEpU2E9U2EuY29uY2F0KGFhLnNsaWNlKDApKSxTYS5wdXNoKGhhWzBdL3hhKSxTYT1TYS5jb25jYXQoaGEuc2xpY2UoMSkpO2Vsc2V7U2E9U2EuY29uY2F0KGhhWzBdKTtjb25zdCBUYT1hYS5sZW5ndGg7Zm9yKGxldCB3YT0wO3dhPFRhOysrd2EpU2E9U2EuY29uY2F0KFtoYVt3YSsxXS9hYVt3YV0sYWFbd2FdXSk7U2E9U2EuY29uY2F0KGhhLnNsaWNlKFRhKzEpKX1yZXR1cm4gU2F9ZnVuY3Rpb24gZ2V0UGVybXV0ZWQoaGEsYWEseGE9ITApe2NvbnN0IGJhPVtdO2lmKHhhKXtiYS5wdXNoKGFhKTtmb3IobGV0IFNhPWFhKzE7U2E8aGE7KytTYSlTYTw9MiphYT8oYmEucHVzaChTYSksYmEucHVzaChTYS0oYWErMSkpKTpiYS5wdXNoKFNhKX1lbHNle2NvbnN0IFNhPVtdLFRhPVtdO2ZvcihsZXQgd2E9MTt3YTxoYTsrK3dhKXdhPj1hYSoyKzF8fHdhJTI9PT0xP1RhLnB1c2god2EpOlNhLnB1c2god2EpO2JhLnB1c2goLi4uU2EpLGJhLnB1c2goMCksYmEucHVzaCguLi5UYSl9cmV0dXJuIGJhfWZ1bmN0aW9uIGdldFJlc2hhcGVkUGVybXV0ZWQoaGEsYWEseGEsYmE9ITApe2NvbnN0IFNhPVtdO2JhP1NhLnB1c2goaGFbMF0veGEpOlNhLnB1c2goaGFbMF0qeGEpO2ZvcihsZXQgVGE9MTtUYTxoYS5sZW5ndGg7KytUYSlUYTw9YWEubGVuZ3RoP2JhP1NhLnB1c2goYWFbVGEtMV0qaGFbVGFdKTpTYS5wdXNoKGhhW1RhXS9hYVtUYS0xXSk6U2EucHVzaChoYVtUYV0pO3JldHVybiBTYX1mdW5jdGlvbiBnZXRTbGljZUJlZ2luQ29vcmRzKGhhLGFhKXtjb25zdCB4YT1bMF07Zm9yKGxldCBiYT0wO2JhPGFhOysrYmEpeGEucHVzaChoYVtiYV1bMF0pO3JldHVybiB4YX1mdW5jdGlvbiBnZXRTbGljZVNpemUoaGEsYWEseGEpe2NvbnN0IGJhPWhhLnNsaWNlKDAsMSk7Zm9yKGxldCBTYT0wO1NhPHhhOysrU2EpYmEucHVzaChoYVtTYSsxXS1hYVtTYV1bMF0tYWFbU2FdWzFdKTtyZXR1cm4gYmF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgU0VMVV9TQ0FMRUFMUEhBPTEuNzU4MDk5MzQwODQ3Mzc2OCxTRUxVX1NDQUxFPTEuMDUwNzAwOTg3MzU1NDgwNTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBFUkZfUD0uMzI3NTkxMSxFUkZfQTE9LjI1NDgyOTU5MixFUkZfQTI9LS4yODQ0OTY3MzYsRVJGX0EzPTEuNDIxNDEzNzQxLEVSRl9BND0tMS40NTMxNTIwMjcsRVJGX0E1PTEuMDYxNDA1NDI5Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1lcmdlUmVhbEFuZEltYWdBcnJheXMoaGEsYWEpe2lmKGhhLmxlbmd0aCE9PWFhLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBtZXJnZSByZWFsIGFuZCBpbWFnIGFycmF5cyBvZiBkaWZmZXJlbnQgbGVuZ3Rocy4gcmVhbDoke2hhLmxlbmd0aH0sIGltYWc6ICR7YWEubGVuZ3RofS5gKTtjb25zdCB4YT1uZXcgRmxvYXQzMkFycmF5KGhhLmxlbmd0aCoyKTtmb3IobGV0IGJhPTA7YmE8eGEubGVuZ3RoO2JhKz0yKXhhW2JhXT1oYVtiYS8yXSx4YVtiYSsxXT1hYVtiYS8yXTtyZXR1cm4geGF9ZnVuY3Rpb24gc3BsaXRSZWFsQW5kSW1hZ0FycmF5cyhoYSl7Y29uc3QgYWE9bmV3IEZsb2F0MzJBcnJheShoYS5sZW5ndGgvMikseGE9bmV3IEZsb2F0MzJBcnJheShoYS5sZW5ndGgvMik7Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDtiYSs9MilhYVtiYS8yXT1oYVtiYV0seGFbYmEvMl09aGFbYmErMV07cmV0dXJue3JlYWw6YWEsaW1hZzp4YX19ZnVuY3Rpb24gY29tcGxleFdpdGhFdmVuSW5kZXgoaGEpe2NvbnN0IGFhPU1hdGguY2VpbChoYS5sZW5ndGgvNCkseGE9bmV3IEZsb2F0MzJBcnJheShhYSksYmE9bmV3IEZsb2F0MzJBcnJheShhYSk7Zm9yKGxldCBTYT0wO1NhPGhhLmxlbmd0aDtTYSs9NCl4YVtNYXRoLmZsb29yKFNhLzQpXT1oYVtTYV0sYmFbTWF0aC5mbG9vcihTYS80KV09aGFbU2ErMV07cmV0dXJue3JlYWw6eGEsaW1hZzpiYX19ZnVuY3Rpb24gY29tcGxleFdpdGhPZGRJbmRleChoYSl7Y29uc3QgYWE9TWF0aC5mbG9vcihoYS5sZW5ndGgvNCkseGE9bmV3IEZsb2F0MzJBcnJheShhYSksYmE9bmV3IEZsb2F0MzJBcnJheShhYSk7Zm9yKGxldCBTYT0yO1NhPGhhLmxlbmd0aDtTYSs9NCl4YVtNYXRoLmZsb29yKFNhLzQpXT1oYVtTYV0sYmFbTWF0aC5mbG9vcihTYS80KV09aGFbU2ErMV07cmV0dXJue3JlYWw6eGEsaW1hZzpiYX19ZnVuY3Rpb24gZ2V0Q29tcGxleFdpdGhJbmRleChoYSxhYSl7Y29uc3QgeGE9aGFbYWEqMl0sYmE9aGFbYWEqMisxXTtyZXR1cm57cmVhbDp4YSxpbWFnOmJhfX1mdW5jdGlvbiBhc3NpZ25Ub1R5cGVkQXJyYXkoaGEsYWEseGEsYmEpe2hhW2JhKjJdPWFhLGhhW2JhKjIrMV09eGF9ZnVuY3Rpb24gZXhwb25lbnRzKGhhLGFhKXtjb25zdCB4YT1uZXcgRmxvYXQzMkFycmF5KGhhLzIpLGJhPW5ldyBGbG9hdDMyQXJyYXkoaGEvMik7Zm9yKGxldCBTYT0wO1NhPE1hdGguY2VpbChoYS8yKTtTYSsrKXtjb25zdCBUYT0oYWE/MjotMikqTWF0aC5QSSooU2EvaGEpO3hhW1NhXT1NYXRoLmNvcyhUYSksYmFbU2FdPU1hdGguc2luKFRhKX1yZXR1cm57cmVhbDp4YSxpbWFnOmJhfX1mdW5jdGlvbiBleHBvbmVudChoYSxhYSx4YSl7Y29uc3QgYmE9KHhhPzI6LTIpKk1hdGguUEkqKGhhL2FhKSxTYT1NYXRoLmNvcyhiYSksVGE9TWF0aC5zaW4oYmEpO3JldHVybntyZWFsOlNhLGltYWc6VGF9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFSUk9XPSItPiIsQVJST1dfUkVHRVg9Ly0+L2csQ09NTUE9IiwiLEVMTElQU0lTPSIuLi4iO2Z1bmN0aW9uIGRlY29kZUVpbnN1bUVxdWF0aW9uKGhhLGFhKXtoYT1oYS5yZXBsYWNlKC9ccy9nLCIiKTtjb25zdCB4YT0oaGEubGVuZ3RoLWhhLnJlcGxhY2UoQVJST1dfUkVHRVgsIiIpLmxlbmd0aCkvQVJST1cubGVuZ3RoO2lmKHhhPDEpdGhyb3cgbmV3IEVycm9yKCJFcXVhdGlvbnMgd2l0aG91dCBhbiBhcnJvdyBhcmUgbm90IHN1cHBvcnRlZC4iKTtpZih4YT4xKXRocm93IG5ldyBFcnJvcihgRXF1YXRpb24gbXVzdCBjb250YWluIGV4YWN0bHkgb25lIGFycm93ICgiJHtBUlJPV30iKS5gKTtjb25zdFtiYSxTYV09aGEuc3BsaXQoQVJST1cpO2Fzc2VydChiYS5pbmRleE9mKEVMTElQU0lTKT09PS0xLCgpPT5gVGhlIGVsbGlwc2lzIG5vdGF0aW9uICgiJHtFTExJUFNJU30iKSBpcyBub3Qgc3VwcG9ydGVkIHlldC5gKTtjb25zdCBUYT1iYS5zcGxpdChDT01NQSksd2E9VGEubGVuZ3RoO2lmKGFhIT09d2EpdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke3dhfSBpbnB1dCB0ZW5zb3JzLCByZWNlaXZlZCAke2FhfWApO2lmKHdhPjIpdGhyb3cgbmV3IEVycm9yKCJTdXBwb3J0IGZvciBtb3JlIHRoYW4gMiBpbnB1dCB0ZW5zb3JzIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuIik7Y29uc3QgRWE9W107Zm9yKGxldCBlbD0wO2VsPFNhLmxlbmd0aDsrK2VsKXtjb25zdCB0bD1TYVtlbF07aWYoIVRhLnNvbWUobmw9Pm5sLmluZGV4T2YodGwpIT09LTEpKXRocm93IG5ldyBFcnJvcihgT3V0cHV0IHN1YnNjcmlwdHMgY29udGFpbiB0aGUgbGFiZWwgJHt0bH0gbm90IHByZXNlbnQgaW4gdGhlIGlucHV0IHN1YnNjcmlwdHMuYCk7RWEuaW5kZXhPZih0bCk9PT0tMSYmRWEucHVzaCh0bCl9Zm9yKGxldCBlbD0wO2VsPGJhLmxlbmd0aDsrK2VsKXtjb25zdCB0bD1iYVtlbF07RWEuaW5kZXhPZih0bCk9PT0tMSYmdGwhPT1DT01NQSYmRWEucHVzaCh0bCl9Y29uc3Qga2E9bmV3IEFycmF5KFRhLmxlbmd0aCk7Zm9yKGxldCBlbD0wO2VsPHdhOysrZWwpe2lmKG5ldyBTZXQoVGFbZWxdLnNwbGl0KCIiKSkuc2l6ZSE9PVRhW2VsXS5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKGBGb3VuZCBkdXBsaWNhdGUgYXhlcyBpbiBpbnB1dCBjb21wb25lbnQgJHtUYVtlbF19LiBTdXBwb3J0IGZvciBkdXBsaWNhdGUgYXhlcyBpbiBpbnB1dCBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LmApO2thW2VsXT1bXTtmb3IobGV0IHRsPTA7dGw8VGFbZWxdLmxlbmd0aDsrK3RsKWthW2VsXS5wdXNoKEVhLmluZGV4T2YoVGFbZWxdW3RsXSkpfWNvbnN0IEFhPUVhLmxlbmd0aCxGYT1TYS5sZW5ndGgsTGE9W107Zm9yKGxldCBlbD1GYTtlbDxBYTsrK2VsKUxhLnB1c2goZWwpO3JldHVybnthbGxEaW1zOkVhLHN1bW1lZERpbXM6TGEsaWREaW1zOmthfX1mdW5jdGlvbiBnZXRFaW5zdW1QZXJtdXRhdGlvbihoYSxhYSl7bGV0IHhhPW5ldyBBcnJheShoYSk7eGEuZmlsbCgtMSk7Zm9yKGxldCBTYT0wO1NhPGFhLmxlbmd0aDsrK1NhKXhhW2FhW1NhXV09U2E7Y29uc3QgYmE9W107Zm9yKGxldCBTYT0wO1NhPGhhOysrU2EpeGFbU2FdPT09LTEmJmJhLnB1c2goU2EpO3JldHVybiB4YT14YS5maWx0ZXIoU2E9PlNhIT09LTEpLHtwZXJtdXRhdGlvbkluZGljZXM6eGEsZXhwYW5kRGltczpiYX19ZnVuY3Rpb24gY2hlY2tFaW5zdW1EaW1TaXplcyhoYSxhYSx4YSl7Y29uc3QgYmE9bmV3IEFycmF5KGhhKTtmb3IobGV0IFNhPTA7U2E8eGEubGVuZ3RoOysrU2Epe2NvbnN0IFRhPXhhW1NhXS5zaGFwZTtmb3IobGV0IHdhPTA7d2E8YWFbU2FdLmxlbmd0aDsrK3dhKWJhW2FhW1NhXVt3YV1dPT09dm9pZCAwP2JhW2FhW1NhXVt3YV1dPVRhW3dhXTphc3NlcnQoYmFbYWFbU2FdW3dhXV09PT1UYVt3YV0sKCk9PmBFeHBlY3RlZCBkaW1lbnNpb24gJHtiYVthYVtTYV1bd2FdXX0gYXQgYXhpcyAke3dhfSBvZiBpbnB1dCBzaGFwZWQgJHtKU09OLnN0cmluZ2lmeShUYSl9LCBidXQgZ290IGRpbWVuc2lvbiAke1RhW3dhXX1gKX19ZnVuY3Rpb24gZ2V0RWluc3VtQ29tcHV0ZVBhdGgoaGEsYWEpe2NvbnN0IHhhPWhhLGJhPVtdO2xldCBTYT0wO2hhLmxlbmd0aD09PTAmJnhhLnB1c2goLTEpLFNhPWhhLmxlbmd0aCsxO2ZvcihsZXQgd2E9MDt3YTxTYTsrK3dhKWJhLnB1c2goW10pO2NvbnN0IFRhPVtdO2ZvcihsZXQgd2E9MDt3YTx4YS5sZW5ndGg7Kyt3YSl7Y29uc3QgRWE9eGFbd2FdLGthPWZpbmRUZXJtc1dpdGhEaW0oYWEsRWEpO2Zvcihjb25zdCBBYSBvZiBrYSlUYS5pbmRleE9mKEFhKT09PS0xJiYoYmFbd2FdLnB1c2goQWEpLFRhLnB1c2goQWEpKX1yZXR1cm57cGF0aDp4YSxzdGVwczpiYX19ZnVuY3Rpb24gaXNJZGVudGl0eVBlcm11dGF0aW9uKGhhKXtyZXR1cm4gaGEuZXZlcnkoKGFhLHhhKT0+YWE9PT14YSl9ZnVuY3Rpb24gZmluZFRlcm1zV2l0aERpbShoYSxhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDsrK2JhKShoYVtiYV0ubGVuZ3RoPT09MHx8aGFbYmFdLmluZGV4T2YoYWEpIT09LTF8fGFhPT09LTEpJiZ4YS5wdXNoKGJhKTtyZXR1cm4geGF9ZnVuY3Rpb24gcHJlcGFyZVNwbGl0U2l6ZShoYSxhYSx4YT0wKXtsZXQgYmE9W107aWYodHlwZW9mIGFhPT0ibnVtYmVyIilhc3NlcnQoaGEuc2hhcGVbeGFdJWFhPT09MCwoKT0+Ik51bWJlciBvZiBzcGxpdHMgbXVzdCBldmVubHkgZGl2aWRlIHRoZSBheGlzLiIpLGJhPW5ldyBBcnJheShhYSkuZmlsbChoYS5zaGFwZVt4YV0vYWEpO2Vsc2V7Y29uc3QgU2E9YWEucmVkdWNlKCh3YSxFYSk9PihFYT09PS0xJiYod2ErPTEpLHdhKSwwKTthc3NlcnQoU2E8PTEsKCk9PiJUaGVyZSBzaG91bGQgYmUgb25seSBvbmUgbmVnYXRpdmUgdmFsdWUgaW4gc3BsaXQgYXJyYXkuIik7Y29uc3QgVGE9YWEuaW5kZXhPZigtMSk7aWYoVGEhPT0tMSl7Y29uc3Qgd2E9YWEucmVkdWNlKChFYSxrYSk9PmthPjA/RWEra2E6RWEpO2FhW1RhXT1oYS5zaGFwZVt4YV0td2F9YXNzZXJ0KGhhLnNoYXBlW3hhXT09PWFhLnJlZHVjZSgod2EsRWEpPT53YStFYSksKCk9PiJUaGUgc3VtIG9mIHNpemVzIG11c3QgbWF0Y2ggdGhlIHNpemUgb2YgdGhlIGF4aXMgZGltZW5zaW9uLiIpLGJhPWFhfXJldHVybiBiYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRTcGFyc2VGaWxsRW1wdHlSb3dzSW5kaWNlc0RlbnNlU2hhcGVNaXNtYXRjaChoYSl7cmV0dXJuYFJlY2VpdmVkIFNwYXJzZVRlbnNvciB3aXRoIGRlbnNlU2hhcGVbMF0gPSAwIGJ1dAogIGluZGljZXMuc2hhcGVbMF0gPSAke2hhfWB9ZnVuY3Rpb24gZ2V0U3BhcnNlRmlsbEVtcHR5Um93c05lZ2F0aXZlSW5kZXhFcnJvck1lc3NhZ2UoaGEsYWEpe3JldHVybmBpbmRpY2VzKCR7aGF9LCAwKSBpcyBpbnZhbGlkOiAke2FhfSA8IDBgfWZ1bmN0aW9uIGdldFNwYXJzZUZpbGxFbXB0eVJvd3NPdXRPZlJhbmdlSW5kZXhFcnJvck1lc3NhZ2UoaGEsYWEseGEpe3JldHVybmBpbmRpY2VzKCR7aGF9LCAwKSBpcyBpbnZhbGlkOiAke2FhfSA+PSAke3hhfWB9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0U3BhcnNlUmVzaGFwZU11bHRpcGxlTmVnYXRpdmVPbmVPdXRwdXREaW1FcnJvck1lc3NhZ2UoaGEsYWEpe3JldHVybmBvbmx5IG9uZSBvdXRwdXQgZGltZW5zaW9uIG1heSBiZSAtMSwgbm90IGJvdGggJHtoYX0gYW5kICR7YWF9YH1mdW5jdGlvbiBnZXRTcGFyc2VSZXNoYXBlTmVnYXRpdmVPdXRwdXREaW1FcnJvck1lc3NhZ2UoaGEsYWEpe3JldHVybmBzaXplICR7aGF9IG11c3QgYmUgbm9uLW5lZ2F0aXZlLCBub3QgJHthYX1gfWZ1bmN0aW9uIGdldFNwYXJzZVJlc2hhcGVFbXB0eVRlbnNvclplcm9PdXRwdXREaW1FcnJvck1lc3NhZ2UoKXtyZXR1cm4icmVzaGFwZSBjYW5ub3QgaW5mZXIgdGhlIG1pc3NpbmcgaW5wdXQgc2l6ZSBmb3IgYW4gZW1wdHkgdGVuc29yIHVubGVzcyBhbGwgc3BlY2lmaWVkIGlucHV0IHNpemVzIGFyZSBub24temVybyJ9ZnVuY3Rpb24gZ2V0U3BhcnNlUmVzaGFwZUlucHV0T3V0cHV0TXVsdGlwbGVFcnJvck1lc3NhZ2UoaGEsYWEpe2NvbnN0IHhhPXNpemVGcm9tU2hhcGUoaGEpLGJhPXNpemVGcm9tU2hhcGUoYWEpO3JldHVybmBJbnB1dCB0byByZXNoYXBlIGlzIGEgU3BhcnNlVGVuc29yIHdpdGggJHt4YX0KICBkZW5zZSB2YWx1ZXMsIGJ1dCB0aGUgcmVxdWVzdGVkIHNoYXBlIHJlcXVpcmVzIGEgbXVsdGlwbGUgb2YgJHtiYX0uIGlucHV0U2hhcGU9JHtoYX0gb3V0cHV0U2hhcGU9ICR7YWF9YH1mdW5jdGlvbiBnZXRTcGFyc2VSZXNoYXBlSW5wdXRPdXRwdXRNaXNtYXRjaEVycm9yTWVzc2FnZShoYSxhYSl7Y29uc3QgeGE9c2l6ZUZyb21TaGFwZShoYSksYmE9c2l6ZUZyb21TaGFwZShhYSk7cmV0dXJuYElucHV0IHRvIHJlc2hhcGUgaXMgYSB0ZW5zb3Igd2l0aCAke3hhfSBkZW5zZSB2YWx1ZXMsIGJ1dCB0aGUgcmVxdWVzdGVkIHNoYXBlIGhhcyAke2JhfS4gaW5wdXRTaGFwZT0ke2hhfSBvdXRwdXRTaGFwZT0ke2FhfWB9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbk5lZ2F0aXZlU2VnbWVudElkc0Vycm9yTWVzc2FnZSgpe3JldHVybiJzZWdtZW50IGlkcyBtdXN0IGJlID49IDAifWZ1bmN0aW9uIGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25Ob25JbmNyZWFzaW5nU2VnbWVudElkc0Vycm9yTWVzc2FnZSgpe3JldHVybiJzZWdtZW50IGlkcyBhcmUgbm90IGluY3JlYXNpbmcifWZ1bmN0aW9uIGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25TZWdtZW50SWRPdXRPZlJhbmdlRXJyb3JNZXNzYWdlKGhhLGFhKXtyZXR1cm5gU2VnbWVudCBpZCAke2hhfSBvdXQgb2YgcmFuZ2UgWzAsICR7YWF9KSwgcG9zc2libHkgYmVjYXVzZSBzZWdtZW50SWRzIGlucHV0IGlzIG5vdCBzb3J0ZWQuYH1mdW5jdGlvbiBnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uSW5kaWNlc091dE9mUmFuZ2VFcnJvck1lc3NhZ2UoaGEsYWEseGEpe3JldHVybmBCYWQ6IGluZGljZXNbJHtoYX1dID09ICR7YWF9IG91dCBvZiByYW5nZSBbMCwgJHt4YX0pYH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzZWdPcENvbXB1dGVPcHRpbWFsV2luZG93U2l6ZShoYSxhYSl7bGV0IHhhPSExLGJhO2ZvcihoYTw9UEFSQUxMRUxJWkVfVEhSRVNIT0xEPyhiYT1oYSx4YT0hMCk6YmE9bmVhcmVzdERpdmlzb3IoaGEsTWF0aC5mbG9vcihNYXRoLnNxcnQoaGEpKSk7IXhhOyliYT5hYXx8YmE9PT1oYT94YT0hMDpiYT1uZWFyZXN0RGl2aXNvcihoYSxiYSsxKTtyZXR1cm4gYmF9ZnVuY3Rpb24gY29tcHV0ZU91dFNoYXBlKGhhLGFhLHhhKXtjb25zdCBiYT1bXSxTYT1oYS5sZW5ndGg7Zm9yKGxldCBUYT0wO1RhPFNhO1RhKyspVGEhPT1hYT9iYS5wdXNoKGhhW1RhXSk6YmEucHVzaCh4YSk7cmV0dXJuIGJhfWZ1bmN0aW9uIGNvbGxlY3RHYXRoZXJPcFNoYXBlSW5mbyhoYSxhYSx4YSxiYSl7Y29uc3QgU2E9YWEuc2hhcGUubGVuZ3RoLFRhPWhhLnNoYXBlLmxlbmd0aDtpZihiYSE9PTAmJihiYTwtU2F8fGJhPlNhKSl0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdCBiYXRjaERpbXMgaW4gdGhlIHJhbmdlIG9mIFstJHtTYX0sICR7U2F9XSwgYnV0IGdvdCAke2JhfWApO2lmKGJhPDAmJihiYSs9U2EpLGJhPlRhKXRocm93IG5ldyBFcnJvcihgYmF0Y2hEaW1zICgke2JhfSkgbXVzdCBiZSBsZXNzIHRoYW4gcmFuayh4KSAoCiAgICAke1RhfSkuYCk7aWYoeGE8YmEpdGhyb3cgbmV3IEVycm9yKGBiYXRjaERpbXMgKCR7YmF9KSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBheGlzICgke3hhfSkuYCk7Zm9yKGxldCBMYT0wO0xhPGJhOysrTGEpaWYoaGEuc2hhcGVbTGFdIT09YWEuc2hhcGVbTGFdKXRocm93IG5ldyBFcnJvcihgeC5zaGFwZVske0xhfV06ICR7aGEuc2hhcGVbTGFdfSBzaG91bGQgYmUgZXF1YWwgdG8gaW5kaWNlcy5zaGFwZVske0xhfV06ICR7YWEuc2hhcGVbTGFdfS5gKTtjb25zdCB3YT1oYS5zaGFwZVt4YV0sRWE9W107bGV0IGthPTEsQWE9MSxGYT0xO2ZvcihsZXQgTGE9MDtMYTxiYTsrK0xhKUVhLnB1c2goaGEuc2hhcGVbTGFdKSxrYSo9aGEuc2hhcGVbTGFdO2ZvcihsZXQgTGE9YmE7TGE8eGE7TGErKylFYS5wdXNoKGhhLnNoYXBlW0xhXSksQWEqPWhhLnNoYXBlW0xhXTtmb3IobGV0IExhPWJhO0xhPFNhO0xhKyspRWEucHVzaChhYS5zaGFwZVtMYV0pO2ZvcihsZXQgTGE9eGErMTtMYTxUYTtMYSsrKUVhLnB1c2goaGEuc2hhcGVbTGFdKSxGYSo9aGEuc2hhcGVbTGFdO3JldHVybntiYXRjaFNpemU6a2Esc2xpY2VTaXplOkZhLG91dGVyU2l6ZTpBYSxkaW1TaXplOndhLG91dHB1dFNoYXBlOkVhfX12YXIgc2VnbWVudF91dGlsPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGNvbGxlY3RHYXRoZXJPcFNoYXBlSW5mbyxjb21wdXRlT3V0U2hhcGUsc2VnT3BDb21wdXRlT3B0aW1hbFdpbmRvd1NpemV9KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmcm9tVWludDhUb1N0cmluZ0FycmF5KGhhKXt0cnl7cmV0dXJuIGhhLm1hcChhYT0+ZGVjb2RlU3RyaW5nKGFhKSl9Y2F0Y2goYWEpe3Rocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlY29kZSBlbmNvZGVkIHN0cmluZyBieXRlcyBpbnRvIHV0Zi04LCBlcnJvcjogJHthYX1gKX19ZnVuY3Rpb24gZnJvbVN0cmluZ0FycmF5VG9VaW50OChoYSl7cmV0dXJuIGhhLm1hcChhYT0+ZW5jb2RlU3RyaW5nKGFhKSl9dmFyIGJhY2tlbmRfdXRpbD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxFUkZfQTEsRVJGX0EyLEVSRl9BMyxFUkZfQTQsRVJGX0E1LEVSRl9QLFBBUkFMTEVMSVpFX1RIUkVTSE9MRCxnZXQgUm93UGFydGl0aW9uVHlwZSgpe3JldHVybiBSb3dQYXJ0aXRpb25UeXBlJDF9LFNFTFVfU0NBTEUsU0VMVV9TQ0FMRUFMUEhBLGFwcGx5QWN0aXZhdGlvbixhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcyxhc3NlcnRQYXJhbXNDb25zaXN0ZW50LGFzc2lnblRvVHlwZWRBcnJheSxheGVzQXJlSW5uZXJNb3N0RGltcyxjYWxjdWxhdGVTaGFwZXMsY2hlY2tFaW5zdW1EaW1TaXplcyxjaGVja1BhZE9uRGltUm91bmRpbmdNb2RlLGNvbWJpbmVMb2NhdGlvbnMsY29tYmluZVJhZ2dlZFRlbnNvclRvVGVuc29yU2hhcGVzLGNvbXBsZXhXaXRoRXZlbkluZGV4LGNvbXBsZXhXaXRoT2RkSW5kZXgsY29tcHV0ZUNvbnYyREluZm8sY29tcHV0ZUNvbnYzREluZm8sY29tcHV0ZURlZmF1bHRQYWQsY29tcHV0ZURpbGF0aW9uMkRJbmZvLGNvbXB1dGVPcHRpbWFsV2luZG93U2l6ZSxjb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzLGNvbXB1dGVPdXRTaGFwZTpjb21wdXRlT3V0U2hhcGUkMSxjb21wdXRlUG9vbDJESW5mbyxjb21wdXRlUG9vbDNESW5mbyxjb252ZXJ0Q29udjJERGF0YUZvcm1hdCxkZWNvZGVFaW5zdW1FcXVhdGlvbixlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUsZXhwYW5kU2hhcGVUb0tlZXBEaW0sZXhwb25lbnQsZXhwb25lbnRzLGZyb21TdHJpbmdBcnJheVRvVWludDgsZnJvbVVpbnQ4VG9TdHJpbmdBcnJheSxnZXRBeGVzUGVybXV0YXRpb24sZ2V0QnJvYWRjYXN0RGltczpnZXRCcm9hZGNhc3REaW1zJDEsZ2V0Q29tcGxleFdpdGhJbmRleCxnZXRFaW5zdW1Db21wdXRlUGF0aCxnZXRFaW5zdW1QZXJtdXRhdGlvbixnZXRGdXNlZEJpYXNHcmFkaWVudCxnZXRGdXNlZER5QWN0aXZhdGlvbixnZXRJbWFnZUNlbnRlcixnZXRJbm5lck1vc3RBeGVzLGdldFBlcm11dGVkLGdldFJhZ2dlZFJhbmssZ2V0UmVkdWN0aW9uQXhlcyxnZXRSZXNoYXBlZCxnZXRSZXNoYXBlZFBlcm11dGVkLGdldFJvd1BhcnRpdGlvblR5cGVzSGVscGVyLGdldFNsaWNlQmVnaW5Db29yZHMsZ2V0U2xpY2VTaXplLGdldFNwYXJzZUZpbGxFbXB0eVJvd3NJbmRpY2VzRGVuc2VTaGFwZU1pc21hdGNoLGdldFNwYXJzZUZpbGxFbXB0eVJvd3NOZWdhdGl2ZUluZGV4RXJyb3JNZXNzYWdlLGdldFNwYXJzZUZpbGxFbXB0eVJvd3NPdXRPZlJhbmdlSW5kZXhFcnJvck1lc3NhZ2UsZ2V0U3BhcnNlUmVzaGFwZUVtcHR5VGVuc29yWmVyb091dHB1dERpbUVycm9yTWVzc2FnZSxnZXRTcGFyc2VSZXNoYXBlSW5wdXRPdXRwdXRNaXNtYXRjaEVycm9yTWVzc2FnZSxnZXRTcGFyc2VSZXNoYXBlSW5wdXRPdXRwdXRNdWx0aXBsZUVycm9yTWVzc2FnZSxnZXRTcGFyc2VSZXNoYXBlTXVsdGlwbGVOZWdhdGl2ZU9uZU91dHB1dERpbUVycm9yTWVzc2FnZSxnZXRTcGFyc2VSZXNoYXBlTmVnYXRpdmVPdXRwdXREaW1FcnJvck1lc3NhZ2UsZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbkluZGljZXNPdXRPZlJhbmdlRXJyb3JNZXNzYWdlLGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25OZWdhdGl2ZVNlZ21lbnRJZHNFcnJvck1lc3NhZ2UsZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbk5vbkluY3JlYXNpbmdTZWdtZW50SWRzRXJyb3JNZXNzYWdlLGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25TZWdtZW50SWRPdXRPZlJhbmdlRXJyb3JNZXNzYWdlLGdldFVuZG9BeGVzUGVybXV0YXRpb24saXNJZGVudGl0eVBlcm11dGF0aW9uLGxvZzpsb2ckMSxtZXJnZVJlYWxBbmRJbWFnQXJyYXlzLHByZXBhcmVBbmRWYWxpZGF0ZSxwcmVwYXJlU3BsaXRTaXplLHNlZ21lbnRfdXRpbCxzaG91bGRGdXNlLHNsaWNlX3V0aWwsc3BsaXRSZWFsQW5kSW1hZ0FycmF5cyxzdHJpZGVzT3JEaWxhdGlvbnNBcmVQb3NpdGl2ZSx0dXBsZVZhbHVlc0FyZU9uZSx1cGNhc3RUeXBlLHZhbGlkYXRlRGVmYXVsdFZhbHVlU2hhcGUsdmFsaWRhdGVJbnB1dCx2YWxpZGF0ZVVwZGF0ZVNoYXBlLHdhcm59KTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9yZWdpc3Rlck9wdGltaXplcnMoKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjb250ZXh0cz17fSxXRUJHTF9BVFRSSUJVVEVTPXthbHBoYTohMSxhbnRpYWxpYXM6ITEscHJlbXVsdGlwbGllZEFscGhhOiExLHByZXNlcnZlRHJhd2luZ0J1ZmZlcjohMSxkZXB0aDohMSxzdGVuY2lsOiExLGZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXQ6ITB9O2Z1bmN0aW9uIHNldFdlYkdMQ29udGV4dChoYSxhYSl7Y29udGV4dHNbaGFdPWFhfWZ1bmN0aW9uIGdldFdlYkdMQ29udGV4dChoYSxhYSl7aWYoIShoYSBpbiBjb250ZXh0cyl8fGFhIT1udWxsKXtjb25zdCBiYT1nZXRXZWJHTFJlbmRlcmluZ0NvbnRleHQoaGEsYWEpO2lmKGJhIT09bnVsbCljb250ZXh0c1toYV09YmE7ZWxzZSByZXR1cm4gY29uc29sZS5sb2coIkNvdWxkIG5vdCBnZXQgY29udGV4dCBmb3IgV2ViR0wgdmVyc2lvbiIsaGEpLG51bGx9Y29uc3QgeGE9Y29udGV4dHNbaGFdO3JldHVybiB4YT09bnVsbHx8eGEuaXNDb250ZXh0TG9zdCgpPyhkZWxldGUgY29udGV4dHNbaGFdLGdldFdlYkdMQ29udGV4dChoYSkpOih4YS5kaXNhYmxlKHhhLkRFUFRIX1RFU1QpLHhhLmRpc2FibGUoeGEuU1RFTkNJTF9URVNUKSx4YS5kaXNhYmxlKHhhLkJMRU5EKSx4YS5kaXNhYmxlKHhhLkRJVEhFUikseGEuZGlzYWJsZSh4YS5QT0xZR09OX09GRlNFVF9GSUxMKSx4YS5kaXNhYmxlKHhhLlNBTVBMRV9DT1ZFUkFHRSkseGEuZW5hYmxlKHhhLlNDSVNTT1JfVEVTVCkseGEuZW5hYmxlKHhhLkNVTExfRkFDRSkseGEuY3VsbEZhY2UoeGEuQkFDSyksY29udGV4dHNbaGFdKX1mdW5jdGlvbiBjcmVhdGVDYW52YXMoaGEpe2lmKCFlbnYoKS5nZXRCb29sKCJJU19TQUZBUkkiKSYmdHlwZW9mIE9mZnNjcmVlbkNhbnZhczwidSImJmhhPT09MilyZXR1cm4gbmV3IE9mZnNjcmVlbkNhbnZhcygzMDAsMTUwKTtpZih0eXBlb2YgZG9jdW1lbnQ8InUiKXJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKTt0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBjcmVhdGUgYSBjYW52YXMgaW4gdGhpcyBjb250ZXh0Iil9ZnVuY3Rpb24gZ2V0V2ViR0xSZW5kZXJpbmdDb250ZXh0KGhhLGFhKXtpZihoYSE9PTEmJmhhIT09Mil0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBnZXQgV2ViR0wgcmVuZGVyaW5nIGNvbnRleHQsIFdlYkdMIGlzIGRpc2FibGVkLiIpO2NvbnN0IHhhPWFhPz9jcmVhdGVDYW52YXMoaGEpO3JldHVybiB4YS5hZGRFdmVudExpc3RlbmVyKCJ3ZWJnbGNvbnRleHRsb3N0IixiYT0+e2JhLnByZXZlbnREZWZhdWx0KCksZGVsZXRlIGNvbnRleHRzW2hhXX0sITEpLGVudigpLmdldEJvb2woIlNPRlRXQVJFX1dFQkdMX0VOQUJMRUQiKSYmKFdFQkdMX0FUVFJJQlVURVMuZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdD0hMSksaGE9PT0xP3hhLmdldENvbnRleHQoIndlYmdsIixXRUJHTF9BVFRSSUJVVEVTKXx8eGEuZ2V0Q29udGV4dCgiZXhwZXJpbWVudGFsLXdlYmdsIixXRUJHTF9BVFRSSUJVVEVTKTp4YS5nZXRDb250ZXh0KCJ3ZWJnbDIiLFdFQkdMX0FUVFJJQlVURVMpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBQYWNraW5nU2NoZW1lOyhmdW5jdGlvbihoYSl7aGFbaGEuREVOU0U9MF09IkRFTlNFIixoYVtoYS5TSEFSRURfQkFUQ0g9MV09IlNIQVJFRF9CQVRDSCJ9KShQYWNraW5nU2NoZW1lfHwoUGFja2luZ1NjaGVtZT17fSkpO3ZhciBUZXh0dXJlVXNhZ2U7KGZ1bmN0aW9uKGhhKXtoYVtoYS5SRU5ERVI9MF09IlJFTkRFUiIsaGFbaGEuVVBMT0FEPTFdPSJVUExPQUQiLGhhW2hhLlBJWEVMUz0yXT0iUElYRUxTIixoYVtoYS5ET1dOTE9BRD0zXT0iRE9XTkxPQUQifSkoVGV4dHVyZVVzYWdlfHwoVGV4dHVyZVVzYWdlPXt9KSk7dmFyIFBoeXNpY2FsVGV4dHVyZVR5cGU7KGZ1bmN0aW9uKGhhKXtoYVtoYS5VTlBBQ0tFRF9GTE9BVDE2PTBdPSJVTlBBQ0tFRF9GTE9BVDE2IixoYVtoYS5VTlBBQ0tFRF9GTE9BVDMyPTFdPSJVTlBBQ0tFRF9GTE9BVDMyIixoYVtoYS5QQUNLRURfNFgxX1VOU0lHTkVEX0JZVEU9Ml09IlBBQ0tFRF80WDFfVU5TSUdORURfQllURSIsaGFbaGEuUEFDS0VEXzJYMl9GTE9BVDMyPTNdPSJQQUNLRURfMlgyX0ZMT0FUMzIiLGhhW2hhLlBBQ0tFRF8yWDJfRkxPQVQxNj00XT0iUEFDS0VEXzJYMl9GTE9BVDE2In0pKFBoeXNpY2FsVGV4dHVyZVR5cGV8fChQaHlzaWNhbFRleHR1cmVUeXBlPXt9KSk7ZnVuY3Rpb24gZ2V0VW5wYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChoYSxhYSl7cmV0dXJuW2FhLGhhXX1mdW5jdGlvbiBnZXRVbnBhY2tlZEFycmF5U2l6ZUZyb21NYXRyaXhTaXplKGhhLGFhKXtyZXR1cm4gaGEqYWF9ZnVuY3Rpb24gZ2V0RGVuc2VUZXhTaGFwZShoYSl7Y29uc3QgYWE9c2l6ZUZyb21TaGFwZShoYSkseGE9TWF0aC5jZWlsKGFhLzQpO3JldHVybiBzaXplVG9TcXVhcmlzaFNoYXBlKHhhKX1mdW5jdGlvbiBnZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChoYSxhYSl7cmV0dXJuW01hdGgubWF4KDEsTWF0aC5jZWlsKGFhLzIpKSxNYXRoLm1heCgxLE1hdGguY2VpbChoYS8yKSldfWZ1bmN0aW9uIGdldFBhY2tlZFJHQkFBcnJheVNpemVGcm9tTWF0cml4U2hhcGUoaGEsYWEpe2NvbnN0W3hhLGJhXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChoYSxhYSk7cmV0dXJuIHhhKmJhKjR9ZnVuY3Rpb24gZ2V0VGV4dHVyZUNvbmZpZyhoYSxhYSl7Y29uc3QgeGE9aGE7bGV0IGJhLFNhLFRhLHdhLEVhLGthLEFhLEZhLExhLGVsO3JldHVybiBlbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTI/KGJhPXhhLlIzMkYsU2E9eGEuUjE2RixUYT14YS5SR0JBMTZGLHdhPXhhLlJHQkEzMkYsRWE9eGEuUkVELEFhPTQsRmE9MSxMYT14YS5IQUxGX0ZMT0FULGVsPXhhLkZMT0FULGthPXhhLlJHQkE4KTooYmE9aGEuUkdCQSxTYT1oYS5SR0JBLFRhPWhhLlJHQkEsd2E9eGEuUkdCQSxFYT1oYS5SR0JBLEFhPTQsRmE9NCxMYT1hYSE9bnVsbD9hYS5IQUxGX0ZMT0FUX09FUzpudWxsLGVsPWhhLkZMT0FULGthPWhhLlJHQkEpLHtpbnRlcm5hbEZvcm1hdEZsb2F0OmJhLGludGVybmFsRm9ybWF0SGFsZkZsb2F0OlNhLGludGVybmFsRm9ybWF0UGFja2VkSGFsZkZsb2F0OlRhLGludGVybmFsRm9ybWF0UGFja2VkRmxvYXQ6d2EsdGV4dHVyZUZvcm1hdEZsb2F0OkVhLGRvd25sb2FkVGV4dHVyZUZvcm1hdDprYSxkb3dubG9hZFVucGFja051bUNoYW5uZWxzOkFhLGRlZmF1bHROdW1DaGFubmVsczpGYSx0ZXh0dXJlVHlwZUhhbGZGbG9hdDpMYSx0ZXh0dXJlVHlwZUZsb2F0OmVsfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjYWxsQW5kQ2hlY2soaGEsYWEpe2NvbnN0IHhhPWFhKCk7cmV0dXJuIGVudigpLmdldEJvb2woIkRFQlVHIikmJmNoZWNrV2ViR0xFcnJvcihoYSkseGF9ZnVuY3Rpb24gY2hlY2tXZWJHTEVycm9yKGhhKXtjb25zdCBhYT1oYS5nZXRFcnJvcigpO2lmKGFhIT09aGEuTk9fRVJST1IpdGhyb3cgbmV3IEVycm9yKCJXZWJHTCBFcnJvcjogIitnZXRXZWJHTEVycm9yTWVzc2FnZShoYSxhYSkpfWNvbnN0IE1JTl9GTE9BVDE2PTU5NmUtMTAsTUFYX0ZMT0FUMTY9NjU1MDQ7ZnVuY3Rpb24gY2FuQmVSZXByZXNlbnRlZChoYSl7cmV0dXJuISEoZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUkVOREVSX0ZMT0FUMzJfRU5BQkxFRCIpfHxoYT09PTB8fE1JTl9GTE9BVDE2PE1hdGguYWJzKGhhKSYmTWF0aC5hYnMoaGEpPE1BWF9GTE9BVDE2KX1mdW5jdGlvbiBnZXRXZWJHTEVycm9yTWVzc2FnZShoYSxhYSl7c3dpdGNoKGFhKXtjYXNlIGhhLk5PX0VSUk9SOnJldHVybiJOT19FUlJPUiI7Y2FzZSBoYS5JTlZBTElEX0VOVU06cmV0dXJuIklOVkFMSURfRU5VTSI7Y2FzZSBoYS5JTlZBTElEX1ZBTFVFOnJldHVybiJJTlZBTElEX1ZBTFVFIjtjYXNlIGhhLklOVkFMSURfT1BFUkFUSU9OOnJldHVybiJJTlZBTElEX09QRVJBVElPTiI7Y2FzZSBoYS5JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTjpyZXR1cm4iSU5WQUxJRF9GUkFNRUJVRkZFUl9PUEVSQVRJT04iO2Nhc2UgaGEuT1VUX09GX01FTU9SWTpyZXR1cm4iT1VUX09GX01FTU9SWSI7Y2FzZSBoYS5DT05URVhUX0xPU1RfV0VCR0w6cmV0dXJuIkNPTlRFWFRfTE9TVF9XRUJHTCI7ZGVmYXVsdDpyZXR1cm5gVW5rbm93biBlcnJvciBjb2RlICR7YWF9YH19ZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uT3JUaHJvdyhoYSxhYSl7cmV0dXJuIHRocm93SWZOdWxsKGhhLCgpPT5oYS5nZXRFeHRlbnNpb24oYWEpLCdFeHRlbnNpb24gIicrYWErJyIgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGJyb3dzZXIuJyl9ZnVuY3Rpb24gY3JlYXRlVmVydGV4U2hhZGVyJDEoaGEsYWEpe2NvbnN0IHhhPXRocm93SWZOdWxsKGhhLCgpPT5oYS5jcmVhdGVTaGFkZXIoaGEuVkVSVEVYX1NIQURFUiksIlVuYWJsZSB0byBjcmVhdGUgdmVydGV4IFdlYkdMU2hhZGVyLiIpO2lmKGNhbGxBbmRDaGVjayhoYSwoKT0+aGEuc2hhZGVyU291cmNlKHhhLGFhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5jb21waWxlU2hhZGVyKHhhKSksaGEuZ2V0U2hhZGVyUGFyYW1ldGVyKHhhLGhhLkNPTVBJTEVfU1RBVFVTKT09PSExKXRocm93IGNvbnNvbGUubG9nKGhhLmdldFNoYWRlckluZm9Mb2coeGEpKSxuZXcgRXJyb3IoIkZhaWxlZCB0byBjb21waWxlIHZlcnRleCBzaGFkZXIuIik7cmV0dXJuIHhhfWZ1bmN0aW9uIGNyZWF0ZUZyYWdtZW50U2hhZGVyKGhhLGFhKXtjb25zdCB4YT10aHJvd0lmTnVsbChoYSwoKT0+aGEuY3JlYXRlU2hhZGVyKGhhLkZSQUdNRU5UX1NIQURFUiksIlVuYWJsZSB0byBjcmVhdGUgZnJhZ21lbnQgV2ViR0xTaGFkZXIuIik7aWYoY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5zaGFkZXJTb3VyY2UoeGEsYWEpKSxjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmNvbXBpbGVTaGFkZXIoeGEpKSxlbnYoKS5nZXQoIkVOR0lORV9DT01QSUxFX09OTFkiKSlyZXR1cm4geGE7aWYoaGEuZ2V0U2hhZGVyUGFyYW1ldGVyKHhhLGhhLkNPTVBJTEVfU1RBVFVTKT09PSExKXRocm93IGxvZ1NoYWRlclNvdXJjZUFuZEluZm9Mb2coYWEsaGEuZ2V0U2hhZGVySW5mb0xvZyh4YSkpLG5ldyBFcnJvcigiRmFpbGVkIHRvIGNvbXBpbGUgZnJhZ21lbnQgc2hhZGVyLiIpO3JldHVybiB4YX1jb25zdCBsaW5lTnVtYmVyUmVnZXg9L0VSUk9SOiBbMC05XSs6KFswLTldKyk6L2c7ZnVuY3Rpb24gbG9nU2hhZGVyU291cmNlQW5kSW5mb0xvZyhoYSxhYSl7Y29uc3QgeGE9bGluZU51bWJlclJlZ2V4LmV4ZWMoYWEpO2lmKHhhPT1udWxsKXtjb25zb2xlLmxvZyhgQ291bGRuJ3QgcGFyc2UgbGluZSBudW1iZXIgaW4gZXJyb3I6ICR7YWF9YCksY29uc29sZS5sb2coaGEpO3JldHVybn1jb25zdCBiYT0reGFbMV0sU2E9aGEuc3BsaXQoYApgKSxUYT1TYS5sZW5ndGgudG9TdHJpbmcoKS5sZW5ndGgrMix3YT1TYS5tYXAoKExhLGVsKT0+cmlnaHRQYWQoKGVsKzEpLnRvU3RyaW5nKCksVGEpK0xhKTtsZXQgRWE9MDtmb3IobGV0IExhPTA7TGE8d2EubGVuZ3RoO0xhKyspRWE9TWF0aC5tYXgod2FbTGFdLmxlbmd0aCxFYSk7Y29uc3Qga2E9d2Euc2xpY2UoMCxiYS0xKSxBYT13YS5zbGljZShiYS0xLGJhKSxGYT13YS5zbGljZShiYSk7Y29uc29sZS5sb2coa2Euam9pbihgCmApKSxjb25zb2xlLmxvZyhhYS5zcGxpdChgCmApWzBdKSxjb25zb2xlLmxvZyhgJWMgJHtyaWdodFBhZChBYVswXSxFYSl9YCwiYm9yZGVyOjFweCBzb2xpZCByZWQ7IGJhY2tncm91bmQtY29sb3I6I2UzZDJkMjsgY29sb3I6I2E2MTcxNyIpLGNvbnNvbGUubG9nKEZhLmpvaW4oYApgKSl9ZnVuY3Rpb24gY3JlYXRlUHJvZ3JhbShoYSl7cmV0dXJuIHRocm93SWZOdWxsKGhhLCgpPT5oYS5jcmVhdGVQcm9ncmFtKCksIlVuYWJsZSB0byBjcmVhdGUgV2ViR0xQcm9ncmFtLiIpfWZ1bmN0aW9uIGxpbmtQcm9ncmFtKGhhLGFhKXtpZihjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmxpbmtQcm9ncmFtKGFhKSksIWVudigpLmdldCgiRU5HSU5FX0NPTVBJTEVfT05MWSIpJiZoYS5nZXRQcm9ncmFtUGFyYW1ldGVyKGFhLGhhLkxJTktfU1RBVFVTKT09PSExKXRocm93IGNvbnNvbGUubG9nKGhhLmdldFByb2dyYW1JbmZvTG9nKGFhKSksbmV3IEVycm9yKCJGYWlsZWQgdG8gbGluayB2ZXJ0ZXggYW5kIGZyYWdtZW50IHNoYWRlcnMuIil9ZnVuY3Rpb24gdmFsaWRhdGVQcm9ncmFtKGhhLGFhKXtpZihjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLnZhbGlkYXRlUHJvZ3JhbShhYSkpLGhhLmdldFByb2dyYW1QYXJhbWV0ZXIoYWEsaGEuVkFMSURBVEVfU1RBVFVTKT09PSExKXRocm93IGNvbnNvbGUubG9nKGhhLmdldFByb2dyYW1JbmZvTG9nKGFhKSksbmV3IEVycm9yKCJTaGFkZXIgcHJvZ3JhbSB2YWxpZGF0aW9uIGZhaWxlZC4iKX1mdW5jdGlvbiBjcmVhdGVTdGF0aWNWZXJ0ZXhCdWZmZXIoaGEsYWEpe2NvbnN0IHhhPXRocm93SWZOdWxsKGhhLCgpPT5oYS5jcmVhdGVCdWZmZXIoKSwiVW5hYmxlIHRvIGNyZWF0ZSBXZWJHTEJ1ZmZlciIpO3JldHVybiBjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRCdWZmZXIoaGEuQVJSQVlfQlVGRkVSLHhhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5idWZmZXJEYXRhKGhhLkFSUkFZX0JVRkZFUixhYSxoYS5TVEFUSUNfRFJBVykpLHhhfWZ1bmN0aW9uIGNyZWF0ZVN0YXRpY0luZGV4QnVmZmVyKGhhLGFhKXtjb25zdCB4YT10aHJvd0lmTnVsbChoYSwoKT0+aGEuY3JlYXRlQnVmZmVyKCksIlVuYWJsZSB0byBjcmVhdGUgV2ViR0xCdWZmZXIiKTtyZXR1cm4gY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5iaW5kQnVmZmVyKGhhLkVMRU1FTlRfQVJSQVlfQlVGRkVSLHhhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5idWZmZXJEYXRhKGhhLkVMRU1FTlRfQVJSQVlfQlVGRkVSLGFhLGhhLlNUQVRJQ19EUkFXKSkseGF9ZnVuY3Rpb24gY3JlYXRlVGV4dHVyZShoYSl7cmV0dXJuIHRocm93SWZOdWxsKGhhLCgpPT5oYS5jcmVhdGVUZXh0dXJlKCksIlVuYWJsZSB0byBjcmVhdGUgV2ViR0xUZXh0dXJlLiIpfWZ1bmN0aW9uIHZhbGlkYXRlVGV4dHVyZVNpemUoaGEsYWEpe2NvbnN0IHhhPWVudigpLmdldE51bWJlcigiV0VCR0xfTUFYX1RFWFRVUkVfU0laRSIpO2lmKGhhPD0wfHxhYTw9MCl7Y29uc3QgYmE9YFske2hhfXgke2FhfV1gO3Rocm93IG5ldyBFcnJvcigiUmVxdWVzdGVkIHRleHR1cmUgc2l6ZSAiK2JhKyIgaXMgaW52YWxpZC4iKX1pZihoYT54YXx8YWE+eGEpe2NvbnN0IGJhPWBbJHtoYX14JHthYX1dYCxTYT1gWyR7eGF9eCR7eGF9XWA7dGhyb3cgbmV3IEVycm9yKCJSZXF1ZXN0ZWQgdGV4dHVyZSBzaXplICIrYmErIiBncmVhdGVyIHRoYW4gV2ViR0wgbWF4aW11bSBvbiB0aGlzIGJyb3dzZXIgLyBHUFUgIitTYSsiLiIpfX1mdW5jdGlvbiBjcmVhdGVGcmFtZWJ1ZmZlcihoYSl7cmV0dXJuIHRocm93SWZOdWxsKGhhLCgpPT5oYS5jcmVhdGVGcmFtZWJ1ZmZlcigpLCJVbmFibGUgdG8gY3JlYXRlIFdlYkdMRnJhbWVidWZmZXIuIil9ZnVuY3Rpb24gYmluZFZlcnRleEJ1ZmZlclRvUHJvZ3JhbUF0dHJpYnV0ZShoYSxhYSx4YSxiYSxTYSxUYSx3YSl7Y29uc3QgRWE9aGEuZ2V0QXR0cmliTG9jYXRpb24oYWEseGEpO3JldHVybiBFYT09PS0xPyExOihjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRCdWZmZXIoaGEuQVJSQVlfQlVGRkVSLGJhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS52ZXJ0ZXhBdHRyaWJQb2ludGVyKEVhLFNhLGhhLkZMT0FULCExLFRhLHdhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShFYSkpLCEwKX1mdW5jdGlvbiBiaW5kVGV4dHVyZVVuaXQoaGEsYWEseGEpe3ZhbGlkYXRlVGV4dHVyZVVuaXQoaGEseGEpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEuYWN0aXZlVGV4dHVyZShoYS5URVhUVVJFMCt4YSkpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEuYmluZFRleHR1cmUoaGEuVEVYVFVSRV8yRCxhYSkpfWZ1bmN0aW9uIGdldFByb2dyYW1Vbmlmb3JtTG9jYXRpb25PclRocm93KGhhLGFhLHhhKXtyZXR1cm4gdGhyb3dJZk51bGwoaGEsKCk9PmhhLmdldFVuaWZvcm1Mb2NhdGlvbihhYSx4YSksJ3VuaWZvcm0gIicreGErJyIgbm90IHByZXNlbnQgaW4gcHJvZ3JhbS4nKX1mdW5jdGlvbiBnZXRQcm9ncmFtVW5pZm9ybUxvY2F0aW9uKGhhLGFhLHhhKXtyZXR1cm4gaGEuZ2V0VW5pZm9ybUxvY2F0aW9uKGFhLHhhKX1mdW5jdGlvbiBiaW5kVGV4dHVyZVRvUHJvZ3JhbVVuaWZvcm1TYW1wbGVyKGhhLGFhLHhhLGJhKXtjYWxsQW5kQ2hlY2soaGEsKCk9PmJpbmRUZXh0dXJlVW5pdChoYSxhYSxiYSkpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEudW5pZm9ybTFpKHhhLGJhKSl9ZnVuY3Rpb24gYmluZENvbG9yVGV4dHVyZVRvRnJhbWVidWZmZXIoaGEsYWEseGEpe2NhbGxBbmRDaGVjayhoYSwoKT0+aGEuYmluZEZyYW1lYnVmZmVyKGhhLkZSQU1FQlVGRkVSLHhhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5mcmFtZWJ1ZmZlclRleHR1cmUyRChoYS5GUkFNRUJVRkZFUixoYS5DT0xPUl9BVFRBQ0hNRU5UMCxoYS5URVhUVVJFXzJELGFhLDApKX1mdW5jdGlvbiB1bmJpbmRDb2xvclRleHR1cmVGcm9tRnJhbWVidWZmZXIoaGEsYWEpe2NhbGxBbmRDaGVjayhoYSwoKT0+aGEuYmluZEZyYW1lYnVmZmVyKGhhLkZSQU1FQlVGRkVSLGFhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5mcmFtZWJ1ZmZlclRleHR1cmUyRChoYS5GUkFNRUJVRkZFUixoYS5DT0xPUl9BVFRBQ0hNRU5UMCxoYS5URVhUVVJFXzJELG51bGwsMCkpfWZ1bmN0aW9uIHZhbGlkYXRlRnJhbWVidWZmZXIoaGEpe2NvbnN0IGFhPWhhLmNoZWNrRnJhbWVidWZmZXJTdGF0dXMoaGEuRlJBTUVCVUZGRVIpO2lmKGFhIT09aGEuRlJBTUVCVUZGRVJfQ09NUExFVEUpdGhyb3cgbmV3IEVycm9yKCJFcnJvciBiaW5kaW5nIGZyYW1lYnVmZmVyOiAiK2dldEZyYW1lYnVmZmVyRXJyb3JNZXNzYWdlKGhhLGFhKSl9ZnVuY3Rpb24gZ2V0RnJhbWVidWZmZXJFcnJvck1lc3NhZ2UoaGEsYWEpe3N3aXRjaChhYSl7Y2FzZSBoYS5GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0FUVEFDSE1FTlQ6cmV0dXJuIkZSQU1FQlVGRkVSX0lOQ09NUExFVEVfQVRUQUNITUVOVCI7Y2FzZSBoYS5GUkFNRUJVRkZFUl9JTkNPTVBMRVRFX01JU1NJTkdfQVRUQUNITUVOVDpyZXR1cm4iRlJBTUVCVUZGRVJfSU5DT01QTEVURV9NSVNTSU5HX0FUVEFDSE1FTlQiO2Nhc2UgaGEuRlJBTUVCVUZGRVJfSU5DT01QTEVURV9ESU1FTlNJT05TOnJldHVybiJGUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0RJTUVOU0lPTlMiO2Nhc2UgaGEuRlJBTUVCVUZGRVJfVU5TVVBQT1JURUQ6cmV0dXJuIkZSQU1FQlVGRkVSX1VOU1VQUE9SVEVEIjtkZWZhdWx0OnJldHVybmB1bmtub3duIGVycm9yICR7YWF9YH19ZnVuY3Rpb24gdGhyb3dJZk51bGwoaGEsYWEseGEpe2NvbnN0IGJhPWNhbGxBbmRDaGVjayhoYSwoKT0+YWEoKSk7aWYoYmE9PW51bGwpdGhyb3cgbmV3IEVycm9yKHhhKTtyZXR1cm4gYmF9ZnVuY3Rpb24gdmFsaWRhdGVUZXh0dXJlVW5pdChoYSxhYSl7Y29uc3QgeGE9aGEuTUFYX0NPTUJJTkVEX1RFWFRVUkVfSU1BR0VfVU5JVFMtMSxiYT1hYStoYS5URVhUVVJFMDtpZihiYTxoYS5URVhUVVJFMHx8YmE+eGEpe2NvbnN0IFNhPWBbZ2wuVEVYVFVSRTAsIGdsLlRFWFRVUkUke3hhfV1gO3Rocm93IG5ldyBFcnJvcihgdGV4dHVyZVVuaXQgbXVzdCBiZSBpbiAke1NhfS5gKX19ZnVuY3Rpb24gZ2V0QmF0Y2hEaW0oaGEsYWE9Mil7cmV0dXJuIHNpemVGcm9tU2hhcGUoaGEuc2xpY2UoMCxoYS5sZW5ndGgtYWEpKX1mdW5jdGlvbiBnZXRSb3dzQ29scyhoYSl7aWYoaGEubGVuZ3RoPT09MCl0aHJvdyBFcnJvcigiQ2Fubm90IGdldCByb3dzIGFuZCBjb2x1bW5zIG9mIGFuIGVtcHR5IHNoYXBlIGFycmF5LiIpO3JldHVybltoYS5sZW5ndGg+MT9oYVtoYS5sZW5ndGgtMl06MSxoYVtoYS5sZW5ndGgtMV1dfWZ1bmN0aW9uIGdldFNoYXBlQXMzRChoYSl7bGV0IGFhPVsxLDEsMV07cmV0dXJuIGhhLmxlbmd0aD09PTB8fGhhLmxlbmd0aD09PTEmJmhhWzBdPT09MXx8KGFhPVtnZXRCYXRjaERpbShoYSksLi4uZ2V0Um93c0NvbHMoaGEpXSksYWF9ZnVuY3Rpb24gZ2V0VGV4dHVyZVNoYXBlRnJvbUxvZ2ljYWxTaGFwZShoYSxhYT0hMSl7bGV0IHhhPWVudigpLmdldE51bWJlcigiV0VCR0xfTUFYX1RFWFRVUkVfU0laRSIpLGJhPWVudigpLmdldE51bWJlcigiV0VCR0xfTUFYX1NJWkVfRk9SX05BUlJPV19URVhUVVJFIik7YmE9PT0xLzAmJmVudigpLmdldEJvb2woIldFQkdMX0FVVE9fU1FVQVJJRllfTkFSUk9XX1RFWFRVUkVfU0hBUEUiKSYmKGJhPXhhLzIpLGFhJiYoeGE9eGEqMixiYT1iYSoyLGhhPWhhLm1hcCgoRWEsa2EpPT5rYT49aGEubGVuZ3RoLTI/bmVhcmVzdExhcmdlckV2ZW4oaGFba2FdKTpoYVtrYV0pLGhhLmxlbmd0aD09PTEmJihoYT1bMixoYVswXV0pKSxoYS5sZW5ndGghPT0yJiYoaGE9c3F1ZWV6ZVNoYXBlKGhhKS5uZXdTaGFwZSk7bGV0IFNhPXNpemVGcm9tU2hhcGUoaGEpLFRhPW51bGw7aGEubGVuZ3RoPD0xJiZTYTw9eGE/VGE9WzEsU2FdOmhhLmxlbmd0aD09PTImJmhhWzBdPD14YSYmaGFbMV08PXhhP1RhPWhhOmhhLmxlbmd0aD09PTMmJmhhWzBdKmhhWzFdPD14YSYmaGFbMl08PXhhP1RhPVtoYVswXSpoYVsxXSxoYVsyXV06aGEubGVuZ3RoPT09MyYmaGFbMF08PXhhJiZoYVsxXSpoYVsyXTw9eGE/VGE9W2hhWzBdLGhhWzFdKmhhWzJdXTpoYS5sZW5ndGg9PT00JiZoYVswXSpoYVsxXSpoYVsyXTw9eGEmJmhhWzNdPD14YT9UYT1baGFbMF0qaGFbMV0qaGFbMl0saGFbM11dOmhhLmxlbmd0aD09PTQmJmhhWzBdPD14YSYmaGFbMV0qaGFbMl0qaGFbM108PXhhJiYoVGE9W2hhWzBdLGhhWzFdKmhhWzJdKmhhWzNdXSk7Y29uc3Qgd2E9VGEhPW51bGwmJk1hdGgubWF4KC4uLlRhKT5iYSYmTWF0aC5taW4oLi4uVGEpPD0oYWE/MjoxKSYmTWF0aC5taW4oLi4uVGEpPjA7aWYoVGE9PW51bGx8fHdhKWlmKGFhKXtjb25zdCBFYT1nZXRCYXRjaERpbShoYSk7bGV0IGthPTIsQWE9MjtoYS5sZW5ndGgmJihba2EsQWFdPWdldFJvd3NDb2xzKGhhKSksU2E9RWEqKGthLzIpKihBYS8yKSxUYT1zaXplVG9TcXVhcmlzaFNoYXBlKFNhKS5tYXAoRmE9PkZhKjIpfWVsc2UgVGE9c2l6ZVRvU3F1YXJpc2hTaGFwZShTYSk7cmV0dXJuIFRhfWZ1bmN0aW9uIGlzRXZlbihoYSl7cmV0dXJuIGhhJTI9PT0wfWZ1bmN0aW9uIGlzUmVzaGFwZUZyZWUoaGEsYWEpe2lmKGhhPWhhLnNsaWNlKC0yKSxhYT1hYS5zbGljZSgtMiksYXJyYXlzRXF1YWwoaGEsYWEpfHwhaGEubGVuZ3RofHwhYWEubGVuZ3RofHxoYVswXT09PTB8fGhhWzFdPT09MHx8YWFbMF09PT0wfHxhYVsxXT09PTApcmV0dXJuITA7aWYoaGEubGVuZ3RoIT09YWEubGVuZ3RoKXtjb25zdCB4YT1oYVtoYS5sZW5ndGgtMV0sYmE9YWFbYWEubGVuZ3RoLTFdO2lmKHhhPT09YmF8fGlzRXZlbih4YSkmJmlzRXZlbihiYSkmJihoYVswXT09PTF8fGFhWzBdPT09MSkpcmV0dXJuITB9cmV0dXJuIGhhWzFdPT09YWFbMV0mJmlzRXZlbihoYVswXSkmJmlzRXZlbihhYVswXSl9bGV0IE1BWF9URVhUVVJFX1NJWkUsTUFYX1RFWFRVUkVTX0lOX1NIQURFUjtmdW5jdGlvbiBnZXRXZWJHTE1heFRleHR1cmVTaXplKGhhKXtpZihNQVhfVEVYVFVSRV9TSVpFPT1udWxsKXtjb25zdCBhYT1nZXRXZWJHTENvbnRleHQoaGEpO01BWF9URVhUVVJFX1NJWkU9YWEuZ2V0UGFyYW1ldGVyKGFhLk1BWF9URVhUVVJFX1NJWkUpfXJldHVybiBNQVhfVEVYVFVSRV9TSVpFfWZ1bmN0aW9uIGdldE1heFRleHR1cmVzSW5TaGFkZXIoaGEpe2lmKE1BWF9URVhUVVJFU19JTl9TSEFERVI9PW51bGwpe2NvbnN0IGFhPWdldFdlYkdMQ29udGV4dChoYSk7TUFYX1RFWFRVUkVTX0lOX1NIQURFUj1hYS5nZXRQYXJhbWV0ZXIoYWEuTUFYX1RFWFRVUkVfSU1BR0VfVU5JVFMpfXJldHVybiBNYXRoLm1pbigxNixNQVhfVEVYVFVSRVNfSU5fU0hBREVSKX1mdW5jdGlvbiBnZXRXZWJHTERpc2pvaW50UXVlcnlUaW1lclZlcnNpb24oaGEpe2lmKGhhPT09MClyZXR1cm4gMDtsZXQgYWE7Y29uc3QgeGE9Z2V0V2ViR0xDb250ZXh0KGhhKTtyZXR1cm4gaGFzRXh0ZW5zaW9uKHhhLCJFWFRfZGlzam9pbnRfdGltZXJfcXVlcnlfd2ViZ2wyIikmJmhhPT09Mj9hYT0yOmhhc0V4dGVuc2lvbih4YSwiRVhUX2Rpc2pvaW50X3RpbWVyX3F1ZXJ5Iik/YWE9MTphYT0wLGFhfWZ1bmN0aW9uIGhhc0V4dGVuc2lvbihoYSxhYSl7cmV0dXJuIGhhLmdldEV4dGVuc2lvbihhYSkhPW51bGx9ZnVuY3Rpb24gaXNXZWJHTFZlcnNpb25FbmFibGVkKGhhKXt0cnl7aWYoZ2V0V2ViR0xDb250ZXh0KGhhKSE9bnVsbClyZXR1cm4hMH1jYXRjaChhYSl7cmV0dXJuIGNvbnNvbGUubG9nKCJFcnJvciB3aGVuIGdldHRpbmcgV2ViR0wgY29udGV4dDogIixhYSksITF9cmV0dXJuITF9ZnVuY3Rpb24gaXNDYXBhYmxlT2ZSZW5kZXJpbmdUb0Zsb2F0VGV4dHVyZShoYSl7aWYoaGE9PT0wKXJldHVybiExO2NvbnN0IGFhPWdldFdlYkdMQ29udGV4dChoYSk7aWYoaGE9PT0xKXtpZighaGFzRXh0ZW5zaW9uKGFhLCJPRVNfdGV4dHVyZV9mbG9hdCIpKXJldHVybiExfWVsc2UgaWYoIWhhc0V4dGVuc2lvbihhYSwiRVhUX2NvbG9yX2J1ZmZlcl9mbG9hdCIpKXJldHVybiExO3JldHVybiBjcmVhdGVGbG9hdFRleHR1cmVBbmRCaW5kVG9GcmFtZWJ1ZmZlcihhYSl9ZnVuY3Rpb24gaXNEb3dubG9hZEZsb2F0VGV4dHVyZUVuYWJsZWQoaGEpe2lmKGhhPT09MClyZXR1cm4hMTtjb25zdCBhYT1nZXRXZWJHTENvbnRleHQoaGEpO2lmKGhhPT09MSl7aWYoIWhhc0V4dGVuc2lvbihhYSwiT0VTX3RleHR1cmVfZmxvYXQiKXx8IWhhc0V4dGVuc2lvbihhYSwiV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0IikpcmV0dXJuITF9ZWxzZXtpZihoYXNFeHRlbnNpb24oYWEsIkVYVF9jb2xvcl9idWZmZXJfZmxvYXQiKSlyZXR1cm4gY3JlYXRlRmxvYXRUZXh0dXJlQW5kQmluZFRvRnJhbWVidWZmZXIoYWEpO2NvbnN0IGJhPSJFWFRfY29sb3JfYnVmZmVyX2hhbGZfZmxvYXQiO2lmKGhhc0V4dGVuc2lvbihhYSxiYSkpe2NvbnN0IFNhPWFhLmdldEV4dGVuc2lvbihiYSk7cmV0dXJuIGNyZWF0ZUhhbGZGbG9hdFRleHR1cmVBbmRCaW5kVG9GcmFtZWJ1ZmZlcihhYSxTYSl9cmV0dXJuITF9cmV0dXJuIGNyZWF0ZUZsb2F0VGV4dHVyZUFuZEJpbmRUb0ZyYW1lYnVmZmVyKGFhKX1mdW5jdGlvbiBjcmVhdGVGbG9hdFRleHR1cmVBbmRCaW5kVG9GcmFtZWJ1ZmZlcihoYSl7Y29uc3QgYWE9Z2V0VGV4dHVyZUNvbmZpZyhoYSkseGE9aGEuY3JlYXRlVGV4dHVyZSgpO2hhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQseGEpLGhhLnRleEltYWdlMkQoaGEuVEVYVFVSRV8yRCwwLGFhLmludGVybmFsRm9ybWF0RmxvYXQsMSwxLDAsYWEudGV4dHVyZUZvcm1hdEZsb2F0LGFhLnRleHR1cmVUeXBlRmxvYXQsbnVsbCk7Y29uc3QgVGE9aGEuY3JlYXRlRnJhbWVidWZmZXIoKTtoYS5iaW5kRnJhbWVidWZmZXIoaGEuRlJBTUVCVUZGRVIsVGEpLGhhLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGhhLkZSQU1FQlVGRkVSLGhhLkNPTE9SX0FUVEFDSE1FTlQwLGhhLlRFWFRVUkVfMkQseGEsMCk7Y29uc3Qgd2E9aGEuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhoYS5GUkFNRUJVRkZFUik9PT1oYS5GUkFNRUJVRkZFUl9DT01QTEVURTtyZXR1cm4gaGEuYmluZFRleHR1cmUoaGEuVEVYVFVSRV8yRCxudWxsKSxoYS5iaW5kRnJhbWVidWZmZXIoaGEuRlJBTUVCVUZGRVIsbnVsbCksaGEuZGVsZXRlVGV4dHVyZSh4YSksaGEuZGVsZXRlRnJhbWVidWZmZXIoVGEpLHdhfWZ1bmN0aW9uIGNyZWF0ZUhhbGZGbG9hdFRleHR1cmVBbmRCaW5kVG9GcmFtZWJ1ZmZlcihoYSxhYSl7Y29uc3QgeGE9Z2V0VGV4dHVyZUNvbmZpZyhoYSxhYSksYmE9aGEuY3JlYXRlVGV4dHVyZSgpO2hhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsYmEpLGhhLnRleEltYWdlMkQoaGEuVEVYVFVSRV8yRCwwLHhhLmludGVybmFsRm9ybWF0SGFsZkZsb2F0LDEsMSwwLHhhLnRleHR1cmVGb3JtYXRGbG9hdCx4YS50ZXh0dXJlVHlwZUhhbGZGbG9hdCxudWxsKTtjb25zdCB3YT1oYS5jcmVhdGVGcmFtZWJ1ZmZlcigpO2hhLmJpbmRGcmFtZWJ1ZmZlcihoYS5GUkFNRUJVRkZFUix3YSksaGEuZnJhbWVidWZmZXJUZXh0dXJlMkQoaGEuRlJBTUVCVUZGRVIsaGEuQ09MT1JfQVRUQUNITUVOVDAsaGEuVEVYVFVSRV8yRCxiYSwwKTtjb25zdCBFYT1oYS5jaGVja0ZyYW1lYnVmZmVyU3RhdHVzKGhhLkZSQU1FQlVGRkVSKT09PWhhLkZSQU1FQlVGRkVSX0NPTVBMRVRFO3JldHVybiBoYS5iaW5kVGV4dHVyZShoYS5URVhUVVJFXzJELG51bGwpLGhhLmJpbmRGcmFtZWJ1ZmZlcihoYS5GUkFNRUJVRkZFUixudWxsKSxoYS5kZWxldGVUZXh0dXJlKGJhKSxoYS5kZWxldGVGcmFtZWJ1ZmZlcih3YSksRWF9ZnVuY3Rpb24gaXNXZWJHTEZlbmNlRW5hYmxlZChoYSl7cmV0dXJuIGhhIT09Mj8hMTpnZXRXZWJHTENvbnRleHQoaGEpLmZlbmNlU3luYyE9bnVsbH1mdW5jdGlvbiBhc3NlcnROb3RDb21wbGV4KGhhLGFhKXtBcnJheS5pc0FycmF5KGhhKXx8KGhhPVtoYV0pLGhhLmZvckVhY2goeGE9Pnt4YSE9bnVsbCYmYXNzZXJ0KHhhLmR0eXBlIT09ImNvbXBsZXg2NCIsKCk9PmAke2FhfSBkb2VzIG5vdCBzdXBwb3J0IGNvbXBsZXg2NCB0ZW5zb3JzIGluIHRoZSBXZWJHTCBiYWNrZW5kLmApfSl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgRU5WPWVudigpO0VOVi5yZWdpc3RlckZsYWcoIkhBU19XRUJHTCIsKCk9PkVOVi5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT4wKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9WRVJTSU9OIiwoKT0+aXNXZWJHTFZlcnNpb25FbmFibGVkKDIpPzI6aXNXZWJHTFZlcnNpb25FbmFibGVkKDEpPzE6MCksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfQ0hFQ0tfTlVNRVJJQ0FMX1BST0JMRU1TIiwoKT0+ITEpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX0JVRkZFUl9TVVBQT1JURUQiLCgpPT5FTlYuZ2V0KCJXRUJHTF9WRVJTSU9OIik9PT0yKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9DUFVfRk9SV0FSRCIsKCk9PiEwKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9GT1JDRV9GMTZfVEVYVFVSRVMiLCgpPT4hMSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDSyIsKCk9PkVOVi5nZXRCb29sKCJIQVNfV0VCR0wiKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19OT1JNQUxJWkFUSU9OIiwoKT0+RU5WLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19DTElQIiwoKT0+RU5WLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19ERVBUSFdJU0VDT05WIiwoKT0+RU5WLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19CSU5BUllfT1BFUkFUSU9OUyIsKCk9PkVOVi5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfVU5BUllfT1BFUkFUSU9OUyIsKCk9PkVOVi5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfQVJSQVlfT1BFUkFUSU9OUyIsKCk9PkVOVi5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfSU1BR0VfT1BFUkFUSU9OUyIsKCk9PkVOVi5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX1BBQ0tfUkVEVUNFIiwoKT0+RU5WLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfTEFaSUxZX1VOUEFDSyIsKCk9PkVOVi5nZXRCb29sKCJXRUJHTF9QQUNLIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX0NPTlZfSU0yQ09MIiwoKT0+RU5WLmdldEJvb2woIldFQkdMX1BBQ0siKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfUEFDS19DT05WMkRUUkFOU1BPU0UiLCgpPT5FTlYuZ2V0Qm9vbCgiV0VCR0xfUEFDSyIpKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9NQVhfVEVYVFVSRV9TSVpFIiwoKT0+Z2V0V2ViR0xNYXhUZXh0dXJlU2l6ZShFTlYuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIikpKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9NQVhfVEVYVFVSRVNfSU5fU0hBREVSIiwoKT0+Z2V0TWF4VGV4dHVyZXNJblNoYWRlcihFTlYuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIikpKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fVkVSU0lPTiIsKCk9Pntjb25zdCBoYT1FTlYuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik7cmV0dXJuIGhhPT09MD8wOmdldFdlYkdMRGlzam9pbnRRdWVyeVRpbWVyVmVyc2lvbihoYSl9KSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiLCgpPT5FTlYuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fVkVSU0lPTiIpPjAmJiFpc01vYmlsZSgpKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9DQVBBQkxFIiwoKT0+aXNDYXBhYmxlT2ZSZW5kZXJpbmdUb0Zsb2F0VGV4dHVyZShFTlYuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIikpKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9FTkFCTEVEIiwoKT0+RU5WLmdldEJvb2woIldFQkdMX0ZPUkNFX0YxNl9URVhUVVJFUyIpPyExOkVOVi5nZXRCb29sKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9DQVBBQkxFIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX0RPV05MT0FEX0ZMT0FUX0VOQUJMRUQiLCgpPT5pc0Rvd25sb2FkRmxvYXRUZXh0dXJlRW5hYmxlZChFTlYuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIikpKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9GRU5DRV9BUElfRU5BQkxFRCIsKCk9PmlzV2ViR0xGZW5jZUVuYWJsZWQoRU5WLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpKSksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfU0laRV9VUExPQURfVU5JRk9STSIsKCk9PkVOVi5nZXRCb29sKCJXRUJHTF9SRU5ERVJfRkxPQVQzMl9FTkFCTEVEIik/NDowKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9ERUxFVEVfVEVYVFVSRV9USFJFU0hPTEQiLCgpPT4tMSxoYT0+e2lmKHR5cGVvZiBoYSE9Im51bWJlciIpdGhyb3cgbmV3IEVycm9yKGBXRUJHTF9ERUxFVEVfVEVYVFVSRV9USFJFU0hPTEQgbXVzdCBiZSBhIG51bWJlciBidXQgZ290ICR7aGF9LmApO2lmKGhhPDAmJmhhIT09LTEpdGhyb3cgbmV3IEVycm9yKGBXRUJHTF9ERUxFVEVfVEVYVFVSRV9USFJFU0hPTEQgbXVzdCBiZSAtMSAoaW5kaWNhdGluZyBuZXZlciBkZWxldGUpIG9yIGF0IGxlYXN0IDAsIGJ1dCBnb3QgJHtoYX0uYCl9KSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTF9GTFVTSF9USFJFU0hPTEQiLCgpPT5pc01vYmlsZSgpPzE6LTEsaGE9PntpZih0eXBlb2YgaGEhPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcihgV0VCR0xfRkxVU0hfVEhSRVNIT0xEIG11c3QgYmUgYSBudW1iZXIgYnV0IGdvdCAke2hhfS5gKTtpZihoYTwwJiZoYSE9PS0xKXRocm93IG5ldyBFcnJvcihgV0VCR0xfRkxVU0hfVEhSRVNIT0xEIG11c3QgYmUgLTEgKGluZGljYXRpbmcgbmV2ZXIgbWFudWFsIGZsdXNoKSBvciBhdCBsZWFzdCAwLCBidXQgZ290ICR7aGF9LmApfSksRU5WLnJlZ2lzdGVyRmxhZygiQ1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQiLCgpPT4xMjgpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX1VTRV9TSEFQRVNfVU5JRk9STVMiLCgpPT4hMSksRU5WLnJlZ2lzdGVyRmxhZygiVE9QS19MQVNUX0RJTV9DUFVfSEFORE9GRl9TSVpFX1RIUkVTSE9MRCIsKCk9PjFlNSksRU5WLnJlZ2lzdGVyRmxhZygiVE9QS19LX0NQVV9IQU5ET0ZGX1RIUkVTSE9MRCIsKCk9PjEyOCksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfRVhQX0NPTlYiLCgpPT4hMSksRU5WLnJlZ2lzdGVyRmxhZygiU09GVFdBUkVfV0VCR0xfRU5BQkxFRCIsKCk9PkVOVi5nZXRCb29sKCJJU19URVNUIikpLEVOVi5yZWdpc3RlckZsYWcoIldFQkdMX01BWF9TSVpFX0ZPUl9OQVJST1dfVEVYVFVSRSIsKCk9PjEvMCksRU5WLnJlZ2lzdGVyRmxhZygiV0VCR0xfQVVUT19TUVVBUklGWV9OQVJST1dfVEVYVFVSRV9TSEFQRSIsKCk9PiExKSxFTlYucmVnaXN0ZXJGbGFnKCJXRUJHTDJfSVNOQU5fQ1VTVE9NIiwoKT0+ITEpLEVOVi5yZWdpc3RlckZsYWcoIkVOR0lORV9DT01QSUxFX09OTFkiLCgpPT4hMSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0R2xzbERpZmZlcmVuY2VzKCl7bGV0IGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthLEFhO3JldHVybiBlbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTI/KGhhPSIjdmVyc2lvbiAzMDAgZXMiLGFhPSJpbiIseGE9Im91dCIsYmE9ImluIixTYT0idGV4dHVyZSIsVGE9Im91dHB1dENvbG9yIix3YT0ib3V0IHZlYzQgb3V0cHV0Q29sb3I7IixFYT1lbnYoKS5nZXRCb29sKCJXRUJHTDJfSVNOQU5fQ1VTVE9NIik/YAogICAgICBib29sIGlzbmFuX2N1c3RvbShmbG9hdCB2YWwpIHsKICAgICAgICB1aW50IGZsb2F0VG9VaW50ID0gZmxvYXRCaXRzVG9VaW50KHZhbCk7CiAgICAgICAgcmV0dXJuIChmbG9hdFRvVWludCAmIDB4N2ZmZmZmZmZ1KSA+IDB4N2Y4MDAwMDB1OwogICAgICB9CgogICAgICBidmVjNCBpc25hbl9jdXN0b20odmVjNCB2YWwpIHsKICAgICAgICByZXR1cm4gYnZlYzQoaXNuYW5fY3VzdG9tKHZhbC54KSwKICAgICAgICAgIGlzbmFuX2N1c3RvbSh2YWwueSksIGlzbmFuX2N1c3RvbSh2YWwueiksIGlzbmFuX2N1c3RvbSh2YWwudykpOwogICAgICB9CgogICAgICAjZGVmaW5lIGlzbmFuKHZhbHVlKSBpc25hbl9jdXN0b20odmFsdWUpCiAgICBgOiIiLGthPSIiLEFhPWAKICAgICAgI2RlZmluZSByb3VuZCh2YWx1ZSkgbmV3Um91bmQodmFsdWUpCiAgICAgIGludCBuZXdSb3VuZChmbG9hdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBpbnQoZmxvb3IodmFsdWUgKyAwLjUpKTsKICAgICAgfQoKICAgICAgaXZlYzQgbmV3Um91bmQodmVjNCB2YWx1ZSkgewogICAgICAgIHJldHVybiBpdmVjNChmbG9vcih2YWx1ZSArIHZlYzQoMC41KSkpOwogICAgICB9CiAgICBgKTooaGE9IiIsYWE9ImF0dHJpYnV0ZSIseGE9InZhcnlpbmciLGJhPSJ2YXJ5aW5nIixTYT0idGV4dHVyZTJEIixUYT0iZ2xfRnJhZ0NvbG9yIix3YT0iIixFYT1gCiAgICAgICNkZWZpbmUgaXNuYW4odmFsdWUpIGlzbmFuX2N1c3RvbSh2YWx1ZSkKICAgICAgYm9vbCBpc25hbl9jdXN0b20oZmxvYXQgdmFsKSB7CiAgICAgICAgcmV0dXJuICh2YWwgPiAwLiB8fCB2YWwgPCAxLiB8fCB2YWwgPT0gMC4pID8gZmFsc2UgOiB0cnVlOwogICAgICB9CiAgICAgIGJ2ZWM0IGlzbmFuX2N1c3RvbSh2ZWM0IHZhbCkgewogICAgICAgIHJldHVybiBidmVjNChpc25hbih2YWwueCksIGlzbmFuKHZhbC55KSwgaXNuYW4odmFsLnopLCBpc25hbih2YWwudykpOwogICAgICB9CiAgICBgLGthPWAKICAgICAgdW5pZm9ybSBmbG9hdCBJTkZJTklUWTsKCiAgICAgIGJvb2wgaXNpbmYoZmxvYXQgdmFsKSB7CiAgICAgICAgcmV0dXJuIGFicyh2YWwpID09IElORklOSVRZOwogICAgICB9CiAgICAgIGJ2ZWM0IGlzaW5mKHZlYzQgdmFsKSB7CiAgICAgICAgcmV0dXJuIGVxdWFsKGFicyh2YWwpLCB2ZWM0KElORklOSVRZKSk7CiAgICAgIH0KICAgIGAsQWE9YAogICAgICBpbnQgcm91bmQoZmxvYXQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gaW50KGZsb29yKHZhbHVlICsgMC41KSk7CiAgICAgIH0KCiAgICAgIGl2ZWM0IHJvdW5kKHZlYzQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gaXZlYzQoZmxvb3IodmFsdWUgKyB2ZWM0KDAuNSkpKTsKICAgICAgfQogICAgYCkse3ZlcnNpb246aGEsYXR0cmlidXRlOmFhLHZhcnlpbmdWczp4YSx2YXJ5aW5nRnM6YmEsdGV4dHVyZTJEOlNhLG91dHB1dDpUYSxkZWZpbmVPdXRwdXQ6d2EsZGVmaW5lU3BlY2lhbE5hTjpFYSxkZWZpbmVTcGVjaWFsSW5mOmthLGRlZmluZVJvdW5kOkFhfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnZXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4KGhhLGFhLHhhPSJpbmRleCIpe2NvbnN0IGJhPWNvbXB1dGVTdHJpZGVzKGFhKTtyZXR1cm4gYmEubWFwKChTYSxUYSk9Pntjb25zdCB3YT1gaW50ICR7aGFbVGFdfSA9ICR7eGF9IC8gJHtTYX1gLEVhPVRhPT09YmEubGVuZ3RoLTE/YGludCAke2hhW1RhKzFdfSA9ICR7eGF9IC0gJHtoYVtUYV19ICogJHtTYX1gOmBpbmRleCAtPSAke2hhW1RhXX0gKiAke1NhfWA7cmV0dXJuYCR7d2F9OyAke0VhfTtgfSkuam9pbigiIil9ZnVuY3Rpb24gZ2V0T3V0cHV0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybShoYSxhYSx4YT0iaW5kZXgiKXtjb25zdCBiYT1jb21wdXRlU3RyaWRlcyhhYSk7cmV0dXJuIGJhLm1hcCgoU2EsVGEpPT57Y29uc3Qgd2E9YGludCAke2hhW1RhXX0gPSAke3hhfSAvIG91dFNoYXBlU3RyaWRlc1ske1RhfV1gLEVhPVRhPT09YmEubGVuZ3RoLTE/YGludCAke2hhW1RhKzFdfSA9ICR7eGF9IC0gJHtoYVtUYV19ICogb3V0U2hhcGVTdHJpZGVzWyR7VGF9XWA6YGluZGV4IC09ICR7aGFbVGFdfSAqIG91dFNoYXBlU3RyaWRlc1ske1RhfV1gO3JldHVybmAke3dhfTsgJHtFYX07YH0pLmpvaW4oIiIpfWZ1bmN0aW9uIHN5bWJvbGljYWxseUNvbXB1dGVTdHJpZGVzKGhhLGFhKXtjb25zdCB4YT1oYS5sZW5ndGgsYmE9aGEubWFwKFRhPT5gJHthYX1bJHtUYX1dYCksU2E9bmV3IEFycmF5KHhhLTEpO1NhW3hhLTJdPWJhW3hhLTFdO2ZvcihsZXQgVGE9eGEtMztUYT49MDstLVRhKVNhW1RhXT1gKCR7U2FbVGErMV19ICogJHtiYVtUYSsxXX0pYDtyZXR1cm4gU2F9ZnVuY3Rpb24gZ2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybShoYSxhYSx4YT0iaW5kZXgiKXtjb25zdCBiYT1oYS5tYXAoKFRhLHdhKT0+d2EpLFNhPXN5bWJvbGljYWxseUNvbXB1dGVTdHJpZGVzKGJhLGFhKTtyZXR1cm4gU2EubWFwKChUYSx3YSk9Pntjb25zdCBFYT1gaW50ICR7aGFbd2FdfSA9ICR7eGF9IC8gJHtTYVt3YV19YCxrYT13YT09PVNhLmxlbmd0aC0xP2BpbnQgJHtoYVt3YSsxXX0gPSAke3hhfSAtICR7aGFbd2FdfSAqICR7U2Fbd2FdfWA6YGluZGV4IC09ICR7aGFbd2FdfSAqICR7U2Fbd2FdfWA7cmV0dXJuYCR7RWF9OyAke2thfTtgfSkuam9pbigiIil9ZnVuY3Rpb24gZ2V0RmxhdEluZGV4RnJvbTNEKGhhKXtjb25zdCBhYT1jb21wdXRlU3RyaWRlcyhoYSkubWFwKHhhPT54YS50b1N0cmluZygpKTtyZXR1cm5gCiAgaW50IGdldEZsYXRJbmRleChpdmVjMyBjb29yZHMpIHsKICAgIHJldHVybiBjb29yZHMueCAqICR7YWFbMF19ICsgY29vcmRzLnkgKiAke2FhWzFdfSArIGNvb3Jkcy56OwogIH0KYH1mdW5jdGlvbiBnZXRGbGF0SW5kZXhGcm9tM0RPdXRwdXQoKXtyZXR1cm5gCiAgaW50IGdldEZsYXRJbmRleChpdmVjMyBjb29yZHMpIHsKICAgIHJldHVybiBjb29yZHMueCAqIG91dFNoYXBlU3RyaWRlc1swXSArIGNvb3Jkcy55ICogb3V0U2hhcGVTdHJpZGVzWzFdICsgY29vcmRzLno7CiAgfQpgfWNvbnN0IEVOQ09ERV9GTE9BVF9TTklQUEVUPWAKICBjb25zdCBmbG9hdCBGTE9BVF9NQVggPSAxLjcwMTQxMTg0ZTM4OwogIGNvbnN0IGZsb2F0IEZMT0FUX01JTiA9IDEuMTc1NDk0MzVlLTM4OwoKICBsb3dwIHZlYzQgZW5jb2RlX2Zsb2F0KGhpZ2hwIGZsb2F0IHYpIHsKICAgIGlmIChpc25hbih2KSkgewogICAgICByZXR1cm4gdmVjNCgyNTUsIDI1NSwgMjU1LCAyNTUpOwogICAgfQoKICAgIGhpZ2hwIGZsb2F0IGF2ID0gYWJzKHYpOwoKICAgIGlmKGF2IDwgRkxPQVRfTUlOKSB7CiAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCk7CiAgICB9IGVsc2UgaWYodiA+IEZMT0FUX01BWCkgewogICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMTI4LjAsIDEyNy4wKSAvIDI1NS4wOwogICAgfSBlbHNlIGlmKHYgPCAtRkxPQVRfTUFYKSB7CiAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAgMTI4LjAsIDI1NS4wKSAvIDI1NS4wOwogICAgfQoKICAgIGhpZ2hwIHZlYzQgYyA9IHZlYzQoMCwwLDAsMCk7CgogICAgaGlnaHAgZmxvYXQgZSA9IGZsb29yKGxvZzIoYXYpKTsKICAgIGhpZ2hwIGZsb2F0IG0gPSBleHAyKGZyYWN0KGxvZzIoYXYpKSkgLSAxLjA7CgogICAgY1syXSA9IGZsb29yKDEyOC4wICogbSk7CiAgICBtIC09IGNbMl0gLyAxMjguMDsKICAgIGNbMV0gPSBmbG9vcigzMjc2OC4wICogbSk7CiAgICBtIC09IGNbMV0gLyAzMjc2OC4wOwogICAgY1swXSA9IGZsb29yKDgzODg2MDguMCAqIG0pOwoKICAgIGhpZ2hwIGZsb2F0IGViaWFzID0gZSArIDEyNy4wOwogICAgY1szXSA9IGZsb29yKGViaWFzIC8gMi4wKTsKICAgIGViaWFzIC09IGNbM10gKiAyLjA7CiAgICBjWzJdICs9IGZsb29yKGViaWFzKSAqIDEyOC4wOwoKICAgIGNbM10gKz0gMTI4LjAgKiBzdGVwKDAuMCwgLXYpOwoKICAgIHJldHVybiBjIC8gMjU1LjA7CiAgfQpgOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0e2dldEJyb2FkY2FzdERpbXN9PWJhY2tlbmRfdXRpbDtmdW5jdGlvbiBtYWtlU2hhZGVyKGhhLGFhLHhhKXtjb25zdCBiYT1bXTtpZihoYS5mb3JFYWNoKHRsPT57Y29uc3Qgbmw9c2l6ZUZyb21TaGFwZSh0bC5zaGFwZUluZm8ubG9naWNhbFNoYXBlKTtpZih0bC5zaGFwZUluZm8uaXNVbmlmb3JtP2JhLnB1c2goYHVuaWZvcm0gZmxvYXQgJHt0bC5uYW1lfSR7bmw+MT9gWyR7bmx9XWA6IiJ9O2ApOihiYS5wdXNoKGB1bmlmb3JtIHNhbXBsZXIyRCAke3RsLm5hbWV9O2ApLGJhLnB1c2goYHVuaWZvcm0gaW50IG9mZnNldCR7dGwubmFtZX07YCkpLHhhLmVuYWJsZVNoYXBlVW5pZm9ybXMpe2NvbnN0e3VuaWZvcm1TaGFwZTpzbH09Z2V0VW5pZm9ybUluZm9Gcm9tU2hhcGUoeGEucGFja2VkSW5wdXRzLHRsLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsdGwuc2hhcGVJbmZvLnRleFNoYXBlKTtzd2l0Y2goc2wubGVuZ3RoKXtjYXNlIDE6YmEucHVzaChgdW5pZm9ybSBpbnQgJHt0bC5uYW1lfVNoYXBlO2ApO2JyZWFrO2Nhc2UgMjpiYS5wdXNoKGB1bmlmb3JtIGl2ZWMyICR7dGwubmFtZX1TaGFwZTtgKTticmVhaztjYXNlIDM6YmEucHVzaChgdW5pZm9ybSBpdmVjMyAke3RsLm5hbWV9U2hhcGU7YCk7YnJlYWs7Y2FzZSA0OmJhLnB1c2goYHVuaWZvcm0gaXZlYzQgJHt0bC5uYW1lfVNoYXBlO2ApO2JyZWFrfWJhLnB1c2goYHVuaWZvcm0gaXZlYzIgJHt0bC5uYW1lfVRleFNoYXBlO2ApfX0pLHhhLmVuYWJsZVNoYXBlVW5pZm9ybXMpe3N3aXRjaChhYS5sb2dpY2FsU2hhcGUubGVuZ3RoKXtjYXNlIDE6YmEucHVzaCgidW5pZm9ybSBpbnQgb3V0U2hhcGU7Iik7YnJlYWs7Y2FzZSAyOmJhLnB1c2goInVuaWZvcm0gaXZlYzIgb3V0U2hhcGU7IiksYmEucHVzaCgidW5pZm9ybSBpbnQgb3V0U2hhcGVTdHJpZGVzOyIpO2JyZWFrO2Nhc2UgMzpiYS5wdXNoKCJ1bmlmb3JtIGl2ZWMzIG91dFNoYXBlOyIpLGJhLnB1c2goInVuaWZvcm0gaXZlYzIgb3V0U2hhcGVTdHJpZGVzOyIpO2JyZWFrO2Nhc2UgNDpiYS5wdXNoKCJ1bmlmb3JtIGl2ZWM0IG91dFNoYXBlOyIpLGJhLnB1c2goInVuaWZvcm0gaXZlYzMgb3V0U2hhcGVTdHJpZGVzOyIpO2JyZWFrfWJhLnB1c2goInVuaWZvcm0gaXZlYzIgb3V0VGV4U2hhcGU7Iil9eGEuY3VzdG9tVW5pZm9ybXMmJnhhLmN1c3RvbVVuaWZvcm1zLmZvckVhY2godGw9PntiYS5wdXNoKGB1bmlmb3JtICR7dGwudHlwZX0gJHt0bC5uYW1lfSR7dGwuYXJyYXlJbmRleD9gWyR7dGwuYXJyYXlJbmRleH1dYDoiIn07YCl9KTtjb25zdCBTYT1iYS5qb2luKGAKYCksVGE9aGEubWFwKHRsPT5nZXRJbnB1dFNhbXBsaW5nU25pcHBldCh0bCxhYSx4YS5wYWNrZWRJbnB1dHMseGEuZW5hYmxlU2hhcGVVbmlmb3JtcykpLmpvaW4oYApgKSx3YT1hYS50ZXhTaGFwZSxFYT1nZXRHbHNsRGlmZmVyZW5jZXMoKSxrYT1nZXRGbG9hdFRleHR1cmVTYW1wbGVTbmlwcGV0KEVhKTtsZXQgQWEsRmEsTGE9Z2V0U2hhZGVyUHJlZml4KEVhKTtyZXR1cm4gYWEuaXNQYWNrZWQ/KEFhPWdldFBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChhYS5sb2dpY2FsU2hhcGUsd2EseGEuZW5hYmxlU2hhcGVVbmlmb3JtcyksRmE9Z2V0RmxvYXRUZXh0dXJlU2V0UkdCQVNuaXBwZXQoRWEpKTooQWE9Z2V0T3V0cHV0U2FtcGxpbmdTbmlwcGV0KGFhLmxvZ2ljYWxTaGFwZSx3YSx4YS5lbmFibGVTaGFwZVVuaWZvcm1zKSxGYT1nZXRGbG9hdFRleHR1cmVTZXRSU25pcHBldChFYSkpLHhhLnBhY2tlZElucHV0cyYmKExhKz1TSEFERVJfUEFDS0VEX1BSRUZJWCksW0xhLGthLEZhLFNhLEFhLFRhLHhhLnVzZXJDb2RlXS5qb2luKGAKYCl9ZnVuY3Rpb24gZ2V0U2FtcGxlckZyb21JbkluZm8oaGEsYWE9ITEpe2NvbnN0IHhhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGU7c3dpdGNoKHhhLmxlbmd0aCl7Y2FzZSAwOnJldHVybiBnZXRTYW1wbGVyU2NhbGFyKGhhLGFhKTtjYXNlIDE6cmV0dXJuIGdldFNhbXBsZXIxRChoYSxhYSk7Y2FzZSAyOnJldHVybiBnZXRTYW1wbGVyMkQoaGEsYWEpO2Nhc2UgMzpyZXR1cm4gZ2V0U2FtcGxlcjNEKGhhLGFhKTtjYXNlIDQ6cmV0dXJuIGdldFNhbXBsZXI0RChoYSxhYSk7Y2FzZSA1OnJldHVybiBnZXRTYW1wbGVyNUQoaGEpO2Nhc2UgNjpyZXR1cm4gZ2V0U2FtcGxlcjZEKGhhKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgJHt4YS5sZW5ndGh9LUQgaW5wdXQgc2FtcGxpbmcgaXMgbm90IHlldCBzdXBwb3J0ZWRgKX19ZnVuY3Rpb24gZ2V0UGFja2VkU2FtcGxlckZyb21JbkluZm8oaGEsYWEpe3N3aXRjaChoYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLmxlbmd0aCl7Y2FzZSAwOnJldHVybiBnZXRQYWNrZWRTYW1wbGVyU2NhbGFyKGhhKTtjYXNlIDE6cmV0dXJuIGdldFBhY2tlZFNhbXBsZXIxRChoYSxhYSk7Y2FzZSAyOnJldHVybiBnZXRQYWNrZWRTYW1wbGVyMkQoaGEsYWEpO2Nhc2UgMzpyZXR1cm4gZ2V0UGFja2VkU2FtcGxlcjNEKGhhLGFhKTtkZWZhdWx0OnJldHVybiBnZXRQYWNrZWRTYW1wbGVyTkQoaGEsYWEpfX1mdW5jdGlvbiBnZXRJbnB1dFNhbXBsaW5nU25pcHBldChoYSxhYSx4YT0hMSxiYSl7bGV0IFNhPSIiO3hhP1NhKz1nZXRQYWNrZWRTYW1wbGVyRnJvbUluSW5mbyhoYSxiYSk6U2ErPWdldFNhbXBsZXJGcm9tSW5JbmZvKGhhLGJhKTtjb25zdCBUYT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLHdhPWFhLmxvZ2ljYWxTaGFwZTtyZXR1cm4gVGEubGVuZ3RoPD13YS5sZW5ndGgmJih4YT9TYSs9Z2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKGhhLGFhKTpTYSs9Z2V0U2FtcGxlckF0T3V0cHV0Q29vcmRzKGhhLGFhKSksU2F9ZnVuY3Rpb24gZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KGhhLGFhLHhhKXtzd2l0Y2goaGEubGVuZ3RoKXtjYXNlIDA6cmV0dXJuIGdldE91dHB1dFNjYWxhckNvb3JkcygpO2Nhc2UgMTpyZXR1cm4gZ2V0T3V0cHV0UGFja2VkMURDb29yZHMoaGEsYWEseGEpO2Nhc2UgMjpyZXR1cm4gZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMoaGEsYWEseGEpO2Nhc2UgMzpyZXR1cm4gZ2V0T3V0cHV0UGFja2VkM0RDb29yZHMoaGEsYWEseGEpO2RlZmF1bHQ6cmV0dXJuIGdldE91dHB1dFBhY2tlZE5EQ29vcmRzKGhhLGFhLHhhKX19ZnVuY3Rpb24gZ2V0T3V0cHV0U2FtcGxpbmdTbmlwcGV0KGhhLGFhLHhhKXtzd2l0Y2goaGEubGVuZ3RoKXtjYXNlIDA6cmV0dXJuIGdldE91dHB1dFNjYWxhckNvb3JkcygpO2Nhc2UgMTpyZXR1cm4gZ2V0T3V0cHV0MURDb29yZHMoaGEsYWEseGEpO2Nhc2UgMjpyZXR1cm4gZ2V0T3V0cHV0MkRDb29yZHMoaGEsYWEseGEpO2Nhc2UgMzpyZXR1cm4gZ2V0T3V0cHV0M0RDb29yZHMoaGEsYWEseGEpO2Nhc2UgNDpyZXR1cm4gZ2V0T3V0cHV0NERDb29yZHMoaGEsYWEseGEpO2Nhc2UgNTpyZXR1cm4gZ2V0T3V0cHV0NURDb29yZHMoaGEsYWEpO2Nhc2UgNjpyZXR1cm4gZ2V0T3V0cHV0NkRDb29yZHMoaGEsYWEpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGAke2hhLmxlbmd0aH0tRCBvdXRwdXQgc2FtcGxpbmcgaXMgbm90IHlldCBzdXBwb3J0ZWRgKX19ZnVuY3Rpb24gZ2V0RmxvYXRUZXh0dXJlU2FtcGxlU25pcHBldChoYSl7cmV0dXJuYAogICAgZmxvYXQgc2FtcGxlVGV4dHVyZShzYW1wbGVyMkQgdGV4dHVyZVNhbXBsZXIsIHZlYzIgdXYpIHsKICAgICAgcmV0dXJuICR7aGEudGV4dHVyZTJEfSh0ZXh0dXJlU2FtcGxlciwgdXYpLnI7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRGbG9hdFRleHR1cmVTZXRSU25pcHBldChoYSl7cmV0dXJuYAogICAgdm9pZCBzZXRPdXRwdXQoZmxvYXQgdmFsKSB7CiAgICAgICR7aGEub3V0cHV0fSA9IHZlYzQodmFsLCAwLCAwLCAwKTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldEZsb2F0VGV4dHVyZVNldFJHQkFTbmlwcGV0KGhhKXtyZXR1cm5gCiAgICB2b2lkIHNldE91dHB1dCh2ZWM0IHZhbCkgewogICAgICAke2hhLm91dHB1dH0gPSB2YWw7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRTaGFkZXJQcmVmaXgoaGEpe3JldHVybmAke2hhLnZlcnNpb259CiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgICBwcmVjaXNpb24gaGlnaHAgaW50OwogICAgcHJlY2lzaW9uIGhpZ2hwIHNhbXBsZXIyRDsKICAgICR7aGEudmFyeWluZ0ZzfSB2ZWMyIHJlc3VsdFVWOwogICAgJHtoYS5kZWZpbmVPdXRwdXR9CiAgICBjb25zdCB2ZWMyIGhhbGZDUiA9IHZlYzIoMC41LCAwLjUpOwoKICAgIHN0cnVjdCBpdmVjNQogICAgewogICAgICBpbnQgeDsKICAgICAgaW50IHk7CiAgICAgIGludCB6OwogICAgICBpbnQgdzsKICAgICAgaW50IHU7CiAgICB9OwoKICAgIHN0cnVjdCBpdmVjNgogICAgewogICAgICBpbnQgeDsKICAgICAgaW50IHk7CiAgICAgIGludCB6OwogICAgICBpbnQgdzsKICAgICAgaW50IHU7CiAgICAgIGludCB2OwogICAgfTsKCiAgICB1bmlmb3JtIGZsb2F0IE5BTjsKICAgICR7aGEuZGVmaW5lU3BlY2lhbE5hTn0KICAgICR7aGEuZGVmaW5lU3BlY2lhbEluZn0KICAgICR7aGEuZGVmaW5lUm91bmR9CgogICAgaW50IGltb2QoaW50IHgsIGludCB5KSB7CiAgICAgIHJldHVybiB4IC0geSAqICh4IC8geSk7CiAgICB9CgogICAgaW50IGlkaXYoaW50IGEsIGludCBiLCBmbG9hdCBzaWduKSB7CiAgICAgIGludCByZXMgPSBhIC8gYjsKICAgICAgaW50IG1vZCA9IGltb2QoYSwgYik7CiAgICAgIGlmIChzaWduIDwgMC4gJiYgbW9kICE9IDApIHsKICAgICAgICByZXMgLT0gMTsKICAgICAgfQogICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIC8vQmFzZWQgb24gdGhlIHdvcmsgb2YgRGF2ZSBIb3NraW5zCiAgICAvL2h0dHBzOi8vd3d3LnNoYWRlcnRveS5jb20vdmlldy80ZGpTUlcKICAgICNkZWZpbmUgSEFTSFNDQUxFMSA0NDMuODk3NQogICAgZmxvYXQgcmFuZG9tKGZsb2F0IHNlZWQpewogICAgICB2ZWMyIHAgPSByZXN1bHRVViAqIHNlZWQ7CiAgICAgIHZlYzMgcDMgID0gZnJhY3QodmVjMyhwLnh5eCkgKiBIQVNIU0NBTEUxKTsKICAgICAgcDMgKz0gZG90KHAzLCBwMy55enggKyAxOS4xOSk7CiAgICAgIHJldHVybiBmcmFjdCgocDMueCArIHAzLnkpICogcDMueik7CiAgICB9CgogICAgJHtTQU1QTEVfMURfU05JUFBFVH0KICAgICR7U0FNUExFXzJEX1NOSVBQRVR9CiAgICAke1NBTVBMRV8zRF9TTklQUEVUfQogIGB9Y29uc3QgU0FNUExFXzFEX1NOSVBQRVQ9YAp2ZWMyIHV2RnJvbUZsYXQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgaW5kZXgpIHsKICBpbnQgdGV4UiA9IGluZGV4IC8gdGV4TnVtQzsKICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqIHRleE51bUM7CiAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7Cn0KdmVjMiBwYWNrZWRVVmZyb20xRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkgewogIGludCB0ZXhlbEluZGV4ID0gaW5kZXggLyAyOwogIGludCB0ZXhSID0gdGV4ZWxJbmRleCAvIHRleE51bUM7CiAgaW50IHRleEMgPSB0ZXhlbEluZGV4IC0gdGV4UiAqIHRleE51bUM7CiAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7Cn0KYCxTQU1QTEVfMkRfU05JUFBFVD1gCnZlYzIgcGFja2VkVVZmcm9tMkQoaW50IHRleGVsc0luTG9naWNhbFJvdywgaW50IHRleE51bVIsCiAgaW50IHRleE51bUMsIGludCByb3csIGludCBjb2wpIHsKICBpbnQgdGV4ZWxJbmRleCA9IChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTsKICBpbnQgdGV4UiA9IHRleGVsSW5kZXggLyB0ZXhOdW1DOwogIGludCB0ZXhDID0gdGV4ZWxJbmRleCAtIHRleFIgKiB0ZXhOdW1DOwogIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpOwp9CmAsU0FNUExFXzNEX1NOSVBQRVQ9YAp2ZWMyIHBhY2tlZFVWZnJvbTNEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywKICAgIGludCB0ZXhlbHNJbkJhdGNoLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgYiwKICAgIGludCByb3csIGludCBjb2wpIHsKICBpbnQgaW5kZXggPSBiICogdGV4ZWxzSW5CYXRjaCArIChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTsKICBpbnQgdGV4UiA9IGluZGV4IC8gdGV4TnVtQzsKICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqIHRleE51bUM7CiAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7Cn0KYCxTSEFERVJfUEFDS0VEX1BSRUZJWD1gCiAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIHZlYzIgaW5uZXJEaW1zKSB7CiAgICB2ZWMyIG1vZENvb3JkID0gbW9kKGlubmVyRGltcywgMi4pOwogICAgcmV0dXJuIG1vZENvb3JkLnggPT0gMC4gPwogICAgICAobW9kQ29vcmQueSA9PSAwLiA/IGZyYWcuciA6IGZyYWcuZykgOgogICAgICAobW9kQ29vcmQueSA9PSAwLiA/IGZyYWcuYiA6IGZyYWcuYSk7CiAgfQogIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCBpbnQgZGltKSB7CiAgICBmbG9hdCBtb2RDb29yZCA9IG1vZChmbG9hdChkaW0pLCAyLik7CiAgICByZXR1cm4gbW9kQ29vcmQgPT0gMC4gPyBmcmFnLnIgOiBmcmFnLmc7CiAgfQpgO2Z1bmN0aW9uIGdldE91dHB1dFNjYWxhckNvb3Jkcygpe3JldHVybmAKICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIHJldHVybiAwOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0UGFja2VkMURDb29yZHMoaGEsYWEseGEpe2NvbnN0IGJhPVtNYXRoLmNlaWwoYWFbMF0vMiksTWF0aC5jZWlsKGFhWzFdLzIpXTtyZXR1cm4gYmFbMF09PT0xP3hhP2AKICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICByZXR1cm4gMiAqIGludChyZXN1bHRVVi54ICogY2VpbChmbG9hdChvdXRUZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgfQogICAgYDpgCiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIDIgKiBpbnQocmVzdWx0VVYueCAqICR7YmFbMV19LjApOwogICAgICB9CiAgICBgOmJhWzFdPT09MT94YT9gCiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIDIgKiBpbnQocmVzdWx0VVYueSAqIGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMF0pIC8gMi4wKSk7CiAgICAgIH0KICAgIGA6YAogICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiAyICogaW50KHJlc3VsdFVWLnkgKiAke2JhWzBdfS4wKTsKICAgICAgfQogICAgYDp4YT9gCiAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiBwYWNrZWRUZXhTaGFwZSA9IGl2ZWMyKGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMF0pIC8gMi4wKSwgY2VpbChmbG9hdChvdXRUZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihwYWNrZWRUZXhTaGFwZVswXSwgcGFja2VkVGV4U2hhcGVbMV0pKTsKICAgICAgcmV0dXJuIDIgKiAocmVzVGV4UkMueCAqIHBhY2tlZFRleFNoYXBlWzFdICsgcmVzVGV4UkMueSk7CiAgICB9CiAgYDpgCiAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YmFbMF19LCAke2JhWzFdfSkpOwogICAgICByZXR1cm4gMiAqIChyZXNUZXhSQy54ICogJHtiYVsxXX0gKyByZXNUZXhSQy55KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldE91dHB1dDFEQ29vcmRzKGhhLGFhLHhhKXtyZXR1cm4gYWFbMF09PT0xP3hhP2AKICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICByZXR1cm4gaW50KHJlc3VsdFVWLnggKiBmbG9hdChvdXRUZXhTaGFwZVsxXSkpOwogICAgICB9CiAgICBgOmAKICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICByZXR1cm4gaW50KHJlc3VsdFVWLnggKiAke2FhWzFdfS4wKTsKICAgICAgfQogICAgYDphYVsxXT09PTE/eGE/YAogICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiBpbnQocmVzdWx0VVYueSAqIGZsb2F0KG91dFRleFNoYXBlWzBdKSk7CiAgICAgIH0KICAgIGA6YAogICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiBpbnQocmVzdWx0VVYueSAqICR7YWFbMF19LjApOwogICAgICB9CiAgICBgOnhhP2AKICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIob3V0VGV4U2hhcGVbMF0sIG91dFRleFNoYXBlWzFdKSk7CiAgICAgIHJldHVybiByZXNUZXhSQy54ICogb3V0VGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwogICAgfQogIGA6YAogICAgaW50IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke2FhWzBdfSwgJHthYVsxXX0pKTsKICAgICAgcmV0dXJuIHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXRQYWNrZWQzRENvb3JkcyhoYSxhYSx4YSl7aWYoeGEpcmV0dXJuYAogICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiBwYWNrZWRUZXhTaGFwZSA9IGl2ZWMyKGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMF0pIC8gMi4wKSwgY2VpbChmbG9hdChvdXRUZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaW50IHRleGVsc0luTG9naWNhbFJvdyA9IGludChjZWlsKGZsb2F0KG91dFNoYXBlWzJdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIGludChjZWlsKGZsb2F0KG91dFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKHBhY2tlZFRleFNoYXBlWzBdLCBwYWNrZWRUZXhTaGFwZVsxXSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogcGFja2VkVGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwoKICAgICAgaW50IGIgPSBpbmRleCAvIHRleGVsc0luQmF0Y2g7CiAgICAgIGluZGV4IC09IGIgKiB0ZXhlbHNJbkJhdGNoOwoKICAgICAgaW50IHIgPSAyICogKGluZGV4IC8gdGV4ZWxzSW5Mb2dpY2FsUm93KTsKICAgICAgaW50IGMgPSBpbW9kKGluZGV4LCB0ZXhlbHNJbkxvZ2ljYWxSb3cpICogMjsKCiAgICAgIHJldHVybiBpdmVjMyhiLCByLCBjKTsKICAgIH0KICBgO2NvbnN0IGJhPVtNYXRoLmNlaWwoYWFbMF0vMiksTWF0aC5jZWlsKGFhWzFdLzIpXSxTYT1NYXRoLmNlaWwoaGFbMl0vMiksVGE9U2EqTWF0aC5jZWlsKGhhWzFdLzIpO3JldHVybmAKICAgIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke2JhWzBdfSwgJHtiYVsxXX0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YmFbMV19ICsgcmVzVGV4UkMueTsKCiAgICAgIGludCBiID0gaW5kZXggLyAke1RhfTsKICAgICAgaW5kZXggLT0gYiAqICR7VGF9OwoKICAgICAgaW50IHIgPSAyICogKGluZGV4IC8gJHtTYX0pOwogICAgICBpbnQgYyA9IGltb2QoaW5kZXgsICR7U2F9KSAqIDI7CgogICAgICByZXR1cm4gaXZlYzMoYiwgciwgYyk7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXQzRENvb3JkcyhoYSxhYSx4YSl7aWYoeGEpcmV0dXJuYAogIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHsKICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKG91dFRleFNoYXBlWzBdLCBvdXRUZXhTaGFwZVsxXSkpOwogICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqIG91dFRleFNoYXBlWzFdICsgcmVzVGV4UkMueTsKICAgICR7Z2V0T3V0cHV0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybShbInIiLCJjIiwiZCJdLGhhKX0KICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTsKICB9CmA7Y29uc3QgYmE9Z2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleChbInIiLCJjIiwiZCJdLGhhKTtyZXR1cm5gCiAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHthYVswXX0sICR7YWFbMV19KSk7CiAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CiAgICAgICR7YmF9CiAgICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldE91dHB1dFBhY2tlZE5EQ29vcmRzKGhhLGFhLHhhKXtpZih4YSlyZXR1cm5gCiAgICBpdmVjNCBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdChvdXRUZXhTaGFwZVswXSkgLyAyLjApLCBjZWlsKGZsb2F0KG91dFRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKHBhY2tlZFRleFNoYXBlWzBdLCBwYWNrZWRUZXhTaGFwZVsxXSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogcGFja2VkVGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwoKICAgICAgaW50IHRleGVsc0luTG9naWNhbFJvdyA9IGludChjZWlsKGZsb2F0KG91dFNoYXBlWzNdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIGludChjZWlsKGZsb2F0KG91dFNoYXBlWzJdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaE4gPSB0ZXhlbHNJbkJhdGNoICogb3V0U2hhcGVbMV07CgogICAgICBpbnQgYjIgPSBpbmRleCAvIHRleGVsc0luQmF0Y2hOOwogICAgICBpbmRleCAtPSBiMiAqIHRleGVsc0luQmF0Y2hOOwoKICAgICAgaW50IGIgPSBpbmRleCAvIHRleGVsc0luQmF0Y2g7CiAgICAgIGluZGV4IC09IGIgKiB0ZXhlbHNJbkJhdGNoOwoKICAgICAgaW50IHIgPSAyICogKGluZGV4IC8gdGV4ZWxzSW5Mb2dpY2FsUm93KTsKICAgICAgaW50IGMgPSBpbW9kKGluZGV4LCB0ZXhlbHNJbkxvZ2ljYWxSb3cpICogMjsKCiAgICAgIHJldHVybiBpdmVjNChiMiwgYiwgciwgYyk7CiAgICB9CiAgYDtjb25zdCBiYT1bTWF0aC5jZWlsKGFhWzBdLzIpLE1hdGguY2VpbChhYVsxXS8yKV0sU2E9TWF0aC5jZWlsKGhhW2hhLmxlbmd0aC0xXS8yKSxUYT1TYSpNYXRoLmNlaWwoaGFbaGEubGVuZ3RoLTJdLzIpO2xldCB3YT1UYSxFYT0iIixrYT0iYiwgciwgYyI7Zm9yKGxldCBBYT0yO0FhPGhhLmxlbmd0aC0xO0FhKyspd2EqPWhhW2hhLmxlbmd0aC1BYS0xXSxFYT1gCiAgICAgIGludCBiJHtBYX0gPSBpbmRleCAvICR7d2F9OwogICAgICBpbmRleCAtPSBiJHtBYX0gKiAke3dhfTsKICAgIGArRWEsa2E9YGIke0FhfSwgYCtrYTtyZXR1cm5gCiAgICBpdmVjJHtoYS5sZW5ndGh9IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke2JhWzBdfSwgJHtiYVsxXX0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YmFbMV19ICsgcmVzVGV4UkMueTsKCiAgICAgICR7RWF9CgogICAgICBpbnQgYiA9IGluZGV4IC8gJHtUYX07CiAgICAgIGluZGV4IC09IGIgKiAke1RhfTsKCiAgICAgIGludCByID0gMiAqIChpbmRleCAvICR7U2F9KTsKICAgICAgaW50IGMgPSBpbW9kKGluZGV4LCAke1NhfSkgKiAyOwoKICAgICAgcmV0dXJuIGl2ZWMke2hhLmxlbmd0aH0oJHtrYX0pOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0NERDb29yZHMoaGEsYWEseGEpe2lmKHhhKXJldHVybmAKICAgIGl2ZWM0IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgdmVjMihvdXRUZXhTaGFwZVswXSwgb3V0VGV4U2hhcGVbMV0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqIG91dFRleFNoYXBlWzFdICsgcmVzVGV4UkMueTsKICAgICAgJHtnZXRPdXRwdXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4QnlVbmlmb3JtKFsiciIsImMiLCJkIiwiZDIiXSxoYSl9CiAgICAgIHJldHVybiBpdmVjNChyLCBjLCBkLCBkMik7CiAgICB9CiAgYDtjb25zdCBiYT1nZXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4KFsiciIsImMiLCJkIiwiZDIiXSxoYSk7cmV0dXJuYAogICAgaXZlYzQgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogJHthYVsxXX0gKyByZXNUZXhSQy55OwogICAgICAke2JhfQogICAgICByZXR1cm4gaXZlYzQociwgYywgZCwgZDIpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0T3V0cHV0NURDb29yZHMoaGEsYWEpe2NvbnN0IHhhPWdldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXgoWyJyIiwiYyIsImQiLCJkMiIsImQzIl0saGEpO3JldHVybmAKICAgIGl2ZWM1IGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIoJHthYVswXX0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHthYVsxXX0pKTsKCiAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CgogICAgICAke3hhfQoKICAgICAgaXZlYzUgb3V0U2hhcGUgPSBpdmVjNShyLCBjLCBkLCBkMiwgZDMpOwogICAgICByZXR1cm4gb3V0U2hhcGU7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXQ2RENvb3JkcyhoYSxhYSl7Y29uc3QgeGE9Z2V0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleChbInIiLCJjIiwiZCIsImQyIiwiZDMiLCJkNCJdLGhhKTtyZXR1cm5gCiAgICBpdmVjNiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgIHZlYzIoJHthYVswXX0sICR7YWFbMV19KSk7CiAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CgogICAgICAke3hhfQoKICAgICAgaXZlYzYgcmVzdWx0ID0gaXZlYzYociwgYywgZCwgZDIsIGQzLCBkNCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXRQYWNrZWQyRENvb3JkcyhoYSxhYSx4YSl7Y29uc3QgYmE9W01hdGguY2VpbChhYVswXS8yKSxNYXRoLmNlaWwoYWFbMV0vMildO2lmKGFycmF5c0VxdWFsKGhhLGFhKSlyZXR1cm4geGE/YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgaXZlYzIgcGFja2VkVGV4U2hhcGUgPSBpdmVjMihjZWlsKGZsb2F0KG91dFRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQob3V0VGV4U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgICAgcmV0dXJuIDIgKiBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIocGFja2VkVGV4U2hhcGVbMF0sIHBhY2tlZFRleFNoYXBlWzFdKSk7CiAgICAgIH0KICAgIGA6YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgcmV0dXJuIDIgKiBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIoJHtiYVswXX0sICR7YmFbMV19KSk7CiAgICAgIH0KICAgIGA7Y29uc3QgU2E9TWF0aC5jZWlsKGhhWzFdLzIpO3JldHVybiB4YT9gCiAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdChvdXRUZXhTaGFwZVswXSkgLyAyLjApLCBjZWlsKGZsb2F0KG91dFRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gaW50KGNlaWwoZmxvYXQob3V0U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIocGFja2VkVGV4U2hhcGVbMF0sIHBhY2tlZFRleFNoYXBlWzFdKSk7CgogICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogcGFja2VkVGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwogICAgICBpbnQgciA9IDIgKiAoaW5kZXggLyB0ZXhlbHNJbkxvZ2ljYWxSb3cpOwogICAgICBpbnQgYyA9IGltb2QoaW5kZXgsIHRleGVsc0luTG9naWNhbFJvdykgKiAyOwoKICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpOwogICAgfQogIGA6YAogICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YmFbMF19LCAke2JhWzFdfSkpOwoKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YmFbMV19ICsgcmVzVGV4UkMueTsKICAgICAgaW50IHIgPSAyICogKGluZGV4IC8gJHtTYX0pOwogICAgICBpbnQgYyA9IGltb2QoaW5kZXgsICR7U2F9KSAqIDI7CgogICAgICByZXR1cm4gaXZlYzIociwgYyk7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRPdXRwdXQyRENvb3JkcyhoYSxhYSx4YSl7cmV0dXJuIGFycmF5c0VxdWFsKGhhLGFhKT94YT9gCiAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICByZXR1cm4gaXZlYzIocmVzdWx0VVYueXggKiB2ZWMyKG91dFRleFNoYXBlWzBdLCBvdXRUZXhTaGFwZVsxXSkpOwogICAgICB9CiAgICBgOmAKICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIHJldHVybiBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIoJHthYVswXX0sICR7YWFbMV19KSk7CiAgICAgIH0KICAgIGA6aGFbMV09PT0xP3hhP2AKICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkgewogICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihvdXRUZXhTaGFwZVswXSwgb3V0VGV4U2hhcGVbMV0pKTsKICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy54ICogb3V0VGV4U2hhcGVbMV0gKyByZXNUZXhSQy55OwogICAgICAgIHJldHVybiBpdmVjMihpbmRleCwgMCk7CiAgICAgIH0KICAgIGA6YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7YWFbMF19LCAke2FhWzFdfSkpOwogICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CiAgICAgICAgcmV0dXJuIGl2ZWMyKGluZGV4LCAwKTsKICAgICAgfQogICAgYDpoYVswXT09PTE/eGE/YAogICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKG91dFRleFNoYXBlWzBdLCBvdXRUZXhTaGFwZVsxXSkpOwogICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiBvdXRUZXhTaGFwZVsxXSArIHJlc1RleFJDLnk7CiAgICAgICAgcmV0dXJuIGl2ZWMyKDAsIGluZGV4KTsKICAgICAgfQogICAgYDpgCiAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKHJlc3VsdFVWLnl4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHthYVswXX0sICR7YWFbMV19KSk7CiAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqICR7YWFbMV19ICsgcmVzVGV4UkMueTsKICAgICAgICByZXR1cm4gaXZlYzIoMCwgaW5kZXgpOwogICAgICB9CiAgICBgOnhhP2AKICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHsKICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMihvdXRUZXhTaGFwZVswXSwgb3V0VGV4U2hhcGVbMV0pKTsKICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueCAqIG91dFRleFNoYXBlWzFdICsgcmVzVGV4UkMueTsKICAgICAgaW50IHIgPSBpbmRleCAvIG91dFNoYXBlWzFdOwogICAgICBpbnQgYyA9IGluZGV4IC0gciAqIG91dFNoYXBlWzFdOwogICAgICByZXR1cm4gaXZlYzIociwgYyk7CiAgICB9CiAgYDpgCiAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7CiAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHthYVswXX0sICR7YWFbMV19KSk7CiAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnggKiAke2FhWzFdfSArIHJlc1RleFJDLnk7CiAgICAgIGludCByID0gaW5kZXggLyAke2hhWzFdfTsKICAgICAgaW50IGMgPSBpbmRleCAtIHIgKiAke2hhWzFdfTsKICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0RmxhdE9mZnNldFVuaWZvcm1OYW1lKGhhKXtyZXR1cm5gb2Zmc2V0JHtoYX1gfWZ1bmN0aW9uIGdldFBhY2tlZFNhbXBsZXJTY2FsYXIoaGEpe2NvbnN0IGFhPWhhLm5hbWUseGE9ImdldCIrYWEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYWEuc2xpY2UoMSksYmE9Z2V0R2xzbERpZmZlcmVuY2VzKCk7cmV0dXJuYAogICAgdmVjNCAke3hhfSgpIHsKICAgICAgcmV0dXJuICR7YmEudGV4dHVyZTJEfSgke2FhfSwgaGFsZkNSKTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXJTY2FsYXIoaGEsYWEpe2NvbnN0IHhhPWhhLm5hbWUsYmE9ImdldCIreGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSk7aWYoaGEuc2hhcGVJbmZvLmlzVW5pZm9ybSlyZXR1cm5gZmxvYXQgJHtiYX0oKSB7cmV0dXJuICR7eGF9O31gO2NvbnN0W1NhLFRhXT1oYS5zaGFwZUluZm8udGV4U2hhcGU7aWYoU2E9PT0xJiZUYT09PTEpcmV0dXJuYAogICAgICBmbG9hdCAke2JhfSgpIHsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgaGFsZkNSKTsKICAgICAgfQogICAgYDtjb25zdCB3YT1nZXRGbGF0T2Zmc2V0VW5pZm9ybU5hbWUoeGEpO2lmKGFhKXJldHVybmAKICAgIGZsb2F0ICR7YmF9KCkgewogICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3hhfVRleFNoYXBlWzBdLCAke3hhfVRleFNoYXBlWzFdLCAke3dhfSk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICB9CiAgYDtjb25zdFtFYSxrYV09aGEuc2hhcGVJbmZvLnRleFNoYXBlO3JldHVybmAKICAgIGZsb2F0ICR7YmF9KCkgewogICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke0VhfSwgJHtrYX0sICR7d2F9KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFBhY2tlZFNhbXBsZXIxRChoYSxhYSl7Y29uc3QgeGE9aGEubmFtZSxiYT0iZ2V0Iit4YS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSt4YS5zbGljZSgxKSxTYT1oYS5zaGFwZUluZm8udGV4U2hhcGUsVGE9Z2V0R2xzbERpZmZlcmVuY2VzKCk7aWYoYWEpcmV0dXJuYAogICAgdmVjNCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgaXZlYzIgcGFja2VkVGV4U2hhcGUgPSBpdmVjMihjZWlsKGZsb2F0KCR7eGF9VGV4U2hhcGVbMF0pIC8gMi4wKSwgY2VpbChmbG9hdCgke3hhfVRleFNoYXBlWzFdKSAvIDIuMCkpOwogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoCiAgICAgICAgcGFja2VkVGV4U2hhcGVbMF0sIHBhY2tlZFRleFNoYXBlWzFdLCBpbmRleCk7CiAgICAgIHJldHVybiAke1RhLnRleHR1cmUyRH0oJHt4YX0sIHV2KTsKICAgIH0KICBgO2NvbnN0IHdhPVtNYXRoLmNlaWwoU2FbMF0vMiksTWF0aC5jZWlsKFNhWzFdLzIpXTtyZXR1cm5gCiAgICB2ZWM0ICR7YmF9KGludCBpbmRleCkgewogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoCiAgICAgICAgJHt3YVswXX0sICR7d2FbMV19LCBpbmRleCk7CiAgICAgIHJldHVybiAke1RhLnRleHR1cmUyRH0oJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXIxRChoYSxhYSl7Y29uc3QgeGE9aGEubmFtZSxiYT0iZ2V0Iit4YS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSt4YS5zbGljZSgxKTtpZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtiYX0oaW50IGluZGV4KSB7CiAgICAgICAgJHtnZXRVbmlmb3JtU2FtcGxlcihoYSl9CiAgICAgIH0KICAgIGA7Y29uc3QgU2E9aGEuc2hhcGVJbmZvLnRleFNoYXBlLFRhPVNhWzBdLHdhPVNhWzFdO2lmKHdhPT09MSYmVGE9PT0xKXJldHVybmAKICAgICAgZmxvYXQgJHtiYX0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIGhhbGZDUik7CiAgICAgIH0KICAgIGA7Y29uc3QgRWE9Z2V0RmxhdE9mZnNldFVuaWZvcm1OYW1lKHhhKTtyZXR1cm4gd2E9PT0xP2FhP2AKICAgICAgZmxvYXQgJHtiYX0oaW50IGluZGV4KSB7CiAgICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoZmxvYXQoaW5kZXggKyAke0VhfSkgKyAwLjUpIC8gZmxvYXQoJHt4YX1UZXhTaGFwZVswXSkpOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICAgIH0KICAgIGA6YAogICAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChmbG9hdChpbmRleCArICR7RWF9KSArIDAuNSkgLyAke1RhfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgOlRhPT09MT9hYT9gCiAgICAgIGZsb2F0ICR7YmF9KGludCBpbmRleCkgewogICAgICAgIHZlYzIgdXYgPSB2ZWMyKChmbG9hdChpbmRleCArICR7RWF9KSArIDAuNSkgLyBmbG9hdCgke3hhfVRleFNoYXBlWzFdKSwgMC41KTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgZmxvYXQgJHtiYX0oaW50IGluZGV4KSB7CiAgICAgICAgdmVjMiB1diA9IHZlYzIoKGZsb2F0KGluZGV4ICsgJHtFYX0pICsgMC41KSAvICR7d2F9LjAsIDAuNSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgICAgfQogICAgYDphYT9gCiAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt4YX1UZXhTaGFwZVswXSwgJHt4YX1UZXhTaGFwZVsxXSwgaW5kZXggKyAke0VhfSk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICB9CiAgYDpgCiAgICBmbG9hdCAke2JhfShpbnQgaW5kZXgpIHsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtUYX0sICR7d2F9LCBpbmRleCArICR7RWF9KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFBhY2tlZFNhbXBsZXIyRChoYSxhYSl7Y29uc3QgeGE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSxiYT1oYS5uYW1lLFNhPSJnZXQiK2JhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2JhLnNsaWNlKDEpLFRhPWhhLnNoYXBlSW5mby50ZXhTaGFwZSx3YT1UYVswXSxFYT1UYVsxXSxrYT1nZXRHbHNsRGlmZmVyZW5jZXMoKTtpZihUYSE9bnVsbCYmYXJyYXlzRXF1YWwoeGEsVGEpKXJldHVybiBhYT9gCiAgICAgIHZlYzQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke2JhfVRleFNoYXBlWzFdLCAke2JhfVRleFNoYXBlWzBdKTsKCiAgICAgICAgcmV0dXJuICR7a2EudGV4dHVyZTJEfSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgdmVjNCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKGNvbCwgcm93KSArIGhhbGZDUikgLyB2ZWMyKCR7RWF9LjAsICR7d2F9LjApOwoKICAgICAgICByZXR1cm4gJHtrYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA7aWYoYWEpcmV0dXJuYAogICAgdmVjNCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdCgke2JhfVRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQoJHtiYX1UZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaW50IHZhbHVlc1BlclJvdyA9IGludChjZWlsKGZsb2F0KCR7YmF9U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20yRCh2YWx1ZXNQZXJSb3csIHBhY2tlZFRleFNoYXBlWzBdLCBwYWNrZWRUZXhTaGFwZVsxXSwgcm93LCBjb2wpOwogICAgICByZXR1cm4gJHtrYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICB9CiAgYDtjb25zdCBBYT1bTWF0aC5jZWlsKFRhWzBdLzIpLE1hdGguY2VpbChUYVsxXS8yKV0sRmE9TWF0aC5jZWlsKHhhWzFdLzIpO3JldHVybmAKICAgIHZlYzQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMkQoJHtGYX0sICR7QWFbMF19LCAke0FhWzFdfSwgcm93LCBjb2wpOwogICAgICByZXR1cm4gJHtrYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICB9CiAgYH1mdW5jdGlvbiBnZXRTYW1wbGVyMkQoaGEsYWEpe2NvbnN0IHhhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsYmE9aGEubmFtZSxTYT0iZ2V0IitiYS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKStiYS5zbGljZSgxKSxUYT1oYS5zaGFwZUluZm8udGV4U2hhcGU7aWYoVGEhPW51bGwmJmFycmF5c0VxdWFsKHhhLFRhKSl7aWYoYWEpcmV0dXJuYAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKGNvbCwgcm93KSArIGhhbGZDUikgLyB2ZWMyKCR7YmF9VGV4U2hhcGVbMV0sICR7YmF9VGV4U2hhcGVbMF0pOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA7Y29uc3QgZWw9VGFbMF0sdGw9VGFbMV07cmV0dXJuYAogICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICB2ZWMyIHV2ID0gKHZlYzIoY29sLCByb3cpICsgaGFsZkNSKSAvIHZlYzIoJHt0bH0uMCwgJHtlbH0uMCk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICB9CiAgYH1jb25zdHtuZXdTaGFwZTp3YSxrZXB0RGltczpFYX09c3F1ZWV6ZVNoYXBlKHhhKSxrYT13YTtpZihrYS5sZW5ndGg8eGEubGVuZ3RoKXtjb25zdCBlbD1zcXVlZXplSW5wdXRJbmZvKGhhLGthKSx0bD1bInJvdyIsImNvbCJdO3JldHVybmAKICAgICAgJHtnZXRTYW1wbGVyRnJvbUluSW5mbyhlbCxhYSl9CiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wpIHsKICAgICAgICByZXR1cm4gJHtTYX0oJHtnZXRTcXVlZXplZFBhcmFtcyh0bCxFYSl9KTsKICAgICAgfQogICAgYH1pZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgICAgIGludCBpbmRleCA9IHJvdW5kKGRvdCh2ZWMyKHJvdywgY29sKSwgdmVjMigke3hhWzFdfSwgMSkpKTsKICAgICAgICAke2dldFVuaWZvcm1TYW1wbGVyKGhhKX0KICAgICAgfQogICAgYDtjb25zdCBBYT1UYVswXSxGYT1UYVsxXSxMYT1nZXRGbGF0T2Zmc2V0VW5pZm9ybU5hbWUoYmEpO3JldHVybiBGYT09PTE/YWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgZmxvYXQgaW5kZXggPSBkb3QodmVjMyhyb3csIGNvbCwgJHtMYX0pLCB2ZWMzKCR7YmF9U2hhcGVbMV0sIDEsIDEpKTsKICAgICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChpbmRleCArIDAuNSkgLyBmbG9hdCgke2JhfVRleFNoYXBlWzBdKSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDpgCiAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsICR7TGF9KSwgdmVjMygke3hhWzFdfSwgMSwgMSkpOwogICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChpbmRleCArIDAuNSkgLyAke0FhfS4wKTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgIH0KICBgOkFhPT09MT9hYT9gCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wpIHsKICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCAke0xhfSksIHZlYzMoJHtiYX1TaGFwZVsxXSwgMSwgMSkpOwogICAgICAgIHZlYzIgdXYgPSB2ZWMyKChpbmRleCArIDAuNSkgLyBmbG9hdCgke2JhfVRleFNoYXBlWzFdKSwgMC41KTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wpIHsKICAgICAgZmxvYXQgaW5kZXggPSBkb3QodmVjMyhyb3csIGNvbCwgJHtMYX0pLCB2ZWMzKCR7eGFbMV19LCAxLCAxKSk7CiAgICAgIHZlYzIgdXYgPSB2ZWMyKChpbmRleCArIDAuNSkgLyAke0ZhfS4wLCAwLjUpOwogICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgfQogIGA6YWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7YmF9U2hhcGVbMV0gKyBjb2wgKyAke0xhfTsKICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke2JhfVRleFNoYXBlWzBdLCAke2JhfVRleFNoYXBlWzFdLCBpbmRleCk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDpgCiAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCkgewogICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgaW50IGluZGV4ID0gcm93ICogJHt4YVsxXX0gKyBjb2wgKyAke0xhfTsKICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7QWF9LCAke0ZhfSwgaW5kZXgpOwogICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICB9CmB9ZnVuY3Rpb24gZ2V0UGFja2VkU2FtcGxlcjNEKGhhLGFhKXtjb25zdCB4YT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLGJhPWhhLm5hbWUsU2E9ImdldCIrYmEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYmEuc2xpY2UoMSksVGE9aGEuc2hhcGVJbmZvLnRleFNoYXBlLHdhPVtNYXRoLmNlaWwoVGFbMF0vMiksTWF0aC5jZWlsKFRhWzFdLzIpXTtpZih4YVswXT09PTEpe2NvbnN0IGVsPXhhLnNsaWNlKDEpLHRsPVsxLDJdLG5sPXNxdWVlemVJbnB1dEluZm8oaGEsZWwpLHNsPVsiYiIsInJvdyIsImNvbCJdO3JldHVybmAKICAgICAgICAke2dldFBhY2tlZFNhbXBsZXJGcm9tSW5JbmZvKG5sLGFhKX0KICAgICAgICB2ZWM0ICR7U2F9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgICAgICByZXR1cm4gJHtTYX0oJHtnZXRTcXVlZXplZFBhcmFtcyhzbCx0bCl9KTsKICAgICAgICB9CiAgICAgIGB9Y29uc3QgRWE9Z2V0R2xzbERpZmZlcmVuY2VzKCk7aWYoYWEpcmV0dXJuYAogICAgdmVjNCAke1NhfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkgewogICAgICBpdmVjMiBwYWNrZWRUZXhTaGFwZSA9IGl2ZWMyKGNlaWwoZmxvYXQoJHtiYX1UZXhTaGFwZVswXSkgLyAyLjApLCBjZWlsKGZsb2F0KCR7YmF9VGV4U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIGludCB2YWx1ZXNQZXJSb3cgPSBpbnQoY2VpbChmbG9hdCgke2JhfVNoYXBlWzJdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIGludChjZWlsKGZsb2F0KCR7YmF9U2hhcGVbMV0pIC8gMi4wKSk7CiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20zRCgKICAgICAgICBwYWNrZWRUZXhTaGFwZVswXSwgcGFja2VkVGV4U2hhcGVbMV0sIHRleGVsc0luQmF0Y2gsIHZhbHVlc1BlclJvdywgYiwgcm93LCBjb2wpOwogICAgICByZXR1cm4gJHtFYS50ZXh0dXJlMkR9KCR7YmF9LCB1dik7CiAgICB9CiAgYDtjb25zdCBrYT13YVswXSxBYT13YVsxXSxGYT1NYXRoLmNlaWwoeGFbMl0vMiksTGE9RmEqTWF0aC5jZWlsKHhhWzFdLzIpO3JldHVybmAKICAgIHZlYzQgJHtTYX0oaW50IGIsIGludCByb3csIGludCBjb2wpIHsKICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTNEKAogICAgICAgICR7a2F9LCAke0FhfSwgJHtMYX0sICR7RmF9LCBiLCByb3csIGNvbCk7CiAgICAgIHJldHVybiAke0VhLnRleHR1cmUyRH0oJHtiYX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXIzRChoYSxhYSl7Y29uc3QgeGE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSxiYT1oYS5uYW1lLFNhPSJnZXQiK2JhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2JhLnNsaWNlKDEpLFRhPXhhWzFdKnhhWzJdLHdhPXhhWzJdLHtuZXdTaGFwZTpFYSxrZXB0RGltczprYX09c3F1ZWV6ZVNoYXBlKHhhKSxBYT1FYTtpZihBYS5sZW5ndGg8eGEubGVuZ3RoKXtjb25zdCBzbD1zcXVlZXplSW5wdXRJbmZvKGhhLEFhKSxybD1bInJvdyIsImNvbCIsImRlcHRoIl07cmV0dXJuYAogICAgICAgICR7Z2V0U2FtcGxlckZyb21JbkluZm8oc2wsYWEpfQogICAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCkgewogICAgICAgICAgcmV0dXJuICR7U2F9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocmwsa2EpfSk7CiAgICAgICAgfQogICAgICBgfWlmKGhhLnNoYXBlSW5mby5pc1VuaWZvcm0pcmV0dXJuYAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICBpbnQgaW5kZXggPSByb3VuZChkb3QodmVjMyhyb3csIGNvbCwgZGVwdGgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzMoJHtUYX0sICR7d2F9LCAxKSkpOwogICAgICAgICR7Z2V0VW5pZm9ybVNhbXBsZXIoaGEpfQogICAgICB9CiAgICBgO2NvbnN0IEZhPWhhLnNoYXBlSW5mby50ZXhTaGFwZSxMYT1GYVswXSxlbD1GYVsxXSx0bD1oYS5zaGFwZUluZm8uZmxhdE9mZnNldDtpZihlbD09PVRhJiZ0bD09bnVsbClyZXR1cm4gYWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICBpbnQgc3RyaWRlMSA9ICR7YmF9U2hhcGVbMl07CiAgICAgICAgZmxvYXQgdGV4UiA9IGZsb2F0KHJvdyk7CiAgICAgICAgZmxvYXQgdGV4QyA9IGRvdCh2ZWMyKGNvbCwgZGVwdGgpLCB2ZWMyKHN0cmlkZTEsIDEpKTsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgIHZlYzIoJHtiYX1UZXhTaGFwZVsxXSwgJHtiYX1UZXhTaGFwZVswXSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDpgCiAgICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoKSB7CiAgICAgICAgICBmbG9hdCB0ZXhSID0gZmxvYXQocm93KTsKICAgICAgICAgIGZsb2F0IHRleEMgPSBkb3QodmVjMihjb2wsIGRlcHRoKSwgdmVjMigke3dhfSwgMSkpOwogICAgICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvCiAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtlbH0uMCwgJHtMYX0uMCk7CiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICAgIH0KICAgICAgYDtpZihlbD09PXdhJiZ0bD09bnVsbClyZXR1cm4gYWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgICBmbG9hdCB0ZXhSID0gZG90KHZlYzIocm93LCBjb2wpLCB2ZWMyKCR7YmF9U2hhcGVbMV0sIDEpKTsKICAgICAgICBmbG9hdCB0ZXhDID0gZmxvYXQoZGVwdGgpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKCR7YmF9VGV4U2hhcGVbMV0sICR7YmF9VGV4U2hhcGVbMF0pOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA6YAogICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoKSB7CiAgICAgIGZsb2F0IHRleFIgPSBkb3QodmVjMihyb3csIGNvbCksIHZlYzIoJHt4YVsxXX0sIDEpKTsKICAgICAgZmxvYXQgdGV4QyA9IGZsb2F0KGRlcHRoKTsKICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHtlbH0uMCwgJHtMYX0uMCk7CiAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICB9CiAgYDtjb25zdCBubD1nZXRGbGF0T2Zmc2V0VW5pZm9ybU5hbWUoYmEpO3JldHVybiBhYT9gCiAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgpIHsKICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgICBpbnQgc3RyaWRlMCA9ICR7YmF9U2hhcGVbMV0gKiAke2JhfVNoYXBlWzJdOwogICAgICBpbnQgc3RyaWRlMSA9ICR7YmF9U2hhcGVbMl07CiAgICAgIGludCBpbmRleCA9IHJvdyAqIHN0cmlkZTAgKyBjb2wgKiBzdHJpZGUxICsgZGVwdGggKyAke25sfTsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtiYX1UZXhTaGFwZVswXSwgJHtiYX1UZXhTaGFwZVsxXSwgaW5kZXgpOwogICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgfQogICAgYDpgCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCkgewogICAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy4KICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke1RhfSArIGNvbCAqICR7d2F9ICsgZGVwdGggKyAke25sfTsKICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke0xhfSwgJHtlbH0sIGluZGV4KTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgYH1mdW5jdGlvbiBnZXRQYWNrZWRTYW1wbGVyTkQoaGEsYWEpe2NvbnN0IHhhPWhhLm5hbWUsYmE9ImdldCIreGEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkreGEuc2xpY2UoMSksU2E9Z2V0R2xzbERpZmZlcmVuY2VzKCk7aWYoYWEpcmV0dXJuYAogICAgdmVjNCAke2JhfShpbnQgYjIsIGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7CiAgICAgIGludCB2YWx1ZXNQZXJSb3cgPSBpbnQoY2VpbChmbG9hdCgke3hhfVNoYXBlWzNdKSAvIDIuMCkpOwogICAgICBpbnQgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIGludChjZWlsKGZsb2F0KCR7eGF9U2hhcGVbMl0pIC8gMi4wKSk7CiAgICAgIGludCBpbmRleCA9IGIgKiB0ZXhlbHNJbkJhdGNoICsgKHJvdyAvIDIpICogdmFsdWVzUGVyUm93ICsgKGNvbCAvIDIpOwogICAgICB0ZXhlbHNJbkJhdGNoICo9ICR7eGF9U2hhcGVbMV07CiAgICAgIGluZGV4ID0gYjIgKiB0ZXhlbHNJbkJhdGNoICsgaW5kZXg7CiAgICAgIGl2ZWMyIHBhY2tlZFRleFNoYXBlID0gaXZlYzIoY2VpbChmbG9hdCgke3hhfVRleFNoYXBlWzBdKSAvIDIuMCksIGNlaWwoZmxvYXQoJHt4YX1UZXhTaGFwZVsxXSkgLyAyLjApKTsKICAgICAgaW50IHRleFIgPSBpbmRleCAvIHBhY2tlZFRleFNoYXBlWzFdOwogICAgICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqIHBhY2tlZFRleFNoYXBlWzFdOwogICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMihwYWNrZWRUZXhTaGFwZVsxXSwgcGFja2VkVGV4U2hhcGVbMF0pOyByZXR1cm4gJHtTYS50ZXh0dXJlMkR9KCR7eGF9LCB1dik7CiAgICB9CiAgYDtjb25zdCBUYT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLHdhPVRhLmxlbmd0aCxFYT1oYS5zaGFwZUluZm8udGV4U2hhcGUsa2E9W01hdGguY2VpbChFYVswXS8yKSxNYXRoLmNlaWwoRWFbMV0vMildLEFhPWthWzBdLEZhPWthWzFdLExhPU1hdGguY2VpbChUYVt3YS0xXS8yKTtsZXQgZWw9TGEqTWF0aC5jZWlsKFRhW3dhLTJdLzIpLHRsPSJpbnQgYiwgaW50IHJvdywgaW50IGNvbCIsbmw9YGIgKiAke2VsfSArIChyb3cgLyAyKSAqICR7TGF9ICsgKGNvbCAvIDIpYDtmb3IobGV0IHNsPTI7c2w8d2EtMTtzbCsrKXRsPWBpbnQgYiR7c2x9LCBgK3RsLGVsKj1UYVt3YS1zbC0xXSxubD1gYiR7c2x9ICogJHtlbH0gKyBgK25sO3JldHVybmAKICAgIHZlYzQgJHtiYX0oJHt0bH0pIHsKICAgICAgaW50IGluZGV4ID0gJHtubH07CiAgICAgIGludCB0ZXhSID0gaW5kZXggLyAke0ZhfTsKICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiAke0ZhfTsKICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHtGYX0sICR7QWF9KTsKICAgICAgcmV0dXJuICR7U2EudGV4dHVyZTJEfSgke3hhfSwgdXYpOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0U2FtcGxlcjREKGhhLGFhKXtjb25zdCB4YT1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLGJhPWhhLm5hbWUsU2E9ImdldCIrYmEuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYmEuc2xpY2UoMSksVGE9eGFbM10sd2E9eGFbMl0qVGEsRWE9eGFbMV0qd2Ese25ld1NoYXBlOmthLGtlcHREaW1zOkFhfT1zcXVlZXplU2hhcGUoeGEpO2lmKGthLmxlbmd0aDx4YS5sZW5ndGgpe2NvbnN0IGFsPXNxdWVlemVJbnB1dEluZm8oaGEsa2EpLGxsPVsicm93IiwiY29sIiwiZGVwdGgiLCJkZXB0aDIiXTtyZXR1cm5gCiAgICAgICR7Z2V0U2FtcGxlckZyb21JbkluZm8oYWwsYWEpfQogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHsKICAgICAgICByZXR1cm4gJHtTYX0oJHtnZXRTcXVlZXplZFBhcmFtcyhsbCxBYSl9KTsKICAgICAgfQogICAgYH1pZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7CiAgICAgICAgaW50IGluZGV4ID0gcm91bmQoZG90KHZlYzQocm93LCBjb2wsIGRlcHRoLCBkZXB0aDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQoJHtFYX0sICR7d2F9LCAke1RhfSwgMSkpKTsKICAgICAgICAke2dldFVuaWZvcm1TYW1wbGVyKGhhKX0KICAgICAgfQogICAgYDtjb25zdCBGYT1oYS5zaGFwZUluZm8uZmxhdE9mZnNldCxMYT1oYS5zaGFwZUluZm8udGV4U2hhcGUsZWw9TGFbMF0sdGw9TGFbMV0sbmw9YGludCBzdHJpZGUyID0gJHtiYX1TaGFwZVszXTtgLHNsPWBpbnQgc3RyaWRlMSA9ICR7YmF9U2hhcGVbMl0gKiBzdHJpZGUyO2Ascmw9YGludCBzdHJpZGUwID0gJHtiYX1TaGFwZVsxXSAqIHN0cmlkZTE7YDtpZih0bD09PUVhJiZGYT09bnVsbClyZXR1cm4gYWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHsKICAgICAgICAke25sfQogICAgICAgICR7c2x9CiAgICAgICAgZmxvYXQgdGV4UiA9IGZsb2F0KHJvdyk7CiAgICAgICAgZmxvYXQgdGV4QyA9CiAgICAgICAgICAgIGRvdCh2ZWMzKGNvbCwgZGVwdGgsIGRlcHRoMiksCiAgICAgICAgICAgICAgICB2ZWMzKHN0cmlkZTEsIHN0cmlkZTIsIDEpKTsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgIHZlYzIoJHtiYX1UZXhTaGFwZVsxXSwgJHtiYX1UZXhTaGFwZVswXSk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDpgCiAgICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikgewogICAgICAgIGZsb2F0IHRleFIgPSBmbG9hdChyb3cpOwogICAgICAgIGZsb2F0IHRleEMgPQogICAgICAgICAgICBkb3QodmVjMyhjb2wsIGRlcHRoLCBkZXB0aDIpLAogICAgICAgICAgICAgICAgdmVjMygke3dhfSwgJHtUYX0sIDEpKTsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0bH0uMCwgJHtlbH0uMCk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgICAgfQogICAgYDtpZih0bD09PVRhJiZGYT09bnVsbClyZXR1cm4gYWE/YAogICAgICBmbG9hdCAke1NhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHsKICAgICAgICBmbG9hdCB0ZXhSID0gZG90KHZlYzMocm93LCBjb2wsIGRlcHRoKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzMoJHtiYX1TaGFwZVsxXSAqICR7YmF9U2hhcGVbMl0sICR7YmF9U2hhcGVbMl0sIDEpKTsKICAgICAgICBmbG9hdCB0ZXhDID0gZmxvYXQoZGVwdGgyKTsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgdmVjMigke2JhfVRleFNoYXBlWzFdLCAke2JhfVRleFNoYXBlWzBdKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke2JhfSwgdXYpOwogICAgICB9CiAgICBgOmAKICAgICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7CiAgICAgICAgZmxvYXQgdGV4UiA9IGRvdCh2ZWMzKHJvdywgY29sLCBkZXB0aCksCiAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMzKCR7eGFbMV0qeGFbMl19LCAke3hhWzJdfSwgMSkpOwogICAgICAgIGZsb2F0IHRleEMgPSBmbG9hdChkZXB0aDIpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICB2ZWMyKCR7dGx9LjAsICR7ZWx9LjApOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7YmF9LCB1dik7CiAgICAgIH0KICAgIGA7Y29uc3Qgb2w9Z2V0RmxhdE9mZnNldFVuaWZvcm1OYW1lKGJhKTtyZXR1cm4gYWE/YAogICAgZmxvYXQgJHtTYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7CiAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy4KICAgICAgJHtubH0KICAgICAgJHtzbH0KICAgICAgJHtybH0KICAgICAgaW50IGluZGV4ID0gcm93ICogc3RyaWRlMCArIGNvbCAqIHN0cmlkZTEgKwogICAgICAgICAgZGVwdGggKiBzdHJpZGUyICsgZGVwdGgyOwogICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke2JhfVRleFNoYXBlWzBdLCAke2JhfVRleFNoYXBlWzFdLCBpbmRleCArICR7b2x9KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgIH0KICBgOmAKICAgIGZsb2F0ICR7U2F9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikgewogICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuCiAgICAgIGludCBpbmRleCA9IHJvdyAqICR7RWF9ICsgY29sICogJHt3YX0gKwogICAgICAgICAgZGVwdGggKiAke1RhfSArIGRlcHRoMjsKICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHtlbH0sICR7dGx9LCBpbmRleCArICR7b2x9KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtiYX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXI1RChoYSl7Y29uc3QgYWE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSx4YT1oYS5uYW1lLGJhPSJnZXQiK3hhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpLFNhPWFhWzRdLFRhPWFhWzNdKlNhLHdhPWFhWzJdKlRhLEVhPWFhWzFdKndhLHtuZXdTaGFwZTprYSxrZXB0RGltczpBYX09c3F1ZWV6ZVNoYXBlKGFhKTtpZihrYS5sZW5ndGg8YWEubGVuZ3RoKXtjb25zdCBzbD1zcXVlZXplSW5wdXRJbmZvKGhhLGthKSxybD1bInJvdyIsImNvbCIsImRlcHRoIiwiZGVwdGgyIiwiZGVwdGgzIl07cmV0dXJuYAogICAgICAke2dldFNhbXBsZXJGcm9tSW5JbmZvKHNsKX0KICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7CiAgICAgICAgcmV0dXJuICR7YmF9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocmwsQWEpfSk7CiAgICAgIH0KICAgIGB9aWYoaGEuc2hhcGVJbmZvLmlzVW5pZm9ybSlyZXR1cm5gCiAgICAgIGZsb2F0ICR7YmF9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykgewogICAgICAgIGZsb2F0IGluZGV4ID0gZG90KAogICAgICAgICAgdmVjNChyb3csIGNvbCwgZGVwdGgsIGRlcHRoMiksCiAgICAgICAgICB2ZWM0KCR7RWF9LCAke3dhfSwgJHtUYX0sICR7U2F9KSkgKwogICAgICAgICAgZGVwdGgzOwogICAgICAgICR7Z2V0VW5pZm9ybVNhbXBsZXIoaGEpfQogICAgICB9CiAgICBgO2NvbnN0IEZhPWhhLnNoYXBlSW5mby5mbGF0T2Zmc2V0LExhPWhhLnNoYXBlSW5mby50ZXhTaGFwZSxlbD1MYVswXSx0bD1MYVsxXTtpZih0bD09PUVhJiZGYT09bnVsbClyZXR1cm5gCiAgICAgIGZsb2F0ICR7YmF9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykgewogICAgICAgIGludCB0ZXhSID0gcm93OwogICAgICAgIGZsb2F0IHRleEMgPSBkb3QodmVjNChjb2wsIGRlcHRoLCBkZXB0aDIsIGRlcHRoMyksCiAgICAgICAgICAgICAgICAgICAgICAgICB2ZWM0KCR7d2F9LCAke1RhfSwgJHtTYX0sIDEpKTsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0bH0uMCwgJHtlbH0uMCk7CiAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgICAgfQogICAgYDtpZih0bD09PVNhJiZGYT09bnVsbClyZXR1cm5gCiAgICAgIGZsb2F0ICR7YmF9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykgewogICAgICAgIGZsb2F0IHRleFIgPSBkb3QoCiAgICAgICAgICB2ZWM0KHJvdywgY29sLCBkZXB0aCwgZGVwdGgyKSwKICAgICAgICAgIHZlYzQoJHthYVsxXSphYVsyXSphYVszXX0sCiAgICAgICAgICAgICAgICR7YWFbMl0qYWFbM119LCAke2FhWzNdfSwgMSkpOwogICAgICAgIGludCB0ZXhDID0gZGVwdGgzOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICB2ZWMyKCR7dGx9LjAsICR7ZWx9LjApOwogICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7eGF9LCB1dik7CiAgICAgIH0KICAgIGA7Y29uc3Qgbmw9Z2V0RmxhdE9mZnNldFVuaWZvcm1OYW1lKHhhKTtyZXR1cm5gCiAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHsKICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLgogICAgICBpbnQgaW5kZXggPSByb3cgKiAke0VhfSArIGNvbCAqICR7d2F9ICsgZGVwdGggKiAke1RhfSArCiAgICAgICAgICBkZXB0aDIgKiAke1NhfSArIGRlcHRoMyArICR7bmx9OwogICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke2VsfSwgJHt0bH0sIGluZGV4KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFNhbXBsZXI2RChoYSl7Y29uc3QgYWE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSx4YT1oYS5uYW1lLGJhPSJnZXQiK3hhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpLHtuZXdTaGFwZTpTYSxrZXB0RGltczpUYX09c3F1ZWV6ZVNoYXBlKGFhKTtpZihTYS5sZW5ndGg8YWEubGVuZ3RoKXtjb25zdCBybD1zcXVlZXplSW5wdXRJbmZvKGhhLFNhKSxvbD1bInJvdyIsImNvbCIsImRlcHRoIiwiZGVwdGgyIiwiZGVwdGgzIiwiZGVwdGg0Il07cmV0dXJuYAogICAgICAke2dldFNhbXBsZXJGcm9tSW5JbmZvKHJsKX0KICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLAogICAgICAgICAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHsKICAgICAgICByZXR1cm4gJHtiYX0oJHtnZXRTcXVlZXplZFBhcmFtcyhvbCxUYSl9KTsKICAgICAgfQogICAgYH1jb25zdCB3YT1hYVs1XSxFYT1hYVs0XSp3YSxrYT1hYVszXSpFYSxBYT1hYVsyXSprYSxGYT1hYVsxXSpBYTtpZihoYS5zaGFwZUluZm8uaXNVbmlmb3JtKXJldHVybmAKICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLAogICAgICAgICAgICAgICAgICBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzLCBpbnQgZGVwdGg0KSB7CiAgICAgICAgaW50IGluZGV4ID0gcm91bmQoZG90KAogICAgICAgICAgdmVjNChyb3csIGNvbCwgZGVwdGgsIGRlcHRoMiksCiAgICAgICAgICB2ZWM0KCR7RmF9LCAke0FhfSwgJHtrYX0sICR7RWF9KSkgKwogICAgICAgICAgZG90KAogICAgICAgICAgICB2ZWMyKGRlcHRoMywgZGVwdGg0KSwKICAgICAgICAgICAgdmVjMigke3dhfSwgMSkpKTsKICAgICAgICAke2dldFVuaWZvcm1TYW1wbGVyKGhhKX0KICAgICAgfQogICAgYDtjb25zdCBMYT1oYS5zaGFwZUluZm8uZmxhdE9mZnNldCxlbD1oYS5zaGFwZUluZm8udGV4U2hhcGUsdGw9ZWxbMF0sbmw9ZWxbMV07aWYobmw9PT1GYSYmTGE9PW51bGwpcmV0dXJuYAogICAgICBmbG9hdCAke2JhfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsCiAgICAgICAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkgewogICAgICAgIGludCB0ZXhSID0gcm93OwogICAgICAgIGZsb2F0IHRleEMgPSBkb3QodmVjNChjb2wsIGRlcHRoLCBkZXB0aDIsIGRlcHRoMyksCiAgICAgICAgICB2ZWM0KCR7QWF9LCAke2thfSwgJHtFYX0sICR7d2F9KSkgKwogICAgICAgICAgICAgICBmbG9hdChkZXB0aDQpOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgdmVjMigke25sfS4wLCAke3RsfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgO2lmKG5sPT09d2EmJkxhPT1udWxsKXJldHVybmAKICAgICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLAogICAgICAgICAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHsKICAgICAgICBmbG9hdCB0ZXhSID0gZG90KHZlYzQocm93LCBjb2wsIGRlcHRoLCBkZXB0aDIpLAogICAgICAgICAgdmVjNCgke2FhWzFdKmFhWzJdKmFhWzNdKmFhWzRdfSwKICAgICAgICAgICAgICAgJHthYVsyXSphYVszXSphYVs0XX0sCiAgICAgICAgICAgICAgICR7YWFbM10qYWFbNF19LAogICAgICAgICAgICAgICAke2FhWzRdfSkpICsgZmxvYXQoZGVwdGgzKTsKICAgICAgICBpbnQgdGV4QyA9IGRlcHRoNDsKICAgICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8KICAgICAgICAgICAgICAgICAgdmVjMigke25sfS4wLCAke3RsfS4wKTsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgdXYpOwogICAgICB9CiAgICBgO2NvbnN0IHNsPWdldEZsYXRPZmZzZXRVbmlmb3JtTmFtZSh4YSk7cmV0dXJuYAogICAgZmxvYXQgJHtiYX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLAogICAgICAgICAgICAgICAgICBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzLCBpbnQgZGVwdGg0KSB7CiAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy4KICAgICAgaW50IGluZGV4ID0gcm93ICogJHtGYX0gKyBjb2wgKiAke0FhfSArIGRlcHRoICogJHtrYX0gKwogICAgICAgICAgZGVwdGgyICogJHtFYX0gKyBkZXB0aDMgKiAke3dhfSArIGRlcHRoNCArICR7c2x9OwogICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RsfSwgJHtubH0sIGluZGV4KTsKICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHt4YX0sIHV2KTsKICAgIH0KICBgfWZ1bmN0aW9uIGdldFVuaWZvcm1TYW1wbGVyKGhhKXtjb25zdCBhYT1oYS5uYW1lLHhhPXNpemVGcm9tU2hhcGUoaGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZSk7cmV0dXJuIHhhPDI/YHJldHVybiAke2FhfTtgOmAKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHt4YX07IGkrKykgewogICAgICBpZiAoaSA9PSBpbmRleCkgewogICAgICAgIHJldHVybiAke2FhfVtpXTsKICAgICAgfQogICAgfQogIGB9ZnVuY3Rpb24gZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKGhhLGFhKXtjb25zdCB4YT1oYS5uYW1lLGJhPXhhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpLFNhPSJnZXQiK2JhKyJBdE91dENvb3JkcyIsVGE9aGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZS5sZW5ndGgsd2E9YWEubG9naWNhbFNoYXBlLmxlbmd0aCxFYT1nZXRCcm9hZGNhc3REaW1zKGhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsYWEubG9naWNhbFNoYXBlKSxrYT1nZXRDb29yZHNEYXRhVHlwZSh3YSksQWE9d2EtVGE7bGV0IEZhO2NvbnN0IExhPVsieCIsInkiLCJ6IiwidyIsInUiLCJ2Il07VGE9PT0wP0ZhPSIiOndhPDImJkVhLmxlbmd0aD49MT9GYT0iY29vcmRzID0gMDsiOkZhPUVhLm1hcChhbD0+YGNvb3Jkcy4ke0xhW2FsK0FhXX0gPSAwO2ApLmpvaW4oYApgKTtsZXQgZWw9IiI7d2E8MiYmVGE+MD9lbD0iY29vcmRzIjplbD1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLm1hcCgoYWwsbGwpPT5gY29vcmRzLiR7TGFbbGwrQWFdfWApLmpvaW4oIiwgIik7bGV0IHRsPSJyZXR1cm4gb3V0cHV0VmFsdWU7Ijtjb25zdCBzbD1zaXplRnJvbVNoYXBlKGhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUpPT09MSxvbD1zaXplRnJvbVNoYXBlKGFhLmxvZ2ljYWxTaGFwZSk9PT0xO2lmKFRhPT09MSYmIXNsJiYhb2wpdGw9YAogICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54eSwgb3V0cHV0VmFsdWUueHkpOwogICAgYDtlbHNlIGlmKHNsJiYhb2wpd2E9PT0xP3RsPWAKICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS54LCAwLiwgMC4pOwogICAgICBgOnRsPWAKICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54KTsKICAgICAgYDtlbHNlIGlmKEVhLmxlbmd0aCl7Y29uc3QgYWw9VGEtMixsbD1UYS0xO0VhLmluZGV4T2YoYWwpPi0xJiZFYS5pbmRleE9mKGxsKT4tMT90bD0icmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7IjpFYS5pbmRleE9mKGFsKT4tMT90bD0icmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSwgb3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSk7IjpFYS5pbmRleE9mKGxsKT4tMSYmKHRsPSJyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54eCwgb3V0cHV0VmFsdWUuenopOyIpfXJldHVybmAKICAgIHZlYzQgJHtTYX0oKSB7CiAgICAgICR7a2F9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAke0ZhfQogICAgICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0JHtiYX0oJHtlbH0pOwogICAgICAke3RsfQogICAgfQogIGB9ZnVuY3Rpb24gZ2V0U2FtcGxlckF0T3V0cHV0Q29vcmRzKGhhLGFhKXtjb25zdCB4YT1oYS5uYW1lLGJhPXhhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK3hhLnNsaWNlKDEpLFNhPSJnZXQiK2JhKyJBdE91dENvb3JkcyIsVGE9YWEudGV4U2hhcGUsd2E9aGEuc2hhcGVJbmZvLnRleFNoYXBlLEVhPWhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUubGVuZ3RoLGthPWFhLmxvZ2ljYWxTaGFwZS5sZW5ndGg7aWYoIWhhLnNoYXBlSW5mby5pc1VuaWZvcm0mJkVhPT09a2EmJmhhLnNoYXBlSW5mby5mbGF0T2Zmc2V0PT1udWxsJiZhcnJheXNFcXVhbCh3YSxUYSkpcmV0dXJuYAogICAgICBmbG9hdCAke1NhfSgpIHsKICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke3hhfSwgcmVzdWx0VVYpOwogICAgICB9CiAgICBgO2NvbnN0IEFhPWdldENvb3Jkc0RhdGFUeXBlKGthKSxGYT1nZXRCcm9hZGNhc3REaW1zKGhhLnNoYXBlSW5mby5sb2dpY2FsU2hhcGUsYWEubG9naWNhbFNoYXBlKSxMYT1rYS1FYTtsZXQgZWw7Y29uc3QgdGw9WyJ4IiwieSIsInoiLCJ3IiwidSIsInYiXTtFYT09PTA/ZWw9IiI6a2E8MiYmRmEubGVuZ3RoPj0xP2VsPSJjb29yZHMgPSAwOyI6ZWw9RmEubWFwKHNsPT5gY29vcmRzLiR7dGxbc2wrTGFdfSA9IDA7YCkuam9pbihgCmApO2xldCBubD0iIjtyZXR1cm4ga2E8MiYmRWE+MD9ubD0iY29vcmRzIjpubD1oYS5zaGFwZUluZm8ubG9naWNhbFNoYXBlLm1hcCgoc2wscmwpPT5gY29vcmRzLiR7dGxbcmwrTGFdfWApLmpvaW4oIiwgIiksYAogICAgZmxvYXQgJHtTYX0oKSB7CiAgICAgICR7QWF9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAke2VsfQogICAgICByZXR1cm4gZ2V0JHtiYX0oJHtubH0pOwogICAgfQogIGB9ZnVuY3Rpb24gZ2V0Q29vcmRzRGF0YVR5cGUoaGEpe2lmKGhhPD0xKXJldHVybiJpbnQiO2lmKGhhPT09MilyZXR1cm4iaXZlYzIiO2lmKGhhPT09MylyZXR1cm4iaXZlYzMiO2lmKGhhPT09NClyZXR1cm4iaXZlYzQiO2lmKGhhPT09NSlyZXR1cm4iaXZlYzUiO2lmKGhhPT09NilyZXR1cm4iaXZlYzYiO3Rocm93IEVycm9yKGBHUFUgZm9yIHJhbmsgJHtoYX0gaXMgbm90IHlldCBzdXBwb3J0ZWRgKX1mdW5jdGlvbiBnZXRVbmlmb3JtSW5mb0Zyb21TaGFwZShoYSxhYSx4YSl7Y29uc3R7bmV3U2hhcGU6YmEsa2VwdERpbXM6U2F9PXNxdWVlemVTaGFwZShhYSksVGE9YWEubGVuZ3RoLHdhPWhhJiZUYT09PTMmJmFhWzBdPT09MSxFYT13YT9hYS5zbGljZSgxKTpiYSxrYT0haGEmJlRhPjEmJiFhcnJheXNFcXVhbChhYSx4YSkmJmJhLmxlbmd0aDxUYXx8d2E7cmV0dXJue3VzZVNxdWVlemVTaGFwZTprYSx1bmlmb3JtU2hhcGU6a2E/RWE6YWEsa2VwdERpbXM6U2F9fWZ1bmN0aW9uIHNxdWVlemVJbnB1dEluZm8oaGEsYWEpe2NvbnN0IHhhPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaGEpKTtyZXR1cm4geGEuc2hhcGVJbmZvLmxvZ2ljYWxTaGFwZT1hYSx4YX1mdW5jdGlvbiBnZXRTcXVlZXplZFBhcmFtcyhoYSxhYSl7cmV0dXJuIGFhLm1hcCh4YT0+aGFbeGFdKS5qb2luKCIsICIpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbXBpbGVQcm9ncmFtKGhhLGFhLHhhLGJhKXtjb25zdCBTYT14YS5tYXAoKEZhLExhKT0+e2NvbnN0IGVsPXtsb2dpY2FsU2hhcGU6RmEuc2hhcGUsdGV4U2hhcGU6RmEuaXNVbmlmb3JtP251bGw6RmEudGV4RGF0YS50ZXhTaGFwZSxpc1VuaWZvcm06RmEuaXNVbmlmb3JtLGlzUGFja2VkOkZhLmlzVW5pZm9ybT8hMTpGYS50ZXhEYXRhLmlzUGFja2VkLGZsYXRPZmZzZXQ6bnVsbH07cmV0dXJuIEZhLnRleERhdGEhPW51bGwmJkZhLnRleERhdGEuc2xpY2UhPW51bGwmJkZhLnRleERhdGEuc2xpY2UuZmxhdE9mZnNldD4wJiYoZWwuZmxhdE9mZnNldD1GYS50ZXhEYXRhLnNsaWNlLmZsYXRPZmZzZXQpLHtuYW1lOmFhLnZhcmlhYmxlTmFtZXNbTGFdLHNoYXBlSW5mbzplbH19KSxUYT1TYS5tYXAoRmE9PkZhLnNoYXBlSW5mbyksd2E9e2xvZ2ljYWxTaGFwZTpiYS5zaGFwZSx0ZXhTaGFwZTpiYS50ZXhEYXRhLnRleFNoYXBlLGlzVW5pZm9ybTohMSxpc1BhY2tlZDpiYS50ZXhEYXRhLmlzUGFja2VkLGZsYXRPZmZzZXQ6bnVsbH0sRWE9bWFrZVNoYWRlcihTYSx3YSxhYSksa2E9Y3JlYXRlRnJhZ21lbnRTaGFkZXIoaGEuZ2wsRWEpLEFhPWhhLmNyZWF0ZVByb2dyYW0oa2EpO3JldHVybiBlbnYoKS5nZXQoIkVOR0lORV9DT01QSUxFX09OTFkiKT97cHJvZ3JhbTphYSxmcmFnbWVudFNoYWRlcjprYSxzb3VyY2U6RWEsd2ViR0xQcm9ncmFtOkFhLGluU2hhcGVJbmZvczpUYSxvdXRTaGFwZUluZm86d2EsdmFyaWFibGVzTG9jYXRpb25zOm51bGwsY3VzdG9tVW5pZm9ybUxvY2F0aW9uczpudWxsLGluZkxvYzpudWxsLG5hbkxvYzpudWxsLG91dFNoYXBlTG9jYXRpb246bnVsbCxvdXRTaGFwZVN0cmlkZXNMb2NhdGlvbjpudWxsLG91dFRleFNoYXBlTG9jYXRpb246bnVsbH06KGhhLmJ1aWxkVmFvKEFhKSxPYmplY3QuYXNzaWduKHtwcm9ncmFtOmFhLGZyYWdtZW50U2hhZGVyOmthLHNvdXJjZTpFYSx3ZWJHTFByb2dyYW06QWEsaW5TaGFwZUluZm9zOlRhLG91dFNoYXBlSW5mbzp3YX0sZ2V0VW5pZm9ybUxvY2F0aW9ucyhoYSxhYSxBYSkpKX1mdW5jdGlvbiBnZXRVbmlmb3JtTG9jYXRpb25zKGhhLGFhLHhhKXtjb25zdCBiYT1bXSxTYT1bXTtsZXQgVGEsd2EsRWEsa2E9bnVsbCxBYT1udWxsO0FhPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSwiTkFOIiwhMSksZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0xJiYoa2E9aGEuZ2V0VW5pZm9ybUxvY2F0aW9uKHhhLCJJTkZJTklUWSIsITEpKTtjb25zdCBGYT0hMTtmb3IoY29uc3QgTGEgb2YgYWEudmFyaWFibGVOYW1lcyl7Y29uc3QgZWw9e25hbWU6TGEsdW5pZm9ybTpoYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsTGEsRmEpLG9mZnNldDpoYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsYG9mZnNldCR7TGF9YCxGYSl9O2FhLmVuYWJsZVNoYXBlVW5pZm9ybXMmJihlbC5zaGFwZT1oYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsYCR7TGF9U2hhcGVgLEZhKSxlbC50ZXhTaGFwZT1oYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsYCR7TGF9VGV4U2hhcGVgLEZhKSksYmEucHVzaChlbCl9aWYoYWEuZW5hYmxlU2hhcGVVbmlmb3JtcyYmKFRhPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSwib3V0U2hhcGUiLEZhKSxFYT1oYS5nZXRVbmlmb3JtTG9jYXRpb24oeGEsIm91dFNoYXBlU3RyaWRlcyIsRmEpLHdhPWhhLmdldFVuaWZvcm1Mb2NhdGlvbih4YSwib3V0VGV4U2hhcGUiLEZhKSksYWEuY3VzdG9tVW5pZm9ybXMpZm9yKGNvbnN0IExhIG9mIGFhLmN1c3RvbVVuaWZvcm1zKVNhLnB1c2goaGEuZ2V0VW5pZm9ybUxvY2F0aW9uKHhhLExhLm5hbWUsRmEpKTtyZXR1cm57dmFyaWFibGVzTG9jYXRpb25zOmJhLGN1c3RvbVVuaWZvcm1Mb2NhdGlvbnM6U2EsaW5mTG9jOmthLG5hbkxvYzpBYSxvdXRTaGFwZUxvY2F0aW9uOlRhLG91dFNoYXBlU3RyaWRlc0xvY2F0aW9uOkVhLG91dFRleFNoYXBlTG9jYXRpb246d2F9fWZ1bmN0aW9uIHZhbGlkYXRlQmluYXJ5QW5kUHJvZ3JhbShoYSxhYSl7aWYoaGEubGVuZ3RoIT09YWEubGVuZ3RoKXRocm93IEVycm9yKGBCaW5hcnkgd2FzIGNvbXBpbGVkIHdpdGggJHtoYS5sZW5ndGh9IGlucHV0cywgYnV0IHdhcyBleGVjdXRlZCB3aXRoICR7YWEubGVuZ3RofSBpbnB1dHNgKTtoYS5mb3JFYWNoKCh4YSxiYSk9Pntjb25zdCBTYT14YS5sb2dpY2FsU2hhcGUsVGE9YWFbYmFdLHdhPVRhLnNoYXBlO2lmKCFhcnJheXNFcXVhbChTYSx3YSkpdGhyb3cgRXJyb3IoYEJpbmFyeSB3YXMgY29tcGlsZWQgd2l0aCBkaWZmZXJlbnQgc2hhcGVzIHRoYW4gdGhlIGN1cnJlbnQgYXJncy4gU2hhcGVzICR7U2F9IGFuZCAke3dhfSBtdXN0IG1hdGNoYCk7aWYoeGEuaXNVbmlmb3JtJiZUYS5pc1VuaWZvcm0pcmV0dXJuO2NvbnN0IEVhPXhhLnRleFNoYXBlLGthPVRhLmlzVW5pZm9ybT9udWxsOlRhLnRleERhdGEudGV4U2hhcGU7aWYoIWFycmF5c0VxdWFsKEVhLGthKSl0aHJvdyBFcnJvcihgQmluYXJ5IHdhcyBjb21waWxlZCB3aXRoIGRpZmZlcmVudCB0ZXh0dXJlIHNoYXBlcyB0aGFuIHRoZSBjdXJyZW50IGFyZ3MuIFNoYXBlICR7RWF9IGFuZCAke2thfSBtdXN0IG1hdGNoYCl9KX1mdW5jdGlvbiBydW5Qcm9ncmFtKGhhLGFhLHhhLGJhLFNhKXthYS5wcm9ncmFtLmVuYWJsZVNoYXBlVW5pZm9ybXN8fCh2YWxpZGF0ZUJpbmFyeUFuZFByb2dyYW0oYWEuaW5TaGFwZUluZm9zLHhhKSx2YWxpZGF0ZUJpbmFyeUFuZFByb2dyYW0oW2FhLm91dFNoYXBlSW5mb10sW2JhXSkpO2NvbnN0IFRhPWJhLnRleERhdGEudGV4dHVyZSx3YT1iYS50ZXhEYXRhLnRleFNoYXBlO2JhLnRleERhdGEuaXNQYWNrZWQ/aGEuc2V0T3V0cHV0UGFja2VkTWF0cml4VGV4dHVyZShUYS50ZXh0dXJlLHdhWzBdLHdhWzFdKTpoYS5zZXRPdXRwdXRNYXRyaXhUZXh0dXJlKFRhLnRleHR1cmUsd2FbMF0sd2FbMV0pLGhhLnNldFByb2dyYW0oYWEud2ViR0xQcm9ncmFtKSxoYS5iaW5kVmVydGV4QXJyYXkoYWEud2ViR0xQcm9ncmFtLnZhbyksZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0xJiZhYS5pbmZMb2MhPT1udWxsJiZoYS5nbC51bmlmb3JtMWYoYWEuaW5mTG9jLDEvMCksYWEubmFuTG9jIT09bnVsbCYmaGEuZ2wudW5pZm9ybTFmKGFhLm5hbkxvYyxOYU4pO2ZvcihsZXQga2E9MDtrYTx4YS5sZW5ndGg7KytrYSl7Y29uc3QgQWE9eGFba2FdLHt1bmlmb3JtOkZhLG9mZnNldDpMYSxzaGFwZTplbCx0ZXhTaGFwZTp0bH09YWEudmFyaWFibGVzTG9jYXRpb25zW2thXTtpZihlbCl7Y29uc3R7dW5pZm9ybVNoYXBlOm5sfT1nZXRVbmlmb3JtSW5mb0Zyb21TaGFwZShhYS5wcm9ncmFtLnBhY2tlZElucHV0cyxBYS5zaGFwZSxBYS50ZXhEYXRhLnRleFNoYXBlKTtzd2l0Y2gobmwubGVuZ3RoKXtjYXNlIDE6aGEuZ2wudW5pZm9ybTFpdihlbCxuZXcgSW50MzJBcnJheShubCkpO2JyZWFrO2Nhc2UgMjpoYS5nbC51bmlmb3JtMml2KGVsLG5ldyBJbnQzMkFycmF5KG5sKSk7YnJlYWs7Y2FzZSAzOmhhLmdsLnVuaWZvcm0zaXYoZWwsbmV3IEludDMyQXJyYXkobmwpKTticmVhaztjYXNlIDQ6aGEuZ2wudW5pZm9ybTRpdihlbCxuZXcgSW50MzJBcnJheShubCkpO2JyZWFrfX1pZih0bCYmaGEuZ2wudW5pZm9ybTJpKHRsLEFhLnRleERhdGEudGV4U2hhcGVbMF0sQWEudGV4RGF0YS50ZXhTaGFwZVsxXSksRmEhPW51bGwpe2lmKEFhLmlzVW5pZm9ybSl7aWYoc2l6ZUZyb21TaGFwZShBYS5zaGFwZSk8MiloYS5nbC51bmlmb3JtMWYoRmEsQWEudW5pZm9ybVZhbHVlc1swXSk7ZWxzZXtsZXQgbmw9QWEudW5pZm9ybVZhbHVlcztubCBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheXx8KG5sPW5ldyBGbG9hdDMyQXJyYXkobmwpKSxoYS5nbC51bmlmb3JtMWZ2KEZhLG5sKX1jb250aW51ZX1BYS50ZXhEYXRhLnNsaWNlIT1udWxsJiZMYSE9bnVsbCYmaGEuZ2wudW5pZm9ybTFpKExhLEFhLnRleERhdGEuc2xpY2UuZmxhdE9mZnNldCksaGEuc2V0SW5wdXRNYXRyaXhUZXh0dXJlKEFhLnRleERhdGEudGV4dHVyZS50ZXh0dXJlLEZhLGthKX19Y29uc3QgRWE9YWEub3V0U2hhcGVMb2NhdGlvbjtpZihFYSlzd2l0Y2goYmEuc2hhcGUubGVuZ3RoKXtjYXNlIDE6aGEuZ2wudW5pZm9ybTFpdihFYSxuZXcgSW50MzJBcnJheShiYS5zaGFwZSkpO2JyZWFrO2Nhc2UgMjpoYS5nbC51bmlmb3JtMml2KEVhLG5ldyBJbnQzMkFycmF5KGJhLnNoYXBlKSk7YnJlYWs7Y2FzZSAzOmhhLmdsLnVuaWZvcm0zaXYoRWEsbmV3IEludDMyQXJyYXkoYmEuc2hhcGUpKTticmVhaztjYXNlIDQ6aGEuZ2wudW5pZm9ybTRpdihFYSxuZXcgSW50MzJBcnJheShiYS5zaGFwZSkpO2JyZWFrfWlmKGFhLm91dFNoYXBlU3RyaWRlc0xvY2F0aW9uKXtjb25zdCBrYT1jb21wdXRlU3RyaWRlcyhiYS5zaGFwZSk7c3dpdGNoKGJhLnNoYXBlLmxlbmd0aCl7Y2FzZSAyOmhhLmdsLnVuaWZvcm0xaXYoYWEub3V0U2hhcGVTdHJpZGVzTG9jYXRpb24sbmV3IEludDMyQXJyYXkoa2EpKTticmVhaztjYXNlIDM6aGEuZ2wudW5pZm9ybTJpdihhYS5vdXRTaGFwZVN0cmlkZXNMb2NhdGlvbixuZXcgSW50MzJBcnJheShrYSkpO2JyZWFrO2Nhc2UgNDpoYS5nbC51bmlmb3JtM2l2KGFhLm91dFNoYXBlU3RyaWRlc0xvY2F0aW9uLG5ldyBJbnQzMkFycmF5KGthKSk7YnJlYWt9fWlmKGFhLm91dFRleFNoYXBlTG9jYXRpb24mJmhhLmdsLnVuaWZvcm0yaShhYS5vdXRUZXhTaGFwZUxvY2F0aW9uLGJhLnRleERhdGEudGV4U2hhcGVbMF0sYmEudGV4RGF0YS50ZXhTaGFwZVsxXSksYWEucHJvZ3JhbS5jdXN0b21Vbmlmb3JtcyYmU2EpZm9yKGxldCBrYT0wO2thPGFhLnByb2dyYW0uY3VzdG9tVW5pZm9ybXMubGVuZ3RoOysra2Epe2NvbnN0IEFhPWFhLnByb2dyYW0uY3VzdG9tVW5pZm9ybXNba2FdLEZhPWFhLmN1c3RvbVVuaWZvcm1Mb2NhdGlvbnNba2FdLExhPVNhW2thXTtpZihBYS50eXBlPT09ImZsb2F0IiloYS5nbC51bmlmb3JtMWZ2KEZhLExhKTtlbHNlIGlmKEFhLnR5cGU9PT0idmVjMiIpaGEuZ2wudW5pZm9ybTJmdihGYSxMYSk7ZWxzZSBpZihBYS50eXBlPT09InZlYzMiKWhhLmdsLnVuaWZvcm0zZnYoRmEsTGEpO2Vsc2UgaWYoQWEudHlwZT09PSJ2ZWM0IiloYS5nbC51bmlmb3JtNGZ2KEZhLExhKTtlbHNlIGlmKEFhLnR5cGU9PT0iaW50IiloYS5nbC51bmlmb3JtMWl2KEZhLExhKTtlbHNlIGlmKEFhLnR5cGU9PT0iaXZlYzIiKWhhLmdsLnVuaWZvcm0yaXYoRmEsTGEpO2Vsc2UgaWYoQWEudHlwZT09PSJpdmVjMyIpaGEuZ2wudW5pZm9ybTNpdihGYSxMYSk7ZWxzZSBpZihBYS50eXBlPT09Iml2ZWM0IiloYS5nbC51bmlmb3JtNGl2KEZhLExhKTtlbHNlIHRocm93IEVycm9yKGB1bmlmb3JtIHR5cGUgJHtBYS50eXBlfSBpcyBub3Qgc3VwcG9ydGVkIHlldC5gKX1oYS5leGVjdXRlUHJvZ3JhbSgpfWZ1bmN0aW9uIG1ha2VTaGFkZXJLZXkoaGEsYWEseGEpe2xldCBiYT0iIjthYS5jb25jYXQoeGEpLmZvckVhY2god2E9Pntjb25zdCBFYT13YS50ZXhEYXRhIT1udWxsJiZ3YS50ZXhEYXRhLnNsaWNlIT1udWxsJiZ3YS50ZXhEYXRhLnNsaWNlLmZsYXRPZmZzZXQ+MDtpZihoYS5lbmFibGVTaGFwZVVuaWZvcm1zJiYhd2EuaXNVbmlmb3JtKXtjb25zdCBrYT13YS50ZXhEYXRhLnRleFNoYXBlLHt1c2VTcXVlZXplU2hhcGU6QWEsdW5pZm9ybVNoYXBlOkZhLGtlcHREaW1zOkxhfT1nZXRVbmlmb3JtSW5mb0Zyb21TaGFwZShoYS5wYWNrZWRJbnB1dHMsd2Euc2hhcGUsa2EpO2xldCBlbD0iIix0bD0iIixubD0iIjtpZihGYS5sZW5ndGg9PT0xJiZoYS5wYWNrZWRJbnB1dHMpe2NvbnN0IGNsPVtNYXRoLmNlaWwoa2FbMF0vMiksTWF0aC5jZWlsKGthWzFdLzIpXTtlbD1gJHtjbFswXT4xfV8ke2NsWzFdPjF9YH1lbHNlIGlmKEZhLmxlbmd0aD09PTImJiFoYS5wYWNrZWRJbnB1dHMpdGw9YCR7RmFbMF0+MX1fJHtGYVsxXT4xfWA7ZWxzZSBpZihGYS5sZW5ndGg+MiYmIWhhLnBhY2tlZElucHV0cyl7Y29uc3QgY2w9Y29tcHV0ZVN0cmlkZXMoRmEpO25sPWAke2NsWzBdPT09a2FbMV19XyR7Y2xbY2wubGVuZ3RoLTFdPT09a2FbMV19YH1jb25zdCBzbD13YS5zaGFwZS5sZW5ndGgscmw9RmEubGVuZ3RoPT09MiYmYXJyYXlzRXF1YWwod2Euc2hhcGUsa2EpLG9sPXNpemVGcm9tU2hhcGUod2Euc2hhcGUpPT09MSxhbD1nZXRCcm9hZGNhc3REaW1zJDEod2Euc2hhcGUseGEuc2hhcGUpLGxsPSFoYS5wYWNrZWRJbnB1dHMmJnNsPT09eGEuc2hhcGUubGVuZ3RoJiZhcnJheXNFcXVhbChrYSx4YS50ZXhEYXRhLnRleFNoYXBlKSxpbD1oYS5wYWNrZWRJbnB1dHN8fEZhLmxlbmd0aD4yPyIiOmAke2thWzBdPjF9XyR7a2FbMV0+MX1gO2JhKz1gJHtzbH1fJHtsbH1fJHtBYT9MYToiIn1fJHtGYS5sZW5ndGh9XyR7b2x9XyR7YWx9XyR7cmx9XyR7ZWx9XyR7dGx9XyR7bmx9XyR7aWx9XyR7RWF9YH1lbHNle2NvbnN0IGthPXdhLmlzVW5pZm9ybT8idW5pZm9ybSI6d2EudGV4RGF0YS50ZXhTaGFwZTtiYSs9YCR7d2Euc2hhcGV9XyR7a2F9XyR7RWF9YH19KTtjb25zdCBTYT1oYS51c2VyQ29kZTtsZXQgVGE9aGEuY29uc3RydWN0b3IubmFtZTtyZXR1cm4gVGErPSJfIitiYSsiXyIrU2ErYCR7ZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIil9YCxUYX1mdW5jdGlvbiB1c2VTaGFwZVVuaWZvcm1zKGhhKXtyZXR1cm4gZW52KCkuZ2V0Qm9vbCgiV0VCR0xfVVNFX1NIQVBFU19VTklGT1JNUyIpJiZoYTw9NH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBEZWNvZGVNYXRyaXhQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITEsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRQYWNraW5nU2NoZW1lPVBhY2tpbmdTY2hlbWUuREVOU0UsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InRleFNoYXBlIix0eXBlOiJpdmVjMiJ9XTtjb25zdCB4YT1nZXRHbHNsRGlmZmVyZW5jZXMoKTt0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgaXZlYzMgb3V0Q29vcmRzRnJvbUZsYXRJbmRleChpbnQgaW5kZXgpIHsKICAgICAgICAke3RoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9nZXRPdXRwdXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4QnlVbmlmb3JtKFsiciIsImMiLCJkIl0sYWEpOmdldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXgoWyJyIiwiYyIsImQiXSxhYSl9CiAgICAgICAgcmV0dXJuIGl2ZWMzKHIsIGMsIGQpOwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihyZXN1bHRVVi55eCAqIHZlYzIodGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdKSk7CiAgICAgICAgaW50IGluZGV4ID0gNCAqIChyZXNUZXhSQy54ICogdGV4U2hhcGVbMV0gKyByZXNUZXhSQy55KTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKCiAgICAgICAgZm9yIChpbnQgaT0wOyBpPDQ7IGkrKykgewogICAgICAgICAgaW50IGZsYXRJbmRleCA9IGluZGV4ICsgaTsKICAgICAgICAgIGl2ZWMzIHJjID0gb3V0Q29vcmRzRnJvbUZsYXRJbmRleChmbGF0SW5kZXgpOwogICAgICAgICAgcmVzdWx0W2ldID0gZ2V0QShyYy54LCByYy55LCByYy56KTsKICAgICAgICB9CgogICAgICAgICR7eGEub3V0cHV0fSA9IHJlc3VsdDsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgRGVjb2RlTWF0cml4UGFja2VkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0UGFja2luZ1NjaGVtZT1QYWNraW5nU2NoZW1lLkRFTlNFLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJ0ZXhTaGFwZSIsdHlwZToiaXZlYzIifV07Y29uc3QgeGE9Z2V0R2xzbERpZmZlcmVuY2VzKCk7dGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3Jtcyh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy51c2VyQ29kZT1gCiAgICAgIGl2ZWMzIG91dENvb3Jkc0Zyb21GbGF0SW5kZXgoaW50IGluZGV4KSB7CiAgICAgICAgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Z2V0T3V0cHV0TG9naWNhbENvb3JkaW5hdGVzRnJvbUZsYXRJbmRleEJ5VW5pZm9ybShbInIiLCJjIiwiZCJdLGFhKTpnZXRMb2dpY2FsQ29vcmRpbmF0ZXNGcm9tRmxhdEluZGV4KFsiciIsImMiLCJkIl0sYWEpfQogICAgICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIocmVzdWx0VVYueXggKiB2ZWMyKHRleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXSkpOwogICAgICAgIGludCBpbmRleCA9IDQgKiAocmVzVGV4UkMueCAqIHRleFNoYXBlWzFdICsgcmVzVGV4UkMueSk7CgogICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLik7CgogICAgICAgIGZvciAoaW50IGk9MDsgaTw0OyBpKyspIHsKICAgICAgICAgIGludCBmbGF0SW5kZXggPSBpbmRleCArIGk7CiAgICAgICAgICBpdmVjMyByYyA9IG91dENvb3Jkc0Zyb21GbGF0SW5kZXgoZmxhdEluZGV4KTsKICAgICAgICAgIHJlc3VsdFtpXSA9IGdldENoYW5uZWwoZ2V0QShyYy54LCByYy55LCByYy56KSwgdmVjMihyYy55LCByYy56KSk7CiAgICAgICAgfQoKICAgICAgICAke3hhLm91dHB1dH0gPSByZXN1bHQ7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEVuY29kZUZsb2F0UHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMub3V0VGV4VXNhZ2U9VGV4dHVyZVVzYWdlLkRPV05MT0FEO2NvbnN0IHhhPWdldEdsc2xEaWZmZXJlbmNlcygpO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgICR7RU5DT0RFX0ZMT0FUX1NOSVBQRVR9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgZmxvYXQgeCA9IGdldEFBdE91dENvb3JkcygpOwogICAgICAgICR7eGEub3V0cHV0fSA9IGVuY29kZV9mbG9hdCh4KTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgRW5jb2RlRmxvYXRQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITEsdGhpcy5vdXRUZXhVc2FnZT1UZXh0dXJlVXNhZ2UuRE9XTkxPQUQ7Y29uc3QgeGE9Z2V0R2xzbERpZmZlcmVuY2VzKCk7dGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgJHtFTkNPREVfRkxPQVRfU05JUFBFVH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMyBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBmbG9hdCB4ID0gZ2V0Q2hhbm5lbChnZXRBQXRPdXRDb29yZHMoKSwgdmVjMihjb29yZHMueSwgY29vcmRzLnopKTsKICAgICAgICAke3hhLm91dHB1dH0gPSBlbmNvZGVfZmxvYXQoeCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IENIQU5ORUxfQ0hBUl9UT19JTkRFWF9NQVA9e1I6MCxHOjEsQjoyLEE6M307Y2xhc3MgRW5jb2RlTWF0cml4UHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YT0hMSxiYT0iUkdCQSIpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToidGV4U2hhcGUiLHR5cGU6Iml2ZWMyIn1dO2NvbnN0IFNhPWdldEdsc2xEaWZmZXJlbmNlcygpO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXModGhpcy5vdXRwdXRTaGFwZS5sZW5ndGgpO2xldCBUYT0icmVzdWx0Ijt4YSYmKFRhPSJmbG9vcihyZXN1bHQgKiAyNTUuICsgMC41KSIpO2xldCB3YT0iIjtmb3IobGV0IEVhPTA7RWE8YmEubGVuZ3RoO0VhKyspe2NvbnN0IGthPWJhW0VhXTt3YSs9YAogICAgICAgICAgaWYob2Zmc2V0ID09ICR7RWF9KSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlc1ske0NIQU5ORUxfQ0hBUl9UT19JTkRFWF9NQVBba2FdfV07CiAgICAgICAgICB9YH10aGlzLnVzZXJDb2RlPWAKICAgICAgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Z2V0RmxhdEluZGV4RnJvbTNET3V0cHV0KCk6Z2V0RmxhdEluZGV4RnJvbTNEKGFhKX0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMyBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgZmxhdEluZGV4ID0gZ2V0RmxhdEluZGV4KGNvb3Jkcyk7CiAgICAgICAgZmxvYXQgcmVzdWx0ID0gMC47CiAgICAgICAgaW50IG9mZnNldCA9IGltb2QoZmxhdEluZGV4LCAke2JhLmxlbmd0aH0pOwoKICAgICAgICBmbGF0SW5kZXggPSBpZGl2KGZsYXRJbmRleCwgJHtiYS5sZW5ndGh9LCAxLik7CgogICAgICAgIGludCByID0gZmxhdEluZGV4IC8gdGV4U2hhcGVbMV07CiAgICAgICAgaWYgKHIgPCB0ZXhTaGFwZVswXSkgewogICAgICAgICAgaW50IGMgPSBpbW9kKGZsYXRJbmRleCwgdGV4U2hhcGVbMV0pOwogICAgICAgICAgdmVjMiB1diA9ICh2ZWMyKGMsIHIpICsgaGFsZkNSKSAvIHZlYzIodGV4U2hhcGVbMV0sIHRleFNoYXBlWzBdKTsKICAgICAgICAgIHZlYzQgdmFsdWVzID0gJHtTYS50ZXh0dXJlMkR9KEEsIHV2KTsKICAgICAgICAgICR7d2F9CiAgICAgICAgfQogICAgICAgICR7U2Eub3V0cHV0fSA9IHZlYzQoJHtUYX0sIDAuLCAwLiwgMC4pOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBFbmNvZGVNYXRyaXhQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhPSExKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITEsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InRleFNoYXBlIix0eXBlOiJpdmVjMiJ9XTtjb25zdCBiYT1nZXRHbHNsRGlmZmVyZW5jZXMoKTt0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtsZXQgU2E9IiIsVGE9InJlc3VsdCI7eGEmJihUYT0iZmxvb3IocmVzdWx0ICogMjU1LiArIDAuNSkiKTtmb3IobGV0IHdhPTA7d2E8PTE7d2ErKylmb3IobGV0IEVhPTA7RWE8PTE7RWErKyl7Y29uc3Qga2E9d2EqMitFYTtTYSs9YAogICAgICAgICAgbG9jYWxDb29yZHMgPSBjb29yZHM7CiAgICAgICAgICBpZihsb2NhbENvb3Jkc1syXSArICR7RWF9IDwgJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlWzJdIjpgJHthYVsyXX1gfSkgewogICAgICAgICAgbG9jYWxDb29yZHNbMl0gKz0gJHtFYX07CiAgICAgICAgICBpZiAobG9jYWxDb29yZHNbMV0gKyAke3dhfSA8ICR7dGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPyJvdXRTaGFwZVsxXSI6YCR7YWFbMV19YH0pIHsKICAgICAgICAgICAgbG9jYWxDb29yZHNbMV0gKz0gJHt3YX07CgogICAgICAgICAgICBmbGF0SW5kZXggPSBnZXRGbGF0SW5kZXgobG9jYWxDb29yZHMpOwogICAgICAgICAgICBvZmZzZXQgPSBpbW9kKGZsYXRJbmRleCwgNCk7CgogICAgICAgICAgICBmbGF0SW5kZXggPSBpZGl2KGZsYXRJbmRleCwgNCwgMS4pOwoKICAgICAgICAgICAgaW50IHIgPSBmbGF0SW5kZXggLyB0ZXhTaGFwZVsxXTsKICAgICAgICAgICAgaW50IGMgPSBpbW9kKGZsYXRJbmRleCwgdGV4U2hhcGVbMV0pOwogICAgICAgICAgICB2ZWMyIHV2ID0gKHZlYzIoYywgcikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhTaGFwZVsxXSwgdGV4U2hhcGVbMF0pOwogICAgICAgICAgICB2YWx1ZXMgPSAke2JhLnRleHR1cmUyRH0oQSwgdXYpOwoKICAgICAgICAgICAgaWYgKG9mZnNldCA9PSAwKSB7CiAgICAgICAgICAgICAgcmVzdWx0WyR7a2F9XSA9IHZhbHVlc1swXTsKICAgICAgICAgICAgfSBlbHNlIGlmIChvZmZzZXQgPT0gMSkgewogICAgICAgICAgICAgIHJlc3VsdFske2thfV0gPSB2YWx1ZXNbMV07CiAgICAgICAgICAgIH0gZWxzZSBpZiAob2Zmc2V0ID09IDIpIHsKICAgICAgICAgICAgICByZXN1bHRbJHtrYX1dID0gdmFsdWVzWzJdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlc3VsdFske2thfV0gPSB2YWx1ZXNbM107CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYH10aGlzLnVzZXJDb2RlPWAKICAgICAgICAke3RoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9nZXRGbGF0SW5kZXhGcm9tM0RPdXRwdXQoKTpnZXRGbGF0SW5kZXhGcm9tM0QoYWEpfQoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICBpdmVjMyBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKCiAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwogICAgICAgICAgaW50IGZsYXRJbmRleCwgciwgYywgb2Zmc2V0OwogICAgICAgICAgaXZlYzMgbG9jYWxDb29yZHM7CiAgICAgICAgICB2ZWMyIHV2OwogICAgICAgICAgdmVjNCB2YWx1ZXM7CgogICAgICAgICAgJHtTYX0KCiAgICAgICAgICAke2JhLm91dHB1dH0gPSAke1RhfTsKICAgICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjcmVhdGVWZXJ0ZXhTaGFkZXIoaGEpe2NvbnN0IGFhPWdldEdsc2xEaWZmZXJlbmNlcygpLHhhPWAke2FhLnZlcnNpb259CiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgICAke2FhLmF0dHJpYnV0ZX0gdmVjMyBjbGlwU3BhY2VQb3M7CiAgICAke2FhLmF0dHJpYnV0ZX0gdmVjMiB1djsKICAgICR7YWEudmFyeWluZ1ZzfSB2ZWMyIHJlc3VsdFVWOwoKICAgIHZvaWQgbWFpbigpIHsKICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KGNsaXBTcGFjZVBvcywgMSk7CiAgICAgIHJlc3VsdFVWID0gdXY7CiAgICB9YDtyZXR1cm4gY3JlYXRlVmVydGV4U2hhZGVyJDEoaGEseGEpfWZ1bmN0aW9uIGNyZWF0ZVZlcnRleEJ1ZmZlcihoYSl7Y29uc3QgYWE9bmV3IEZsb2F0MzJBcnJheShbLTEsMSwwLDAsMSwtMSwtMSwwLDAsMCwxLDEsMCwxLDEsMSwtMSwwLDEsMF0pO3JldHVybiBjcmVhdGVTdGF0aWNWZXJ0ZXhCdWZmZXIoaGEsYWEpfWZ1bmN0aW9uIGNyZWF0ZUluZGV4QnVmZmVyKGhhKXtjb25zdCBhYT1uZXcgVWludDE2QXJyYXkoWzAsMSwyLDIsMSwzXSk7cmV0dXJuIGNyZWF0ZVN0YXRpY0luZGV4QnVmZmVyKGhhLGFhKX1mdW5jdGlvbiBjcmVhdGVBbmRDb25maWd1cmVUZXh0dXJlKGhhLGFhLHhhLGJhLFNhLFRhKXt2YWxpZGF0ZVRleHR1cmVTaXplKGFhLHhhKTtjb25zdCB3YT1jcmVhdGVUZXh0dXJlKGhhKSxFYT1oYS5URVhUVVJFXzJEO3JldHVybiBjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRUZXh0dXJlKEVhLHdhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS50ZXhQYXJhbWV0ZXJpKEVhLGhhLlRFWFRVUkVfV1JBUF9TLGhhLkNMQU1QX1RPX0VER0UpKSxjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLnRleFBhcmFtZXRlcmkoRWEsaGEuVEVYVFVSRV9XUkFQX1QsaGEuQ0xBTVBfVE9fRURHRSkpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEudGV4UGFyYW1ldGVyaShFYSxoYS5URVhUVVJFX01JTl9GSUxURVIsaGEuTkVBUkVTVCkpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEudGV4UGFyYW1ldGVyaShFYSxoYS5URVhUVVJFX01BR19GSUxURVIsaGEuTkVBUkVTVCkpLGVudigpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpPT09MT9jYWxsQW5kQ2hlY2soaGEsKCk9PmhhLnRleEltYWdlMkQoRWEsMCxiYSxhYSx4YSwwLFNhLFRhLG51bGwpKTpjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLnRleFN0b3JhZ2UyRChFYSwxLGJhLGFhLHhhKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5iaW5kVGV4dHVyZShoYS5URVhUVVJFXzJELG51bGwpKSx7dGV4dHVyZTp3YSx0ZXhTaGFwZTpbeGEsYWFdfX1mdW5jdGlvbiBnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MzJNYXRyaXhUZXh0dXJlKGhhKXtyZXR1cm4gaGEuaW50ZXJuYWxGb3JtYXRGbG9hdH1mdW5jdGlvbiBjcmVhdGVGbG9hdDMyTWF0cml4VGV4dHVyZShoYSxhYSx4YSxiYSl7Y29uc3RbU2EsVGFdPWdldFVucGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQoYWEseGEpO3JldHVybiBjcmVhdGVBbmRDb25maWd1cmVUZXh0dXJlKGhhLFNhLFRhLGdldEludGVybmFsRm9ybWF0Rm9yRmxvYXQzMk1hdHJpeFRleHR1cmUoYmEpLGJhLnRleHR1cmVGb3JtYXRGbG9hdCxoYS5GTE9BVCl9ZnVuY3Rpb24gZ2V0SW50ZXJuYWxGb3JtYXRGb3JGbG9hdDE2TWF0cml4VGV4dHVyZShoYSl7cmV0dXJuIGhhLmludGVybmFsRm9ybWF0SGFsZkZsb2F0fWZ1bmN0aW9uIGNyZWF0ZUZsb2F0MTZNYXRyaXhUZXh0dXJlKGhhLGFhLHhhLGJhKXtjb25zdFtTYSxUYV09Z2V0VW5wYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUoaGEsU2EsVGEsZ2V0SW50ZXJuYWxGb3JtYXRGb3JGbG9hdDE2TWF0cml4VGV4dHVyZShiYSksYmEudGV4dHVyZUZvcm1hdEZsb2F0LGJhLnRleHR1cmVUeXBlSGFsZkZsb2F0KX1mdW5jdGlvbiBnZXRJbnRlcm5hbEZvcm1hdEZvclVuc2lnbmVkQnl0ZXNNYXRyaXhUZXh0dXJlKGhhKXtyZXR1cm4gaGEuZG93bmxvYWRUZXh0dXJlRm9ybWF0fWZ1bmN0aW9uIGNyZWF0ZVVuc2lnbmVkQnl0ZXNNYXRyaXhUZXh0dXJlKGhhLGFhLHhhLGJhKXtjb25zdFtTYSxUYV09Z2V0VW5wYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUoaGEsU2EsVGEsZ2V0SW50ZXJuYWxGb3JtYXRGb3JVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZShiYSksaGEuUkdCQSxoYS5VTlNJR05FRF9CWVRFKX1mdW5jdGlvbiBnZXRJbnRlcm5hbEZvcm1hdEZvclBhY2tlZE1hdHJpeFRleHR1cmUoaGEpe3JldHVybiBoYS5pbnRlcm5hbEZvcm1hdFBhY2tlZEZsb2F0fWZ1bmN0aW9uIGNyZWF0ZVBhY2tlZE1hdHJpeFRleHR1cmUoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUoaGEsU2EsVGEsZ2V0SW50ZXJuYWxGb3JtYXRGb3JQYWNrZWRNYXRyaXhUZXh0dXJlKGJhKSxoYS5SR0JBLGhhLkZMT0FUKX1mdW5jdGlvbiBnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlKGhhKXtyZXR1cm4gaGEuaW50ZXJuYWxGb3JtYXRQYWNrZWRIYWxmRmxvYXR9ZnVuY3Rpb24gY3JlYXRlRmxvYXQxNlBhY2tlZE1hdHJpeFRleHR1cmUoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChhYSx4YSk7cmV0dXJuIGNyZWF0ZUFuZENvbmZpZ3VyZVRleHR1cmUoaGEsU2EsVGEsZ2V0SW50ZXJuYWxGb3JtYXRGb3JGbG9hdDE2UGFja2VkTWF0cml4VGV4dHVyZShiYSksaGEuUkdCQSxiYS50ZXh0dXJlVHlwZUhhbGZGbG9hdCl9ZnVuY3Rpb24gYmluZFZlcnRleFByb2dyYW1BdHRyaWJ1dGVTdHJlYW1zKGhhLGFhLHhhKXtyZXR1cm4gY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5iaW5kQnVmZmVyKGhhLkFSUkFZX0JVRkZFUix4YSkpLGJpbmRWZXJ0ZXhCdWZmZXJUb1Byb2dyYW1BdHRyaWJ1dGUoaGEsYWEsImNsaXBTcGFjZVBvcyIseGEsMywyMCwwKSYmYmluZFZlcnRleEJ1ZmZlclRvUHJvZ3JhbUF0dHJpYnV0ZShoYSxhYSwidXYiLHhhLDIsMjAsMTIpfWZ1bmN0aW9uIHVwbG9hZERlbnNlTWF0cml4VG9UZXh0dXJlKGhhLGFhLHhhLGJhLFNhLFRhKXtjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsYWEpKTtsZXQgd2EsRWEsa2E7U2EgaW5zdGFuY2VvZiBVaW50OEFycmF5Pyh3YT1uZXcgVWludDhBcnJheSh4YSpiYSo0KSxFYT1oYS5VTlNJR05FRF9CWVRFLGthPWhhLlJHQkEpOih3YT1uZXcgRmxvYXQzMkFycmF5KHhhKmJhKjQpLEVhPWhhLkZMT0FULGthPVRhLmludGVybmFsRm9ybWF0UGFja2VkRmxvYXQpLHdhLnNldChTYSksZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yP2NhbGxBbmRDaGVjayhoYSwoKT0+aGEudGV4U3ViSW1hZ2UyRChoYS5URVhUVVJFXzJELDAsMCwwLHhhLGJhLGhhLlJHQkEsRWEsd2EpKTpjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLnRleEltYWdlMkQoaGEuVEVYVFVSRV8yRCwwLGthLHhhLGJhLDAsaGEuUkdCQSxFYSx3YSkpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEuYmluZFRleHR1cmUoaGEuVEVYVFVSRV8yRCxudWxsKSl9ZnVuY3Rpb24gdXBsb2FkUGl4ZWxEYXRhVG9UZXh0dXJlKGhhLGFhLHhhKXtjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsYWEpKSx4YS5kYXRhIGluc3RhbmNlb2YgVWludDhBcnJheT9lbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTI/Y2FsbEFuZENoZWNrKGhhLCgpPT5oYS50ZXhTdWJJbWFnZTJEKGhhLlRFWFRVUkVfMkQsMCwwLDAseGEud2lkdGgseGEuaGVpZ2h0LGhhLlJHQkEsaGEuVU5TSUdORURfQllURSx4YS5kYXRhKSk6Y2FsbEFuZENoZWNrKGhhLCgpPT5oYS50ZXhJbWFnZTJEKGhhLlRFWFRVUkVfMkQsMCxoYS5SR0JBLHhhLndpZHRoLHhhLmhlaWdodCwwLGhhLlJHQkEsaGEuVU5TSUdORURfQllURSx4YS5kYXRhKSk6ZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0yP2NhbGxBbmRDaGVjayhoYSwoKT0+aGEudGV4U3ViSW1hZ2UyRChoYS5URVhUVVJFXzJELDAsMCwwLGhhLlJHQkEsaGEuVU5TSUdORURfQllURSx4YSkpOmNhbGxBbmRDaGVjayhoYSwoKT0+aGEudGV4SW1hZ2UyRChoYS5URVhUVVJFXzJELDAsaGEuUkdCQSxoYS5SR0JBLGhhLlVOU0lHTkVEX0JZVEUseGEpKSxjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRUZXh0dXJlKGhhLlRFWFRVUkVfMkQsbnVsbCkpfWZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlckZyb21PdXRwdXRUZXh0dXJlKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1oYS5jcmVhdGVCdWZmZXIoKTtjYWxsQW5kQ2hlY2soaGEsKCk9PmhhLmJpbmRCdWZmZXIoaGEuUElYRUxfUEFDS19CVUZGRVIsU2EpKTtjb25zdCBFYT00KjQqYWEqeGE7cmV0dXJuIGNhbGxBbmRDaGVjayhoYSwoKT0+aGEuYnVmZmVyRGF0YShoYS5QSVhFTF9QQUNLX0JVRkZFUixFYSxoYS5TVFJFQU1fUkVBRCkpLGNhbGxBbmRDaGVjayhoYSwoKT0+aGEucmVhZFBpeGVscygwLDAseGEsYWEsaGEuUkdCQSxoYS5GTE9BVCwwKSksY2FsbEFuZENoZWNrKGhhLCgpPT5oYS5iaW5kQnVmZmVyKGhhLlBJWEVMX1BBQ0tfQlVGRkVSLG51bGwpKSxTYX1mdW5jdGlvbiBkb3dubG9hZEZsb2F0MzJNYXRyaXhGcm9tQnVmZmVyKGhhLGFhLHhhKXtjb25zdCBiYT1oYSxTYT1uZXcgRmxvYXQzMkFycmF5KHhhKTtyZXR1cm4gYmEuYmluZEJ1ZmZlcihiYS5QSVhFTF9QQUNLX0JVRkZFUixhYSksYmEuZ2V0QnVmZmVyU3ViRGF0YShiYS5QSVhFTF9QQUNLX0JVRkZFUiwwLFNhKSxiYS5iaW5kQnVmZmVyKGJhLlBJWEVMX1BBQ0tfQlVGRkVSLG51bGwpLFNhfWZ1bmN0aW9uIGRvd25sb2FkQnl0ZUVuY29kZWRGbG9hdE1hdHJpeEZyb21PdXRwdXRUZXh0dXJlKGhhLGFhLHhhLGJhKXtjb25zdFtTYSxUYV09Z2V0VW5wYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChhYSx4YSksd2E9NCxFYT1uZXcgVWludDhBcnJheShnZXRVbnBhY2tlZEFycmF5U2l6ZUZyb21NYXRyaXhTaXplKGFhKnhhLHdhKSk7cmV0dXJuIGNhbGxBbmRDaGVjayhoYSwoKT0+aGEucmVhZFBpeGVscygwLDAsU2EsVGEsYmEuZG93bmxvYWRUZXh0dXJlRm9ybWF0LGhhLlVOU0lHTkVEX0JZVEUsRWEpKSxuZXcgRmxvYXQzMkFycmF5KEVhLmJ1ZmZlcil9ZnVuY3Rpb24gZG93bmxvYWRQYWNrZWRNYXRyaXhGcm9tQnVmZmVyKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhKXtjb25zdCBrYT1oYSxBYT1uZXcgRmxvYXQzMkFycmF5KGdldFBhY2tlZFJHQkFBcnJheVNpemVGcm9tTWF0cml4U2hhcGUoVGEsd2EpKTtyZXR1cm4ga2EuYmluZEJ1ZmZlcihrYS5QSVhFTF9QQUNLX0JVRkZFUixhYSksa2EuZ2V0QnVmZmVyU3ViRGF0YShrYS5QSVhFTF9QQUNLX0JVRkZFUiwwLEFhKSxrYS5iaW5kQnVmZmVyKGthLlBJWEVMX1BBQ0tfQlVGRkVSLG51bGwpLEFhfWZ1bmN0aW9uIGRvd25sb2FkTWF0cml4RnJvbVBhY2tlZE91dHB1dFRleHR1cmUoaGEsYWEseGEpe2NvbnN0IGJhPW5ldyBGbG9hdDMyQXJyYXkoYWEqeGEqNCk7cmV0dXJuIGNhbGxBbmRDaGVjayhoYSwoKT0+aGEucmVhZFBpeGVscygwLDAseGEsYWEsaGEuUkdCQSxoYS5GTE9BVCxiYSkpLGJhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEdQR1BVQ29udGV4dHtjb25zdHJ1Y3RvcihhYSl7dGhpcy5vdXRwdXRUZXh0dXJlPW51bGwsdGhpcy5wcm9ncmFtPW51bGwsdGhpcy5kaXNwb3NlZD0hMSx0aGlzLml0ZW1zVG9Qb2xsPVtdO2NvbnN0IHhhPWVudigpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpO2lmKGFhIT1udWxsPyh0aGlzLmdsPWFhLHNldFdlYkdMQ29udGV4dCh4YSxhYSkpOnRoaXMuZ2w9Z2V0V2ViR0xDb250ZXh0KHhhKSxhYT10aGlzLmdsLGVudigpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpPT09Mil7Y29uc3QgVGE9YWE7dGhpcy5jcmVhdGVWZXJ0ZXhBcnJheT0oKT0+Y2FsbEFuZENoZWNrKFRhLCgpPT5UYS5jcmVhdGVWZXJ0ZXhBcnJheSgpKSx0aGlzLmJpbmRWZXJ0ZXhBcnJheT13YT0+Y2FsbEFuZENoZWNrKFRhLCgpPT5UYS5iaW5kVmVydGV4QXJyYXkod2EpKSx0aGlzLmRlbGV0ZVZlcnRleEFycmF5PXdhPT5jYWxsQW5kQ2hlY2soVGEsKCk9PlRhLmRlbGV0ZVZlcnRleEFycmF5KHdhKSksdGhpcy5nZXRWZXJ0ZXhBcnJheT0oKT0+Y2FsbEFuZENoZWNrKFRhLCgpPT5UYS5nZXRQYXJhbWV0ZXIoVGEuVkVSVEVYX0FSUkFZX0JJTkRJTkcpKX1lbHNlIGlmKGFhIT1udWxsKXtjb25zdCBUYT1hYS5nZXRFeHRlbnNpb24oIk9FU192ZXJ0ZXhfYXJyYXlfb2JqZWN0Iik7aWYoVGE9PW51bGwpdGhyb3cgbmV3IEVycm9yKCJBbGwgV2ViR0wxIGltcGxlbWVudGF0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gb2ZmZXIgT0VTX3ZlcnRleF9hcnJheV9vYmplY3QuIik7dGhpcy5jcmVhdGVWZXJ0ZXhBcnJheT0oKT0+Y2FsbEFuZENoZWNrKGFhLCgpPT5UYS5jcmVhdGVWZXJ0ZXhBcnJheU9FUygpKSx0aGlzLmJpbmRWZXJ0ZXhBcnJheT13YT0+Y2FsbEFuZENoZWNrKGFhLCgpPT5UYS5iaW5kVmVydGV4QXJyYXlPRVMod2EpKSx0aGlzLmRlbGV0ZVZlcnRleEFycmF5PXdhPT5jYWxsQW5kQ2hlY2soYWEsKCk9PlRhLmRlbGV0ZVZlcnRleEFycmF5T0VTKHdhKSksdGhpcy5nZXRWZXJ0ZXhBcnJheT0oKT0+Y2FsbEFuZENoZWNrKGFhLCgpPT5hYS5nZXRQYXJhbWV0ZXIoVGEuVkVSVEVYX0FSUkFZX0JJTkRJTkdfT0VTKSl9bGV0IGJhPSJXRUJHTF9jb2xvcl9idWZmZXJfZmxvYXQiO2NvbnN0IFNhPSJFWFRfY29sb3JfYnVmZmVyX2hhbGZfZmxvYXQiO2lmKHRoaXMucGFyYWxsZWxDb21waWxhdGlvbkV4dGVuc2lvbj10aGlzLmdsLmdldEV4dGVuc2lvbigiS0hSX3BhcmFsbGVsX3NoYWRlcl9jb21waWxlIiksZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9WRVJTSU9OIik9PT0xKXtjb25zdCBUYT0iT0VTX3RleHR1cmVfZmxvYXQiLHdhPSJPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IjtpZih0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbj1nZXRFeHRlbnNpb25PclRocm93KHRoaXMuZ2wsVGEpLGhhc0V4dGVuc2lvbih0aGlzLmdsLHdhKSl0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb249Z2V0RXh0ZW5zaW9uT3JUaHJvdyh0aGlzLmdsLHdhKTtlbHNlIGlmKGVudigpLmdldCgiV0VCR0xfRk9SQ0VfRjE2X1RFWFRVUkVTIikpdGhyb3cgbmV3IEVycm9yKCJHTCBjb250ZXh0IGRvZXMgbm90IHN1cHBvcnQgaGFsZiBmbG9hdCB0ZXh0dXJlcywgeWV0IHRoZSBlbnZpcm9ubWVudCBmbGFnIFdFQkdMX0ZPUkNFX0YxNl9URVhUVVJFUyBpcyBzZXQgdG8gdHJ1ZS4iKTtpZih0aGlzLmNvbG9yQnVmZmVyRmxvYXRFeHRlbnNpb249dGhpcy5nbC5nZXRFeHRlbnNpb24oYmEpLGhhc0V4dGVuc2lvbih0aGlzLmdsLFNhKSl0aGlzLmNvbG9yQnVmZmVySGFsZkZsb2F0RXh0ZW5zaW9uPWdldEV4dGVuc2lvbk9yVGhyb3codGhpcy5nbCxTYSk7ZWxzZSBpZihlbnYoKS5nZXQoIldFQkdMX0ZPUkNFX0YxNl9URVhUVVJFUyIpKXRocm93IG5ldyBFcnJvcigiR0wgY29udGV4dCBkb2VzIG5vdCBzdXBwb3J0IGNvbG9yIHJlbmRlcmFibGUgaGFsZiBmbG9hdHMsIHlldCB0aGUgZW52aXJvbm1lbnQgZmxhZyBXRUJHTF9GT1JDRV9GMTZfVEVYVFVSRVMgaXMgc2V0IHRvIHRydWUuIil9ZWxzZSBpZihiYT0iRVhUX2NvbG9yX2J1ZmZlcl9mbG9hdCIsaGFzRXh0ZW5zaW9uKHRoaXMuZ2wsYmEpKXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbj10aGlzLmdsLmdldEV4dGVuc2lvbihiYSk7ZWxzZSBpZihoYXNFeHRlbnNpb24odGhpcy5nbCxTYSkpdGhpcy5jb2xvckJ1ZmZlckhhbGZGbG9hdEV4dGVuc2lvbj10aGlzLmdsLmdldEV4dGVuc2lvbihTYSk7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoIkdMIGNvbnRleHQgZG9lcyBub3Qgc3VwcG9ydCBjb2xvciByZW5kZXJhYmxlIGZsb2F0cyIpO3RoaXMudmVydGV4QnVmZmVyPWNyZWF0ZVZlcnRleEJ1ZmZlcih0aGlzLmdsKSx0aGlzLmluZGV4QnVmZmVyPWNyZWF0ZUluZGV4QnVmZmVyKHRoaXMuZ2wpLHRoaXMuZnJhbWVidWZmZXI9Y3JlYXRlRnJhbWVidWZmZXIodGhpcy5nbCksdGhpcy50ZXh0dXJlQ29uZmlnPWdldFRleHR1cmVDb25maWcodGhpcy5nbCx0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24pfWdldCBkZWJ1Zygpe3JldHVybiBlbnYoKS5nZXRCb29sKCJERUJVRyIpfWRpc3Bvc2UoKXtpZih0aGlzLmRpc3Bvc2VkKXJldHVybjt0aGlzLnByb2dyYW0hPW51bGwmJmNvbnNvbGUud2FybigiRGlzcG9zaW5nIGEgR1BHUFVDb250ZXh0IHRoYXQgc3RpbGwgaGFzIGEgYm91bmQgV2ViR0xQcm9ncmFtLiBUaGlzIGlzIHByb2JhYmx5IGEgcmVzb3VyY2UgbGVhaywgZGVsZXRlIHRoZSBwcm9ncmFtIHdpdGggR1BHUFVDb250ZXh0LmRlbGV0ZVByb2dyYW0gYmVmb3JlIGRpc3Bvc2luZy4iKSx0aGlzLm91dHB1dFRleHR1cmUhPW51bGwmJmNvbnNvbGUud2FybigiRGlzcG9zaW5nIGEgR1BHUFVDb250ZXh0IHRoYXQgc3RpbGwgaGFzIGEgYm91bmQgb3V0cHV0IG1hdHJpeCB0ZXh0dXJlLiAgVGhpcyBpcyBwcm9iYWJseSBhIHJlc291cmNlIGxlYWssIGRlbGV0ZSB0aGUgb3V0cHV0IG1hdHJpeCB0ZXh0dXJlIHdpdGggR1BHUFVDb250ZXh0LmRlbGV0ZU1hdHJpeFRleHR1cmUgYmVmb3JlIGRpc3Bvc2luZy4iKTtjb25zdCBhYT10aGlzLmdsO2NhbGxBbmRDaGVjayhhYSwoKT0+YWEuZmluaXNoKCkpLGNhbGxBbmRDaGVjayhhYSwoKT0+YWEuYmluZEZyYW1lYnVmZmVyKGFhLkZSQU1FQlVGRkVSLG51bGwpKSxjYWxsQW5kQ2hlY2soYWEsKCk9PmFhLmRlbGV0ZUZyYW1lYnVmZmVyKHRoaXMuZnJhbWVidWZmZXIpKSxjYWxsQW5kQ2hlY2soYWEsKCk9PmFhLmJpbmRCdWZmZXIoYWEuQVJSQVlfQlVGRkVSLG51bGwpKSxjYWxsQW5kQ2hlY2soYWEsKCk9PmFhLmJpbmRCdWZmZXIoYWEuRUxFTUVOVF9BUlJBWV9CVUZGRVIsbnVsbCkpLGNhbGxBbmRDaGVjayhhYSwoKT0+YWEuZGVsZXRlQnVmZmVyKHRoaXMuaW5kZXhCdWZmZXIpKSx0aGlzLmRpc3Bvc2VkPSEwfWNyZWF0ZUZsb2F0MzJNYXRyaXhUZXh0dXJlKGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjcmVhdGVGbG9hdDMyTWF0cml4VGV4dHVyZSh0aGlzLmdsLGFhLHhhLHRoaXMudGV4dHVyZUNvbmZpZyl9Y3JlYXRlRmxvYXQxNk1hdHJpeFRleHR1cmUoYWEseGEpe3JldHVybiB0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNyZWF0ZUZsb2F0MTZNYXRyaXhUZXh0dXJlKHRoaXMuZ2wsYWEseGEsdGhpcy50ZXh0dXJlQ29uZmlnKX1jcmVhdGVVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZShhYSx4YSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY3JlYXRlVW5zaWduZWRCeXRlc01hdHJpeFRleHR1cmUodGhpcy5nbCxhYSx4YSx0aGlzLnRleHR1cmVDb25maWcpfXVwbG9hZFBpeGVsRGF0YVRvVGV4dHVyZShhYSx4YSl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSx1cGxvYWRQaXhlbERhdGFUb1RleHR1cmUodGhpcy5nbCxhYSx4YSl9dXBsb2FkRGVuc2VNYXRyaXhUb1RleHR1cmUoYWEseGEsYmEsU2Epe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksdXBsb2FkRGVuc2VNYXRyaXhUb1RleHR1cmUodGhpcy5nbCxhYSx4YSxiYSxTYSx0aGlzLnRleHR1cmVDb25maWcpfWNyZWF0ZUZsb2F0MTZQYWNrZWRNYXRyaXhUZXh0dXJlKGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjcmVhdGVGbG9hdDE2UGFja2VkTWF0cml4VGV4dHVyZSh0aGlzLmdsLGFhLHhhLHRoaXMudGV4dHVyZUNvbmZpZyl9Y3JlYXRlUGFja2VkTWF0cml4VGV4dHVyZShhYSx4YSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY3JlYXRlUGFja2VkTWF0cml4VGV4dHVyZSh0aGlzLmdsLGFhLHhhLHRoaXMudGV4dHVyZUNvbmZpZyl9ZGVsZXRlTWF0cml4VGV4dHVyZShhYSl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0aGlzLm91dHB1dFRleHR1cmU9PT1hYSYmKHVuYmluZENvbG9yVGV4dHVyZUZyb21GcmFtZWJ1ZmZlcih0aGlzLmdsLHRoaXMuZnJhbWVidWZmZXIpLHRoaXMub3V0cHV0VGV4dHVyZT1udWxsKSxjYWxsQW5kQ2hlY2sodGhpcy5nbCwoKT0+dGhpcy5nbC5kZWxldGVUZXh0dXJlKGFhKSl9ZG93bmxvYWRCeXRlRW5jb2RlZEZsb2F0TWF0cml4RnJvbU91dHB1dFRleHR1cmUoYWEseGEsYmEpe3JldHVybiB0aGlzLmRvd25sb2FkTWF0cml4RHJpdmVyKGFhLCgpPT5kb3dubG9hZEJ5dGVFbmNvZGVkRmxvYXRNYXRyaXhGcm9tT3V0cHV0VGV4dHVyZSh0aGlzLmdsLHhhLGJhLHRoaXMudGV4dHVyZUNvbmZpZykpfWRvd25sb2FkUGFja2VkTWF0cml4RnJvbUJ1ZmZlcihhYSx4YSxiYSxTYSxUYSx3YSl7cmV0dXJuIGRvd25sb2FkUGFja2VkTWF0cml4RnJvbUJ1ZmZlcih0aGlzLmdsLGFhLHhhLGJhLFNhLFRhLHdhLHRoaXMudGV4dHVyZUNvbmZpZyl9ZG93bmxvYWRGbG9hdDMyTWF0cml4RnJvbUJ1ZmZlcihhYSx4YSl7cmV0dXJuIGRvd25sb2FkRmxvYXQzMk1hdHJpeEZyb21CdWZmZXIodGhpcy5nbCxhYSx4YSl9Y3JlYXRlQnVmZmVyRnJvbVRleHR1cmUoYWEseGEsYmEpe3RoaXMuYmluZFRleHR1cmVUb0ZyYW1lQnVmZmVyKGFhKTtjb25zdCBTYT1jcmVhdGVCdWZmZXJGcm9tT3V0cHV0VGV4dHVyZSh0aGlzLmdsLHhhLGJhLHRoaXMudGV4dHVyZUNvbmZpZyk7cmV0dXJuIHRoaXMudW5iaW5kVGV4dHVyZVRvRnJhbWVCdWZmZXIoKSxTYX1jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKXtjb25zdCBhYT10aGlzLmNyZWF0ZUZlbmNlKHRoaXMuZ2wpO3JldHVybiB0aGlzLnBvbGxGZW5jZShhYSl9Y3JlYXRlRmVuY2UoYWEpe2xldCB4YSxiYTtpZihlbnYoKS5nZXRCb29sKCJXRUJHTF9GRU5DRV9BUElfRU5BQkxFRCIpKXtjb25zdCBTYT1hYSxUYT1TYS5mZW5jZVN5bmMoU2EuU1lOQ19HUFVfQ09NTUFORFNfQ09NUExFVEUsMCk7YWEuZmx1c2goKSxiYT0oKT0+e2NvbnN0IHdhPVNhLmNsaWVudFdhaXRTeW5jKFRhLDAsMCk7cmV0dXJuIHdhPT09U2EuQUxSRUFEWV9TSUdOQUxFRHx8d2E9PT1TYS5DT05ESVRJT05fU0FUSVNGSUVEfSx4YT1UYX1lbHNlIGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1ZFUlNJT04iKT4wPyh4YT10aGlzLmJlZ2luUXVlcnkoKSx0aGlzLmVuZFF1ZXJ5KCksYmE9KCk9PnRoaXMuaXNRdWVyeUF2YWlsYWJsZSh4YSxlbnYoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIikpKTpiYT0oKT0+ITA7cmV0dXJue3F1ZXJ5OnhhLGlzRmVuY2VQYXNzZWQ6YmF9fWRvd25sb2FkTWF0cml4RnJvbVBhY2tlZFRleHR1cmUoYWEseGEsYmEpe3JldHVybiB0aGlzLmRvd25sb2FkTWF0cml4RHJpdmVyKGFhLCgpPT5kb3dubG9hZE1hdHJpeEZyb21QYWNrZWRPdXRwdXRUZXh0dXJlKHRoaXMuZ2wseGEsYmEpKX1jcmVhdGVQcm9ncmFtKGFhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpO2NvbnN0IHhhPXRoaXMuZ2w7dGhpcy52ZXJ0ZXhTaGFkZXI9PW51bGwmJih0aGlzLnZlcnRleFNoYWRlcj1jcmVhdGVWZXJ0ZXhTaGFkZXIoeGEpKTtjb25zdCBiYT1jcmVhdGVQcm9ncmFtKHhhKTtjYWxsQW5kQ2hlY2soeGEsKCk9PnhhLmF0dGFjaFNoYWRlcihiYSx0aGlzLnZlcnRleFNoYWRlcikpLGNhbGxBbmRDaGVjayh4YSwoKT0+eGEuYXR0YWNoU2hhZGVyKGJhLGFhKSksbGlua1Byb2dyYW0oeGEsYmEpO2NvbnN0IFNhPU9iamVjdC5hc3NpZ24oYmEse3Zhbzp0aGlzLmNyZWF0ZVZlcnRleEFycmF5KCl9KTtyZXR1cm4gdGhpcy5kZWJ1ZyYmdmFsaWRhdGVQcm9ncmFtKHhhLFNhKSxTYX1idWlsZFZhbyhhYSl7dGhpcy5zZXRQcm9ncmFtKGFhKSx0aGlzLmJpbmRWZXJ0ZXhBcnJheShhYS52YW8pO2NvbnN0IHhhPXRoaXMuZ2w7Y2FsbEFuZENoZWNrKHhhLCgpPT54YS5iaW5kQnVmZmVyKHhhLkVMRU1FTlRfQVJSQVlfQlVGRkVSLHRoaXMuaW5kZXhCdWZmZXIpKSxiaW5kVmVydGV4UHJvZ3JhbUF0dHJpYnV0ZVN0cmVhbXMoeGEsYWEsdGhpcy52ZXJ0ZXhCdWZmZXIpfWRlbGV0ZVByb2dyYW0oYWEpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksYWE9PT10aGlzLnByb2dyYW0mJih0aGlzLnByb2dyYW09bnVsbCksYWEhPW51bGwmJihjYWxsQW5kQ2hlY2sodGhpcy5nbCwoKT0+dGhpcy5nbC5kZWxldGVQcm9ncmFtKGFhKSksdGhpcy5kZWxldGVWZXJ0ZXhBcnJheShhYS52YW8pKX1zZXRQcm9ncmFtKGFhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRoaXMucHJvZ3JhbT1hYSx0aGlzLnByb2dyYW0hPW51bGwmJnRoaXMuZGVidWcmJnZhbGlkYXRlUHJvZ3JhbSh0aGlzLmdsLHRoaXMucHJvZ3JhbSksY2FsbEFuZENoZWNrKHRoaXMuZ2wsKCk9PnRoaXMuZ2wudXNlUHJvZ3JhbShhYSkpfWdldFVuaWZvcm1Mb2NhdGlvbihhYSx4YSxiYT0hMCl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksYmE/Z2V0UHJvZ3JhbVVuaWZvcm1Mb2NhdGlvbk9yVGhyb3codGhpcy5nbCxhYSx4YSk6Z2V0UHJvZ3JhbVVuaWZvcm1Mb2NhdGlvbih0aGlzLmdsLGFhLHhhKX1nZXRBdHRyaWJ1dGVMb2NhdGlvbihhYSx4YSl7cmV0dXJuIHRoaXMudGhyb3dJZkRpc3Bvc2VkKCksY2FsbEFuZENoZWNrKHRoaXMuZ2wsKCk9PnRoaXMuZ2wuZ2V0QXR0cmliTG9jYXRpb24oYWEseGEpKX1nZXRVbmlmb3JtTG9jYXRpb25Ob1Rocm93KGFhLHhhKXtyZXR1cm4gdGhpcy50aHJvd0lmRGlzcG9zZWQoKSx0aGlzLmdsLmdldFVuaWZvcm1Mb2NhdGlvbihhYSx4YSl9c2V0SW5wdXRNYXRyaXhUZXh0dXJlKGFhLHhhLGJhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpLHRoaXMudGhyb3dJZk5vUHJvZ3JhbSgpLGJpbmRUZXh0dXJlVG9Qcm9ncmFtVW5pZm9ybVNhbXBsZXIodGhpcy5nbCxhYSx4YSxiYSl9c2V0T3V0cHV0TWF0cml4VGV4dHVyZShhYSx4YSxiYSl7dGhpcy5zZXRPdXRwdXRNYXRyaXhUZXh0dXJlRHJpdmVyKGFhLGJhLHhhKX1zZXRPdXRwdXRQYWNrZWRNYXRyaXhUZXh0dXJlKGFhLHhhLGJhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpO2NvbnN0W1NhLFRhXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodCh4YSxiYSk7dGhpcy5zZXRPdXRwdXRNYXRyaXhUZXh0dXJlRHJpdmVyKGFhLFNhLFRhKX1zZXRPdXRwdXRNYXRyaXhXcml0ZVJlZ2lvbihhYSx4YSxiYSxTYSl7dGhpcy5zZXRPdXRwdXRNYXRyaXhXcml0ZVJlZ2lvbkRyaXZlcihiYSxhYSxTYSx4YSl9c2V0T3V0cHV0UGFja2VkTWF0cml4V3JpdGVSZWdpb24oYWEseGEsYmEsU2Epe3Rocm93IG5ldyBFcnJvcigic2V0T3V0cHV0UGFja2VkTWF0cml4V3JpdGVSZWdpb24gbm90IGltcGxlbWVudGVkLiIpfWRlYnVnVmFsaWRhdGUoKXt0aGlzLnByb2dyYW0hPW51bGwmJnZhbGlkYXRlUHJvZ3JhbSh0aGlzLmdsLHRoaXMucHJvZ3JhbSksdmFsaWRhdGVGcmFtZWJ1ZmZlcih0aGlzLmdsKX1leGVjdXRlUHJvZ3JhbSgpe3RoaXMudGhyb3dJZkRpc3Bvc2VkKCksdGhpcy50aHJvd0lmTm9Qcm9ncmFtKCk7Y29uc3QgYWE9dGhpcy5nbDtpZih0aGlzLmRlYnVnKXtjb25zdCB4YT10aGlzLmdldFZlcnRleEFycmF5KCk7Y29uc29sZS5hc3NlcnQoeGE9PT10aGlzLnByb2dyYW0udmFvLCJWQU8gY2hhbmdlZCBiZXR3ZWVuIHNldFByb2dyYW0gYW5kIGV4ZWN1dGVQcm9ncmFtISIpLHRoaXMuZGVidWdWYWxpZGF0ZSgpfWNhbGxBbmRDaGVjayhhYSwoKT0+YWEuZHJhd0VsZW1lbnRzKGFhLlRSSUFOR0xFUyw2LGFhLlVOU0lHTkVEX1NIT1JULDApKX1ibG9ja1VudGlsQWxsUHJvZ3JhbXNDb21wbGV0ZWQoKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpLGNhbGxBbmRDaGVjayh0aGlzLmdsLCgpPT50aGlzLmdsLmZpbmlzaCgpKX1nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uKCl7cmV0dXJuIHRoaXMuZGlzam9pbnRRdWVyeVRpbWVyRXh0ZW5zaW9uPT1udWxsJiYodGhpcy5kaXNqb2ludFF1ZXJ5VGltZXJFeHRlbnNpb249Z2V0RXh0ZW5zaW9uT3JUaHJvdyh0aGlzLmdsLGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1ZFUlNJT04iKT09PTI/IkVYVF9kaXNqb2ludF90aW1lcl9xdWVyeV93ZWJnbDIiOiJFWFRfZGlzam9pbnRfdGltZXJfcXVlcnkiKSksdGhpcy5kaXNqb2ludFF1ZXJ5VGltZXJFeHRlbnNpb259Z2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMigpe3JldHVybiB0aGlzLmdldFF1ZXJ5VGltZXJFeHRlbnNpb24oKX1nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wxKCl7cmV0dXJuIHRoaXMuZ2V0UXVlcnlUaW1lckV4dGVuc2lvbigpfWJlZ2luUXVlcnkoKXtpZihlbnYoKS5nZXROdW1iZXIoIldFQkdMX0RJU0pPSU5UX1FVRVJZX1RJTUVSX0VYVEVOU0lPTl9WRVJTSU9OIik9PT0yKXtjb25zdCBiYT10aGlzLmdsLFNhPXRoaXMuZ2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMigpLFRhPWJhLmNyZWF0ZVF1ZXJ5KCk7cmV0dXJuIGJhLmJlZ2luUXVlcnkoU2EuVElNRV9FTEFQU0VEX0VYVCxUYSksVGF9Y29uc3QgYWE9dGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wxKCkseGE9YWEuY3JlYXRlUXVlcnlFWFQoKTtyZXR1cm4gYWEuYmVnaW5RdWVyeUVYVChhYS5USU1FX0VMQVBTRURfRVhULHhhKSx4YX1lbmRRdWVyeSgpe2lmKGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1ZFUlNJT04iKT09PTIpe2NvbnN0IHhhPXRoaXMuZ2wsYmE9dGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wyKCk7eGEuZW5kUXVlcnkoYmEuVElNRV9FTEFQU0VEX0VYVCk7cmV0dXJufWNvbnN0IGFhPXRoaXMuZ2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMSgpO2FhLmVuZFF1ZXJ5RVhUKGFhLlRJTUVfRUxBUFNFRF9FWFQpfWFzeW5jIHdhaXRGb3JRdWVyeUFuZEdldFRpbWUoYWEpe3JldHVybiBhd2FpdCByZXBlYXRlZFRyeSgoKT0+dGhpcy5kaXNwb3NlZHx8dGhpcy5pc1F1ZXJ5QXZhaWxhYmxlKGFhLGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1ZFUlNJT04iKSkpLHRoaXMuZ2V0UXVlcnlUaW1lKGFhLGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1ZFUlNJT04iKSl9Z2V0UXVlcnlUaW1lKGFhLHhhKXtpZih4YT09PTApcmV0dXJuIG51bGw7aWYoeGE9PT0yKXtjb25zdCBiYT10aGlzLmdsO3JldHVybiBiYS5nZXRRdWVyeVBhcmFtZXRlcihhYSxiYS5RVUVSWV9SRVNVTFQpLzFlNn1lbHNle2NvbnN0IGJhPXRoaXMuZ2V0UXVlcnlUaW1lckV4dGVuc2lvbldlYkdMMSgpO3JldHVybiBiYS5nZXRRdWVyeU9iamVjdEVYVChhYSxiYS5RVUVSWV9SRVNVTFRfRVhUKS8xZTZ9fWlzUXVlcnlBdmFpbGFibGUoYWEseGEpe2lmKHhhPT09MClyZXR1cm4hMDtpZih4YT09PTIpe2NvbnN0IGJhPXRoaXMuZ2wsU2E9dGhpcy5nZXRRdWVyeVRpbWVyRXh0ZW5zaW9uV2ViR0wyKCksVGE9YmEuZ2V0UXVlcnlQYXJhbWV0ZXIoYWEsYmEuUVVFUllfUkVTVUxUX0FWQUlMQUJMRSk7cmV0dXJuIHRoaXMuZGlzam9pbnQ9PW51bGwmJih0aGlzLmRpc2pvaW50PXRoaXMuZ2wuZ2V0UGFyYW1ldGVyKFNhLkdQVV9ESVNKT0lOVF9FWFQpKSxUYSYmIXRoaXMuZGlzam9pbnR9ZWxzZXtjb25zdCBiYT10aGlzLmdldFF1ZXJ5VGltZXJFeHRlbnNpb25XZWJHTDEoKSxTYT1iYS5nZXRRdWVyeU9iamVjdEVYVChhYSxiYS5RVUVSWV9SRVNVTFRfQVZBSUxBQkxFX0VYVCk7cmV0dXJuIHRoaXMuZGlzam9pbnQ9PW51bGwmJih0aGlzLmRpc2pvaW50PXRoaXMuZ2wuZ2V0UGFyYW1ldGVyKGJhLkdQVV9ESVNKT0lOVF9FWFQpKSxTYSYmIXRoaXMuZGlzam9pbnR9fXBvbGxGZW5jZShhYSl7cmV0dXJuIG5ldyBQcm9taXNlKHhhPT57dGhpcy5hZGRJdGVtVG9Qb2xsKCgpPT5hYS5pc0ZlbmNlUGFzc2VkKCksKCk9PnhhKCkpfSl9cG9sbEl0ZW1zKCl7Y29uc3QgYWE9bGluZWFyU2VhcmNoTGFzdFRydWUodGhpcy5pdGVtc1RvUG9sbC5tYXAoeGE9PnhhLmlzRG9uZUZuKSk7Zm9yKGxldCB4YT0wO3hhPD1hYTsrK3hhKXtjb25zdHtyZXNvbHZlRm46YmF9PXRoaXMuaXRlbXNUb1BvbGxbeGFdO2JhKCl9dGhpcy5pdGVtc1RvUG9sbD10aGlzLml0ZW1zVG9Qb2xsLnNsaWNlKGFhKzEpfWFkZEl0ZW1Ub1BvbGwoYWEseGEpe2lmKHRoaXMuaXRlbXNUb1BvbGwucHVzaCh7aXNEb25lRm46YWEscmVzb2x2ZUZuOnhhfSksdGhpcy5pdGVtc1RvUG9sbC5sZW5ndGg+MSlyZXR1cm47bGV0IGJhOyJzZXRUaW1lb3V0Q3VzdG9tImluIGVudigpLnBsYXRmb3JtJiYoYmE9ZW52KCkucGxhdGZvcm0uc2V0VGltZW91dEN1c3RvbS5iaW5kKGVudigpLnBsYXRmb3JtKSkscmVwZWF0ZWRUcnkoKCk9Pih0aGlzLnBvbGxJdGVtcygpLHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoPT09MCksKCk9PjAsbnVsbCxiYSl9YmluZFRleHR1cmVUb0ZyYW1lQnVmZmVyKGFhKXt0aGlzLnRocm93SWZEaXNwb3NlZCgpLGJpbmRDb2xvclRleHR1cmVUb0ZyYW1lYnVmZmVyKHRoaXMuZ2wsYWEsdGhpcy5mcmFtZWJ1ZmZlciksdGhpcy5kZWJ1ZyYmdmFsaWRhdGVGcmFtZWJ1ZmZlcih0aGlzLmdsKX11bmJpbmRUZXh0dXJlVG9GcmFtZUJ1ZmZlcigpe3RoaXMub3V0cHV0VGV4dHVyZSE9bnVsbD8oYmluZENvbG9yVGV4dHVyZVRvRnJhbWVidWZmZXIodGhpcy5nbCx0aGlzLm91dHB1dFRleHR1cmUsdGhpcy5mcmFtZWJ1ZmZlciksdGhpcy5kZWJ1ZyYmdmFsaWRhdGVGcmFtZWJ1ZmZlcih0aGlzLmdsKSk6dW5iaW5kQ29sb3JUZXh0dXJlRnJvbUZyYW1lYnVmZmVyKHRoaXMuZ2wsdGhpcy5mcmFtZWJ1ZmZlcil9ZG93bmxvYWRNYXRyaXhEcml2ZXIoYWEseGEpe3RoaXMuYmluZFRleHR1cmVUb0ZyYW1lQnVmZmVyKGFhKTtjb25zdCBiYT14YSgpO3JldHVybiB0aGlzLnVuYmluZFRleHR1cmVUb0ZyYW1lQnVmZmVyKCksYmF9c2V0T3V0cHV0TWF0cml4VGV4dHVyZURyaXZlcihhYSx4YSxiYSl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKTtjb25zdCBTYT10aGlzLmdsO2JpbmRDb2xvclRleHR1cmVUb0ZyYW1lYnVmZmVyKFNhLGFhLHRoaXMuZnJhbWVidWZmZXIpLHRoaXMuZGVidWcmJnZhbGlkYXRlRnJhbWVidWZmZXIoU2EpLHRoaXMub3V0cHV0VGV4dHVyZT1hYSxjYWxsQW5kQ2hlY2soU2EsKCk9PlNhLnZpZXdwb3J0KDAsMCx4YSxiYSkpLGNhbGxBbmRDaGVjayhTYSwoKT0+U2Euc2Npc3NvcigwLDAseGEsYmEpKX1zZXRPdXRwdXRNYXRyaXhXcml0ZVJlZ2lvbkRyaXZlcihhYSx4YSxiYSxTYSl7dGhpcy50aHJvd0lmRGlzcG9zZWQoKSxjYWxsQW5kQ2hlY2sodGhpcy5nbCwoKT0+dGhpcy5nbC5zY2lzc29yKGFhLHhhLGJhLFNhKSl9dGhyb3dJZkRpc3Bvc2VkKCl7aWYodGhpcy5kaXNwb3NlZCl0aHJvdyBuZXcgRXJyb3IoIkF0dGVtcHRlZCB0byB1c2UgZGlzcG9zZWQgR1BHUFVDb250ZXh0LiIpfXRocm93SWZOb1Byb2dyYW0oKXtpZih0aGlzLnByb2dyYW09PW51bGwpdGhyb3cgbmV3IEVycm9yKCJObyBHUFUgcHJvZ3JhbSBpcyBjdXJyZW50bHkgc2V0LiIpfX1mdW5jdGlvbiBsaW5lYXJTZWFyY2hMYXN0VHJ1ZShoYSl7bGV0IGFhPTA7Zm9yKDthYTxoYS5sZW5ndGgmJmhhW2FhXSgpOysrYWEpO3JldHVybiBhYS0xfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2ltcGxlQWJzSW1wbChoYSl7Y29uc3QgYWE9bmV3IEZsb2F0MzJBcnJheShoYS5sZW5ndGgpO2ZvcihsZXQgeGE9MDt4YTxoYS5sZW5ndGg7Kyt4YSlhYVt4YV09TWF0aC5hYnMoaGFbeGFdKTtyZXR1cm4gYWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbChoYSl7cmV0dXJuKGFhLHhhLGJhLFNhLFRhKT0+e2NvbnN0IHdhPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlKGFhLHhhKSxFYT13YS5sZW5ndGgsa2E9Y29tcHV0ZVN0cmlkZXMod2EpLEFhPXNpemVGcm9tU2hhcGUod2EpLEZhPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUoVGEsQWEpLExhPWFhLmxlbmd0aCxlbD14YS5sZW5ndGgsdGw9Y29tcHV0ZVN0cmlkZXMoYWEpLG5sPWNvbXB1dGVTdHJpZGVzKHhhKSxzbD1nZXRCcm9hZGNhc3REaW1zJDEoYWEsd2EpLHJsPWdldEJyb2FkY2FzdERpbXMkMSh4YSx3YSk7aWYoc2wubGVuZ3RoK3JsLmxlbmd0aD09PTApZm9yKGxldCBvbD0wO29sPEZhLmxlbmd0aDsrK29sKUZhW29sXT1oYShiYVtvbCViYS5sZW5ndGhdLFNhW29sJVNhLmxlbmd0aF0pO2Vsc2UgZm9yKGxldCBvbD0wO29sPEZhLmxlbmd0aDsrK29sKXtjb25zdCBhbD1pbmRleFRvTG9jKG9sLEVhLGthKSxsbD1hbC5zbGljZSgtTGEpO3NsLmZvckVhY2goZGw9PmxsW2RsXT0wKTtjb25zdCBpbD1sb2NUb0luZGV4KGxsLExhLHRsKSxjbD1hbC5zbGljZSgtZWwpO3JsLmZvckVhY2goZGw9PmNsW2RsXT0wKTtjb25zdCB1bD1sb2NUb0luZGV4KGNsLGVsLG5sKTtGYVtvbF09aGEoYmFbaWxdLFNhW3VsXSl9cmV0dXJuW0ZhLHdhXX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2FzdEltcGwoaGEsYWEseGEsYmEpe2lmKGJhPT09ImludDMyIil7Y29uc3QgU2E9SW50MzJBcnJheS5mcm9tKGhhKTtyZXR1cm5bYWEsImludDMyIixTYV19aWYoYmE9PT0iYm9vbCIpe2NvbnN0IFNhPXRvVHlwZWRBcnJheShbMF0seGEpLFtUYSx3YV09Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCgoRWEsa2EpPT5FYSE9PWthPzE6MCkoYWEsW10saGEsU2EsImJvb2wiKTtyZXR1cm5bd2EsImJvb2wiLFRhXX10aHJvdyBuZXcgRXJyb3IoYEVycm9yIGluIENhc3Q6IGZhaWxlZCB0byBjYXN0ICR7eGF9IHRvICR7YmF9YCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgYWRkSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9PmhhK2FhKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiaW5jb3VudEltcGwoaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPXNpemVGcm9tU2hhcGUoYmEpLHdhPW1ha2VaZXJvc1R5cGVkQXJyYXkoU2EseGEpO2ZvcihsZXQgRWE9MDtFYTxoYS5sZW5ndGg7RWErKyl7Y29uc3Qga2E9aGFbRWFdO2lmKGthPDApdGhyb3cgbmV3IEVycm9yKCJJbnB1dCB4IG11c3QgYmUgbm9uLW5lZ2F0aXZlISIpO2thPj1TYXx8KFRhPjA/d2Fba2FdKz1hYVtFYV06d2Fba2FdKz0xKX1yZXR1cm4gd2F9ZnVuY3Rpb24gYmluY291bnRSZWR1Y2VJbXBsKGhhLGFhLHhhLGJhPSExKXtjb25zdCBTYT1oYS5zaGFwZVswXSxUYT1oYS5zaGFwZVsxXSx3YT1idWZmZXIoW1NhLHhhXSxhYS5kdHlwZSk7Zm9yKGxldCBFYT0wO0VhPFNhO0VhKyspZm9yKGxldCBrYT0wO2thPFRhO2thKyspe2NvbnN0IEFhPWhhLmdldChFYSxrYSk7aWYoQWE8MCl0aHJvdyBuZXcgRXJyb3IoIklucHV0IHggbXVzdCBiZSBub24tbmVnYXRpdmUhIik7QWE+PXhhfHwoYmE/d2Euc2V0KDEsRWEsQWEpOmFhLnNpemU+MD93YS5zZXQod2EuZ2V0KEVhLEFhKSthYS5nZXQoRWEsa2EpLEVhLEFhKTp3YS5zZXQod2EuZ2V0KEVhLEFhKSsxLEVhLEFhKSl9cmV0dXJuIHdhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGJpdHdpc2VBbmRJbXBsPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwoKGhhLGFhKT0+aGEmYWEpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNyZWF0ZVNpbXBsZVVuYXJ5SW1wbChoYSl7cmV0dXJuKGFhLHhhLGJhKT0+e2NvbnN0IFNhPWdldEFycmF5RnJvbURUeXBlKHhhLGFhLmxlbmd0aCk7Zm9yKGxldCBUYT0wO1RhPGFhLmxlbmd0aDsrK1RhKVNhW1RhXT1oYShhYVtUYV0sYmEpO3JldHVybiBTYX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBMaWNlbnNlKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gQVMgSVMgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjZWlsSW1wbD1jcmVhdGVTaW1wbGVVbmFyeUltcGwoaGE9Pk1hdGguY2VpbChoYSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbmNhdEltcGwkMShoYSxhYSx4YSxiYSl7Y29uc3QgU2E9Z2V0QXJyYXlGcm9tRFR5cGUoeGEsc2l6ZUZyb21TaGFwZShhYSkpO2lmKGJhJiZ4YSE9PSJzdHJpbmciKXtsZXQgVGE9MDtoYS5mb3JFYWNoKHdhPT57Y29uc3QgRWE9c2l6ZUZyb21TaGFwZSh3YS5zaGFwZSk7U2Euc2V0KHdhLnZhbHMsVGEpLFRhKz1FYX0pfWVsc2V7bGV0IFRhPTA7aGEuZm9yRWFjaCh3YT0+e2NvbnN0IEVhPXhhPT09InN0cmluZyI/ZnJvbVVpbnQ4VG9TdHJpbmdBcnJheSh3YS52YWxzKTp3YS52YWxzO2xldCBrYT0wO2ZvcihsZXQgQWE9MDtBYTx3YS5zaGFwZVswXTsrK0FhKXtjb25zdCBGYT1BYSphYVsxXStUYTtmb3IobGV0IExhPTA7TGE8d2Euc2hhcGVbMV07KytMYSlTYVtGYStMYV09RWFba2ErK119VGErPXdhLnNoYXBlWzFdfSl9cmV0dXJuIFNhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGVxdWFsSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9PmhhPT09YWE/MTowKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGV4cEltcGw9Y3JlYXRlU2ltcGxlVW5hcnlJbXBsKGhhPT5NYXRoLmV4cChoYSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZXhwbTFJbXBsPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbChoYT0+TWF0aC5leHBtMShoYSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZmxvb3JJbXBsPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbChoYT0+TWF0aC5mbG9vcihoYSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGZsb29yRGl2SW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9Pk1hdGguZmxvb3IoaGEvYWEpKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBnYXRoZXJOZEltcGwoaGEsYWEseGEsYmEsU2EsVGEsd2EsRWEsa2Epe2NvbnN0IEFhPWJ1ZmZlcihbYmEsVGFdLHhhKTtmb3IobGV0IEZhPTA7RmE8YmE7RmErKyl7Y29uc3QgTGE9W107bGV0IGVsPTA7Zm9yKGxldCB0bD0wO3RsPFNhO3RsKyspe2NvbnN0IG5sPWhhW0ZhKlNhK3RsXTtlbCs9bmwqd2FbdGxdLExhLnB1c2gobmwpfWlmKGVsPDB8fGVsPj1rYS9UYSl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaW5kaWNlczogJHtMYX0gZG9lcyBub3QgaW5kZXggaW50byAke0VhfWApO2ZvcihsZXQgdGw9MDt0bDxUYTt0bCsrKUFhLnZhbHVlc1tGYSpUYSt0bF09YWEuZ2V0KC4uLmFhLmluZGV4VG9Mb2MoZWwqVGErdGwpKX1yZXR1cm4gQWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2F0aGVyVjJJbXBsKGhhLGFhLHhhKXtjb25zdCBiYT1idWZmZXIoeGEsaGEuZHR5cGUpO2ZvcihsZXQgU2E9MDtTYTxiYS5zaXplOysrU2Epe2NvbnN0IHdhPWJhLmluZGV4VG9Mb2MoU2EpLnNsaWNlKCksRWE9d2FbMF0sa2E9d2FbMl0sQWE9YWEubG9jVG9JbmRleChbRWEsa2FdKTt3YVsyXT1hYS52YWx1ZXNbQWFdO2NvbnN0IEZhPWhhLmxvY1RvSW5kZXgod2EpOzA8PUZhJiZGYTxoYS52YWx1ZXMubGVuZ3RoJiYoYmEudmFsdWVzW1NhXT1oYS52YWx1ZXNbRmFdKX1yZXR1cm4gYmF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgZ3JlYXRlckltcGw9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCgoaGEsYWEpPT5oYT5hYT8xOjApOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGdyZWF0ZXJFcXVhbEltcGw9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCgoaGEsYWEpPT5oYT49YWE/MTowKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBsZXNzSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9PmhhPGFhPzE6MCk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbGVzc0VxdWFsSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9PmhhPD1hYT8xOjApOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxpblNwYWNlSW1wbChoYSxhYSx4YSl7Y29uc3QgYmE9KGFhLWhhKS8oeGEtMSksU2E9bWFrZVplcm9zVHlwZWRBcnJheSh4YSwiZmxvYXQzMiIpO1NhWzBdPWhhO2ZvcihsZXQgVGE9MTtUYTxTYS5sZW5ndGg7VGErKylTYVtUYV09U2FbVGEtMV0rYmE7cmV0dXJuIFNhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbG9nSW1wbD1jcmVhdGVTaW1wbGVVbmFyeUltcGwoaGE9Pk1hdGgubG9nKGhhKSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4SW1wbCQxKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1nZXRUeXBlZEFycmF5RnJvbURUeXBlKGJhLHNpemVGcm9tU2hhcGUoeGEpKTtmb3IobGV0IFRhPTA7VGE8U2EubGVuZ3RoOysrVGEpe2NvbnN0IHdhPVRhKmFhO2xldCBFYT1oYVt3YV07Zm9yKGxldCBrYT0wO2thPGFhOysra2Epe2NvbnN0IEFhPWhhW3dhK2thXTsoTnVtYmVyLmlzTmFOKEFhKXx8QWE+RWEpJiYoRWE9QWEpfVNhW1RhXT1FYX1yZXR1cm4gU2F9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWF4aW11bUltcGw9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCgoaGEsYWEpPT5NYXRoLm1heChoYSxhYSkpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG1pbmltdW1JbXBsPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwoKGhhLGFhKT0+TWF0aC5taW4oaGEsYWEpKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBtdWx0aXBseUltcGw9Y3JlYXRlU2ltcGxlQmluYXJ5S2VybmVsSW1wbCgoaGEsYWEpPT5oYSphYSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbmVnSW1wbChoYSxhYSx4YSl7Y29uc3QgYmE9Y3JlYXRlU2NhbGFyVmFsdWUoLTEseGEpO3JldHVybiBtdWx0aXBseUltcGwoW10sYWEsYmEsaGEseGEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG5vdEVxdWFsSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9PmhhIT09YWE/MTowKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0cmFuc3Bvc2VJbXBsJDEoaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPWFhLmxlbmd0aCx3YT1zaXplRnJvbVNoYXBlKGFhKSxFYT1jb21wdXRlU3RyaWRlcyhhYSksa2E9Y29tcHV0ZVN0cmlkZXMoU2EpLEFhPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUoeGEsc2l6ZUZyb21TaGFwZShTYSkpO2ZvcihsZXQgRmE9MDtGYTx3YTsrK0ZhKXtjb25zdCBMYT1pbmRleFRvTG9jKEZhLFRhLEVhKSxlbD1uZXcgQXJyYXkoTGEubGVuZ3RoKTtmb3IobGV0IG5sPTA7bmw8ZWwubGVuZ3RoO25sKyspZWxbbmxdPUxhW2JhW25sXV07Y29uc3QgdGw9bG9jVG9JbmRleChlbCxUYSxrYSk7QWFbdGxdPWhhW0ZhXX1yZXR1cm4gQWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcHJvZEltcGwoaGEsYWEseGEsYmEpe2NvbnN0W1NhLFRhXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKGhhLGJhKSx3YT11cGNhc3RUeXBlKGFhLCJpbnQzMiIpLEVhPW1ha2VaZXJvc1R5cGVkQXJyYXkoc2l6ZUZyb21TaGFwZShTYSksd2EpLGthPXNpemVGcm9tU2hhcGUoVGEpO2ZvcihsZXQgQWE9MDtBYTxFYS5sZW5ndGg7KytBYSl7Y29uc3QgRmE9QWEqa2E7bGV0IExhPTE7Zm9yKGxldCBlbD0wO2VsPGthOysrZWwpTGEqPXhhW0ZhK2VsXTtFYVtBYV09TGF9cmV0dXJue291dFZhbHM6RWEsb3V0U2hhcGU6U2Esb3V0RHR5cGU6d2F9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHZhbGlkYXRlSW5kaWNlcyhoYSxhYSx4YSl7aGEuZm9yRWFjaCgoYmEsU2EpPT57aWYoYmE8MHx8YmE+PXhhKXtjb25zdCBUYT1pbmRleFRvTG9jKFNhLGFhLmxlbmd0aCxjb21wdXRlU3RyaWRlcyhhYSkpLmpvaW4oIiwiKTt0aHJvdyBuZXcgRXJyb3IoYGluZGljZXNbJHtUYX1dID0gJHtiYX0gaXMgbm90IGluIFswLCAke3hhfSlgKX19KX1mdW5jdGlvbiB2YWxpZGF0ZVNwbGl0cyhoYSxhYSl7Zm9yKGxldCB4YT0wO3hhPGhhLmxlbmd0aDsrK3hhKXtjb25zdCBiYT1oYVt4YV0sU2E9eGE9PT1oYS5sZW5ndGgtMT9hYTpoYVt4YSsxXS5sZW5ndGg7aWYoYmEubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoIlJhZ2dlZCBzcGxpdHMgbWF5IG5vdCBiZSBlbXB0eSIpO2lmKGJhWzBdPDApdGhyb3cgbmV3IEVycm9yKCJSYWdnZWQgc3BsaXRzIG11c3QgYmUgbm9uLW5lZ2F0aXZlIik7aWYoYmFbYmEubGVuZ3RoLTFdPlNhKXRocm93IG5ldyBFcnJvcigiUmFnZ2VkIHNwbGl0cyBtdXN0IG5vdCBwb2ludCBwYXN0IHZhbHVlcyIpO2ZvcihsZXQgVGE9MTtUYTxiYS5sZW5ndGg7KytUYSlpZihiYVtUYS0xXT5iYVtUYV0pdGhyb3cgbmV3IEVycm9yKCJSYWdnZWQgc3BsaXRzIG11c3QgYmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlciIpfX1mdW5jdGlvbiBtYWtlU3BsaXRzKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1bXTtsZXQgVGE9MDtjb25zdCB3YT1hYS5sZW5ndGgtMSt4YS5sZW5ndGgsRWE9bmV3IEFycmF5KHdhKS5maWxsKG51bGwpLm1hcCgoKT0+WzBdKTt2YWxpZGF0ZVNwbGl0cyh4YSxiYSk7bGV0IGthPTE7Zm9yKGxldCBBYT0wO0FhPGFhLmxlbmd0aC0xOysrQWEpe2thKj1hYVtBYV07Y29uc3QgRmE9YWFbQWErMV07Zm9yKGxldCBMYT0xO0xhPGthKzE7KytMYSlFYVtBYV0ucHVzaChMYSpGYSl9Zm9yKGxldCBBYT0wO0FhPGhhLmxlbmd0aDsrK0FhKXtsZXQgRmE9aGFbQWFdLExhPWhhW0FhXSsxO2ZvcihsZXQgZWw9MDtlbDx4YS5sZW5ndGg7KytlbCl7Y29uc3QgdGw9eGFbZWxdLG5sPWVsK2FhLmxlbmd0aC0xO2lmKG5sPj0wKXtjb25zdCBzbD1FYVtubF0scmw9c2xbc2wubGVuZ3RoLTFdLXRsW0ZhXTtmb3IobGV0IG9sPUZhO29sPExhOysrb2wpRWFbbmxdLnB1c2godGxbb2wrMV0rcmwpfUZhPXRsW0ZhXSxMYT10bFtMYV19TGEhPT1GYSYmKFNhLnB1c2goW0ZhLExhXSksVGErPUxhLUZhKX1yZXR1cm57b3V0U3BsaXRzOkVhLHZhbHVlU2xpY2VzOlNhLG51bVZhbHVlczpUYX19ZnVuY3Rpb24gZ2V0U3BsaXRzKGhhKXtjb25zdCBhYT1bXTtmb3IobGV0IHhhPTA7eGE8aGEubGVuZ3RoOysreGEpe2NvbnN0IGJhPWhhW3hhXS5sZW5ndGgsU2E9Z2V0QXJyYXlGcm9tRFR5cGUoImludDMyIixiYSk7YWEucHVzaChTYSksaGFbeGFdLmZvckVhY2goKFRhLHdhKT0+U2Fbd2FdPVRhKX1yZXR1cm4gYWF9ZnVuY3Rpb24gY29tcHV0ZUZsYXRPdXRlckRpbXMoaGEsYWEpe2NvbnN0IHhhPWhhLnNsaWNlKDAsYWEpO2Zvcig7eGEubGVuZ3RoPGFhOyl4YS5wdXNoKDEpO2ZvcihsZXQgYmE9YWE7YmE8aGEubGVuZ3RoO2JhKyspeGFbYWEtMV0qPWhhW2JhXTtyZXR1cm4geGF9ZnVuY3Rpb24gd3JpdGVWYWx1ZVNsaWNlcyhoYSxhYSx4YSxiYSxTYSxUYSl7Y29uc3Qgd2E9Y29tcHV0ZUZsYXRPdXRlckRpbXMoYWEsMilbMV0sRWE9Y29tcHV0ZUZsYXRPdXRlckRpbXMoVGEsMilbMV07bGV0IGthPTA7Zm9yKGNvbnN0IEFhIG9mIHhhKWZvcihsZXQgRmE9QWFbMF07RmE8QWFbMV07KytGYSl7Zm9yKGxldCBMYT0wO0xhPGJhOysrTGEpU2Fba2EqRWErTGFdPWhhW0ZhKndhK0xhXTsrK2thfX1mdW5jdGlvbiBnZXRWYWx1ZXMoaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPWFhLnNsaWNlKCk7VGFbMF09U2E7Y29uc3Qgd2E9Z2V0QXJyYXlGcm9tRFR5cGUoeGEsc2l6ZUZyb21TaGFwZShUYSkpLEVhPWhhLmxlbmd0aCxrYT1FYT09PTA/MDpFYS9hYVswXTtyZXR1cm4gd3JpdGVWYWx1ZVNsaWNlcyhoYSxhYSxiYSxrYSx3YSxUYSksW3dhLFRhXX1mdW5jdGlvbiByYWdnZWRHYXRoZXJJbXBsKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhKXtpZihoYS5sZW5ndGg9PT0wKXRocm93IG5ldyBFcnJvcigicGFyYW1zTmVzdGVkU3BsaXRzIG11c3QgYmUgbm9uIGVtcHR5Iik7aWYoYWFbMF0ubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoIlNwbGl0IHRlbnNvcnMgbXVzdCBub3QgYmUgc2NhbGFycyIpO2NvbnN0IGthPWFhWzBdWzBdLTE7aWYodmFsaWRhdGVJbmRpY2VzKFRhLHdhLGthKSxiYS5sZW5ndGg9PT0wKXRocm93IG5ldyBFcnJvcigicGFyYW1zLnJhbmsgbXVzdCBiZSBub256ZXJvIik7Y29uc3QgQWE9YmFbMF0se291dFNwbGl0czpGYSx2YWx1ZVNsaWNlczpMYSxudW1WYWx1ZXM6ZWx9PW1ha2VTcGxpdHMoVGEsd2EsaGEsQWEpLHRsPWdldFNwbGl0cyhGYSksbmw9Z2V0VmFsdWVzKHhhLGJhLFNhLExhLGVsKTtyZXR1cm5bdGwsbmxbMF0sbmxbMV1dfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IElOVDMyX01BWD0yMTQ3NDgzNjQ3O2Z1bmN0aW9uIHJhZ2dlZFJhbmdlSW1wbChoYSxhYSx4YSxiYSxTYSxUYSx3YSl7aWYoYWEubGVuZ3RoPjEpdGhyb3cgbmV3IEVycm9yKCJzdGFydHMgbXVzdCBiZSBhIHNjYWxhciBvciB2ZWN0b3IiKTtpZihTYS5sZW5ndGg+MSl0aHJvdyBuZXcgRXJyb3IoImxpbWl0cyBtdXN0IGJlIGEgc2NhbGFyIG9yIHZlY3RvciIpO2lmKHdhLmxlbmd0aD4xKXRocm93IG5ldyBFcnJvcigiZGVsdGFzIG11c3QgYmUgYSBzY2FsYXIgb3IgdmVjdG9yIik7Y29uc3QgRWE9YWEubGVuZ3RoPT09MCxrYT1TYS5sZW5ndGg9PT0wLEFhPXdhLmxlbmd0aD09PTAsRmE9W107RWF8fEZhLnB1c2goYWFbMF0pLGthfHxGYS5wdXNoKFNhWzBdKSxBYXx8RmEucHVzaCh3YVswXSk7Zm9yKGxldCBybD0xO3JsPEZhLmxlbmd0aDsrK3JsKWlmKEZhW3JsXSE9PUZhW3JsLTFdKXRocm93IG5ldyBFcnJvcigic3RhcnRzLCBsaW1pdHMsIGFuZCBkZWx0YXMgbXVzdCBoYXZlIHRoZSBzYW1lIHNoYXBlIik7Y29uc3QgTGE9RmEubGVuZ3RoPT09MD8xOkZhWzBdLGVsPWdldEFycmF5RnJvbURUeXBlKCJpbnQzMiIsTGErMSk7ZWxbMF09MDtmb3IobGV0IHJsPTA7cmw8TGE7KytybCl7Y29uc3Qgb2w9RWE/aGFbMF06aGFbcmxdLGFsPWthP2JhWzBdOmJhW3JsXSxsbD1BYT9UYVswXTpUYVtybF07aWYobGw9PT0wKXRocm93IG5ldyBFcnJvcigiUmVxdWlyZXMgZGVsdGEgIT0gMCIpO2xldCBpbDtpZihsbD4wJiZhbDxvbHx8bGw8MCYmYWw+b2wpaWw9MDtlbHNlIGlmKGlsPU1hdGguY2VpbChNYXRoLmFicygoYWwtb2wpL2xsKSksaWw+SU5UMzJfTUFYKXRocm93IG5ldyBFcnJvcihgUmVxdWlyZXMgKChsaW1pdCAtIHN0YXJ0KSAvIGRlbHRhKSA8PSAke0lOVDMyX01BWH1gKTtlbFtybCsxXT1lbFtybF0raWx9Y29uc3QgdGw9ZWxbTGFdLG5sPWdldEFycmF5RnJvbURUeXBlKHhhLHRsKTtsZXQgc2w9MDtmb3IobGV0IHJsPTA7cmw8TGE7KytybCl7Y29uc3Qgb2w9ZWxbcmwrMV0tZWxbcmxdO2xldCBhbD1FYT9oYVswXTpoYVtybF07Y29uc3QgbGw9QWE/VGFbMF06VGFbcmxdO2ZvcihsZXQgaWw9MDtpbDxvbDsrK2lsKW5sW3NsKytdPWFsLGFsKz1sbH1yZXR1cm5bZWwsbmxdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBSb3dQYXJ0aXRpb25UeXBlPVJvd1BhcnRpdGlvblR5cGUkMTtjbGFzcyBSYWdnZWRUZW5zb3JUb1RlbnNvck9we2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthLEFhLEZhKXt0aGlzLnNoYXBlPWFhLHRoaXMuc2hhcGVTaGFwZT14YSx0aGlzLnZhbHVlcz1iYSx0aGlzLnZhbHVlc1NoYXBlPVNhLHRoaXMudmFsdWVzRFR5cGU9VGEsdGhpcy5kZWZhdWx0VmFsdWU9d2EsdGhpcy5kZWZhdWx0VmFsdWVTaGFwZT1FYSx0aGlzLnJvd1BhcnRpdGlvblZhbHVlcz1rYSx0aGlzLnJvd1BhcnRpdGlvblZhbHVlc1NoYXBlcz1BYSx0aGlzLnJvd1BhcnRpdGlvblR5cGVzPWdldFJvd1BhcnRpdGlvblR5cGVzSGVscGVyKEZhKSx0aGlzLnJhZ2dlZFJhbms9Z2V0UmFnZ2VkUmFuayh0aGlzLnJvd1BhcnRpdGlvblR5cGVzKX1nZXRSb3dQYXJ0aXRpb25UeXBlQnlEaW1lbnNpb24oYWEpe3JldHVybiB0aGlzLnJvd1BhcnRpdGlvblR5cGVzWzBdPT09Um93UGFydGl0aW9uVHlwZS5GSVJTVF9ESU1fU0laRT90aGlzLnJvd1BhcnRpdGlvblR5cGVzW2FhKzFdOnRoaXMucm93UGFydGl0aW9uVHlwZXNbYWFdfWdldFJvd1BhcnRpdGlvblRlbnNvcihhYSl7cmV0dXJuIHRoaXMucm93UGFydGl0aW9uVHlwZXNbMF09PT1Sb3dQYXJ0aXRpb25UeXBlLkZJUlNUX0RJTV9TSVpFP3RoaXMucm93UGFydGl0aW9uVmFsdWVzW2FhKzFdOnRoaXMucm93UGFydGl0aW9uVmFsdWVzW2FhXX1nZXRNYXhXaWR0aChhYSl7Y29uc3QgeGE9dGhpcy5nZXRSb3dQYXJ0aXRpb25UZW5zb3IoYWEtMSk7c3dpdGNoKHRoaXMuZ2V0Um93UGFydGl0aW9uVHlwZUJ5RGltZW5zaW9uKGFhLTEpKXtjYXNlIFJvd1BhcnRpdGlvblR5cGUuVkFMVUVfUk9XSURTOnJldHVybiBSYWdnZWRUZW5zb3JUb1RlbnNvck9wLmdldE1heFdpZHRoVmFsdWVSb3dJRCh4YSk7Y2FzZSBSb3dQYXJ0aXRpb25UeXBlLlJPV19TUExJVFM6cmV0dXJuIFJhZ2dlZFRlbnNvclRvVGVuc29yT3AuZ2V0TWF4V2lkdGhSb3dTcGxpdCh4YSk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBoYW5kbGUgcGFydGl0aW9uIHR5cGUgJHtSb3dQYXJ0aXRpb25UeXBlW3RoaXMuZ2V0Um93UGFydGl0aW9uVHlwZUJ5RGltZW5zaW9uKGFhLTEpXX1gKX19c3RhdGljIGdldE1heFdpZHRoUm93U3BsaXQoYWEpe2NvbnN0IHhhPWFhLmxlbmd0aDtpZih4YT09PTB8fHhhPT09MSlyZXR1cm4gMDtsZXQgYmE9MDtmb3IobGV0IFNhPTA7U2E8eGEtMTsrK1NhKXtjb25zdCBUYT1hYVtTYSsxXS1hYVtTYV07VGE+YmEmJihiYT1UYSl9cmV0dXJuIGJhfXN0YXRpYyBnZXRNYXhXaWR0aFZhbHVlUm93SUQoYWEpe2NvbnN0IHhhPWFhLmxlbmd0aDtpZih4YT09PTApcmV0dXJuIDA7bGV0IGJhPTAsU2E9YWFbMF0sVGE9MDtmb3IobGV0IHdhPTE7d2E8eGE7Kyt3YSl7Y29uc3QgRWE9YWFbd2FdO0VhIT09U2EmJihTYT1FYSxUYT1NYXRoLm1heCh3YS1iYSxUYSksYmE9d2EpfXJldHVybiBNYXRoLm1heCh4YS1iYSxUYSl9dGVuc29yU2hhcGVGcm9tVGVuc29yKGFhLHhhLGJhPSEwKXtpZih4YS5sZW5ndGg9PT0wKXtpZihhYVswXT09PS0xKXJldHVybltdO3Rocm93IG5ldyBFcnJvcigiVGhlIG9ubHkgdmFsaWQgc2NhbGFyIHNoYXBlIHRlbnNvciBpcyB0aGUgZnVsbHkgdW5rbm93biBzaGFwZSBzcGVjaWZpZWQgYXMgLTEuIil9cmV0dXJuIG1ha2VTaGFwZShhYSxiYSl9Y2FsY3VsYXRlT3V0cHV0U2l6ZShhYSl7Y29uc3QgeGE9dGhpcy52YWx1ZXNTaGFwZSxiYT10aGlzLmRlZmF1bHRWYWx1ZVNoYXBlO3ZhbGlkYXRlRGVmYXVsdFZhbHVlU2hhcGUoYmEseGEpO2NvbnN0IFNhPXRoaXMudGVuc29yU2hhcGVGcm9tVGVuc29yKHRoaXMuc2hhcGUsdGhpcy5zaGFwZVNoYXBlKSx3YT1jb21iaW5lUmFnZ2VkVGVuc29yVG9UZW5zb3JTaGFwZXModGhpcy5yYWdnZWRSYW5rLFNhLHhhKTt3YVswXTwwJiYod2FbMF09YWEpO2ZvcihsZXQgRWE9MTtFYTw9dGhpcy5yYWdnZWRSYW5rOysrRWEpd2FbRWFdPDAmJih3YVtFYV09dGhpcy5nZXRNYXhXaWR0aChFYSkpO3JldHVybiB3YX1jYWxjdWxhdGVGaXJzdFBhcmVudE91dHB1dEluZGV4KGFhLHhhLGJhKXtjb25zdCBTYT1NYXRoLm1pbihhYSxiYSksVGE9W107bGV0IHdhPTA7Zm9yKGxldCBFYT0wO0VhPFNhOysrRWEsd2ErPXhhKVRhLnB1c2god2EpO2ZvcihsZXQgRWE9U2E7RWE8YWE7KytFYSlUYS5wdXNoKC0xKTtyZXR1cm4gYXNzZXJ0KFRhLmxlbmd0aD09PWFhLCgpPT4iRmluYWwgbGVuZ3RoIG9mIHJlc3VsdCBtdXN0IGJlIGVxdWFsIHRvIGZpcnN0RGltZW5zaW9uLiIpLFRhfWNhbGN1bGF0ZU91dHB1dEluZGV4Um93U3BsaXQoYWEseGEsYmEsU2Epe2NvbnN0IFRhPWFhLmxlbmd0aCx3YT1bXTtmb3IobGV0IEVhPTA7RWE8VGEtMTsrK0VhKXtjb25zdCBrYT1hYVtFYSsxXS1hYVtFYV07bGV0IEFhPU1hdGgubWluKFNhLGthKSxGYT14YVtFYV07RmE9PT0tMSYmKEFhPTApO2ZvcihsZXQgTGE9MDtMYTxBYTsrK0xhKXdhLnB1c2goRmEpLEZhKz1iYTtmb3IobGV0IExhPTA7TGE8a2EtQWE7KytMYSl3YS5wdXNoKC0xKX1pZihUYT4wJiZ3YS5sZW5ndGghPT1hYVtUYS0xXSl0aHJvdyBuZXcgRXJyb3IoIkludmFsaWQgcm93IHNwbGl0IHNpemUuIik7cmV0dXJuIHdhfWNhbGN1bGF0ZU91dHB1dEluZGV4VmFsdWVSb3dJRChhYSx4YSxiYSxTYSl7Y29uc3QgVGE9YWEubGVuZ3RoLHdhPVtdO2lmKFRhPT09MClyZXR1cm5bXTtsZXQgRWE9MCxrYT1hYVswXTtpZihrYT49eGEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgR290IGN1cnJlbnRWYWx1ZVJvd0lkPSR7a2F9LCB3aGljaCBpcyBub3QgbGVzcyB0aGFuICR7eGEubGVuZ3RofWApO2xldCBBYT14YVtrYV07d2EucHVzaChBYSk7Zm9yKGxldCBGYT0xO0ZhPFRhOysrRmEpe2NvbnN0IExhPWFhW0ZhXTtpZihMYT09PWthKUFhPj0wJiYoKytFYSxFYTxTYT9BYSs9YmE6QWE9LTEpO2Vsc2V7aWYoRWE9MCxrYT1MYSxMYT49eGEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgR290IG5leHRWYWx1ZVJvd0lkPSR7TGF9IHdoaWNoIGlzIG5vdCBsZXNzIHRoYW4gJHt4YS5sZW5ndGh9YCk7QWE9eGFbTGFdfXdhLnB1c2goQWEpfWlmKHdhLmxlbmd0aCE9PWFhLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoIkludmFsaWQgcm93IGlkcy4iKTtyZXR1cm4gd2F9Y2FsY3VsYXRlT3V0cHV0SW5kZXgoYWEseGEsYmEsU2Epe2NvbnN0IFRhPXRoaXMuZ2V0Um93UGFydGl0aW9uVGVuc29yKGFhKSx3YT10aGlzLmdldFJvd1BhcnRpdGlvblR5cGVCeURpbWVuc2lvbihhYSk7c3dpdGNoKHdhKXtjYXNlIFJvd1BhcnRpdGlvblR5cGUuVkFMVUVfUk9XSURTOnJldHVybiB0aGlzLmNhbGN1bGF0ZU91dHB1dEluZGV4VmFsdWVSb3dJRChUYSx4YSxiYSxTYSk7Y2FzZSBSb3dQYXJ0aXRpb25UeXBlLlJPV19TUExJVFM6aWYoVGEubGVuZ3RoLTE+eGEubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgUm93IHBhcnRpdGlvbiBzaXplIGlzIGdyZWF0ZXIgdGhhbiBvdXRwdXQgc2l6ZTogJHtUYS5sZW5ndGgtMX0gPiAke3hhLmxlbmd0aH1gKTtyZXR1cm4gdGhpcy5jYWxjdWxhdGVPdXRwdXRJbmRleFJvd1NwbGl0KFRhLHhhLGJhLFNhKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcGFydGl0aW9uIHR5cGU6ICR7Um93UGFydGl0aW9uVHlwZVt3YV19YCl9fWdldEZpcnN0RGltZW5zaW9uU2l6ZSgpe2NvbnN0IGFhPXRoaXMucm93UGFydGl0aW9uVmFsdWVzWzBdO2lmKHRoaXMucm93UGFydGl0aW9uVHlwZXMubGVuZ3RoPT09MCl0aHJvdyBuZXcgRXJyb3IoIk5vIHJvd19wYXJ0aXRpb25fdHlwZXMgZ2l2ZW4uIik7Y29uc3QgeGE9dGhpcy5yb3dQYXJ0aXRpb25UeXBlc1swXTtzd2l0Y2goeGEpe2Nhc2UgUm93UGFydGl0aW9uVHlwZS5GSVJTVF9ESU1fU0laRTpyZXR1cm4gYWFbMF07Y2FzZSBSb3dQYXJ0aXRpb25UeXBlLlZBTFVFX1JPV0lEUzp0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCBoYW5kbGUgVkFMVUVfUk9XSURTIGluIGZpcnN0IGRpbWVuc2lvbi4iKTtjYXNlIFJvd1BhcnRpdGlvblR5cGUuUk9XX1NQTElUUzpyZXR1cm4gdGhpcy5yb3dQYXJ0aXRpb25WYWx1ZXNTaGFwZXNbMF1bMF0tMTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgQ2Fubm90IGhhbmRsZSB0eXBlICR7Um93UGFydGl0aW9uVHlwZVt4YV19YCl9fWNvbXB1dGUoKXtpZih0aGlzLnJvd1BhcnRpdGlvblZhbHVlc1swXS5sZW5ndGg8PTApdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGZpcnN0IHBhcnRpdGlvbiBpbnB1dC4gVGVuc29yIHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBlbGVtZW50LiIpO2NvbnN0IHhhPXRoaXMuZ2V0Rmlyc3REaW1lbnNpb25TaXplKCksYmE9dGhpcy5jYWxjdWxhdGVPdXRwdXRTaXplKHhhKSxTYT1uZXcgQXJyYXkodGhpcy5yYWdnZWRSYW5rKzEpO1NhW1NhLmxlbmd0aC0xXT0xO2ZvcihsZXQga2E9U2EubGVuZ3RoLTI7a2E+PTA7LS1rYSlTYVtrYV09U2Fba2ErMV0qYmFba2ErMV07Y29uc3QgVGE9bWFrZVNoYXBlKGJhLCExKSx3YT1nZXRBcnJheUZyb21EVHlwZSh0aGlzLnZhbHVlc0RUeXBlLHNpemVGcm9tU2hhcGUoVGEpKTtpZihTYVswXSpiYVswXT4wKXtsZXQga2E9dGhpcy5jYWxjdWxhdGVGaXJzdFBhcmVudE91dHB1dEluZGV4KHhhLFNhWzBdLGJhWzBdKTtmb3IobGV0IEFhPTE7QWE8PXRoaXMucmFnZ2VkUmFuazsrK0FhKWthPXRoaXMuY2FsY3VsYXRlT3V0cHV0SW5kZXgoQWEtMSxrYSxTYVtBYV0sYmFbQWFdKTt0aGlzLnNldE91dHB1dCh0aGlzLnJhZ2dlZFJhbmssa2Esd2EsVGEpfXJldHVybltUYSx3YV19c2V0T3V0cHV0KGFhLHhhLGJhLFNhKXtpZihiYS5sZW5ndGg9PT0wKXJldHVybjtjb25zdCBUYT10aGlzLnZhbHVlcyx3YT1iYTtsZXQgRWE9U2Euc2xpY2UoKTtFYT1FYS5zbGljZShhYSsxKTtjb25zdCBrYT1zaXplRnJvbVNoYXBlKEVhKSxBYT14YS5sZW5ndGg7bGV0IEZhPXRoaXMuZGVmYXVsdFZhbHVlO2lmKEZhLmxlbmd0aCE9PWthJiZGYS5sZW5ndGghPT0xKXtjb25zdCBubD10aGlzLmRlZmF1bHRWYWx1ZVNoYXBlO3RpZHkoKCk9Pntjb25zdCBzbD1yZXNoYXBlJDEoRmEsbmwpO0ZhPWJyb2FkY2FzdFRvKHNsLEVhKS5kYXRhU3luYygpfSl9bGV0IExhPTAsZWw9MCx0bD0wO2ZvcihsZXQgbmw9MDtubDw9QWE7KytubCl7bGV0IHNsPW5sPEFhP3hhW25sXTotMTtpZihzbD09PXRsKXsrK3RsO2NvbnRpbnVlfWlmKGVsPHRsKXtjb25zdCBybD1UYS5zdWJhcnJheShMYSprYSksb2w9d2Euc3ViYXJyYXkoZWwqa2EpLGFsPSh0bC1lbCkqa2E7Y29weUFycmF5KG9sLHJsLGFsKX1pZihubD49QWEpe2NvbnN0IHJsPWJhLmxlbmd0aDtzbD1NYXRoLmZsb29yKHJsL2thKX1pZihzbD50bClpZih0aGlzLmRlZmF1bHRWYWx1ZS5sZW5ndGg9PT0xKXdhLnN1YmFycmF5KHRsKmthLHNsKmthKS5maWxsKHRoaXMuZGVmYXVsdFZhbHVlWzBdKSx0bD1zbDtlbHNlIGZvcig7c2w+dGw7KXtjb25zdCBybD13YS5zbGljZSh0bCprYSk7Y29weUFycmF5KHJsLEZhLGthKSwrK3RsfXNsPDA/KExhPW5sKzEsZWw9dGwpOihMYT1ubCxlbD10bCx0bD1lbCsxKX19fWZ1bmN0aW9uIGNvcHlBcnJheShoYSxhYSx4YSl7Zm9yKGxldCBiYT0wO2JhPHhhO2JhKyspaGFbYmFdPWFhW2JhXX1mdW5jdGlvbiBtYWtlU2hhcGUoaGEsYWEpe2NvbnN0IHhhPVtdO2ZvcihsZXQgYmEgb2YgaGEpe2lmKGJhPDApe2lmKCFhYSl0aHJvdyBuZXcgRXJyb3IoYERpbWVuc2lvbiAke2JhfSBtdXN0IGJlID49IDBgKTtpZihiYTwtMSl0aHJvdyBuZXcgRXJyb3IoYERpbWVuc2lvbiAke2JhfSBtdXN0IGJlID49IC0xYCk7YmE9LTF9eGEucHVzaChiYSl9cmV0dXJuIHhhfWZ1bmN0aW9uIHJhZ2dlZFRlbnNvclRvVGVuc29ySW1wbChoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSl7cmV0dXJuIG5ldyBSYWdnZWRUZW5zb3JUb1RlbnNvck9wKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhLGthLEFhKS5jb21wdXRlKCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFuZ2VJbXBsKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1oYT09PWFhLFRhPWhhPGFhJiZ4YTwwLHdhPWFhPGhhJiZ4YT4xO2lmKFNhfHxUYXx8d2EpcmV0dXJuIG1ha2VaZXJvc1R5cGVkQXJyYXkoMCxiYSk7Y29uc3QgRWE9TWF0aC5hYnMoTWF0aC5jZWlsKChhYS1oYSkveGEpKSxrYT1tYWtlWmVyb3NUeXBlZEFycmF5KEVhLGJhKTthYTxoYSYmeGE9PT0xJiYoeGE9LTEpLGthWzBdPWhhO2ZvcihsZXQgQWE9MTtBYTxrYS5sZW5ndGg7QWErKylrYVtBYV09a2FbQWEtMV0reGE7cmV0dXJuIGthfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgcnNxcnRJbXBsPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbChoYT0+MS9NYXRoLnNxcnQoaGEpKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzY2F0dGVySW1wbChoYSxhYSx4YSxiYSxTYSxUYSx3YSxFYSxrYSxBYSl7Y29uc3QgRmE9W2JhL1NhLFNhXSxMYT1oYS52YWx1ZXMsZWw9YWEudmFsdWVzO2lmKGJhPT09MClyZXR1cm4gYnVmZmVyKHhhLGFhLmR0eXBlKTtjb25zdCB0bD1rYSBpbnN0YW5jZW9mIFRlbnNvckJ1ZmZlcj9rYTpidWZmZXIoRmEsYWEuZHR5cGUpO3R5cGVvZiBrYT09InN0cmluZyJ8fHR5cGVvZiBrYT09Im51bWJlciI/dGwudmFsdWVzLmZpbGwoa2EpOnR5cGVvZiBrYT09ImJvb2xlYW4iJiZ0bC52YWx1ZXMuZmlsbCgra2EpO2ZvcihsZXQgbmw9MDtubDxUYTtubCsrKXtjb25zdCBzbD1bXTtsZXQgcmw9MDtmb3IobGV0IG9sPTA7b2w8d2E7b2wrKyl7Y29uc3QgYWw9TGFbbmwqd2Erb2xdO3NsLnB1c2goYWwpLHJsKz1hbCpFYVtvbF19aWYocmw8MHx8cmw+PWJhL1NhKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbmRpY2VzOiAke3NsfSBkb2VzIG5vdCBpbmRleCBpbnRvICR7eGF9YCk7Zm9yKGxldCBvbD0wO29sPFNhO29sKyspQWE/dGwudmFsdWVzW3JsKlNhK29sXSs9ZWxbbmwqU2Erb2xdOnRsLnZhbHVlc1tybCpTYStvbF09YWEucmFuaz09PTA/ZWxbMF06ZWxbbmwqU2Erb2xdfXJldHVybiB0bH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNpZ21vaWRJbXBsPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbChoYT0+MS8oMStNYXRoLmV4cCgtaGEpKSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc2xpY2VJbXBsKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1pc1NsaWNlQ29udGlub3VzKGJhLGFhLHhhKSx3YT1zaXplRnJvbVNoYXBlKHhhKSxFYT1jb21wdXRlU3RyaWRlcyhiYSk7aWYoVGEpe2NvbnN0IExhPWNvbXB1dGVGbGF0T2Zmc2V0KGFhLEVhKTtyZXR1cm4gU2E9PT0ic3RyaW5nIj9oYS5zbGljZShMYSxMYSt3YSk6aGEuc3ViYXJyYXkoTGEsTGErd2EpfWNvbnN0IGthPVNhPT09InN0cmluZyI/ZnJvbVVpbnQ4VG9TdHJpbmdBcnJheShoYSk6aGEsQWE9YnVmZmVyKGJhLFNhLGthKSxGYT1idWZmZXIoeGEsU2EpO2ZvcihsZXQgTGE9MDtMYTxGYS5zaXplOysrTGEpe2NvbnN0IGVsPUZhLmluZGV4VG9Mb2MoTGEpLHRsPWVsLm1hcCgobmwsc2wpPT5ubCthYVtzbF0pO0ZhLnNldChBYS5nZXQoLi4udGwpLC4uLmVsKX1yZXR1cm4gU2E9PT0ic3RyaW5nIj9mcm9tU3RyaW5nQXJyYXlUb1VpbnQ4KEZhLnZhbHVlcyk6RmEudmFsdWVzfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZUZpbGxFbXB0eVJvd3NJbXBsKGhhLGFhLHhhLGJhLFNhLFRhLHdhKXtjb25zdCBFYT1hYVswXSxrYT1UYVswXSxBYT1uZXcgQXJyYXkoa2EpLEZhPW5ldyBBcnJheShFYSksTGE9YWFbMV07aWYoa2E9PT0wKXtpZihFYSE9PTApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZUZpbGxFbXB0eVJvd3NJbmRpY2VzRGVuc2VTaGFwZU1pc21hdGNoKEVhKSk7Y29uc3Qgcmw9Z2V0QXJyYXlGcm9tRFR5cGUoeGEsMCksb2w9Z2V0QXJyYXlGcm9tRFR5cGUoU2EsMCk7cmV0dXJuW3JsLFswLExhXSxvbCxBYSxGYV19bGV0IGVsPSEwLHRsPTA7Y29uc3Qgbmw9bmV3IEFycmF5KGthKS5maWxsKDApO2ZvcihsZXQgcmw9MDtybDxFYTsrK3JsKXtjb25zdCBvbD1oYVtybCpMYV07aWYob2w8MCl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlRmlsbEVtcHR5Um93c05lZ2F0aXZlSW5kZXhFcnJvck1lc3NhZ2Uocmwsb2wpKTtpZihvbD49a2EpdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZUZpbGxFbXB0eVJvd3NPdXRPZlJhbmdlSW5kZXhFcnJvck1lc3NhZ2Uocmwsb2wsa2EpKTsrK25sW29sXSxlbD1lbCYmb2w+PXRsLHRsPW9sfWxldCBzbD0hMDtmb3IobGV0IHJsPTA7cmw8a2E7KytybCl7Y29uc3Qgb2w9bmxbcmxdPT09MDtBYVtybF09b2wsc2w9c2wmJiFvbCxubFtybF09TWF0aC5tYXgobmxbcmxdLDEpLHJsPjAmJihubFtybF0rPW5sW3JsLTFdKX1pZihzbCYmZWwpe2NvbnN0IHJsPWhhLG9sPWJhO2ZvcihsZXQgYWw9MDthbDxFYTsrK2FsKUZhW2FsXT1hbDtyZXR1cm5bcmwsW0VhLExhXSxvbCxBYSxGYV19ZWxzZXtjb25zdCBybD1ubFtrYS0xXSxvbD1nZXRBcnJheUZyb21EVHlwZSh4YSxybCpMYSksYWw9Z2V0QXJyYXlGcm9tRFR5cGUoU2EscmwpLGxsPW5ldyBBcnJheShrYSkuZmlsbCgwKTtmb3IobGV0IGlsPTA7aWw8RWE7KytpbCl7Y29uc3QgY2w9aGFbaWwqTGFdLHVsPWxsW2NsXSxkbD0oY2w9PT0wPzA6bmxbY2wtMV0pK3VsO2xsW2NsXSsrO2ZvcihsZXQgaGw9MDtobDxMYTsrK2hsKW9sW2RsKkxhK2hsXT1oYVtpbCpMYStobF07YWxbZGxdPWJhW2lsXSxGYVtpbF09ZGx9Zm9yKGxldCBpbD0wO2lsPGthOysraWwpaWYobGxbaWxdPT09MCl7Y29uc3QgdWw9aWw9PT0wPzA6bmxbaWwtMV07b2xbdWwqTGErMF09aWw7Zm9yKGxldCBkbD0xO2RsPExhOysrZGwpb2xbdWwqTGErZGxdPTA7YWxbdWxdPXdhfXJldHVybltvbCxbcmwsTGFdLGFsLEFhLEZhXX19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlUmVzaGFwZUltcGwoaGEsYWEseGEsYmEsU2Epe2NvbnN0IFRhPXNpemVGcm9tU2hhcGUoYmEpLHdhPWFhWzBdLEVhPVNhLmxlbmd0aCxrYT1bXTtsZXQgQWE9MSxGYT0tMTtmb3IobGV0IHJsPTA7cmw8RWE7KytybCl7Y29uc3Qgb2w9U2FbcmxdO2lmKG9sPT09LTEpe2lmKEZhIT09LTEpdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVJlc2hhcGVNdWx0aXBsZU5lZ2F0aXZlT25lT3V0cHV0RGltRXJyb3JNZXNzYWdlKEZhLHJsKSk7RmE9cmwsa2EucHVzaCgxKX1lbHNle2lmKG9sPDApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVJlc2hhcGVOZWdhdGl2ZU91dHB1dERpbUVycm9yTWVzc2FnZShybCxvbCkpO0FhKj1vbCxrYS5wdXNoKG9sKX19aWYoRmEhPT0tMSl7aWYoQWE8PTApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVJlc2hhcGVFbXB0eVRlbnNvclplcm9PdXRwdXREaW1FcnJvck1lc3NhZ2UoKSk7Y29uc3Qgcmw9TWF0aC50cnVuYyhUYS9BYSk7aWYoQWEqcmwhPT1UYSl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlUmVzaGFwZUlucHV0T3V0cHV0TXVsdGlwbGVFcnJvck1lc3NhZ2UoYmEsa2EpKTtrYVtGYV09cmx9aWYoc2l6ZUZyb21TaGFwZShrYSkhPT1UYSl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlUmVzaGFwZUlucHV0T3V0cHV0TWlzbWF0Y2hFcnJvck1lc3NhZ2UoYmEsa2EpKTtjb25zdCBlbD1iYS5sZW5ndGgsdGw9W107aWYoZWw+MCl7dGxbZWwtMV09MTtmb3IobGV0IHJsPWVsLTI7cmw+PTA7LS1ybCl0bFtybF09dGxbcmwrMV0qYmFbcmwrMV19Y29uc3Qgbmw9W107aWYoRWE+MCl7bmxbRWEtMV09MTtmb3IobGV0IHJsPUVhLTI7cmw+PTA7LS1ybClubFtybF09bmxbcmwrMV0qa2FbcmwrMV19Y29uc3Qgc2w9Z2V0QXJyYXlGcm9tRFR5cGUoeGEsd2EqRWEpO2ZvcihsZXQgcmw9MDtybDx3YTsrK3JsKXtsZXQgb2w9MDtmb3IobGV0IGFsPTA7YWw8ZWw7KythbClvbCs9aGFbcmwqZWwrYWxdKnRsW2FsXTtmb3IobGV0IGFsPTA7YWw8RWE7KythbClzbFtybCpFYSthbF09TWF0aC50cnVuYyhvbC9ubFthbF0pLG9sJT1ubFthbF19cmV0dXJuW3NsLFt3YSxFYV0sa2FdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25JbXBsKGhhLGFhLHhhLGJhLFNhLFRhPSExLHdhPTApe2NvbnN0IEVhPWJhLmxlbmd0aCxrYT1bYWFbMF0saGEubGVuZ3RoL2FhWzBdXSxBYT1rYVsxXSxMYT1FYT4wP1NhW0VhLTFdKzE6MDtpZihMYTwwKXRocm93IG5ldyBFcnJvcihnZXRTcGFyc2VTZWdtZW50UmVkdWN0aW9uTmVnYXRpdmVTZWdtZW50SWRzRXJyb3JNZXNzYWdlKCkpO2NvbnN0IGVsPWFhLnNsaWNlKCk7ZWxbMF09TGE7Y29uc3QgdGw9ZWwucmVkdWNlKChsbCxpbCk9PmxsKmlsLDEpLG5sPWdldEFycmF5RnJvbURUeXBlKHhhLHRsKTtpZihFYT09PTApcmV0dXJuIExhPjAmJm5sLmZpbGwod2EpLFtubCxlbF07aWYoTGE8PTApdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25OZWdhdGl2ZVNlZ21lbnRJZHNFcnJvck1lc3NhZ2UoKSk7bGV0IHNsPTAscmw9MSxvbD0wLGFsPVNhW3NsXTtmb3IoOzspe2xldCBsbD0wO2lmKHJsPEVhKXtpZihsbD1TYVtybF0sYWw9PT1sbCl7KytybDtjb250aW51ZX1pZihhbD49bGwpdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25Ob25JbmNyZWFzaW5nU2VnbWVudElkc0Vycm9yTWVzc2FnZSgpKX1pZihhbDwwfHxhbD49TGEpdGhyb3cgbmV3IEVycm9yKGdldFNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25TZWdtZW50SWRPdXRPZlJhbmdlRXJyb3JNZXNzYWdlKGFsLExhKSk7YWw+b2wmJm5sLmZpbGwod2Esb2wqQWEsYWwqQWEpO2ZvcihsZXQgaWw9c2w7aWw8cmw7KytpbCl7Y29uc3QgY2w9YmFbaWxdO2lmKGNsPDB8fGNsPj1rYVswXSl0aHJvdyBuZXcgRXJyb3IoZ2V0U3BhcnNlU2VnbWVudFJlZHVjdGlvbkluZGljZXNPdXRPZlJhbmdlRXJyb3JNZXNzYWdlKGlsLGJhW2lsXSxrYVswXSkpO2ZvcihsZXQgdWw9MDt1bDxBYTt1bCsrKW5sW2FsKkFhK3VsXSs9aGFbY2wqQWErdWxdfWlmKFRhKWZvcihsZXQgaWw9MDtpbDxBYTtpbCsrKW5sW2FsKkFhK2lsXS89cmwtc2w7aWYoc2w9cmwsKytybCxvbD1hbCsxLGFsPWxsLHJsPkVhKWJyZWFrfXJldHVybiBvbDxMYSYmbmwuZmlsbCh3YSxvbCpBYSxMYSpBYSksW25sLGVsXX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHNxcnRJbXBsPWNyZWF0ZVNpbXBsZVVuYXJ5SW1wbChoYT0+TWF0aC5zcXJ0KGhhKSk7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3F1YXJlZERpZmZlcmVuY2VJbXBsPWNyZWF0ZVNpbXBsZUJpbmFyeUtlcm5lbEltcGwoKGhhLGFhKT0+e2NvbnN0IHhhPWhhLWFhO3JldHVybiB4YSp4YX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHN0YXRpY1JlZ2V4UmVwbGFjZUltcGw9Y3JlYXRlU2ltcGxlVW5hcnlJbXBsKChoYSxhYSk9Pntjb25zdHtwYXR0ZXJuOnhhLHJlcGxhY2VHbG9iYWw6YmEscmV3cml0ZTpTYX09YWE7cmV0dXJuIGhhLnJlcGxhY2UobmV3IFJlZ0V4cCh4YSxiYT8iZyI6IiIpLFNhKX0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0cmlkZWRTbGljZUltcGwoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWJ1ZmZlcihoYSxhYS5kdHlwZSk7Zm9yKGxldCBUYT0wO1RhPFNhLnNpemU7VGErKyl7Y29uc3Qgd2E9U2EuaW5kZXhUb0xvYyhUYSksRWE9bmV3IEFycmF5KHdhLmxlbmd0aCk7Zm9yKGxldCBrYT0wO2thPEVhLmxlbmd0aDtrYSsrKUVhW2thXT13YVtrYV0qeGFba2FdK2JhW2thXTtTYS5zZXQoYWEuZ2V0KC4uLkVhKSwuLi53YSl9cmV0dXJuIFNhfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFN0cmluZ05HcmFtc09we2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhKXt0aGlzLnNlcGFyYXRvcj1lbmNvZGVTdHJpbmcoYWEpLHRoaXMubkdyYW1XaWR0aHM9eGEsdGhpcy5sZWZ0UGFkPWVuY29kZVN0cmluZyhiYSksdGhpcy5yaWdodFBhZD1lbmNvZGVTdHJpbmcoU2EpLHRoaXMucGFkV2lkdGg9VGEsdGhpcy5wcmVzZXJ2ZVNob3J0PXdhfWdldFBhZFdpZHRoKGFhKXtyZXR1cm4gTWF0aC5taW4odGhpcy5wYWRXaWR0aDwwP2FhLTE6dGhpcy5wYWRXaWR0aCxhYS0xKX1nZXROdW1OR3JhbXMoYWEseGEpe2NvbnN0IGJhPXRoaXMuZ2V0UGFkV2lkdGgoeGEpO3JldHVybiBNYXRoLm1heCgwLGFhKzIqYmEteGErMSl9Y3JlYXRlTkdyYW1zKGFhLHhhLGJhLFNhLFRhLHdhKXtmb3IobGV0IEVhPTA7RWE8VGE7KytFYSl7Y29uc3Qga2E9dGhpcy5nZXRQYWRXaWR0aCh3YSksQWE9TWF0aC5tYXgoMCxrYS1FYSksRmE9TWF0aC5tYXgoMCxrYS0oVGEtKEVhKzEpKSksTGE9d2EtKEFhK0ZhKSxlbD14YSsoQWE+MD8wOkVhLWthKTtsZXQgdGw9MDt0bCs9QWEqdGhpcy5sZWZ0UGFkLmxlbmd0aDtmb3IobGV0IGFsPTA7YWw8TGE7KythbCl0bCs9YWFbZWwrYWxdLmxlbmd0aDt0bCs9RmEqdGhpcy5yaWdodFBhZC5sZW5ndGg7Y29uc3Qgbmw9QWErRmErTGEtMTt0bCs9bmwqdGhpcy5zZXBhcmF0b3IubGVuZ3RoLGJhW1NhK0VhXT1uZXcgVWludDhBcnJheSh0bCk7Y29uc3Qgc2w9YmFbU2ErRWFdO2xldCBybD0wO2NvbnN0IG9sPWFsPT5hbC5mb3JFYWNoKGxsPT5zbFtybCsrXT1sbCk7Zm9yKGxldCBhbD0wO2FsPEFhOysrYWwpb2wodGhpcy5sZWZ0UGFkKSxvbCh0aGlzLnNlcGFyYXRvcik7Zm9yKGxldCBhbD0wO2FsPExhLTE7KythbClvbChhYVtlbCthbF0pLG9sKHRoaXMuc2VwYXJhdG9yKTtpZihMYT4wKXtvbChhYVtlbCtMYS0xXSk7Zm9yKGxldCBhbD0wO2FsPEZhOysrYWwpb2wodGhpcy5zZXBhcmF0b3IpLG9sKHRoaXMucmlnaHRQYWQpfWVsc2V7Zm9yKGxldCBhbD0wO2FsPEZhLTE7KythbClvbCh0aGlzLnJpZ2h0UGFkKSxvbCh0aGlzLnNlcGFyYXRvcik7b2wodGhpcy5yaWdodFBhZCl9fX1jb21wdXRlKGFhLHhhKXtjb25zdCBiYT1hYS5sZW5ndGgsU2E9eGEubGVuZ3RoO2lmKFNhPjApe2xldCBrYT14YVswXTtpZihrYSE9PTApdGhyb3cgbmV3IEVycm9yKGBGaXJzdCBzcGxpdCB2YWx1ZSBtdXN0IGJlIDAsIGdvdCAke2thfWApO2ZvcihsZXQgQWE9MTtBYTxTYTsrK0FhKXtsZXQgRmE9eGFbQWFdPj1rYTtpZihGYT1GYSYmeGFbQWFdPD1iYSwhRmEpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNwbGl0IHZhbHVlICR7eGFbQWFdfSwgbXVzdCBiZSBpbiBbJHtrYX0sICR7YmF9XWApO2thPXhhW0FhXX1pZihrYSE9PWJhKXRocm93IG5ldyBFcnJvcihgTGFzdCBzcGxpdCB2YWx1ZSBtdXN0IGJlIGRhdGEgc2l6ZS4gRXhwZWN0ZWQgJHtiYX0sIGdvdCAke2thfWApfWNvbnN0IFRhPVNhLTEsd2E9Z2V0QXJyYXlGcm9tRFR5cGUoImludDMyIixTYSk7aWYoYmE9PT0wfHxTYT09PTApe2NvbnN0IGthPW5ldyBBcnJheShiYSk7Zm9yKGxldCBBYT0wO0FhPD1UYTsrK0FhKXdhW0FhXT0wO3JldHVybltrYSx3YV19d2FbMF09MDtmb3IobGV0IGthPTE7a2E8PVRhOysra2Epe2NvbnN0IEFhPXhhW2thXS14YVtrYS0xXTtsZXQgRmE9MDt0aGlzLm5HcmFtV2lkdGhzLmZvckVhY2goTGE9PntGYSs9dGhpcy5nZXROdW1OR3JhbXMoQWEsTGEpfSksdGhpcy5wcmVzZXJ2ZVNob3J0JiZBYT4wJiZGYT09PTAmJihGYT0xKSx3YVtrYV09d2Fba2EtMV0rRmF9Y29uc3QgRWE9bmV3IEFycmF5KHdhW1RhXSk7Zm9yKGxldCBrYT0wO2thPFRhOysra2Epe2NvbnN0IEFhPXhhW2thXTtsZXQgRmE9d2Fba2FdO2lmKHRoaXMubkdyYW1XaWR0aHMuZm9yRWFjaChMYT0+e2NvbnN0IGVsPXhhW2thKzFdLXhhW2thXSx0bD10aGlzLmdldE51bU5HcmFtcyhlbCxMYSk7dGhpcy5jcmVhdGVOR3JhbXMoYWEsQWEsRWEsRmEsdGwsTGEpLEZhKz10bH0pLHRoaXMucHJlc2VydmVTaG9ydCYmRmE9PT13YVtrYV0pe2NvbnN0IExhPXhhW2thKzFdLXhhW2thXTtpZihMYT09PTApY29udGludWU7Y29uc3QgZWw9TGErMip0aGlzLnBhZFdpZHRoO3RoaXMuY3JlYXRlTkdyYW1zKGFhLEFhLEVhLEZhLDEsZWwpfX1yZXR1cm5bRWEsd2FdfX1mdW5jdGlvbiBzdHJpbmdOR3JhbXNJbXBsKGhhLGFhLHhhLGJhLFNhLFRhLHdhLEVhKXtyZXR1cm4gbmV3IFN0cmluZ05HcmFtc09wKHhhLGJhLFNhLFRhLHdhLEVhKS5jb21wdXRlKGhhLGFhKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGxpdChoYSxhYSx4YSxiYSl7aWYoIWhhLmxlbmd0aClyZXR1cm47aWYoYWEubGVuZ3RoPT09MCl7Zm9yKGxldCBUYT0wO1RhPGhhLmxlbmd0aDsrK1RhKWJhLnB1c2goaGEuc3ViYXJyYXkoVGEsVGErMSkpO3JldHVybn1pZihhYS5sZW5ndGg9PT0xKXtjb25zdCBUYT1hYVswXTtsZXQgd2E9aGEuaW5kZXhPZihUYSk7Zm9yKDt3YSE9PS0xOyl7Y29uc3QgRWE9aGEuc3ViYXJyYXkoMCx3YSk7KCF4YXx8RWEubGVuZ3RoIT09MCkmJmJhLnB1c2goRWEpLGhhPWhhLnN1YmFycmF5KHdhKzEpLHdhPWhhLmluZGV4T2YoVGEpfSgheGF8fGhhLmxlbmd0aCE9PTApJiZiYS5wdXNoKGhhKTtyZXR1cm59bGV0IFNhPTA7Zm9yKGxldCBUYT0wO1RhPGhhLmxlbmd0aCsxO1RhKyspaWYoVGE9PT1oYS5sZW5ndGh8fGFhLmluZGV4T2YoaGFbVGFdKSE9PS0xKXtjb25zdCB3YT1oYS5zdWJhcnJheShTYSxUYSk7KCF4YXx8d2EubGVuZ3RoIT09MCkmJmJhLnB1c2god2EpLFNhPVRhKzF9fWZ1bmN0aW9uIHN0cmluZ1NwbGl0SW1wbChoYSxhYSx4YSl7Y29uc3QgYmE9aGEubGVuZ3RoLFNhPVtdO2xldCBUYT0wLHdhPTA7Y29uc3QgRWE9bmV3IEFycmF5KGJhKTtmb3IobGV0IGVsPTA7ZWw8YmE7KytlbCl7Y29uc3QgdGw9U2EubGVuZ3RoO3NwbGl0KGhhW2VsXSxhYSx4YSxTYSk7Y29uc3Qgbmw9U2EubGVuZ3RoLXRsO0VhW2VsXT1ubCxUYSs9bmwsd2E9TWF0aC5tYXgod2EsbmwpfWNvbnN0IGthPWdldEFycmF5RnJvbURUeXBlKCJpbnQzMiIsVGEqMiksQWE9bmV3IEFycmF5KFRhKSxGYT1bYmEsd2FdO2xldCBMYT0wO2ZvcihsZXQgZWw9MDtlbDxiYTsrK2VsKWZvcihsZXQgdGw9MDt0bDxFYVtlbF07Kyt0bClrYVtMYSoyXT1lbCxrYVtMYSoyKzFdPXRsLEFhW0xhXT1TYVtMYV0sKytMYTtyZXR1cm5ba2EsQWEsRmFdfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0cmluZ1RvSGFzaEJ1Y2tldEZhc3RJbXBsKGhhLGFhKXtjb25zdCB4YT1nZXRBcnJheUZyb21EVHlwZSgiaW50MzIiLGhhLmxlbmd0aCk7Zm9yKGxldCBiYT0wO2JhPGhhLmxlbmd0aDsrK2JhKXhhW2JhXT1maW5nZXJQcmludDY0KGhhW2JhXSkubW9kdWxvKGFhKS5nZXRMb3dCaXRzVW5zaWduZWQoKTtyZXR1cm4geGF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3ViSW1wbD1jcmVhdGVTaW1wbGVCaW5hcnlLZXJuZWxJbXBsKChoYSxhYSk9PmhhLWFhKTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0aWxlSW1wbChoYSxhYSl7Y29uc3QgeGE9bmV3IEFycmF5KGhhLnJhbmspO2ZvcihsZXQgU2E9MDtTYTx4YS5sZW5ndGg7U2ErKyl4YVtTYV09aGEuc2hhcGVbU2FdKmFhW1NhXTtjb25zdCBiYT1idWZmZXIoeGEsaGEuZHR5cGUpO2ZvcihsZXQgU2E9MDtTYTxiYS52YWx1ZXMubGVuZ3RoOysrU2Epe2NvbnN0IFRhPWJhLmluZGV4VG9Mb2MoU2EpLHdhPW5ldyBBcnJheShoYS5yYW5rKTtmb3IobGV0IGthPTA7a2E8d2EubGVuZ3RoO2thKyspd2Fba2FdPVRhW2thXSVoYS5zaGFwZVtrYV07Y29uc3QgRWE9aGEubG9jVG9JbmRleCh3YSk7YmEudmFsdWVzW1NhXT1oYS52YWx1ZXNbRWFdfXJldHVybiBiYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjb21wYXJlUGFpcj0oaGEsYWEpPT57Y29uc3QgeGE9YWEudmFsdWUtaGEudmFsdWU7cmV0dXJuIHhhPT09MD9oYS5pbmRleC1hYS5pbmRleDp4YX07ZnVuY3Rpb24gc2VsZWN0JDEoaGEsYWEseGE9MCxiYT1oYS5sZW5ndGgtMSl7Zm9yKDtiYT54YTspe2lmKGJhLXhhPjYwMCl7Y29uc3QgRWE9YmEteGErMSxrYT1hYS14YSsxLEFhPU1hdGgubG9nKEVhKSxGYT0uNSpNYXRoLmV4cCgyKkFhLzMpLExhPS41Kk1hdGguc3FydChBYSpGYSooRWEtRmEpL0VhKSpNYXRoLnNpZ24oa2EtRWEvMiksZWw9TWF0aC5tYXgoeGEsTWF0aC5mbG9vcihhYS1rYSpGYS9FYStMYSkpLHRsPU1hdGgubWluKGJhLE1hdGguZmxvb3IoYWErKEVhLWthKSpGYS9FYStMYSkpO3NlbGVjdCQxKGhhLGFhLGVsLHRsKX1jb25zdCBTYT1oYVthYV07bGV0IFRhPXhhLHdhPWJhO2Zvcihzd2FwKGhhLHhhLGFhKSxjb21wYXJlUGFpcihoYVtiYV0sU2EpPjAmJnN3YXAoaGEseGEsYmEpO1RhPHdhOyl7Zm9yKHN3YXAoaGEsVGEsd2EpLFRhKyssd2EtLTtjb21wYXJlUGFpcihoYVtUYV0sU2EpPDA7KVRhPVRhKzE7Zm9yKDtjb21wYXJlUGFpcihoYVt3YV0sU2EpPjA7KXdhPXdhLTF9Y29tcGFyZVBhaXIoaGFbeGFdLFNhKT09PTA/c3dhcChoYSx4YSx3YSk6KHdhPXdhKzEsc3dhcChoYSx3YSxiYSkpLHdhPD1hYSYmKHhhPXdhKzEpLGFhPD13YSYmKGJhPXdhLTEpfX1mdW5jdGlvbiB0b3BLSW1wbChoYSxhYSx4YSxiYSxTYSl7Y29uc3QgVGE9YWFbYWEubGVuZ3RoLTFdLFt3YSxFYV09W2hhLmxlbmd0aC9UYSxUYV0sa2E9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSh4YSx3YSpiYSksQWE9Z2V0VHlwZWRBcnJheUZyb21EVHlwZSgiaW50MzIiLHdhKmJhKTtmb3IobGV0IExhPTA7TGE8d2E7TGErKyl7Y29uc3QgZWw9TGEqRWEsdGw9aGEuc3ViYXJyYXkoZWwsZWwrRWEpO2xldCBubD1uZXcgQXJyYXkodGwubGVuZ3RoKTt0bC5mb3JFYWNoKChhbCxsbCk9Pm5sW2xsXT17dmFsdWU6YWwsaW5kZXg6bGx9KSxiYTxubC5sZW5ndGgmJihzZWxlY3QkMShubCxiYSksbmw9bmwuc2xpY2UoMCxiYSkpLFNhJiZubC5zb3J0KGNvbXBhcmVQYWlyKTtjb25zdCBzbD1MYSpiYSxybD1rYS5zdWJhcnJheShzbCxzbCtiYSksb2w9QWEuc3ViYXJyYXkoc2wsc2wrYmEpO2ZvcihsZXQgYWw9MDthbDxiYTthbCsrKXJsW2FsXT1ubFthbF0udmFsdWUsb2xbYWxdPW5sW2FsXS5pbmRleH1jb25zdCBGYT1hYS5zbGljZSgpO3JldHVybiBGYVtGYS5sZW5ndGgtMV09YmEsW2J1ZmZlcihGYSx4YSxrYSksYnVmZmVyKEZhLCJpbnQzMiIsQWEpXX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB1bmlxdWVJbXBsKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1wYXJzZUF4aXNQYXJhbShhYSx4YSlbMF0sVGE9WzEseGFbMF0sMV07Zm9yKGxldCBubD0wO25sPFNhO25sKyspVGFbMF0qPXhhW25sXTtUYVsxXT14YVtTYV07Zm9yKGxldCBubD1TYSsxO25sPHhhLmxlbmd0aDtubCsrKVRhWzJdKj14YVtubF07Y29uc3Qgd2E9bmV3IE1hcCxFYT1uZXcgSW50MzJBcnJheSh4YVtTYV0pLGthPW5ldyBUZW5zb3JCdWZmZXIoVGEsYmEsaGEpLEFhPVtdLEZhPVRhWzBdPT09MSYmVGFbMl09PT0xO2ZvcihsZXQgbmw9MDtubDx4YVtTYV07bmwrKyl7bGV0IHNsO2lmKEZhKXNsPWhhW25sXS50b1N0cmluZygpO2Vsc2V7Y29uc3Qgb2w9W107Zm9yKGxldCBhbD0wO2FsPFRhWzBdO2FsKyspZm9yKGxldCBsbD0wO2xsPFRhWzJdO2xsKyspb2wucHVzaChrYS5nZXQoYWwsbmwsbGwpKTtzbD1vbC5qb2luKCIsIil9Y29uc3Qgcmw9d2EuZ2V0KHNsKTtpZihybCE9bnVsbClFYVtubF09cmw7ZWxzZXtjb25zdCBvbD13YS5zaXplO3dhLnNldChzbCxvbCksRWFbbmxdPW9sLEFhLnB1c2gobmwpfX1jb25zdCBMYT1UYS5zbGljZSgpO0xhWzFdPXdhLnNpemU7Y29uc3QgZWw9bmV3IFRlbnNvckJ1ZmZlcihMYSxiYSk7QWEuZm9yRWFjaCgobmwsc2wpPT57Zm9yKGxldCBybD0wO3JsPFRhWzBdO3JsKyspZm9yKGxldCBvbD0wO29sPFRhWzJdO29sKyspZWwuc2V0KGthLmdldChybCxubCxvbCkscmwsc2wsb2wpfSk7Y29uc3QgdGw9eGEuc2xpY2UoKTtyZXR1cm4gdGxbU2FdPUxhWzFdLHtvdXRwdXRWYWx1ZXM6ZWwudmFsdWVzLG91dHB1dFNoYXBlOnRsLGluZGljZXM6RWF9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL3ZhciBzaGFyZWQ9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsYWRkSW1wbCxiaW5jb3VudEltcGwsYmluY291bnRSZWR1Y2VJbXBsLGJpdHdpc2VBbmRJbXBsLGNhc3RJbXBsLGNlaWxJbXBsLGNvbmNhdEltcGw6Y29uY2F0SW1wbCQxLGVxdWFsSW1wbCxleHBJbXBsLGV4cG0xSW1wbCxmbG9vckRpdkltcGwsZmxvb3JJbXBsLGdhdGhlck5kSW1wbCxnYXRoZXJWMkltcGwsZ3JlYXRlckVxdWFsSW1wbCxncmVhdGVySW1wbCxsZXNzRXF1YWxJbXBsLGxlc3NJbXBsLGxpblNwYWNlSW1wbCxsb2dJbXBsLG1heEltcGw6bWF4SW1wbCQxLG1heGltdW1JbXBsLG1pbmltdW1JbXBsLG11bHRpcGx5SW1wbCxuZWdJbXBsLG5vdEVxdWFsSW1wbCxwcm9kSW1wbCxyYWdnZWRHYXRoZXJJbXBsLHJhZ2dlZFJhbmdlSW1wbCxyYWdnZWRUZW5zb3JUb1RlbnNvckltcGwscmFuZ2VJbXBsLHJzcXJ0SW1wbCxzY2F0dGVySW1wbCxzaWdtb2lkSW1wbCxzaW1wbGVBYnNJbXBsLHNsaWNlSW1wbCxzcGFyc2VGaWxsRW1wdHlSb3dzSW1wbCxzcGFyc2VSZXNoYXBlSW1wbCxzcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbCxzcXJ0SW1wbCxzcXVhcmVkRGlmZmVyZW5jZUltcGwsc3RhdGljUmVnZXhSZXBsYWNlSW1wbCxzdHJpZGVkU2xpY2VJbXBsLHN0cmluZ05HcmFtc0ltcGwsc3RyaW5nU3BsaXRJbXBsLHN0cmluZ1RvSGFzaEJ1Y2tldEZhc3RJbXBsLHN1YkltcGwsdGlsZUltcGwsdG9wS0ltcGwsdHJhbnNwb3NlSW1wbDp0cmFuc3Bvc2VJbXBsJDEsdW5pcXVlSW1wbH0pOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0e2FkZEltcGw6YWRkSW1wbENQVSxiaW5jb3VudEltcGw6YmluY291bnRJbXBsQ1BVLGJpbmNvdW50UmVkdWNlSW1wbDpiaW5jb3VudFJlZHVjZUltcGxDUFUsYml0d2lzZUFuZEltcGw6Yml0d2lzZUFuZEltcGxDUFUsY2FzdEltcGw6Y2FzdEltcGxDUFUsY2VpbEltcGw6Y2VpbEltcGxDUFUsY29uY2F0SW1wbDpjb25jYXRJbXBsQ1BVLGVxdWFsSW1wbDplcXVhbEltcGxDUFUsZXhwSW1wbDpleHBJbXBsQ1BVLGV4cG0xSW1wbDpleHBtMUltcGxDUFUsZmxvb3JJbXBsOmZsb29ySW1wbENQVSxnYXRoZXJOZEltcGw6Z2F0aGVyTmRJbXBsQ1BVLGdhdGhlclYySW1wbDpnYXRoZXJWMkltcGxDUFUsZ3JlYXRlckltcGw6Z3JlYXRlckltcGxDUFUsZ3JlYXRlckVxdWFsSW1wbDpncmVhdGVyRXF1YWxJbXBsQ1BVLGxlc3NJbXBsOmxlc3NJbXBsQ1BVLGxlc3NFcXVhbEltcGw6bGVzc0VxdWFsSW1wbENQVSxsaW5TcGFjZUltcGw6bGluU3BhY2VJbXBsQ1BVLGxvZ0ltcGw6bG9nSW1wbENQVSxtYXhJbXBsOm1heEltcGxDUFUsbWF4aW11bUltcGw6bWF4aW11bUltcGxDUFUsbWluaW11bUltcGw6bWluaW11bUltcGxDUFUsbXVsdGlwbHlJbXBsOm11bHRpcGx5SW1wbENQVSxuZWdJbXBsOm5lZ0ltcGxDUFUsbm90RXF1YWxJbXBsOm5vdEVxdWFsSW1wbENQVSxwcm9kSW1wbDpwcm9kSW1wbENQVSxyYWdnZWRHYXRoZXJJbXBsOnJhZ2dlZEdhdGhlckltcGxDUFUscmFnZ2VkUmFuZ2VJbXBsOnJhZ2dlZFJhbmdlSW1wbENQVSxyYWdnZWRUZW5zb3JUb1RlbnNvckltcGw6cmFnZ2VkVGVuc29yVG9UZW5zb3JJbXBsQ1BVLHJhbmdlSW1wbDpyYW5nZUltcGxDUFUscnNxcnRJbXBsOnJzcXJ0SW1wbENQVSxzY2F0dGVySW1wbDpzY2F0dGVySW1wbENQVSxzaWdtb2lkSW1wbDpzaWdtb2lkSW1wbENQVSxzaW1wbGVBYnNJbXBsOnNpbXBsZUFic0ltcGxDUFUsc2xpY2VJbXBsOnNsaWNlSW1wbENQVSxzcGFyc2VGaWxsRW1wdHlSb3dzSW1wbDpzcGFyc2VGaWxsRW1wdHlSb3dzSW1wbENQVSxzcGFyc2VSZXNoYXBlSW1wbDpzcGFyc2VSZXNoYXBlSW1wbENQVSxzcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbDpzcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbENQVSxzcXJ0SW1wbDpzcXJ0SW1wbENQVSxzdGF0aWNSZWdleFJlcGxhY2VJbXBsOnN0YXRpY1JlZ2V4UmVwbGFjZUltcGxDUFUsc3RyaWRlZFNsaWNlSW1wbDpzdHJpZGVkU2xpY2VJbXBsQ1BVLHN0cmluZ05HcmFtc0ltcGw6c3RyaW5nTkdyYW1zSW1wbENQVSxzdHJpbmdTcGxpdEltcGw6c3RyaW5nU3BsaXRJbXBsQ1BVLHN0cmluZ1RvSGFzaEJ1Y2tldEZhc3RJbXBsOnN0cmluZ1RvSGFzaEJ1Y2tldEZhc3RJbXBsQ1BVLHN1YkltcGw6c3ViSW1wbENQVSx0aWxlSW1wbDp0aWxlSW1wbENQVSx0b3BLSW1wbDp0b3BLSW1wbENQVSx0cmFuc3Bvc2VJbXBsOnRyYW5zcG9zZUltcGxDUFUsdW5pcXVlSW1wbDp1bmlxdWVJbXBsQ1BVfT1zaGFyZWQ7LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0VmVjQ2hhbm5lbHMoaGEsYWEpe3JldHVyblsieCIsInkiLCJ6IiwidyIsInUiLCJ2Il0uc2xpY2UoMCxhYSkubWFwKHhhPT5gJHtoYX0uJHt4YX1gKX1mdW5jdGlvbiBnZXRDaGFubmVscyhoYSxhYSl7cmV0dXJuIGFhPT09MT9baGFdOmdldFZlY0NoYW5uZWxzKGhhLGFhKX1mdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMkMihoYSxhYSl7aWYoaGE9PT0xKXJldHVybiJyYyI7bGV0IHhhPSIiO2ZvcihsZXQgYmE9MDtiYTxoYTtiYSsrKXhhKz1hYVtiYV0sYmE8aGEtMSYmKHhhKz0iLCIpO3JldHVybiB4YX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBQYWNrUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7aWYodGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSExLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5yYW5rPWFhLmxlbmd0aCx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3Jtcyh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy5yYW5rPT09MCl0aGlzLnVzZXJDb2RlPWAKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICBzZXRPdXRwdXQodmVjNChnZXRBKCksIDAuLCAwLiwgMC4pKTsKICAgICAgICB9CiAgICAgIGA7ZWxzZXtjb25zdCB4YT1nZXRDaGFubmVscygicmMiLHRoaXMucmFuayksYmE9Z2V0Q29vcmRzRGF0YVR5cGUodGhpcy5yYW5rKSxTYT10aGlzLmdldE91dE9mQm91bmRzQ29uZGl0aW9uKHhhKSxUYT10aGlzLmdldFNldHVwKHhhKSx3YT10aGlzLmdldE91dHB1dCh4YSk7dGhpcy51c2VyQ29kZT1gCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgJHtiYX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTsKCiAgICAgICAgICBpZigke1NhfSkgewogICAgICAgICAgICBzZXRPdXRwdXQodmVjNCgwKSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAke1RhfQoKICAgICAgICAgICAgc2V0T3V0cHV0KHZlYzQoJHt3YX0pKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIGB9fWdldFNvdXJjZUNvb3Jkc0FycihhYSl7Y29uc3QgeGE9W107Zm9yKGxldCBiYT0wO2JhPD0xO2JhKyspZm9yKGxldCBTYT0wO1NhPD0xO1NhKyspe2xldCBUYT1gJHtiYT09PTA/InIiOiJycDEifSwgJHtTYT09PTA/ImMiOiJjcDEifWA7Zm9yKGxldCB3YT0yO3dhPHRoaXMucmFuazt3YSsrKVRhPWAke2FhW2FhLmxlbmd0aC0xLXdhXX0sYCtUYTt4YS5wdXNoKFRhKX1yZXR1cm4geGF9Z2V0T3V0T2ZCb3VuZHNDb25kaXRpb24oYWEpe2lmKHRoaXMucmFuaz09PTEpcmV0dXJuYHJjID4gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlIjp0aGlzLm91dHB1dFNoYXBlWzBdfWA7bGV0IHhhPSIiO2ZvcihsZXQgYmE9dGhpcy5yYW5rLTI7YmE8dGhpcy5yYW5rO2JhKyspeGErPWAke2FhW2JhXX0gPj0gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/YG91dFNoYXBlWyR7YmF9XWA6dGhpcy5vdXRwdXRTaGFwZVtiYV19YCxiYTx0aGlzLnJhbmstMSYmKHhhKz0ifHwiKTtyZXR1cm4geGF9Z2V0U2V0dXAoYWEpe2lmKHRoaXMucmFuaz09PTEpcmV0dXJuIiI7Y29uc3QgeGE9YWEuc2xpY2UoLTIpLGJhPXRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9gb3V0U2hhcGVbJHt0aGlzLnJhbmt9IC0gMV1gOnRoaXMub3V0cHV0U2hhcGVbdGhpcy5yYW5rLTFdLFNhPXRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz9gb3V0U2hhcGVbJHt0aGlzLnJhbmt9IC0gMl1gOnRoaXMub3V0cHV0U2hhcGVbdGhpcy5yYW5rLTJdO3JldHVybmAKICAgICAgaW50IHIgPSAke3hhWzBdfTsKICAgICAgaW50IGMgPSAke3hhWzFdfTsKICAgICAgaW50IHJwMSA9IHIgKyAxOwogICAgICBpbnQgY3AxID0gYyArIDE7CgogICAgICBib29sIGNFZGdlID0gY3AxID49ICR7YmF9OwogICAgICBib29sIHJFZGdlID0gcnAxID49ICR7U2F9OwogICAgYH1nZXRPdXRwdXQoYWEpe2NvbnN0IHhhPXRoaXMuZ2V0U291cmNlQ29vcmRzQXJyKGFhKTtyZXR1cm4gdGhpcy5yYW5rPT09MT9gZ2V0QShyYyksIChyYyArIDEgPj0gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlIjp0aGlzLm91dHB1dFNoYXBlWzBdfSA/IDAuIDogZ2V0QShyYyArIDEpKSwgMCwgMGA6YGdldEEoJHt4YVswXX0pLAogICAgICAgICAgICBjRWRnZSA/IDAuIDogZ2V0QSgke3hhWzFdfSksCiAgICAgICAgICAgIHJFZGdlID8gMC4gOiBnZXRBKCR7eGFbMl19KSwKICAgICAgICAgICAgckVkZ2UgfHwgY0VkZ2UgPyAwLiA6IGdldEEoJHt4YVszXX0pYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmVzaGFwZVBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToiaW5wdXRTaGFwZSIsdHlwZToiaXZlYzMifV0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3Jtcyh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCk7bGV0IGJhPSIiO2ZvcihsZXQgU2E9MDtTYTw0O1NhKyspe2xldCBUYT0idGhpc1JDID0gcmM7IjtTYSUyPT09MSYmKFRhKz0idGhpc1JDLnogKz0gMTsiKSxTYT4xJiYoVGErPSJ0aGlzUkMueSArPSAxOyIpLGJhKz1gCiAgICAgICAgJHtUYX0KICAgICAgICAke1NhPjA/ImlmKHRoaXNSQy55IDwgcm93cyAmJiB0aGlzUkMueiA8IGNvbHMpeyI6IiJ9CiAgICAgICAgICBpbnQgZmxhdEluZGV4ID0gZ2V0RmxhdEluZGV4KHRoaXNSQyk7CgogICAgICAgICAgaXZlYzMgaW5wdXRSQyA9IGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGZsYXRJbmRleCk7CiAgICAgICAgICB2ZWMyIGlucHV0UkNJbm5lckRpbXMgPSB2ZWMyKGZsb2F0KGlucHV0UkMueSksZmxvYXQoaW5wdXRSQy56KSk7CgogICAgICAgICAgcmVzdWx0WyR7U2F9XSA9CiAgICAgICAgICAgIGdldENoYW5uZWwoZ2V0QShpbnB1dFJDLngsIGlucHV0UkMueSwgaW5wdXRSQy56KSwgaW5wdXRSQ0lubmVyRGltcyk7CiAgICAgICAgJHtTYT4wPyJ9IjoiIn0KICAgICAgYH10aGlzLnVzZXJDb2RlPWAKICAgICAgJHtnZXRSZXNoYXBlZElucHV0Q29vcmRzKHhhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcyl9CiAgICAgICR7dGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zP2dldEZsYXRJbmRleEZyb20zRE91dHB1dCgpOmdldEZsYXRJbmRleEZyb20zRChhYSl9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzMgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKCiAgICAgICAgaXZlYzMgdGhpc1JDOwogICAgICAgIGludCByb3dzID0gJHt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM/Im91dFNoYXBlWzFdIjphYVsxXX07CiAgICAgICAgaW50IGNvbHMgPSAke3RoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz8ib3V0U2hhcGVbMl0iOmFhWzJdfTsKCiAgICAgICAgJHtiYX0KCiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fWZ1bmN0aW9uIGdldFJlc2hhcGVkSW5wdXRDb29yZHMoaGEsYWEpe3JldHVybmAKICAgIGl2ZWMzIGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGludCBpbmRleCkgewogICAgICAke2FhP2dldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXhCeVVuaWZvcm0oWyJyIiwiYyIsImQiXSwiaW5wdXRTaGFwZSIpOmdldExvZ2ljYWxDb29yZGluYXRlc0Zyb21GbGF0SW5kZXgoWyJyIiwiYyIsImQiXSxoYSl9CiAgICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTsKICAgIH0KICBgfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFRleHR1cmVNYW5hZ2Vye2NvbnN0cnVjdG9yKGFhKXt0aGlzLmdwZ3B1PWFhLHRoaXMubnVtVXNlZFRleHR1cmVzPTAsdGhpcy5udW1GcmVlVGV4dHVyZXM9MCx0aGlzLl9udW1CeXRlc0FsbG9jYXRlZD0wLHRoaXMuX251bUJ5dGVzRnJlZT0wLHRoaXMuZnJlZVRleHR1cmVzPXt9LHRoaXMudXNlZFRleHR1cmVzPXt9LHRoaXMubG9nRW5hYmxlZD0hMX1hY3F1aXJlVGV4dHVyZShhYSx4YSxiYSl7Y29uc3QgU2E9Z2V0UGh5c2ljYWxGcm9tTG9naWNhbFRleHR1cmVUeXBlKHhhLGJhKSxUYT1nZXRLZXlGcm9tVGV4dHVyZVNoYXBlKGFhLFNhLGJhKTtUYSBpbiB0aGlzLmZyZWVUZXh0dXJlc3x8KHRoaXMuZnJlZVRleHR1cmVzW1RhXT1bXSksVGEgaW4gdGhpcy51c2VkVGV4dHVyZXN8fCh0aGlzLnVzZWRUZXh0dXJlc1tUYV09W10pO2NvbnN0IHdhPWNvbXB1dGVCeXRlcyhhYSxTYSx0aGlzLmdwZ3B1LmdsLHRoaXMuZ3BncHUudGV4dHVyZUNvbmZpZyxiYSk7aWYodGhpcy5mcmVlVGV4dHVyZXNbVGFdLmxlbmd0aD4wKXt0aGlzLm51bUZyZWVUZXh0dXJlcy0tLHRoaXMubnVtVXNlZFRleHR1cmVzKyssdGhpcy5fbnVtQnl0ZXNGcmVlLT13YSx0aGlzLmxvZygpO2NvbnN0IGthPXRoaXMuZnJlZVRleHR1cmVzW1RhXS5wb3AoKTtyZXR1cm4gdGhpcy51c2VkVGV4dHVyZXNbVGFdLnB1c2goa2EpLGthfWxldCBFYTtyZXR1cm4gU2E9PT1QaHlzaWNhbFRleHR1cmVUeXBlLlBBQ0tFRF8yWDJfRkxPQVQzMj9FYT10aGlzLmdwZ3B1LmNyZWF0ZVBhY2tlZE1hdHJpeFRleHR1cmUoYWFbMF0sYWFbMV0pOlNhPT09UGh5c2ljYWxUZXh0dXJlVHlwZS5QQUNLRURfMlgyX0ZMT0FUMTY/RWE9dGhpcy5ncGdwdS5jcmVhdGVGbG9hdDE2UGFja2VkTWF0cml4VGV4dHVyZShhYVswXSxhYVsxXSk6U2E9PT1QaHlzaWNhbFRleHR1cmVUeXBlLlVOUEFDS0VEX0ZMT0FUMzI/RWE9dGhpcy5ncGdwdS5jcmVhdGVGbG9hdDMyTWF0cml4VGV4dHVyZShhYVswXSxhYVsxXSk6U2E9PT1QaHlzaWNhbFRleHR1cmVUeXBlLlVOUEFDS0VEX0ZMT0FUMTY/RWE9dGhpcy5ncGdwdS5jcmVhdGVGbG9hdDE2TWF0cml4VGV4dHVyZShhYVswXSxhYVsxXSk6U2E9PT1QaHlzaWNhbFRleHR1cmVUeXBlLlBBQ0tFRF80WDFfVU5TSUdORURfQllURSYmKEVhPXRoaXMuZ3BncHUuY3JlYXRlVW5zaWduZWRCeXRlc01hdHJpeFRleHR1cmUoYWFbMF0sYWFbMV0pKSx0aGlzLnVzZWRUZXh0dXJlc1tUYV0ucHVzaChFYSksdGhpcy5udW1Vc2VkVGV4dHVyZXMrKyx0aGlzLl9udW1CeXRlc0FsbG9jYXRlZCs9d2EsdGhpcy5sb2coKSxFYX1yZWxlYXNlVGV4dHVyZShhYSx4YSxiYSxTYSl7aWYodGhpcy5mcmVlVGV4dHVyZXM9PW51bGwpcmV0dXJuO2NvbnN0IFRhPWdldFBoeXNpY2FsRnJvbUxvZ2ljYWxUZXh0dXJlVHlwZShiYSxTYSksd2E9Z2V0S2V5RnJvbVRleHR1cmVTaGFwZSh4YSxUYSxTYSk7d2EgaW4gdGhpcy5mcmVlVGV4dHVyZXN8fCh0aGlzLmZyZWVUZXh0dXJlc1t3YV09W10pO2NvbnN0IEVhPWNvbXB1dGVCeXRlcyh4YSxUYSx0aGlzLmdwZ3B1LmdsLHRoaXMuZ3BncHUudGV4dHVyZUNvbmZpZyxTYSksa2E9ZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9ERUxFVEVfVEVYVFVSRV9USFJFU0hPTEQiKTtrYSE9PS0xJiZ0aGlzLl9udW1CeXRlc0FsbG9jYXRlZD5rYT8odGhpcy5ncGdwdS5kZWxldGVNYXRyaXhUZXh0dXJlKGFhLnRleHR1cmUpLHRoaXMuX251bUJ5dGVzQWxsb2NhdGVkLT1FYSk6KHRoaXMuZnJlZVRleHR1cmVzW3dhXS5wdXNoKGFhKSx0aGlzLm51bUZyZWVUZXh0dXJlcysrLHRoaXMuX251bUJ5dGVzRnJlZSs9RWEpLHRoaXMubnVtVXNlZFRleHR1cmVzLS07Y29uc3QgQWE9dGhpcy51c2VkVGV4dHVyZXNbd2FdLEZhPUFhJiZBYS5pbmRleE9mKGFhKTtpZihGYT09bnVsbHx8RmE8MCl0aHJvdyBuZXcgRXJyb3IoIkNhbm5vdCByZWxlYXNlIGEgdGV4dHVyZSB0aGF0IHdhcyBuZXZlciBwcm92aWRlZCBieSB0aGlzIHRleHR1cmUgbWFuYWdlciIpO0FhW0ZhXT1BYVtBYS5sZW5ndGgtMV0sQWEucG9wKCksdGhpcy5sb2coKX1sb2coKXtpZighdGhpcy5sb2dFbmFibGVkKXJldHVybjtjb25zdCBhYT10aGlzLm51bUZyZWVUZXh0dXJlcyt0aGlzLm51bVVzZWRUZXh0dXJlcztjb25zb2xlLmxvZygiRnJlZS9Vc2VkIixgJHt0aGlzLm51bUZyZWVUZXh0dXJlc30gLyAke3RoaXMubnVtVXNlZFRleHR1cmVzfWAsYCgke2FhfSlgKTtjb25zdCB4YT10aGlzLl9udW1CeXRlc0ZyZWUvdGhpcy5fbnVtQnl0ZXNBbGxvY2F0ZWQ7Y29uc29sZS5sb2coYEJ5dGVzIGFsbG9jYXRlZDogJHt0aGlzLl9udW1CeXRlc0FsbG9jYXRlZH1gKSxjb25zb2xlLmxvZyhgQnl0ZXMgdW51c2VkOiAke3RoaXMuX251bUJ5dGVzRnJlZX0gKCR7TWF0aC5yb3VuZCgxMDAqeGEpfSUpYCl9Z2V0IG51bUJ5dGVzQWxsb2NhdGVkKCl7cmV0dXJuIHRoaXMuX251bUJ5dGVzQWxsb2NhdGVkfWdldCBudW1CeXRlc0ZyZWUoKXtyZXR1cm4gdGhpcy5fbnVtQnl0ZXNGcmVlfWdldE51bVVzZWRUZXh0dXJlcygpe3JldHVybiB0aGlzLm51bVVzZWRUZXh0dXJlc31nZXROdW1GcmVlVGV4dHVyZXMoKXtyZXR1cm4gdGhpcy5udW1GcmVlVGV4dHVyZXN9ZGlzcG9zZSgpe2lmKHRoaXMuZnJlZVRleHR1cmVzIT1udWxsKXtmb3IoY29uc3QgYWEgaW4gdGhpcy5mcmVlVGV4dHVyZXMpdGhpcy5mcmVlVGV4dHVyZXNbYWFdLmZvckVhY2goeGE9Pnt0aGlzLmdwZ3B1LmRlbGV0ZU1hdHJpeFRleHR1cmUoeGEudGV4dHVyZSl9KTtmb3IoY29uc3QgYWEgaW4gdGhpcy51c2VkVGV4dHVyZXMpdGhpcy51c2VkVGV4dHVyZXNbYWFdLmZvckVhY2goeGE9Pnt0aGlzLmdwZ3B1LmRlbGV0ZU1hdHJpeFRleHR1cmUoeGEudGV4dHVyZSl9KTt0aGlzLmZyZWVUZXh0dXJlcz1udWxsLHRoaXMudXNlZFRleHR1cmVzPW51bGwsdGhpcy5udW1Vc2VkVGV4dHVyZXM9MCx0aGlzLm51bUZyZWVUZXh0dXJlcz0wLHRoaXMuX251bUJ5dGVzQWxsb2NhdGVkPTAsdGhpcy5fbnVtQnl0ZXNGcmVlPTB9fX1mdW5jdGlvbiBudW1CeXRlc0ZvckludGVybmFsRm9ybWF0KGhhLGFhKXtjb25zdCB4YT1oYTtpZihhYT09PXhhLlIzMkYpcmV0dXJuIDQ7aWYoYWE9PT14YS5SMTZGKXJldHVybiAyO2lmKGFhPT09eGEuUkdCQTMyRilyZXR1cm4gMTY7aWYoYWE9PT1oYS5SR0JBKXJldHVybiAxNjtpZihhYT09PXhhLlJHQkExNkYpcmV0dXJuIDg7aWYoYWE9PT14YS5SR0JBOClyZXR1cm4gNDt0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gaW50ZXJuYWwgZm9ybWF0ICR7YWF9YCl9ZnVuY3Rpb24gY29tcHV0ZUJ5dGVzKGhhLGFhLHhhLGJhLFNhKXtjb25zdCBUYT1pbnRlcm5hbEZvcm1hdEZvclBoeXNpY2FsVGV4VHlwZShhYSxiYSk7bGV0IHdhO2lmKFNhKXtjb25zdFtrYSxBYV09Z2V0UGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQoaGFbMF0saGFbMV0pO3dhPWthKkFhfWVsc2V7Y29uc3Rba2EsQWFdPWdldFVucGFja2VkTWF0cml4VGV4dHVyZVNoYXBlV2lkdGhIZWlnaHQoaGFbMF0saGFbMV0pO3dhPWthKkFhfWNvbnN0IEVhPW51bUJ5dGVzRm9ySW50ZXJuYWxGb3JtYXQoeGEsVGEpO3JldHVybiB3YSpFYX1mdW5jdGlvbiBpbnRlcm5hbEZvcm1hdEZvclBoeXNpY2FsVGV4VHlwZShoYSxhYSl7c3dpdGNoKGhhKXtjYXNlIFBoeXNpY2FsVGV4dHVyZVR5cGUuUEFDS0VEXzJYMl9GTE9BVDMyOnJldHVybiBnZXRJbnRlcm5hbEZvcm1hdEZvclBhY2tlZE1hdHJpeFRleHR1cmUoYWEpO2Nhc2UgUGh5c2ljYWxUZXh0dXJlVHlwZS5QQUNLRURfMlgyX0ZMT0FUMTY6cmV0dXJuIGdldEludGVybmFsRm9ybWF0Rm9yRmxvYXQxNlBhY2tlZE1hdHJpeFRleHR1cmUoYWEpO2Nhc2UgUGh5c2ljYWxUZXh0dXJlVHlwZS5VTlBBQ0tFRF9GTE9BVDMyOnJldHVybiBnZXRJbnRlcm5hbEZvcm1hdEZvckZsb2F0MzJNYXRyaXhUZXh0dXJlKGFhKTtjYXNlIFBoeXNpY2FsVGV4dHVyZVR5cGUuVU5QQUNLRURfRkxPQVQxNjpyZXR1cm4gZ2V0SW50ZXJuYWxGb3JtYXRGb3JGbG9hdDE2TWF0cml4VGV4dHVyZShhYSk7Y2FzZSBQaHlzaWNhbFRleHR1cmVUeXBlLlBBQ0tFRF80WDFfVU5TSUdORURfQllURTpyZXR1cm4gZ2V0SW50ZXJuYWxGb3JtYXRGb3JVbnNpZ25lZEJ5dGVzTWF0cml4VGV4dHVyZShhYSk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcGh5c2ljYWwgdGV4dHVyZSB0eXBlICR7aGF9YCl9fWZ1bmN0aW9uIGdldFBoeXNpY2FsVGV4dHVyZUZvclJlbmRlcmluZyhoYSl7cmV0dXJuIGVudigpLmdldEJvb2woIldFQkdMX1JFTkRFUl9GTE9BVDMyX0VOQUJMRUQiKT9oYT9QaHlzaWNhbFRleHR1cmVUeXBlLlBBQ0tFRF8yWDJfRkxPQVQzMjpQaHlzaWNhbFRleHR1cmVUeXBlLlVOUEFDS0VEX0ZMT0FUMzI6aGE/UGh5c2ljYWxUZXh0dXJlVHlwZS5QQUNLRURfMlgyX0ZMT0FUMTY6UGh5c2ljYWxUZXh0dXJlVHlwZS5VTlBBQ0tFRF9GTE9BVDE2fWZ1bmN0aW9uIGdldFBoeXNpY2FsRnJvbUxvZ2ljYWxUZXh0dXJlVHlwZShoYSxhYSl7aWYoaGE9PT1UZXh0dXJlVXNhZ2UuVVBMT0FEKXJldHVybiBQaHlzaWNhbFRleHR1cmVUeXBlLlBBQ0tFRF8yWDJfRkxPQVQzMjtpZihoYT09PVRleHR1cmVVc2FnZS5SRU5ERVJ8fGhhPT1udWxsKXJldHVybiBnZXRQaHlzaWNhbFRleHR1cmVGb3JSZW5kZXJpbmcoYWEpO2lmKGhhPT09VGV4dHVyZVVzYWdlLkRPV05MT0FEfHxoYT09PVRleHR1cmVVc2FnZS5QSVhFTFMpcmV0dXJuIFBoeXNpY2FsVGV4dHVyZVR5cGUuUEFDS0VEXzRYMV9VTlNJR05FRF9CWVRFO3Rocm93IG5ldyBFcnJvcihgVW5rbm93biBsb2dpY2FsIHRleHR1cmUgdHlwZSAke2hhfWApfWZ1bmN0aW9uIGdldEtleUZyb21UZXh0dXJlU2hhcGUoaGEsYWEseGEpe3JldHVybmAke2hhWzBdfV8ke2hhWzFdfV8ke2FhfV8ke3hhfWB9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgVW5hcnlPcFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgZmxvYXQgdW5hcnlPcGVyYXRpb24oZmxvYXQgeCkgewogICAgICAgICR7eGF9CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBmbG9hdCB4ID0gZ2V0QUF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgeSA9IHVuYXJ5T3BlcmF0aW9uKHgpOwoKICAgICAgICBzZXRPdXRwdXQoeSk7CiAgICAgIH0KICAgIGB9fWNvbnN0IENIRUNLX05BTl9TTklQUEVUJDE9ImlmIChpc25hbih4KSkgcmV0dXJuIHg7IixMSU5FQVIkMT0icmV0dXJuIHg7IixBQlMkMT0icmV0dXJuIGFicyh4KTsiLEVMVSQyPSJyZXR1cm4gKHggPj0gMC4wKSA/IHggOiAoZXhwKHgpIC0gMS4wKTsiLFJFTFUkMj1DSEVDS19OQU5fU05JUFBFVCQxK2AKICByZXR1cm4gKHggPCAwLjApID8gMC4wIDogeDsKYCxSRUxVNiQyPUNIRUNLX05BTl9TTklQUEVUJDErYAogIHJldHVybiAoeCA8IDAuMCkgPyAwLjAgOiBtaW4oNi4wLCB4KTsKYCxDTE9ORT0icmV0dXJuIHg7IixTSUdNT0lEJDI9InJldHVybiAxLjAgLyAoMS4wICsgZXhwKC0xLjAgKiB4KSk7IjsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMSU5FQVI9InJldHVybiB4OyIsRUxVJDE9YAogIHZlYzQgcmVzdWx0OwoKICByZXN1bHQuciA9ICh4LnIgPj0gMC4wKSA/IHguciA6IChleHAoeC5yKSAtIDEuMCk7CiAgcmVzdWx0LmcgPSAoeC5nID49IDAuMCkgPyB4LmcgOiAoZXhwKHguZykgLSAxLjApOwogIHJlc3VsdC5iID0gKHguYiA+PSAwLjApID8geC5iIDogKGV4cCh4LmIpIC0gMS4wKTsKICByZXN1bHQuYSA9ICh4LmEgPj0gMC4wKSA/IHguYSA6IChleHAoeC5hKSAtIDEuMCk7CgogIHJldHVybiByZXN1bHQ7CmAsUkVMVSQxPWAKICB2ZWM0IHJlc3VsdCA9IHggKiB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoeCwgdmVjNCgwLjApKSk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKCiAgcmVzdWx0LnIgPSBpc05hTi5yID8geC5yIDogcmVzdWx0LnI7CiAgcmVzdWx0LmcgPSBpc05hTi5nID8geC5nIDogcmVzdWx0Lmc7CiAgcmVzdWx0LmIgPSBpc05hTi5iID8geC5iIDogcmVzdWx0LmI7CiAgcmVzdWx0LmEgPSBpc05hTi5hID8geC5hIDogcmVzdWx0LmE7CgogIHJldHVybiByZXN1bHQ7CmAsUkVMVTYkMT1gCiAgdmVjNCByZXN1bHQgPSBtaW4oeCwgdmVjNCg2LikpICogdmVjNChncmVhdGVyVGhhbkVxdWFsKHgsIHZlYzQoMC4wKSkpOwogIGJ2ZWM0IGlzTmFOID0gaXNuYW4oeCk7CgogIHJlc3VsdC5yID0gaXNOYU4uciA/IHguciA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNOYU4uZyA/IHguZyA6IHJlc3VsdC5nOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6IHJlc3VsdC5iOwogIHJlc3VsdC5hID0gaXNOYU4uYSA/IHguYSA6IHJlc3VsdC5hOwoKICByZXR1cm4gcmVzdWx0OwpgLFNJR01PSUQkMT0icmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLTEuMCAqIHgpKTsiO2NsYXNzIFVuYXJ5T3BQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3Jtcyh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCksdGhpcy51c2VyQ29kZT1gCiAgICAgIHZlYzQgdW5hcnlPcGVyYXRpb24odmVjNCB4KSB7CiAgICAgICAgJHt4YX0KICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIHZlYzQgeCA9IGdldEFBdE91dENvb3JkcygpOwogICAgICAgIHZlYzQgeSA9IHVuYXJ5T3BlcmF0aW9uKHgpOwoKICAgICAgICBzZXRPdXRwdXQoeSk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFVucGFja1Byb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdCB4YT1hYS5sZW5ndGgsYmE9Z2V0Q2hhbm5lbHMoInJjIix4YSksU2E9Z2V0Q29vcmRzRGF0YVR5cGUoeGEpLFRhPWdldFNvdXJjZUNvb3JkcyQyKHhhLGJhKSx3YT1iYS5zbGljZSgtMiksRWE9eGE8PTE/InJjIjpgdmVjMigke3dhLmpvaW4oIiwiKX0pYDt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7U2F9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgdmVjNCBwYWNrZWRJbnB1dCA9IGdldEEoJHtUYX0pOwoKICAgICAgICBzZXRPdXRwdXQoZ2V0Q2hhbm5lbChwYWNrZWRJbnB1dCwgJHtFYX0pKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgd2hlcmVJbXBsPXdoZXJlSW1wbCQxLEVQU0lMT05fRkxPQVQzMj0xZS03LEVQU0lMT05fRkxPQVQxNj0xZS00LGJpbmFyeUNhY2hlcz17fTtmdW5jdGlvbiBnZXRCaW5hcnlDYWNoZShoYSl7cmV0dXJuIGhhIGluIGJpbmFyeUNhY2hlc3x8KGJpbmFyeUNhY2hlc1toYV09e30pLGJpbmFyeUNhY2hlc1toYV19Y29uc3QgQ1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQ9ZW52KCkuZ2V0TnVtYmVyKCJDUFVfSEFORE9GRl9TSVpFX1RIUkVTSE9MRCIpLEJFRk9SRV9QQUdJTkdfQ09OU1RBTlQ9NjAwO2Z1bmN0aW9uIG51bU1CQmVmb3JlV2FybmluZygpe3JldHVybiBlbnYoKS5nbG9iYWwuc2NyZWVuPT1udWxsPzEwMjQ6ZW52KCkuZ2xvYmFsLnNjcmVlbi5oZWlnaHQqZW52KCkuZ2xvYmFsLnNjcmVlbi53aWR0aCp3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbypCRUZPUkVfUEFHSU5HX0NPTlNUQU5ULzEwMjQvMTAyNH1jbGFzcyBNYXRoQmFja2VuZFdlYkdMIGV4dGVuZHMgS2VybmVsQmFja2VuZHtuZXh0RGF0YUlkKCl7cmV0dXJuIE1hdGhCYWNrZW5kV2ViR0wubmV4dERhdGFJZCsrfWNvbnN0cnVjdG9yKGFhKXtpZihzdXBlcigpLHRoaXMucGVuZGluZ1JlYWQ9bmV3IFdlYWtNYXAsdGhpcy5wZW5kaW5nRGlzcG9zYWw9bmV3IFdlYWtTZXQsdGhpcy5kYXRhUmVmQ291bnQ9bmV3IFdlYWtNYXAsdGhpcy5udW1CeXRlc0luR1BVPTAsdGhpcy51cGxvYWRXYWl0TXM9MCx0aGlzLmRvd25sb2FkV2FpdE1zPTAsdGhpcy5sYXN0R2xGbHVzaFRpbWU9MCx0aGlzLndhcm5lZEFib3V0TWVtb3J5PSExLHRoaXMucGVuZGluZ0RlbGV0ZXM9MCx0aGlzLmRpc3Bvc2VkPSExLCFlbnYoKS5nZXRCb29sKCJIQVNfV0VCR0wiKSl0aHJvdyBuZXcgRXJyb3IoIldlYkdMIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBkZXZpY2UiKTtsZXQgeGE7aWYoYWEhPW51bGwpe2lmKGFhIGluc3RhbmNlb2YgR1BHUFVDb250ZXh0KXhhPWFhO2Vsc2V7Y29uc3QgYmE9Z2V0V2ViR0xDb250ZXh0KGVudigpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpLGFhKTt4YT1uZXcgR1BHUFVDb250ZXh0KGJhKX10aGlzLmJpbmFyeUNhY2hlPXt9LHRoaXMuZ3BncHVDcmVhdGVkTG9jYWxseT0hMX1lbHNle2NvbnN0IGJhPWdldFdlYkdMQ29udGV4dChlbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKSk7eGE9bmV3IEdQR1BVQ29udGV4dChiYSksdGhpcy5iaW5hcnlDYWNoZT1nZXRCaW5hcnlDYWNoZShlbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKSksdGhpcy5ncGdwdUNyZWF0ZWRMb2NhbGx5PSEwfXRoaXMuZ3BncHU9eGEsdGhpcy5jYW52YXM9dGhpcy5ncGdwdS5nbC5jYW52YXMsdGhpcy50ZXh0dXJlTWFuYWdlcj1uZXcgVGV4dHVyZU1hbmFnZXIodGhpcy5ncGdwdSksdGhpcy5udW1NQkJlZm9yZVdhcm5pbmc9bnVtTUJCZWZvcmVXYXJuaW5nKCksdGhpcy50ZXhEYXRhPW5ldyBEYXRhU3RvcmFnZSh0aGlzLGVuZ2luZSgpKX1udW1EYXRhSWRzKCl7cmV0dXJuIHRoaXMudGV4RGF0YS5udW1EYXRhSWRzKCktdGhpcy5wZW5kaW5nRGVsZXRlc313cml0ZVRleHR1cmUoYWEseGEsYmEsU2EsVGEsd2Epe2NvbnN0IEVhPXRoaXMubWFrZVRlbnNvckluZm8oeGEsYmEpLGthPXRoaXMudGV4RGF0YS5nZXQoRWEuZGF0YUlkKTtrYS5pc1BhY2tlZD0hMSxrYS50ZXh0dXJlPXt0ZXh0dXJlOmFhLHRleFNoYXBlOltTYSxUYV19LGthLnRleFNoYXBlPVtTYSxUYV07Y29uc3QgQWE9Z2V0U2hhcGVBczNEKHhhKSxGYT1uZXcgRW5jb2RlTWF0cml4UHJvZ3JhbShBYSwhMSx3YSksTGE9dGhpcy5ydW5XZWJHTFByb2dyYW0oRmEsW0VhXSxiYSxbW1NhLFRhXV0pO3JldHVybiBMYS5zaGFwZT14YSxrYS50ZXh0dXJlPW51bGwsdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSksTGEuZGF0YUlkfXdyaXRlKGFhLHhhLGJhKXtpZigoZW52KCkuZ2V0Qm9vbCgiV0VCR0xfQ0hFQ0tfTlVNRVJJQ0FMX1BST0JMRU1TIil8fGVudigpLmdldEJvb2woIkRFQlVHIikpJiZ0aGlzLmNoZWNrTnVtZXJpY2FsUHJvYmxlbXMoYWEpLGJhPT09ImNvbXBsZXg2NCImJmFhIT1udWxsKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IHdyaXRlIHRvIGEgY29tcGxleDY0IGR0eXBlLiBQbGVhc2UgdXNlIHRmLmNvbXBsZXgocmVhbCwgaW1hZykuIik7Y29uc3QgU2E9e2lkOnRoaXMubmV4dERhdGFJZCgpfTtyZXR1cm4gdGhpcy50ZXhEYXRhLnNldChTYSx7c2hhcGU6eGEsZHR5cGU6YmEsdmFsdWVzOmFhLHVzYWdlOlRleHR1cmVVc2FnZS5VUExPQUQscmVmQ291bnQ6MX0pLFNhfXJlZkNvdW50KGFhKXtyZXR1cm4gdGhpcy50ZXhEYXRhLmhhcyhhYSk/dGhpcy50ZXhEYXRhLmdldChhYSkucmVmQ291bnQ6MH1pbmNSZWYoYWEpe2NvbnN0IHhhPXRoaXMudGV4RGF0YS5nZXQoYWEpO3hhLnJlZkNvdW50Kyt9ZGVjUmVmKGFhKXtpZih0aGlzLnRleERhdGEuaGFzKGFhKSl7Y29uc3QgeGE9dGhpcy50ZXhEYXRhLmdldChhYSk7eGEucmVmQ291bnQtLX19bW92ZShhYSx4YSxiYSxTYSxUYSl7aWYoZW52KCkuZ2V0Qm9vbCgiREVCVUciKSYmdGhpcy5jaGVja051bWVyaWNhbFByb2JsZW1zKHhhKSxTYT09PSJjb21wbGV4NjQiKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IHdyaXRlIHRvIGEgY29tcGxleDY0IGR0eXBlLiBQbGVhc2UgdXNlIHRmLmNvbXBsZXgocmVhbCwgaW1hZykuIik7dGhpcy50ZXhEYXRhLnNldChhYSx7c2hhcGU6YmEsZHR5cGU6U2EsdmFsdWVzOnhhLHVzYWdlOlRleHR1cmVVc2FnZS5VUExPQUQscmVmQ291bnQ6VGF9KX1kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhYSl7dGhpcy5kaXNwb3NlRGF0YShhYS5kYXRhSWQpfXJlYWRTeW5jKGFhKXtjb25zdCB4YT10aGlzLnRleERhdGEuZ2V0KGFhKSx7dmFsdWVzOmJhLGR0eXBlOlNhLGNvbXBsZXhUZW5zb3JJbmZvczpUYSxzbGljZTp3YSxzaGFwZTpFYSxpc1BhY2tlZDprYX09eGE7aWYod2EhPW51bGwpe2xldCBlbDtrYT9lbD1uZXcgVW5hcnlPcFBhY2tlZFByb2dyYW0oRWEsQ0xPTkUpOmVsPW5ldyBVbmFyeU9wUHJvZ3JhbShFYSxDTE9ORSk7Y29uc3QgdGw9dGhpcy5ydW5XZWJHTFByb2dyYW0oZWwsW3tkYXRhSWQ6YWEsc2hhcGU6RWEsZHR5cGU6U2F9XSxTYSksbmw9dGhpcy5yZWFkU3luYyh0bC5kYXRhSWQpO3JldHVybiB0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSxubH1pZihiYSE9bnVsbClyZXR1cm4gdGhpcy5jb252ZXJ0QW5kQ2FjaGVPbkNQVShhYSk7aWYoU2E9PT0ic3RyaW5nIilyZXR1cm4gYmE7Y29uc3QgQWE9dGhpcy5hY3RpdmVUaW1lcnMhPW51bGw7bGV0IEZhO0FhJiYoRmE9bm93KCkpO2xldCBMYTtpZihTYT09PSJjb21wbGV4NjQiKXtjb25zdCBlbD10aGlzLnJlYWRTeW5jKFRhLnJlYWwuZGF0YUlkKSx0bD10aGlzLnJlYWRTeW5jKFRhLmltYWcuZGF0YUlkKTtMYT1tZXJnZVJlYWxBbmRJbWFnQXJyYXlzKGVsLHRsKX1lbHNlIExhPXRoaXMuZ2V0VmFsdWVzRnJvbVRleHR1cmUoYWEpO3JldHVybiBBYSYmKHRoaXMuZG93bmxvYWRXYWl0TXMrPW5vdygpLUZhKSx0aGlzLmNvbnZlcnRBbmRDYWNoZU9uQ1BVKGFhLExhKX1hc3luYyByZWFkKGFhKXtpZih0aGlzLnBlbmRpbmdSZWFkLmhhcyhhYSkpe2NvbnN0IG5sPXRoaXMucGVuZGluZ1JlYWQuZ2V0KGFhKTtyZXR1cm4gbmV3IFByb21pc2Uoc2w9Pm5sLnB1c2goc2wpKX1jb25zdCB4YT10aGlzLnRleERhdGEuZ2V0KGFhKSx7dmFsdWVzOmJhLHNoYXBlOlNhLHNsaWNlOlRhLGR0eXBlOndhLGNvbXBsZXhUZW5zb3JJbmZvczpFYSxpc1BhY2tlZDprYX09eGE7aWYoVGEhPW51bGwpe2xldCBubDtrYT9ubD1uZXcgVW5hcnlPcFBhY2tlZFByb2dyYW0oU2EsQ0xPTkUpOm5sPW5ldyBVbmFyeU9wUHJvZ3JhbShTYSxDTE9ORSk7Y29uc3Qgc2w9dGhpcy5ydW5XZWJHTFByb2dyYW0obmwsW3tkYXRhSWQ6YWEsc2hhcGU6U2EsZHR5cGU6d2F9XSx3YSkscmw9dGhpcy5yZWFkKHNsLmRhdGFJZCk7cmV0dXJuIHRoaXMuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLHJsfWlmKGJhIT1udWxsKXJldHVybiB0aGlzLmNvbnZlcnRBbmRDYWNoZU9uQ1BVKGFhKTtpZihlbnYoKS5nZXRCb29sKCJERUJVRyIpJiYhZW52KCkuZ2V0Qm9vbCgiV0VCR0xfRE9XTkxPQURfRkxPQVRfRU5BQkxFRCIpJiZlbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTIpdGhyb3cgbmV3IEVycm9yKCJ0ZW5zb3IuZGF0YSgpIHdpdGggV0VCR0xfRE9XTkxPQURfRkxPQVRfRU5BQkxFRD1mYWxzZSBhbmQgV0VCR0xfVkVSU0lPTj0yIG5vdCB5ZXQgc3VwcG9ydGVkLiIpO2xldCBBYT1udWxsLEZhO2lmKHdhIT09ImNvbXBsZXg2NCImJmVudigpLmdldCgiV0VCR0xfQlVGRkVSX1NVUFBPUlRFRCIpKXtGYT10aGlzLmRlY29kZShhYSk7Y29uc3Qgbmw9dGhpcy50ZXhEYXRhLmdldChGYS5kYXRhSWQpO0FhPXRoaXMuZ3BncHUuY3JlYXRlQnVmZmVyRnJvbVRleHR1cmUobmwudGV4dHVyZS50ZXh0dXJlLC4uLmdldERlbnNlVGV4U2hhcGUoU2EpKX10aGlzLnBlbmRpbmdSZWFkLnNldChhYSxbXSksd2EhPT0iY29tcGxleDY0IiYmYXdhaXQgdGhpcy5ncGdwdS5jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTtsZXQgTGE7aWYod2E9PT0iY29tcGxleDY0Iil7Y29uc3Qgbmw9YXdhaXQgUHJvbWlzZS5hbGwoW3RoaXMucmVhZChFYS5yZWFsLmRhdGFJZCksdGhpcy5yZWFkKEVhLmltYWcuZGF0YUlkKV0pLHNsPW5sWzBdLHJsPW5sWzFdO0xhPW1lcmdlUmVhbEFuZEltYWdBcnJheXMoc2wscmwpfWVsc2UgaWYoQWE9PW51bGwpTGE9dGhpcy5nZXRWYWx1ZXNGcm9tVGV4dHVyZShhYSk7ZWxzZXtjb25zdCBubD1zaXplRnJvbVNoYXBlKFNhKTtMYT10aGlzLmdwZ3B1LmRvd25sb2FkRmxvYXQzMk1hdHJpeEZyb21CdWZmZXIoQWEsbmwpfWlmKEZhIT1udWxsJiZ0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKSxBYSE9bnVsbCl7Y29uc3Qgbmw9dGhpcy5ncGdwdS5nbDtjYWxsQW5kQ2hlY2sobmwsKCk9Pm5sLmRlbGV0ZUJ1ZmZlcihBYSkpfWNvbnN0IGVsPXRoaXMuY29udmVydEFuZENhY2hlT25DUFUoYWEsTGEpLHRsPXRoaXMucGVuZGluZ1JlYWQuZ2V0KGFhKTtyZXR1cm4gdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoYWEpLHRsLmZvckVhY2gobmw9Pm5sKGVsKSksdGhpcy5wZW5kaW5nRGlzcG9zYWwuaGFzKGFhKSYmKHRoaXMucGVuZGluZ0Rpc3Bvc2FsLmRlbGV0ZShhYSksdGhpcy5kaXNwb3NlRGF0YShhYSkmJmVuZ2luZSgpLnJlbW92ZURhdGFJZChhYSx0aGlzKSx0aGlzLnBlbmRpbmdEZWxldGVzLS0pLGVsfXJlYWRUb0dQVShhYSx4YT17fSl7Y29uc3QgYmE9dGhpcy50ZXhEYXRhLmdldChhYSkse3ZhbHVlczpTYSxzaGFwZTpUYSxzbGljZTp3YSxkdHlwZTpFYSxpc1BhY2tlZDprYSx0ZXh0dXJlOkFhfT1iYTtpZihFYT09PSJjb21wbGV4NjQiKXRocm93IG5ldyBFcnJvcigiRG9lcyBub3Qgc3VwcG9ydCByZWFkaW5nIHRleHR1cmUgZm9yIGNvbXBsZXg2NCBkdHlwZS4iKTtpZih3YSE9bnVsbCl7bGV0IHRsO2thP3RsPW5ldyBVbmFyeU9wUGFja2VkUHJvZ3JhbShUYSxDTE9ORSk6dGw9bmV3IFVuYXJ5T3BQcm9ncmFtKFRhLENMT05FKTtjb25zdCBubD10aGlzLnJ1bldlYkdMUHJvZ3JhbSh0bCxbe2RhdGFJZDphYSxzaGFwZTpUYSxkdHlwZTpFYX1dLEVhKSxzbD10aGlzLnJlYWRUb0dQVShubCx4YSk7cmV0dXJuIHRoaXMuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8obmwpLHNsfWlmKEFhPT1udWxsKXRocm93IFNhIT1udWxsP25ldyBFcnJvcigiRGF0YSBpcyBub3Qgb24gR1BVIGJ1dCBvbiBDUFUuIik6bmV3IEVycm9yKCJUaGVyZSBpcyBubyBkYXRhIG9uIEdQVSBvciBDUFUuIik7Y29uc3QgRmE9dGhpcy5kZWNvZGUoYWEseGEuY3VzdG9tVGV4U2hhcGUpLExhPWVuZ2luZSgpLm1ha2VUZW5zb3JGcm9tVGVuc29ySW5mbyhGYSksZWw9dGhpcy50ZXhEYXRhLmdldChGYS5kYXRhSWQpO3JldHVybiBPYmplY3QuYXNzaWduKHt0ZW5zb3JSZWY6TGF9LGVsLnRleHR1cmUpfWJ1ZmZlclN5bmMoYWEpe2NvbnN0IHhhPXRoaXMucmVhZFN5bmMoYWEuZGF0YUlkKTtpZihhYS5kdHlwZT09PSJzdHJpbmciKXRyeXtjb25zdCBiYT14YS5tYXAoU2E9PmRlY29kZVN0cmluZyhTYSkpO3JldHVybiBidWZmZXIoYWEuc2hhcGUsYWEuZHR5cGUsYmEpfWNhdGNoe3Rocm93IG5ldyBFcnJvcigiRmFpbGVkIHRvIGRlY29kZSBlbmNvZGVkIHN0cmluZyBieXRlcyBpbnRvIHV0Zi04Iil9cmV0dXJuIGJ1ZmZlcihhYS5zaGFwZSxhYS5kdHlwZSx4YSl9Y2hlY2tOdW1lcmljYWxQcm9ibGVtcyhhYSl7aWYoYWEhPW51bGwpZm9yKGxldCB4YT0wO3hhPGFhLmxlbmd0aDt4YSsrKXtjb25zdCBiYT1hYVt4YV07aWYoIWNhbkJlUmVwcmVzZW50ZWQoYmEpKXRocm93IGVudigpLmdldEJvb2woIldFQkdMX1JFTkRFUl9GTE9BVDMyX0NBUEFCTEUiKT9FcnJvcihgVGhlIHZhbHVlICR7YmF9IGNhbm5vdCBiZSByZXByZXNlbnRlZCB3aXRoIHlvdXIgY3VycmVudCBzZXR0aW5ncy4gQ29uc2lkZXIgZW5hYmxpbmcgZmxvYXQzMiByZW5kZXJpbmc6ICd0Zi5lbnYoKS5zZXQoJ1dFQkdMX1JFTkRFUl9GTE9BVDMyX0VOQUJMRUQnLCB0cnVlKTsnYCk6RXJyb3IoYFRoZSB2YWx1ZSAke2JhfSBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgb24gdGhpcyBkZXZpY2UuYCl9fWdldFZhbHVlc0Zyb21UZXh0dXJlKGFhKXtjb25zdHtzaGFwZTp4YSxkdHlwZTpiYSxpc1BhY2tlZDpTYX09dGhpcy50ZXhEYXRhLmdldChhYSksVGE9c2l6ZUZyb21TaGFwZSh4YSk7aWYoZW52KCkuZ2V0Qm9vbCgiV0VCR0xfRE9XTkxPQURfRkxPQVRfRU5BQkxFRCIpKXtjb25zdCBlbD10aGlzLmRlY29kZShhYSksdGw9dGhpcy50ZXhEYXRhLmdldChlbC5kYXRhSWQpLG5sPXRoaXMuZ3BncHUuZG93bmxvYWRNYXRyaXhGcm9tUGFja2VkVGV4dHVyZSh0bC50ZXh0dXJlLnRleHR1cmUsLi4uZ2V0RGVuc2VUZXhTaGFwZSh4YSkpLnN1YmFycmF5KDAsVGEpO3JldHVybiB0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGVsKSxubH1jb25zdCB3YT1lbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLIikmJlNhPT09ITAsRWE9d2E/Z2V0U2hhcGVBczNEKHhhKTp4YSxrYT13YT9uZXcgRW5jb2RlRmxvYXRQYWNrZWRQcm9ncmFtKEVhKTpuZXcgRW5jb2RlRmxvYXRQcm9ncmFtKEVhKSxBYT10aGlzLnJ1bldlYkdMUHJvZ3JhbShrYSxbe3NoYXBlOkVhLGR0eXBlOmJhLGRhdGFJZDphYX1dLCJmbG9hdDMyIiksRmE9dGhpcy50ZXhEYXRhLmdldChBYS5kYXRhSWQpLExhPXRoaXMuZ3BncHUuZG93bmxvYWRCeXRlRW5jb2RlZEZsb2F0TWF0cml4RnJvbU91dHB1dFRleHR1cmUoRmEudGV4dHVyZS50ZXh0dXJlLEZhLnRleFNoYXBlWzBdLEZhLnRleFNoYXBlWzFdKS5zdWJhcnJheSgwLFRhKTtyZXR1cm4gdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhBYSksTGF9dGltZXJBdmFpbGFibGUoKXtyZXR1cm4gZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiKT4wfXRpbWUoYWEpe2NvbnN0IHhhPXRoaXMuYWN0aXZlVGltZXJzLGJhPVtdO2xldCBTYT0hMTt0aGlzLnByb2dyYW1UaW1lcnNTdGFjaz09bnVsbD8odGhpcy5wcm9ncmFtVGltZXJzU3RhY2s9YmEsU2E9ITApOnRoaXMuYWN0aXZlVGltZXJzLnB1c2goYmEpLHRoaXMuYWN0aXZlVGltZXJzPWJhLGFhKCk7Y29uc3QgVGE9ZmxhdHRlbih0aGlzLmFjdGl2ZVRpbWVycy5tYXAoa2E9PmthLnF1ZXJ5KSkuZmlsdGVyKGthPT5rYSE9bnVsbCksd2E9ZmxhdHRlbih0aGlzLmFjdGl2ZVRpbWVycy5tYXAoa2E9PmthLm5hbWUpKS5maWx0ZXIoa2E9PmthIT1udWxsKTt0aGlzLmFjdGl2ZVRpbWVycz14YSxTYSYmKHRoaXMucHJvZ3JhbVRpbWVyc1N0YWNrPW51bGwpO2NvbnN0IEVhPXt1cGxvYWRXYWl0TXM6dGhpcy51cGxvYWRXYWl0TXMsZG93bmxvYWRXYWl0TXM6dGhpcy5kb3dubG9hZFdhaXRNcyxrZXJuZWxNczpudWxsLHdhbGxNczpudWxsfTtyZXR1cm4oYXN5bmMoKT0+e2lmKGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1JFTElBQkxFIik+MCl7Y29uc3Qga2E9YXdhaXQgUHJvbWlzZS5hbGwoVGEpO0VhLmtlcm5lbE1zPXN1bSQyKGthKSxFYS5nZXRFeHRyYVByb2ZpbGVJbmZvPSgpPT5rYS5tYXAoKEFhLEZhKT0+KHtuYW1lOndhW0ZhXSxtczpBYX0pKS5tYXAoQWE9PmAke0FhLm5hbWV9OiAke0FhLm1zfWApLmpvaW4oIiwgIil9ZWxzZSBFYS5rZXJuZWxNcz17ZXJyb3I6IldlYkdMIHF1ZXJ5IHRpbWVycyBhcmUgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGVudmlyb25tZW50LiJ9O3JldHVybiB0aGlzLnVwbG9hZFdhaXRNcz0wLHRoaXMuZG93bmxvYWRXYWl0TXM9MCxFYX0pKCl9bWVtb3J5KCl7cmV0dXJue3VucmVsaWFibGU6ITEsbnVtQnl0ZXNJbkdQVTp0aGlzLm51bUJ5dGVzSW5HUFUsbnVtQnl0ZXNJbkdQVUFsbG9jYXRlZDp0aGlzLnRleHR1cmVNYW5hZ2VyLm51bUJ5dGVzQWxsb2NhdGVkLG51bUJ5dGVzSW5HUFVGcmVlOnRoaXMudGV4dHVyZU1hbmFnZXIubnVtQnl0ZXNGcmVlfX1zdGFydFRpbWVyKCl7cmV0dXJuIGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1JFTElBQkxFIik+MD90aGlzLmdwZ3B1LmJlZ2luUXVlcnkoKTp7c3RhcnRNczpub3coKSxlbmRNczpudWxsfX1lbmRUaW1lcihhYSl7cmV0dXJuIGVudigpLmdldE51bWJlcigiV0VCR0xfRElTSk9JTlRfUVVFUllfVElNRVJfRVhURU5TSU9OX1JFTElBQkxFIik+MD8odGhpcy5ncGdwdS5lbmRRdWVyeSgpLGFhKTooYWEuZW5kTXM9bm93KCksYWEpfWFzeW5jIGdldFF1ZXJ5VGltZShhYSl7aWYoZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9ESVNKT0lOVF9RVUVSWV9USU1FUl9FWFRFTlNJT05fUkVMSUFCTEUiKT4wKXJldHVybiB0aGlzLmdwZ3B1LndhaXRGb3JRdWVyeUFuZEdldFRpbWUoYWEpO2NvbnN0IHhhPWFhO3JldHVybiB4YS5lbmRNcy14YS5zdGFydE1zfWRpc3Bvc2VEYXRhKGFhLHhhPSExKXtpZih0aGlzLnBlbmRpbmdEaXNwb3NhbC5oYXMoYWEpKXJldHVybiExO2lmKCF0aGlzLnRleERhdGEuaGFzKGFhKSlyZXR1cm4hMDtpZih4YT90aGlzLnRleERhdGEuZ2V0KGFhKS5yZWZDb3VudD0wOnRoaXMudGV4RGF0YS5nZXQoYWEpLnJlZkNvdW50LS0sIXhhJiZ0aGlzLnRleERhdGEuZ2V0KGFhKS5yZWZDb3VudD4wKXJldHVybiExO2lmKHRoaXMucGVuZGluZ1JlYWQuaGFzKGFhKSlyZXR1cm4gdGhpcy5wZW5kaW5nRGlzcG9zYWwuYWRkKGFhKSx0aGlzLnBlbmRpbmdEZWxldGVzKyssITE7dGhpcy5yZWxlYXNlR1BVRGF0YShhYSk7Y29uc3R7Y29tcGxleFRlbnNvckluZm9zOmJhfT10aGlzLnRleERhdGEuZ2V0KGFhKTtyZXR1cm4gYmEhPW51bGwmJih0aGlzLmRpc3Bvc2VEYXRhKGJhLnJlYWwuZGF0YUlkLHhhKSx0aGlzLmRpc3Bvc2VEYXRhKGJhLmltYWcuZGF0YUlkLHhhKSksdGhpcy50ZXhEYXRhLmRlbGV0ZShhYSksITB9cmVsZWFzZUdQVURhdGEoYWEpe2NvbnN0e3RleHR1cmU6eGEsZHR5cGU6YmEsdGV4U2hhcGU6U2EsdXNhZ2U6VGEsaXNQYWNrZWQ6d2Esc2xpY2U6RWF9PXRoaXMudGV4RGF0YS5nZXQoYWEpLGthPUVhJiZFYS5vcmlnRGF0YUlkfHxhYSxBYT10aGlzLmRhdGFSZWZDb3VudC5nZXQoa2EpO0FhPjE/dGhpcy5kYXRhUmVmQ291bnQuc2V0KGthLEFhLTEpOih0aGlzLmRhdGFSZWZDb3VudC5kZWxldGUoa2EpLHhhIT1udWxsJiYodGhpcy5udW1CeXRlc0luR1BVLT10aGlzLmNvbXB1dGVCeXRlcyhTYSxiYSksdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh4YSxTYSxUYSx3YSkpKTtjb25zdCBGYT10aGlzLnRleERhdGEuZ2V0KGFhKTtGYS50ZXh0dXJlPW51bGwsRmEudGV4U2hhcGU9bnVsbCxGYS5pc1BhY2tlZD0hMSxGYS5zbGljZT1udWxsfWdldFRleHR1cmUoYWEpe3JldHVybiB0aGlzLnVwbG9hZFRvR1BVKGFhKSx0aGlzLnRleERhdGEuZ2V0KGFhKS50ZXh0dXJlLnRleHR1cmV9Z2V0RGF0YUluZm8oYWEpe3JldHVybiB0aGlzLnRleERhdGEuZ2V0KGFhKX1zaG91bGRFeGVjdXRlT25DUFUoYWEseGE9Q1BVX0hBTkRPRkZfU0laRV9USFJFU0hPTEQpe3JldHVybiBlbnYoKS5nZXRCb29sKCJXRUJHTF9DUFVfRk9SV0FSRCIpJiZhYS5ldmVyeShiYT0+dGhpcy50ZXhEYXRhLmdldChiYS5kYXRhSWQpLnRleHR1cmU9PW51bGwmJnNpemVGcm9tU2hhcGUoYmEuc2hhcGUpPHhhKX1nZXRHUEdQVUNvbnRleHQoKXtyZXR1cm4gdGhpcy5ncGdwdX13aGVyZShhYSl7d2FybigidGYud2hlcmUoKSBpbiB3ZWJnbCBsb2NrcyB0aGUgVUkgdGhyZWFkLiBDYWxsIHRmLndoZXJlQXN5bmMoKSBpbnN0ZWFkIik7Y29uc3QgeGE9YWEuZGF0YVN5bmMoKTtyZXR1cm4gd2hlcmVJbXBsKGFhLnNoYXBlLHhhKX1wYWNrZWRVbmFyeU9wKGFhLHhhLGJhKXtjb25zdCBTYT1uZXcgVW5hcnlPcFBhY2tlZFByb2dyYW0oYWEuc2hhcGUseGEpLFRhPXRoaXMuY29tcGlsZUFuZFJ1bihTYSxbYWFdLGJhKTtyZXR1cm4gZW5naW5lKCkubWFrZVRlbnNvckZyb21UZW5zb3JJbmZvKFRhKX1hYnMoYWEpe2lmKHRoaXMuc2hvdWxkRXhlY3V0ZU9uQ1BVKFthYV0pJiZhYS5kdHlwZSE9PSJjb21wbGV4NjQiKXtjb25zdCBTYT1zaW1wbGVBYnNJbXBsQ1BVKHRoaXMudGV4RGF0YS5nZXQoYWEuZGF0YUlkKS52YWx1ZXMpO3JldHVybiB0aGlzLm1ha2VPdXRwdXQoYWEuc2hhcGUsYWEuZHR5cGUsU2EpfWlmKGVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfVU5BUllfT1BFUkFUSU9OUyIpKXJldHVybiB0aGlzLnBhY2tlZFVuYXJ5T3AoYWEsQUJTJDEsYWEuZHR5cGUpO2NvbnN0IHhhPW5ldyBVbmFyeU9wUHJvZ3JhbShhYS5zaGFwZSxBQlMkMSksYmE9dGhpcy5jb21waWxlQW5kUnVuKHhhLFthYV0pO3JldHVybiBlbmdpbmUoKS5tYWtlVGVuc29yRnJvbVRlbnNvckluZm8oYmEpfW1ha2VUZW5zb3JJbmZvKGFhLHhhLGJhKXtsZXQgU2E7aWYoeGE9PT0ic3RyaW5nIiYmYmEhPW51bGwmJmJhLmxlbmd0aD4wJiZpc1N0cmluZyhiYVswXSkpe2NvbnN0IFRhPWJhLm1hcCh3YT0+ZW5jb2RlU3RyaW5nKHdhKSk7U2E9dGhpcy53cml0ZShUYSxhYSx4YSl9ZWxzZSBTYT10aGlzLndyaXRlKGJhLGFhLHhhKTtyZXR1cm4gdGhpcy50ZXhEYXRhLmdldChTYSkudXNhZ2U9bnVsbCx7ZGF0YUlkOlNhLHNoYXBlOmFhLGR0eXBlOnhhfX1tYWtlT3V0cHV0KGFhLHhhLGJhKXtyZXR1cm4gZW5naW5lKCkubWFrZVRlbnNvckZyb21UZW5zb3JJbmZvKHRoaXMubWFrZVRlbnNvckluZm8oYWEseGEsYmEpLHRoaXMpfXVucGFja1RlbnNvcihhYSl7Y29uc3QgeGE9bmV3IFVucGFja1Byb2dyYW0oYWEuc2hhcGUpO3JldHVybiB0aGlzLnJ1bldlYkdMUHJvZ3JhbSh4YSxbYWFdLGFhLmR0eXBlKX1wYWNrVGVuc29yKGFhKXtjb25zdCB4YT1uZXcgUGFja1Byb2dyYW0oYWEuc2hhcGUpO3JldHVybiB0aGlzLnJ1bldlYkdMUHJvZ3JhbSh4YSxbYWFdLGFhLmR0eXBlLG51bGwsITApfXBhY2tlZFJlc2hhcGUoYWEseGEpe2NvbnN0IGJhPVtnZXRCYXRjaERpbShhYS5zaGFwZSksLi4uZ2V0Um93c0NvbHMoYWEuc2hhcGUpXSxTYT17ZHR5cGU6YWEuZHR5cGUsc2hhcGU6YmEsZGF0YUlkOmFhLmRhdGFJZH0sVGE9W2dldEJhdGNoRGltKHhhKSwuLi5nZXRSb3dzQ29scyh4YSldLHdhPW5ldyBSZXNoYXBlUGFja2VkUHJvZ3JhbShUYSxiYSksRWE9ITAsa2E9W2JhXSxBYT10aGlzLnJ1bldlYkdMUHJvZ3JhbSh3YSxbU2FdLGFhLmR0eXBlLGthLEVhKTtyZXR1cm57ZGF0YUlkOkFhLmRhdGFJZCxzaGFwZTp4YSxkdHlwZTpBYS5kdHlwZX19ZGVjb2RlKGFhLHhhKXtjb25zdCBiYT10aGlzLnRleERhdGEuZ2V0KGFhKSx7aXNQYWNrZWQ6U2Esc2hhcGU6VGEsZHR5cGU6d2F9PWJhO2lmKHhhIT1udWxsKXtjb25zdCBlbD1zaXplRnJvbVNoYXBlKFRhKSx0bD14YVswXSp4YVsxXSo0O2Fzc2VydChlbDw9dGwsKCk9PiJjdXN0b21UZXhTaGFwZSBpcyB0b28gc21hbGwuIFJvdyAqIENvbHVtbiAqIDQgc2hvdWxkIGJlIGVxdWFsIG9yIGxhcmdlciB0aGFuIHRoZSBzaXplIG9mIHRoZSB0ZW5zb3IgZGF0YS4iKX1jb25zdCBFYT1nZXRTaGFwZUFzM0QoVGEpO2xldCBrYTtTYT9rYT1uZXcgRGVjb2RlTWF0cml4UGFja2VkUHJvZ3JhbShFYSk6a2E9bmV3IERlY29kZU1hdHJpeFByb2dyYW0oRWEpO2NvbnN0IEFhPSEwLEZhPVt4YT8/Z2V0RGVuc2VUZXhTaGFwZShFYSldLExhPXRoaXMucnVuV2ViR0xQcm9ncmFtKGthLFt7c2hhcGU6RWEsZHR5cGU6d2EsZGF0YUlkOmFhfV0sd2EsRmEsQWEseGEpO3JldHVybntkdHlwZTp3YSxzaGFwZTpUYSxkYXRhSWQ6TGEuZGF0YUlkfX1ydW5XZWJHTFByb2dyYW0oYWEseGEsYmEsU2EsVGE9ITEsd2Epe2NvbnN0IEVhPXRoaXMubWFrZVRlbnNvckluZm8oYWEub3V0cHV0U2hhcGUsYmEpLGthPXRoaXMudGV4RGF0YS5nZXQoRWEuZGF0YUlkKTtpZihhYS5wYWNrZWRPdXRwdXQmJihrYS5pc1BhY2tlZD0hMCksYWEub3V0UGFja2luZ1NjaGVtZT09PVBhY2tpbmdTY2hlbWUuREVOU0Upe2NvbnN0IG9sPXdhPz9nZXREZW5zZVRleFNoYXBlKGFhLm91dHB1dFNoYXBlKTtrYS50ZXhTaGFwZT1vbC5tYXAoYWw9PmFsKjIpfWlmKGFhLm91dFRleFVzYWdlIT1udWxsJiYoa2EudXNhZ2U9YWEub3V0VGV4VXNhZ2UpLHNpemVGcm9tU2hhcGUoRWEuc2hhcGUpPT09MClyZXR1cm4ga2EudmFsdWVzPWdldFR5cGVkQXJyYXlGcm9tRFR5cGUoRWEuZHR5cGUsMCksRWE7Y29uc3QgQWE9W10sRmE9eGEubWFwKG9sPT57aWYob2wuZHR5cGU9PT0iY29tcGxleDY0Iil0aHJvdyBuZXcgRXJyb3IoIkdQR1BVUHJvZ3JhbSBkb2VzIG5vdCBzdXBwb3J0IGNvbXBsZXg2NCBpbnB1dC4gRm9yIGNvbXBsZXg2NCBkdHlwZXMsIHBsZWFzZSBzZXBhcmF0ZSB0aGUgcHJvZ3JhbSBpbnRvIHJlYWwgYW5kIGltYWdpbmFyeSBwYXJ0cy4iKTtsZXQgYWw9dGhpcy50ZXhEYXRhLmdldChvbC5kYXRhSWQpO2lmKGFsLnRleHR1cmU9PW51bGwpe2lmKCFhYS5wYWNrZWRJbnB1dHMmJnNpemVGcm9tU2hhcGUob2wuc2hhcGUpPD1lbnYoKS5nZXROdW1iZXIoIldFQkdMX1NJWkVfVVBMT0FEX1VOSUZPUk0iKSlyZXR1cm57c2hhcGU6b2wuc2hhcGUsdGV4RGF0YTpudWxsLGlzVW5pZm9ybTohMCx1bmlmb3JtVmFsdWVzOmFsLnZhbHVlc307YWEucGFja2VkSW5wdXRzJiYoYWwuaXNQYWNrZWQ9ITAsYWwuc2hhcGU9b2wuc2hhcGUpfWlmKHRoaXMudXBsb2FkVG9HUFUob2wuZGF0YUlkKSwhIWFsLmlzUGFja2VkIT0hIWFhLnBhY2tlZElucHV0cylvbD1hbC5pc1BhY2tlZD90aGlzLnVucGFja1RlbnNvcihvbCk6dGhpcy5wYWNrVGVuc29yKG9sKSxBYS5wdXNoKG9sKSxhbD10aGlzLnRleERhdGEuZ2V0KG9sLmRhdGFJZCk7ZWxzZSBpZihhbC5pc1BhY2tlZCYmIWlzUmVzaGFwZUZyZWUoYWwuc2hhcGUsb2wuc2hhcGUpKXtjb25zdCBsbD1vbCxpbD1vbC5zaGFwZTtvbC5zaGFwZT1hbC5zaGFwZSxvbD10aGlzLnBhY2tlZFJlc2hhcGUob2wsaWwpLEFhLnB1c2gob2wpLGFsPXRoaXMudGV4RGF0YS5nZXQob2wuZGF0YUlkKSxsbC5zaGFwZT1pbH1yZXR1cm57c2hhcGU6b2wuc2hhcGUsdGV4RGF0YTphbCxpc1VuaWZvcm06ITF9fSk7dGhpcy51cGxvYWRUb0dQVShFYS5kYXRhSWQpO2NvbnN0IExhPXtzaGFwZTpFYS5zaGFwZSx0ZXhEYXRhOmthLGlzVW5pZm9ybTohMX0sZWw9bWFrZVNoYWRlcktleShhYSxGYSxMYSksdGw9dGhpcy5nZXRBbmRTYXZlQmluYXJ5KGVsLCgpPT5jb21waWxlUHJvZ3JhbSh0aGlzLmdwZ3B1LGFhLEZhLExhKSksbmw9dGhpcy5hY3RpdmVUaW1lcnMhPW51bGw7bGV0IHNsO25sJiYoc2w9dGhpcy5zdGFydFRpbWVyKCkpLGVudigpLmdldCgiRU5HSU5FX0NPTVBJTEVfT05MWSIpfHxydW5Qcm9ncmFtKHRoaXMuZ3BncHUsdGwsRmEsTGEsU2EpLEFhLmZvckVhY2gob2w9PnRoaXMuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpKSxubCYmKHNsPXRoaXMuZW5kVGltZXIoc2wpLHRoaXMuYWN0aXZlVGltZXJzLnB1c2goe25hbWU6YWEuY29uc3RydWN0b3IubmFtZSxxdWVyeTp0aGlzLmdldFF1ZXJ5VGltZShzbCl9KSk7Y29uc3Qgcmw9ZW52KCkuZ2V0TnVtYmVyKCJXRUJHTF9GTFVTSF9USFJFU0hPTEQiKTtpZihybD4wKXtjb25zdCBvbD1ub3coKTtvbC10aGlzLmxhc3RHbEZsdXNoVGltZT5ybCYmKHRoaXMuZ3BncHUuZ2wuZmx1c2goKSx0aGlzLmxhc3RHbEZsdXNoVGltZT1vbCl9aWYoIWVudigpLmdldEJvb2woIldFQkdMX0xBWklMWV9VTlBBQ0siKSYma2EuaXNQYWNrZWQmJlRhPT09ITEpe2NvbnN0IG9sPXRoaXMudW5wYWNrVGVuc29yKEVhKTtyZXR1cm4gdGhpcy5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSksb2x9cmV0dXJuIEVhfWNvbXBpbGVBbmRSdW4oYWEseGEsYmEsU2EsVGE9ITEpe3JldHVybiBiYT1iYXx8eGFbMF0uZHR5cGUsdGhpcy5ydW5XZWJHTFByb2dyYW0oYWEseGEsYmEsU2EsVGEpfWdldEFuZFNhdmVCaW5hcnkoYWEseGEpe3JldHVybiBhYSBpbiB0aGlzLmJpbmFyeUNhY2hlfHwodGhpcy5iaW5hcnlDYWNoZVthYV09eGEoKSksdGhpcy5iaW5hcnlDYWNoZVthYV19Z2V0VGV4dHVyZU1hbmFnZXIoKXtyZXR1cm4gdGhpcy50ZXh0dXJlTWFuYWdlcn1kaXNwb3NlKCl7dGhpcy5kaXNwb3NlZHx8KGVudigpLmdldEJvb2woIklTX1RFU1QiKXx8T2JqZWN0LmtleXModGhpcy5iaW5hcnlDYWNoZSkuZm9yRWFjaCh4YT0+e3RoaXMuZ3BncHUuZGVsZXRlUHJvZ3JhbSh0aGlzLmJpbmFyeUNhY2hlW3hhXS53ZWJHTFByb2dyYW0pLGRlbGV0ZSB0aGlzLmJpbmFyeUNhY2hlW3hhXX0pLHRoaXMudGV4dHVyZU1hbmFnZXIuZGlzcG9zZSgpLHRoaXMuY2FudmFzIT1udWxsJiZ0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQ8InUiJiZ0aGlzLmNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50P3RoaXMuY2FudmFzLnJlbW92ZSgpOnRoaXMuY2FudmFzPW51bGwsdGhpcy5ncGdwdUNyZWF0ZWRMb2NhbGx5JiYodGhpcy5ncGdwdS5wcm9ncmFtPW51bGwsdGhpcy5ncGdwdS5kaXNwb3NlKCkpLHRoaXMuZGlzcG9zZWQ9ITApfWZsb2F0UHJlY2lzaW9uKCl7cmV0dXJuIHRoaXMuZmxvYXRQcmVjaXNpb25WYWx1ZT09bnVsbCYmKHRoaXMuZmxvYXRQcmVjaXNpb25WYWx1ZT10aWR5KCgpPT57aWYoIWVudigpLmdldCgiV0VCR0xfUkVOREVSX0ZMT0FUMzJfRU5BQkxFRCIpKXtjb25zdCBhYT1lbnYoKS5nZXRCb29sKCJERUJVRyIpO2VudigpLnNldCgiREVCVUciLCExKTtjb25zdCB4YT10aGlzLmFicyhzY2FsYXIoMWUtOCkpLmRhdGFTeW5jKClbMF07aWYoZW52KCkuc2V0KCJERUJVRyIsYWEpLHhhPjApcmV0dXJuIDMyfXJldHVybiAxNn0pKSx0aGlzLmZsb2F0UHJlY2lzaW9uVmFsdWV9ZXBzaWxvbigpe3JldHVybiB0aGlzLmZsb2F0UHJlY2lzaW9uKCk9PT0zMj9FUFNJTE9OX0ZMT0FUMzI6RVBTSUxPTl9GTE9BVDE2fXVwbG9hZFRvR1BVKGFhKXtjb25zdCB4YT10aGlzLnRleERhdGEuZ2V0KGFhKSx7c2hhcGU6YmEsZHR5cGU6U2EsdmFsdWVzOlRhLHRleHR1cmU6d2EsdXNhZ2U6RWEsaXNQYWNrZWQ6a2F9PXhhO2lmKHdhIT1udWxsKXJldHVybjtjb25zdCBBYT10aGlzLmFjdGl2ZVRpbWVycyE9bnVsbDtsZXQgRmE7QWEmJihGYT1ub3coKSk7bGV0IExhPXhhLnRleFNoYXBlO2lmKExhPT1udWxsJiYoTGE9Z2V0VGV4dHVyZVNoYXBlRnJvbUxvZ2ljYWxTaGFwZShiYSxrYSkseGEudGV4U2hhcGU9TGEpLFRhIT1udWxsKXtjb25zdCBlbD1nZXRTaGFwZUFzM0QoYmEpO2xldCB0bCxubD1MYVsxXSxzbD1MYVswXTtjb25zdCBybD1UYSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fFRhIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXk7KGthfHwhcmwpJiYoW25sLHNsXT1nZXRQYWNrZWRNYXRyaXhUZXh0dXJlU2hhcGVXaWR0aEhlaWdodChMYVswXSxMYVsxXSkpLGthP3RsPW5ldyBFbmNvZGVNYXRyaXhQYWNrZWRQcm9ncmFtKGVsLHJsKTp0bD1uZXcgRW5jb2RlTWF0cml4UHJvZ3JhbShlbCxybCk7Y29uc3Qgb2w9cmw/W3NsLG5sXTpMYSxhbD10aGlzLm1ha2VUZW5zb3JJbmZvKG9sLFNhKSxsbD10aGlzLnRleERhdGEuZ2V0KGFsLmRhdGFJZCk7cmw/bGwudXNhZ2U9VGV4dHVyZVVzYWdlLlBJWEVMUzpsbC51c2FnZT1UZXh0dXJlVXNhZ2UuVVBMT0FELGxsLnRleFNoYXBlPW9sLHRoaXMuZ3BncHUudXBsb2FkRGVuc2VNYXRyaXhUb1RleHR1cmUodGhpcy5nZXRUZXh0dXJlKGFsLmRhdGFJZCksbmwsc2wsVGEpO2NvbnN0IGlsPVtbc2wsbmxdXSx1bD10aGlzLnJ1bldlYkdMUHJvZ3JhbSh0bCxbYWxdLFNhLGlsLCEwKSxkbD10aGlzLnRleERhdGEuZ2V0KHVsLmRhdGFJZCk7eGEudGV4U2hhcGU9ZGwudGV4U2hhcGUseGEuaXNQYWNrZWQ9ZGwuaXNQYWNrZWQseGEudXNhZ2U9ZGwudXNhZ2UsZW52KCkuZ2V0KCJFTkdJTkVfQ09NUElMRV9PTkxZIik/dGhpcy5kaXNwb3NlRGF0YSh1bC5kYXRhSWQpOih4YS50ZXh0dXJlPWRsLnRleHR1cmUseGEudmFsdWVzPW51bGwsdGhpcy50ZXhEYXRhLmRlbGV0ZSh1bC5kYXRhSWQpKSx0aGlzLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGFsKSxBYSYmKHRoaXMudXBsb2FkV2FpdE1zKz1ub3coKS1GYSl9ZWxzZXtjb25zdCBlbD10aGlzLmFjcXVpcmVUZXh0dXJlKExhLEVhLFNhLGthKTt4YS50ZXh0dXJlPWVsfX1jb252ZXJ0QW5kQ2FjaGVPbkNQVShhYSx4YSl7Y29uc3QgYmE9dGhpcy50ZXhEYXRhLmdldChhYSkse2R0eXBlOlNhfT1iYTtyZXR1cm4geGEhPW51bGwmJihiYS52YWx1ZXM9ZmxvYXQzMlRvVHlwZWRBcnJheSh4YSxTYSkpLGJhLnZhbHVlc31hY3F1aXJlVGV4dHVyZShhYSx4YSxiYSxTYSl7aWYodGhpcy5udW1CeXRlc0luR1BVKz10aGlzLmNvbXB1dGVCeXRlcyhhYSxiYSksIXRoaXMud2FybmVkQWJvdXRNZW1vcnkmJnRoaXMubnVtQnl0ZXNJbkdQVT50aGlzLm51bU1CQmVmb3JlV2FybmluZyoxMDI0KjEwMjQpe2NvbnN0IFRhPSh0aGlzLm51bUJ5dGVzSW5HUFUvMTAyNC8xMDI0KS50b0ZpeGVkKDIpO3RoaXMud2FybmVkQWJvdXRNZW1vcnk9ITAsY29uc29sZS53YXJuKGBIaWdoIG1lbW9yeSB1c2FnZSBpbiBHUFU6ICR7VGF9IE1CLCBtb3N0IGxpa2VseSBkdWUgdG8gYSBtZW1vcnkgbGVha2ApfXJldHVybiB0aGlzLnRleHR1cmVNYW5hZ2VyLmFjcXVpcmVUZXh0dXJlKGFhLHhhLFNhKX1jb21wdXRlQnl0ZXMoYWEseGEpe3JldHVybiBhYVswXSphYVsxXSpieXRlc1BlckVsZW1lbnQoeGEpfWNoZWNrQ29tcGlsZUNvbXBsZXRpb24oKXtmb3IoY29uc3RbLGFhXW9mIE9iamVjdC5lbnRyaWVzKHRoaXMuYmluYXJ5Q2FjaGUpKXRoaXMuY2hlY2tDb21wbGV0aW9uXyhhYSl9YXN5bmMgY2hlY2tDb21waWxlQ29tcGxldGlvbkFzeW5jKCl7Y29uc3QgYWE9W107aWYodGhpcy5ncGdwdS5wYXJhbGxlbENvbXBpbGF0aW9uRXh0ZW5zaW9uKXtmb3IoY29uc3RbLHhhXW9mIE9iamVjdC5lbnRyaWVzKHRoaXMuYmluYXJ5Q2FjaGUpKWFhLnB1c2godGhpcy5jaGVja0NvbXBsZXRpb25Bc3luY18oeGEpKTtyZXR1cm4gUHJvbWlzZS5hbGwoYWEpfWVsc2V7Zm9yKGNvbnN0Wyx4YV1vZiBPYmplY3QuZW50cmllcyh0aGlzLmJpbmFyeUNhY2hlKSl7Y29uc3QgYmE9bmV3IFByb21pc2UoU2E9Pnt0cnl7dGhpcy5jaGVja0NvbXBsZXRpb25fKHhhKSxTYSghMCl9Y2F0Y2goVGEpe3Rocm93IFRhfX0pO2FhLnB1c2goYmEpfXJldHVybiBQcm9taXNlLmFsbChhYSl9fWFzeW5jIGNoZWNrQ29tcGxldGlvbkFzeW5jXyhhYSl7cmV0dXJuIHRoaXMuZ3BncHUuZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihhYS53ZWJHTFByb2dyYW0sdGhpcy5ncGdwdS5wYXJhbGxlbENvbXBpbGF0aW9uRXh0ZW5zaW9uLkNPTVBMRVRJT05fU1RBVFVTX0tIUik/dGhpcy5jaGVja0NvbXBsZXRpb25fKGFhKTooYXdhaXQgbmV4dEZyYW1lKCksdGhpcy5jaGVja0NvbXBsZXRpb25Bc3luY18oYWEpKX1jaGVja0NvbXBsZXRpb25fKGFhKXtpZih0aGlzLmdwZ3B1LmdsLmdldFByb2dyYW1QYXJhbWV0ZXIoYWEud2ViR0xQcm9ncmFtLHRoaXMuZ3BncHUuZ2wuTElOS19TVEFUVVMpPT09ITEpdGhyb3cgY29uc29sZS5sb2codGhpcy5ncGdwdS5nbC5nZXRQcm9ncmFtSW5mb0xvZyhhYS53ZWJHTFByb2dyYW0pKSx0aGlzLmdwZ3B1LmdsLmdldFNoYWRlclBhcmFtZXRlcihhYS5mcmFnbWVudFNoYWRlcix0aGlzLmdwZ3B1LmdsLkNPTVBJTEVfU1RBVFVTKT09PSExPyhsb2dTaGFkZXJTb3VyY2VBbmRJbmZvTG9nKGFhLnNvdXJjZSx0aGlzLmdwZ3B1LmdsLmdldFNoYWRlckluZm9Mb2coYWEuZnJhZ21lbnRTaGFkZXIpKSxuZXcgRXJyb3IoIkZhaWxlZCB0byBjb21waWxlIGZyYWdtZW50IHNoYWRlci4iKSk6bmV3IEVycm9yKCJGYWlsZWQgdG8gbGluayB2ZXJ0ZXggYW5kIGZyYWdtZW50IHNoYWRlcnMuIik7cmV0dXJuITB9Z2V0VW5pZm9ybUxvY2F0aW9ucygpe2Zvcihjb25zdCBhYSBvZiBPYmplY3QudmFsdWVzKHRoaXMuYmluYXJ5Q2FjaGUpKXt0aGlzLmdwZ3B1LmJ1aWxkVmFvKGFhLndlYkdMUHJvZ3JhbSk7Y29uc3R7dmFyaWFibGVzTG9jYXRpb25zOnhhLGN1c3RvbVVuaWZvcm1Mb2NhdGlvbnM6YmEsaW5mTG9jOlNhLG5hbkxvYzpUYSxvdXRTaGFwZUxvY2F0aW9uOndhLG91dFNoYXBlU3RyaWRlc0xvY2F0aW9uOkVhLG91dFRleFNoYXBlTG9jYXRpb246a2F9PWdldFVuaWZvcm1Mb2NhdGlvbnModGhpcy5ncGdwdSxhYS5wcm9ncmFtLGFhLndlYkdMUHJvZ3JhbSk7YWEudmFyaWFibGVzTG9jYXRpb25zPXhhLGFhLmN1c3RvbVVuaWZvcm1Mb2NhdGlvbnM9YmEsYWEuaW5mTG9jPVNhLGFhLm5hbkxvYz1UYSxhYS5vdXRTaGFwZUxvY2F0aW9uPXdhLGFhLm91dFNoYXBlU3RyaWRlc0xvY2F0aW9uPUVhLGFhLm91dFRleFNoYXBlTG9jYXRpb249a2F9fWNyZWF0ZVRlbnNvckZyb21HUFVEYXRhKGFhLHhhLGJhKXthYS5jaGFubmVscz1hYS5jaGFubmVsc3x8IlJHQkEiO2NvbnN0e3RleHR1cmU6U2EsaGVpZ2h0OlRhLHdpZHRoOndhLGNoYW5uZWxzOkVhfT1hYSxrYT1lbmdpbmUoKS5iYWNrZW5kO2lmKCFrYS5ncGdwdS5nbC5pc1RleHR1cmUoU2EpKXRocm93IG5ldyBFcnJvcigiVGhlIHRleHR1cmUgaXMgaW52YWxpZC4gQWxzbywgcGxlYXNlIG1ha2Ugc3VyZSB0aGUgdGV4dHVyZSBhbmQgdGhlIFRGSlMgV2ViR0wgYmFja2VuZCBhcmUgdXNpbmcgdGhlIHNhbWUgY2FudmFzLiBJZiB5b3Ugd2FudCB0byB1c2UgeW91ciBvd24gY3VzdG9tIGNhbnZhcywgeW91IGhhdmUgdG8gY3JlYXRlIGFuZCB1c2UgdGhlIGN1c3RvbSBURkpTIFdlYkdMIGJhY2tlbmQgY3JlYXRlZCBmcm9tIHRoZSBjYW52YXMgdGhyb3VnaCAnbmV3IHRmLk1hdGhCYWNrZW5kV2ViR0woY3VzdG9tQ2FudmFzKScuIik7Y29uc3QgQWE9a2Eud3JpdGVUZXh0dXJlKFNhLHhhLGJhLFRhLHdhLEVhKTtyZXR1cm4gZW5naW5lKCkubWFrZVRlbnNvckZyb21EYXRhSWQoQWEseGEsYmEsa2EpfX1NYXRoQmFja2VuZFdlYkdMLm5leHREYXRhSWQ9MDtmdW5jdGlvbiBmbG9hdDMyVG9UeXBlZEFycmF5KGhhLGFhKXtpZihhYT09PSJmbG9hdDMyInx8YWE9PT0iY29tcGxleDY0IilyZXR1cm4gaGE7aWYoYWE9PT0iaW50MzIifHxhYT09PSJib29sIil7Y29uc3QgeGE9YWE9PT0iaW50MzIiP25ldyBJbnQzMkFycmF5KGhhLmxlbmd0aCk6bmV3IFVpbnQ4QXJyYXkoaGEubGVuZ3RoKTtmb3IobGV0IGJhPTA7YmE8eGEubGVuZ3RoOysrYmEpeGFbYmFdPU1hdGgucm91bmQoaGFbYmFdKTtyZXR1cm4geGF9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZHR5cGUgJHthYX1gKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9pc0Jyb3dzZXIoKSYmcmVnaXN0ZXJCYWNrZW5kKCJ3ZWJnbCIsKCk9Pm5ldyBNYXRoQmFja2VuZFdlYkdMLDIpOy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IENIRUNLX05BTl9TTklQUEVUPWAKICBpZiAoaXNuYW4oYSkpIHJldHVybiBhOwogIGlmIChpc25hbihiKSkgcmV0dXJuIGI7CmA7Y2xhc3MgQmluYXJ5T3BQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIiwiQiJdLHRoaXMub3V0cHV0U2hhcGU9YXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUoeGEsYmEpLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgZmxvYXQgYmluYXJ5T3BlcmF0aW9uKGZsb2F0IGEsIGZsb2F0IGIpIHsKICAgICAgICAke2FhfQogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgZmxvYXQgYSA9IGdldEFBdE91dENvb3JkcygpOwogICAgICAgIGZsb2F0IGIgPSBnZXRCQXRPdXRDb29yZHMoKTsKICAgICAgICBzZXRPdXRwdXQoYmluYXJ5T3BlcmF0aW9uKGEsIGIpKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQ0hFQ0tfTkFOX1NOSVBQRVRfUEFDS0VEPWAKICByZXN1bHQuciA9IGlzTmFOLnIgPyBOQU4gOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyBOQU4gOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyBOQU4gOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyBOQU4gOiByZXN1bHQuYTsKYDtjbGFzcyBCaW5hcnlPcFBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2E9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiLCJCIl0sdGhpcy5zdXBwb3J0c0Jyb2FkY2FzdGluZz0hMCx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLm91dHB1dFNoYXBlPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlKHhhLGJhKTtjb25zdCBUYT10aGlzLm91dHB1dFNoYXBlLmxlbmd0aDt0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3JtcyhUYSk7bGV0IHdhPSIiO2lmKFNhKWlmKFRhPT09MHx8c2l6ZUZyb21TaGFwZSh0aGlzLm91dHB1dFNoYXBlKT09PTEpd2E9YAogICAgICAgICAgcmVzdWx0LnkgPSAwLjsKICAgICAgICAgIHJlc3VsdC56ID0gMC47CiAgICAgICAgICByZXN1bHQudyA9IDAuOwogICAgICAgIGA7ZWxzZSBpZih3YT1gCiAgICAgICAgICAke2dldENvb3Jkc0RhdGFUeXBlKFRhKX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgYCxUYT09PTEpdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zP3dhKz1gCiAgICAgICAgICAgIHJlc3VsdC55ID0gKGNvb3JkcyArIDEpID49IG91dFNoYXBlID8gMC4gOiByZXN1bHQueTsKICAgICAgICAgICAgcmVzdWx0LnogPSAwLjsKICAgICAgICAgICAgcmVzdWx0LncgPSAwLjsKICAgICAgICAgIGA6d2ErPWAKICAgICAgICAgICAgcmVzdWx0LnkgPSAoY29vcmRzICsgMSkgPj0gJHt0aGlzLm91dHB1dFNoYXBlWzBdfSA/IDAuIDogcmVzdWx0Lnk7CiAgICAgICAgICAgIHJlc3VsdC56ID0gMC47CiAgICAgICAgICAgIHJlc3VsdC53ID0gMC47CiAgICAgICAgICBgO2Vsc2V7Y29uc3Qga2E9Z2V0Q2hhbm5lbHMoImNvb3JkcyIsVGEpO3RoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz93YSs9YAogICAgICAgICAgICBib29sIG5leHRSb3dPdXRPZkJvdW5kcyA9CiAgICAgICAgICAgICAgKCR7a2FbVGEtMl19ICsgMSkgPj0gb3V0U2hhcGVbJHtUYX0gLSAyXTsKICAgICAgICAgICAgYm9vbCBuZXh0Q29sT3V0T2ZCb3VuZHMgPQogICAgICAgICAgICAgICgke2thW1RhLTFdfSArIDEpID49IG91dFNoYXBlWyR7VGF9IC0gMV07CiAgICAgICAgICAgIHJlc3VsdC55ID0gbmV4dENvbE91dE9mQm91bmRzID8gMC4gOiByZXN1bHQueTsKICAgICAgICAgICAgcmVzdWx0LnogPSBuZXh0Um93T3V0T2ZCb3VuZHMgPyAwLiA6IHJlc3VsdC56OwogICAgICAgICAgICByZXN1bHQudyA9IG5leHRDb2xPdXRPZkJvdW5kcyB8fCBuZXh0Um93T3V0T2ZCb3VuZHMgPyAwLiA6IHJlc3VsdC53OwogICAgICAgICAgYDp3YSs9YAogICAgICAgICAgICBib29sIG5leHRSb3dPdXRPZkJvdW5kcyA9CiAgICAgICAgICAgICAgKCR7a2FbVGEtMl19ICsgMSkgPj0gJHt0aGlzLm91dHB1dFNoYXBlW1RhLTJdfTsKICAgICAgICAgICAgYm9vbCBuZXh0Q29sT3V0T2ZCb3VuZHMgPQogICAgICAgICAgICAgICgke2thW1RhLTFdfSArIDEpID49ICR7dGhpcy5vdXRwdXRTaGFwZVtUYS0xXX07CiAgICAgICAgICAgIHJlc3VsdC55ID0gbmV4dENvbE91dE9mQm91bmRzID8gMC4gOiByZXN1bHQueTsKICAgICAgICAgICAgcmVzdWx0LnogPSBuZXh0Um93T3V0T2ZCb3VuZHMgPyAwLiA6IHJlc3VsdC56OwogICAgICAgICAgICByZXN1bHQudyA9IG5leHRDb2xPdXRPZkJvdW5kcyB8fCBuZXh0Um93T3V0T2ZCb3VuZHMgPyAwLiA6IHJlc3VsdC53OwogICAgICAgICAgYH10aGlzLnVzZXJDb2RlPWAKICAgICAgdmVjNCBiaW5hcnlPcGVyYXRpb24odmVjNCBhLCB2ZWM0IGIpIHsKICAgICAgICAke2FhfQogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgdmVjNCBhID0gZ2V0QUF0T3V0Q29vcmRzKCk7CiAgICAgICAgdmVjNCBiID0gZ2V0QkF0T3V0Q29vcmRzKCk7CgogICAgICAgIHZlYzQgcmVzdWx0ID0gYmluYXJ5T3BlcmF0aW9uKGEsIGIpOwogICAgICAgICR7d2F9CgogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBpZGVudGl0eShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYTtyZXR1cm4geGEuaW5jUmVmKGJhLmRhdGFJZCkse2RhdGFJZDpiYS5kYXRhSWQsc2hhcGU6YmEuc2hhcGUsZHR5cGU6YmEuZHR5cGV9fWNvbnN0IGlkZW50aXR5Q29uZmlnPXtrZXJuZWxOYW1lOklkZW50aXR5LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzppZGVudGl0eX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29tcGxleChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtyZWFsOmJhLGltYWc6U2F9PWFhLFRhPXhhLm1ha2VUZW5zb3JJbmZvKGJhLnNoYXBlLCJjb21wbGV4NjQiKSx3YT14YS50ZXhEYXRhLmdldChUYS5kYXRhSWQpLEVhPWlkZW50aXR5KHtpbnB1dHM6e3g6YmF9LGJhY2tlbmQ6eGF9KSxrYT1pZGVudGl0eSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhfSk7cmV0dXJuIHdhLmNvbXBsZXhUZW5zb3JJbmZvcz17cmVhbDpFYSxpbWFnOmthfSxUYX1jb25zdCBjb21wbGV4Q29uZmlnPXtrZXJuZWxOYW1lOkNvbXBsZXgsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbXBsZXh9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExFQUtZUkVMVT0icmV0dXJuIChhIDwgMC4pID8gYiAqIGEgOiBhOyIsTEVBS1lSRUxVX1BBQ0tFRD1gCiAgdmVjNCBhTGVzc1RoYW5aZXJvID0gdmVjNChsZXNzVGhhbihhLCB2ZWM0KDAuKSkpOwogIHJldHVybiAoYUxlc3NUaGFuWmVybyAqIChiICogYSkpICsgKCh2ZWM0KDEuMCkgLSBhTGVzc1RoYW5aZXJvKSAqIGEpOwpgO2Z1bmN0aW9uIGxlYWt5UmVsdShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YWxwaGE6VGF9PWJhLHdhPXhhLm1ha2VUZW5zb3JJbmZvKFtdLCJmbG9hdDMyIixjcmVhdGVTY2FsYXJWYWx1ZShUYSwiZmxvYXQzMiIpKSxFYT1lbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0JJTkFSWV9PUEVSQVRJT05TIik/bmV3IEJpbmFyeU9wUGFja2VkUHJvZ3JhbShMRUFLWVJFTFVfUEFDS0VELFNhLnNoYXBlLHdhLnNoYXBlKTpuZXcgQmluYXJ5T3BQcm9ncmFtKExFQUtZUkVMVSxTYS5zaGFwZSx3YS5zaGFwZSksa2E9eGEucnVuV2ViR0xQcm9ncmFtKEVhLFtTYSx3YV0sImZsb2F0MzIiKTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLGthfWNvbnN0IGxlYWt5UmVsdUNvbmZpZz17a2VybmVsTmFtZTpMZWFreVJlbHUsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmxlYWt5UmVsdX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgUFJFTFU9InJldHVybiAoYSA8IDAuKSA/IGIgKiBhIDogYTsiLFBSRUxVX1BBQ0tFRD1gCiAgdmVjNCBhTGVzc1RoYW5aZXJvID0gdmVjNChsZXNzVGhhbihhLCB2ZWM0KDAuKSkpOwogIHJldHVybiAoYUxlc3NUaGFuWmVybyAqIChiICogYSkpICsgKCh2ZWM0KDEuMCkgLSBhTGVzc1RoYW5aZXJvKSAqIGEpOwpgO2Z1bmN0aW9uIHByZWx1KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3g6YmEsYWxwaGE6U2F9PWFhLFRhPWVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfQklOQVJZX09QRVJBVElPTlMiKT9uZXcgQmluYXJ5T3BQYWNrZWRQcm9ncmFtKFBSRUxVX1BBQ0tFRCxiYS5zaGFwZSxTYS5zaGFwZSk6bmV3IEJpbmFyeU9wUHJvZ3JhbShQUkVMVSxiYS5zaGFwZSxTYS5zaGFwZSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShUYSxbYmEsU2FdLCJmbG9hdDMyIil9Y29uc3QgcHJlbHVDb25maWc9e2tlcm5lbE5hbWU6UHJlbHUsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnByZWx1fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDSEVDS19OQU5fU05JUFBFVF9VTkFSWT0iaWYgKGlzbmFuKHgpKSByZXR1cm4geDsiO2Z1bmN0aW9uIHVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OmhhLHBhY2tlZE9wU25pcHBldDphYSxjcHVLZXJuZWxJbXBsOnhhLGR0eXBlOmJhfSl7cmV0dXJuKHtpbnB1dHM6U2EsYmFja2VuZDpUYX0pPT57Y29uc3R7eDp3YX09U2EsRWE9VGEsa2E9YmF8fHdhLmR0eXBlO2lmKEVhLnNob3VsZEV4ZWN1dGVPbkNQVShbd2FdKSYmeGEhPW51bGwpe2NvbnN0IExhPUVhLnRleERhdGEuZ2V0KHdhLmRhdGFJZCksZWw9eGEoTGEudmFsdWVzLGthKTtyZXR1cm4gRWEubWFrZVRlbnNvckluZm8od2Euc2hhcGUsa2EsZWwpfWNvbnN0IEFhPWVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfVU5BUllfT1BFUkFUSU9OUyIpJiZhYSE9bnVsbDtsZXQgRmE7cmV0dXJuIEFhP0ZhPW5ldyBVbmFyeU9wUGFja2VkUHJvZ3JhbSh3YS5zaGFwZSxhYSk6RmE9bmV3IFVuYXJ5T3BQcm9ncmFtKHdhLnNoYXBlLGhhKSxFYS5ydW5XZWJHTFByb2dyYW0oRmEsW3dhXSxrYSl9fWZ1bmN0aW9uIGJpbmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpoYSxwYWNrZWRPcFNuaXBwZXQ6YWEsY2hlY2tPdXRPZkJvdW5kczp4YT0hMSxzdXBwb3J0c0NvbXBsZXg6YmE9ITEsY3B1S2VybmVsSW1wbDpTYSxkdHlwZTpUYX0pe3JldHVybih7aW5wdXRzOndhLGJhY2tlbmQ6RWF9KT0+e2NvbnN0e2E6a2EsYjpBYX09d2EsRmE9RWE7aWYoYmEmJmthLmR0eXBlPT09ImNvbXBsZXg2NCIpe2NvbnN0IG5sPUZhLnRleERhdGEuZ2V0KGthLmRhdGFJZCksc2w9RmEudGV4RGF0YS5nZXQoQWEuZGF0YUlkKSxbcmwsb2xdPVtbbmwuY29tcGxleFRlbnNvckluZm9zLnJlYWwsc2wuY29tcGxleFRlbnNvckluZm9zLnJlYWxdLFtubC5jb21wbGV4VGVuc29ySW5mb3MuaW1hZyxzbC5jb21wbGV4VGVuc29ySW5mb3MuaW1hZ11dLm1hcChsbD0+e2NvbnN0W2lsLGNsXT1sbCx1bD17ZGF0YUlkOmlsLmRhdGFJZCxkdHlwZTppbC5kdHlwZSxzaGFwZTprYS5zaGFwZX0sZGw9e2RhdGFJZDpjbC5kYXRhSWQsZHR5cGU6Y2wuZHR5cGUsc2hhcGU6QWEuc2hhcGV9LGhsPW5ldyBCaW5hcnlPcFByb2dyYW0oaGEsa2Euc2hhcGUsQWEuc2hhcGUpO3JldHVybiBGYS5ydW5XZWJHTFByb2dyYW0oaGwsW3VsLGRsXSx1cGNhc3RUeXBlKGlsLmR0eXBlLGNsLmR0eXBlKSl9KSxhbD1jb21wbGV4KHtpbnB1dHM6e3JlYWw6cmwsaW1hZzpvbH0sYmFja2VuZDpGYX0pO3JldHVybiBGYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhybCksRmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpLGFsfWNvbnN0IExhPVRhfHx1cGNhc3RUeXBlKGthLmR0eXBlLEFhLmR0eXBlKTtpZigoa2EuZHR5cGU9PT0ic3RyaW5nInx8QWEuZHR5cGU9PT0ic3RyaW5nInx8RmEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtrYSxBYV0pKSYmU2EhPW51bGwpe2NvbnN0IG5sPUZhLnRleERhdGEuZ2V0KGthLmRhdGFJZCkudmFsdWVzLHNsPUZhLnRleERhdGEuZ2V0KEFhLmRhdGFJZCkudmFsdWVzLHJsPWthLmR0eXBlPT09InN0cmluZyI/ZnJvbVVpbnQ4VG9TdHJpbmdBcnJheShubCk6bmwsb2w9a2EuZHR5cGU9PT0ic3RyaW5nIj9mcm9tVWludDhUb1N0cmluZ0FycmF5KHNsKTpzbCxbYWwsbGxdPVNhKGthLnNoYXBlLEFhLnNoYXBlLHJsLG9sLExhKSxpbD1GYS5tYWtlVGVuc29ySW5mbyhsbCxMYSksY2w9RmEudGV4RGF0YS5nZXQoaWwuZGF0YUlkKTtyZXR1cm4gY2wudmFsdWVzPWFsLGlsfWNvbnN0IGVsPWVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfQklOQVJZX09QRVJBVElPTlMiKSYmYWEhPW51bGw7bGV0IHRsO3JldHVybiBlbD90bD1uZXcgQmluYXJ5T3BQYWNrZWRQcm9ncmFtKGFhLGthLnNoYXBlLEFhLnNoYXBlLHhhKTp0bD1uZXcgQmluYXJ5T3BQcm9ncmFtKGhhLGthLnNoYXBlLEFhLnNoYXBlKSxGYS5ydW5XZWJHTFByb2dyYW0odGwsW2thLEFhXSxMYSl9fWZ1bmN0aW9uIG1hcEFjdGl2YXRpb25Ub1NoYWRlclByb2dyYW0oaGEsYWE9ITEpe2lmKGhhPT09ImxpbmVhciIpcmV0dXJuIGFhP0xJTkVBUjpMSU5FQVIkMTtpZihoYT09PSJyZWx1IilyZXR1cm4gYWE/UkVMVSQxOlJFTFUkMjtpZihoYT09PSJlbHUiKXJldHVybiBhYT9FTFUkMTpFTFUkMjtpZihoYT09PSJyZWx1NiIpcmV0dXJuIGFhP1JFTFU2JDE6UkVMVTYkMjtpZihoYT09PSJwcmVsdSIpcmV0dXJuIGFhP1BSRUxVX1BBQ0tFRDpQUkVMVTtpZihoYT09PSJsZWFreXJlbHUiKXJldHVybiBhYT9MRUFLWVJFTFVfUEFDS0VEOkxFQUtZUkVMVTtpZihoYT09PSJzaWdtb2lkIilyZXR1cm4gYWE/U0lHTU9JRCQxOlNJR01PSUQkMjt0aHJvdyBuZXcgRXJyb3IoYEFjdGl2YXRpb24gJHtoYX0gaGFzIG5vdCBiZWVuIGltcGxlbWVudGVkIGZvciB0aGUgV2ViR0wgYmFja2VuZC5gKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBNYXRNdWxQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhPSExLFRhPSExLHdhPSExLEVhPW51bGwsa2E9ITEsQWE9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIm1hdHJpeEEiLCJtYXRyaXhCIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT1iYSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3Jtcyh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCk7Y29uc3QgRmE9U2E/YWFbMV06YWFbMl0sTGE9TWF0aC5jZWlsKEZhLzIpLGVsPVNhPyJpICogMiwgcmMueSI6InJjLnksIGkgKiAyIix0bD1UYT8icmMueiwgaSAqIDIiOiJpICogMiwgcmMueiIsbmw9U2E/WyJhLnh4eXkiLCJhLnp6d3ciXTpbImEueHh6eiIsImEueXl3dyJdLHNsPVRhP1siYi54enh6IiwiYi55d3l3Il06WyJiLnh5eHkiLCJiLnp3enciXTtsZXQgcmw9IiIsb2w9IiI7RWEmJihrYT9ybD1gdmVjNCBhY3RpdmF0aW9uKHZlYzQgYSkgewogICAgICAgICAgdmVjNCBiID0gZ2V0UHJlbHVBY3RpdmF0aW9uV2VpZ2h0c0F0T3V0Q29vcmRzKCk7CiAgICAgICAgICAke0VhfQogICAgICAgIH1gOkFhP3JsPWB2ZWM0IGFjdGl2YXRpb24odmVjNCBhKSB7CiAgICAgICAgICB2ZWM0IGIgPSBnZXRMZWFreXJlbHVBbHBoYUF0T3V0Q29vcmRzKCk7CiAgICAgICAgICAke0VhfQogICAgICAgIH1gOnJsPWB2ZWM0IGFjdGl2YXRpb24odmVjNCB4KSB7CiAgICAgICAgICAke0VhfQogICAgICAgIH1gLG9sPSJyZXN1bHQgPSBhY3RpdmF0aW9uKHJlc3VsdCk7Iik7Y29uc3QgYWw9d2E/InJlc3VsdCArPSBnZXRCaWFzQXRPdXRDb29yZHMoKTsiOiIiO3dhJiZ0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgiYmlhcyIpLGthJiZ0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgicHJlbHVBY3RpdmF0aW9uV2VpZ2h0cyIpLEFhJiZ0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgibGVha3lyZWx1QWxwaGEiKTtsZXQgbGw9InJjLngiLGlsPSJyYy54IjthYVswXTx4YVswXT9sbD1gaW1vZChyYy54LCAke2FhWzBdfSlgOnhhWzBdPGFhWzBdJiYoaWw9YGltb2QocmMueCwgJHt4YVswXX0pYCksdGhpcy51c2VyQ29kZT1gCiAgICAgICR7cmx9CiAgICAgIC8vIERvbid0IHVzZSB1bmlmb3JtIGZvciBzaGFyZWREaW1lbnNpb25QYWNrZWQgZm9yIHBlcmZvcm1hbmNlLgogICAgICBjb25zdCBmbG9hdCBzaGFyZWREaW1lbnNpb24gPSAke0xhfS4wOwoKICAgICAgdmVjNCBkb3QyeDJBUm93QkNvbChpdmVjMyByYykgewogICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwKTsKICAgICAgICBpbnQgYmF0Y2hBID0gJHtsbH07CiAgICAgICAgaW50IGJhdGNoQiA9ICR7aWx9OwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtMYX07IGkrKykgewogICAgICAgICAgdmVjNCBhID0gZ2V0TWF0cml4QShiYXRjaEEsICR7ZWx9KTsKICAgICAgICAgIHZlYzQgYiA9IGdldE1hdHJpeEIoYmF0Y2hCLCAke3RsfSk7CgogICAgICAgICAgLy8gVGhlc2Ugc3dpenpsZWQgcHJvZHVjdHMgbmVlZCB0byBiZSBzZXBhcmF0ZWx5IGFkZGVkLgogICAgICAgICAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vdGVuc29yZmxvdy90ZmpzL2lzc3Vlcy8xNzM1CiAgICAgICAgICByZXN1bHQgKz0gKCR7bmxbMF19ICogJHtzbFswXX0pOwogICAgICAgICAgcmVzdWx0ICs9ICgke25sWzFdfSAqICR7c2xbMV19KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMzIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgdmVjNCByZXN1bHQgPSBkb3QyeDJBUm93QkNvbChyYyk7CgogICAgICAgICR7YWx9CgogICAgICAgICR7b2x9CgogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBDT01QTEVYX01VTFRJUExZPXtSRUFMOiJyZXR1cm4gYXJlYWwgKiBicmVhbCAtIGFpbWFnICogYmltYWc7IixJTUFHOiJyZXR1cm4gYXJlYWwgKiBiaW1hZyArIGFpbWFnICogYnJlYWw7In07Y2xhc3MgQmluYXJ5T3BDb21wbGV4UHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQVJlYWwiLCJBSW1hZyIsIkJSZWFsIiwiQkltYWciXSx0aGlzLm91dHB1dFNoYXBlPWFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlKHhhLGJhKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgZmxvYXQgYmluYXJ5T3BDb21wbGV4KAogICAgICAgICAgZmxvYXQgYXJlYWwsIGZsb2F0IGFpbWFnLCBmbG9hdCBicmVhbCwgZmxvYXQgYmltYWcpIHsKICAgICAgICAke2FhfQogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgZmxvYXQgYXJlYWwgPSBnZXRBUmVhbEF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgYWltYWcgPSBnZXRBSW1hZ0F0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgYnJlYWwgPSBnZXRCUmVhbEF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgYmltYWcgPSBnZXRCSW1hZ0F0T3V0Q29vcmRzKCk7CiAgICAgICAgc2V0T3V0cHV0KGJpbmFyeU9wQ29tcGxleChhcmVhbCwgYWltYWcsIGJyZWFsLCBiaW1hZykpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBNVUw9InJldHVybiBhICogYjsiO2Z1bmN0aW9uIG11bHRpcGx5KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2E6YmEsYjpTYX09YWEsVGE9dXBjYXN0VHlwZShiYS5kdHlwZSxTYS5kdHlwZSk7aWYoYmEuZHR5cGU9PT0iY29tcGxleDY0Iil7Y29uc3QgRWE9eGEudGV4RGF0YS5nZXQoYmEuZGF0YUlkKSxrYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLEFhPW5ldyBCaW5hcnlPcENvbXBsZXhQcm9ncmFtKENPTVBMRVhfTVVMVElQTFkuUkVBTCxiYS5zaGFwZSxTYS5zaGFwZSksRmE9bmV3IEJpbmFyeU9wQ29tcGxleFByb2dyYW0oQ09NUExFWF9NVUxUSVBMWS5JTUFHLGJhLnNoYXBlLFNhLnNoYXBlKSxMYT1be2RhdGFJZDpFYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbC5kYXRhSWQsZHR5cGU6RWEuY29tcGxleFRlbnNvckluZm9zLnJlYWwuZHR5cGUsc2hhcGU6YmEuc2hhcGV9LHtkYXRhSWQ6RWEuY29tcGxleFRlbnNvckluZm9zLmltYWcuZGF0YUlkLGR0eXBlOkVhLmNvbXBsZXhUZW5zb3JJbmZvcy5pbWFnLmR0eXBlLHNoYXBlOmJhLnNoYXBlfSx7ZGF0YUlkOmthLmNvbXBsZXhUZW5zb3JJbmZvcy5yZWFsLmRhdGFJZCxkdHlwZTprYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbC5kdHlwZSxzaGFwZTpTYS5zaGFwZX0se2RhdGFJZDprYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZy5kYXRhSWQsZHR5cGU6a2EuY29tcGxleFRlbnNvckluZm9zLmltYWcuZHR5cGUsc2hhcGU6U2Euc2hhcGV9XSxlbD14YS5ydW5XZWJHTFByb2dyYW0oQWEsTGEsImZsb2F0MzIiKSx0bD14YS5ydW5XZWJHTFByb2dyYW0oRmEsTGEsImZsb2F0MzIiKSxubD1jb21wbGV4KHtpbnB1dHM6e3JlYWw6ZWwsaW1hZzp0bH0sYmFja2VuZDp4YX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLG5sfWlmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbYmEsU2FdKSl7Y29uc3QgRWE9eGEudGV4RGF0YS5nZXQoYmEuZGF0YUlkKSxrYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLFtBYSxGYV09bXVsdGlwbHlJbXBsQ1BVKGJhLnNoYXBlLFNhLnNoYXBlLEVhLnZhbHVlcyxrYS52YWx1ZXMsVGEpLExhPXhhLm1ha2VUZW5zb3JJbmZvKEZhLFRhKSxlbD14YS50ZXhEYXRhLmdldChMYS5kYXRhSWQpO3JldHVybiBlbC52YWx1ZXM9QWEsTGF9bGV0IHdhO3JldHVybiBlbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0JJTkFSWV9PUEVSQVRJT05TIik/d2E9bmV3IEJpbmFyeU9wUGFja2VkUHJvZ3JhbShNVUwsYmEuc2hhcGUsU2Euc2hhcGUpOndhPW5ldyBCaW5hcnlPcFByb2dyYW0oTVVMLGJhLnNoYXBlLFNhLnNoYXBlKSx4YS5ydW5XZWJHTFByb2dyYW0od2EsW2JhLFNhXSxUYSl9Y29uc3QgbXVsdGlwbHlDb25maWc9e2tlcm5lbE5hbWU6TXVsdGlwbHksYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm11bHRpcGx5fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBwYWNrZWRSZXNoYXBlKGhhLGFhLHhhKXtjb25zdCBiYT1bZ2V0QmF0Y2hEaW0oaGEuc2hhcGUpLC4uLmdldFJvd3NDb2xzKGhhLnNoYXBlKV0sU2E9e2R0eXBlOmhhLmR0eXBlLHNoYXBlOmJhLGRhdGFJZDpoYS5kYXRhSWR9LFRhPVtnZXRCYXRjaERpbShhYSksLi4uZ2V0Um93c0NvbHMoYWEpXSx3YT1uZXcgUmVzaGFwZVBhY2tlZFByb2dyYW0oVGEsYmEpLEVhPSEwLGthPVtiYV0sQWE9eGEucnVuV2ViR0xQcm9ncmFtKHdhLFtTYV0saGEuZHR5cGUsa2EsRWEpO3JldHVybntkYXRhSWQ6QWEuZGF0YUlkLHNoYXBlOmFhLGR0eXBlOkFhLmR0eXBlfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNoYXBlKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtzaGFwZTpUYX09YmEsd2E9eGEsRWE9c2l6ZUZyb21TaGFwZShTYS5zaGFwZSksa2E9aW5mZXJGcm9tSW1wbGljaXRTaGFwZShUYSxFYSksQWE9c2l6ZUZyb21TaGFwZShrYSk7YXNzZXJ0KEVhPT09QWEsKCk9PmBUaGUgbmV3IHNoYXBlICgke2thfSkgaGFzICR7QWF9IGVsZW1lbnRzIGFuZCB0aGUgb2xkIHNoYXBlICgke1NhLnNoYXBlfSkgaGFzICR7RWF9IGVsZW1lbnRzLiBUaGUgbmV3IHNoYXBlIGFuZCBvbGQgc2hhcGUgbXVzdCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBlbGVtZW50cy5gKTtjb25zdCBGYT13YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpO3JldHVybiBGYS5pc1BhY2tlZCYmIWlzUmVzaGFwZUZyZWUoU2Euc2hhcGUsa2EpJiYhKEZhLnRleHR1cmUhPT1udWxsJiZpc1Jlc2hhcGVGcmVlKEZhLnNoYXBlLGthKSk/cGFja2VkUmVzaGFwZShTYSxrYSx3YSk6KHdhLmluY1JlZihTYS5kYXRhSWQpLHtkYXRhSWQ6U2EuZGF0YUlkLHNoYXBlOmthLGR0eXBlOlNhLmR0eXBlfSl9Y29uc3QgcmVzaGFwZUNvbmZpZz17a2VybmVsTmFtZTpSZXNoYXBlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyZXNoYXBlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBNZWFuUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdO2NvbnN0e3dpbmRvd1NpemU6YmEsYmF0Y2hTaXplOlNhLGluU2l6ZTpUYSxvdXRTaXplOndhfT1hYTt0aGlzLm91dHB1dFNoYXBlPVtTYSx3YV07Y29uc3QgRWE9TWF0aC5mbG9vcihiYS80KSo0LGthPWJhJTQ7bGV0IEFhPSJzdW1WYWx1ZSArPSBkb3QodmFsdWVzLCBvbmVzKTsiO2lmKHhhIT1udWxsKXtjb25zdCBMYT0xL3hhO0FhPWBzdW1WYWx1ZSArPSBkb3QodmFsdWVzICogJHtpc0ludChMYSk/TGEudG9QcmVjaXNpb24oMik6TGF9LCBvbmVzKTtgfWxldCBGYT0iIjtUYSViYT4wJiYoRmE9YAogICAgICAgIGlmIChpbklkeCA8IDAgfHwgaW5JZHggPj0gJHtUYX0pIHsKICAgICAgICAgIHJldHVybiAwLjA7CiAgICAgICAgfQogICAgICBgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgdmVjNCBvbmVzID0gdmVjNCgxLjAsIDEuMCwgMS4wLCAxLjApOwoKICAgICAgZmxvYXQgZ2V0VmFsdWUoaW50IGJhdGNoLCBpbnQgaW5JZHgpIHsKICAgICAgICAke0ZhfQogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCBpbklkeCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgaW50IG91dElkeCA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgaW5PZmZzZXQgPSBvdXRJZHggKiAke2JhfTsKCiAgICAgICAgZmxvYXQgc3VtVmFsdWUgPSAwLjA7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtFYX07IGkgKz0gNCkgewogICAgICAgICAgaW50IGluSWR4ID0gaW5PZmZzZXQgKyBpOwogICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAxKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMiksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDMpCiAgICAgICAgICApOwoKICAgICAgICAgICR7QWF9CiAgICAgICAgfQoKICAgICAgICBpbnQgaW5JZHggPSBpbk9mZnNldCArICR7RWF9OwogICAgICAgIGlmICgke2thPT09MX0pIHsKICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNChnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLCAwLjAsIDAuMCwgMC4wKTsKCiAgICAgICAgICAke0FhfQogICAgICAgIH0gZWxzZSBpZiAoJHtrYT09PTJ9KSB7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLCAwLjAsIDAuMCk7CgogICAgICAgICAgJHtBYX0KICAgICAgICB9IGVsc2UgaWYgKCR7a2E9PT0zfSkgewogICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAxKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMiksIDAuMCk7CgogICAgICAgICAgJHtBYX0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KHN1bVZhbHVlKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmVkdWNlUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdO2NvbnN0e3dpbmRvd1NpemU6YmEsYmF0Y2hTaXplOlNhLGluU2l6ZTpUYSxvdXRTaXplOndhfT1hYTt0aGlzLm91dHB1dFNoYXBlPVtTYSx3YV07bGV0IEVhPSIwLjAiLGthPSIiO3hhPT09InByb2QiP0VhPSIxLjAiOnhhPT09Im1pbiI/KEVhPSIxLjAgLyAxZS0yMCIsa2E9Im1pbiIpOnhhPT09Im1heCImJihFYT0iLTEuMCAvIDFlLTIwIixrYT0ibWF4Iik7bGV0IEFhPWAke3hhfSgke3hhfSgke3hhfShtaW5NYXhWYWx1ZVswXSwgbWluTWF4VmFsdWVbMV0pLCBtaW5NYXhWYWx1ZVsyXSksIG1pbk1heFZhbHVlWzNdKWA7eGE9PT0ic3VtIj9BYT0ic3VtVmFsdWUiOnhhPT09InByb2QiP0FhPSJwcm9kVmFsdWUiOnhhPT09ImFsbCI/QWE9ImFsbFZhbHVlIjp4YT09PSJhbnkiJiYoQWE9ImFueVZhbHVlIik7Y29uc3QgRmE9TWF0aC5mbG9vcihiYS80KSo0LExhPWJhJTQ7bGV0IGVsPWAKICAgICAgaWYgKCR7eGE9PT0ic3VtIn0pIHsKICAgICAgICBzdW1WYWx1ZSArPSBkb3QodmFsdWVzLCBvbmVzKTsKICAgICAgfSBlbHNlIGlmICgke3hhPT09InByb2QifSkgewogICAgICAgIHZlYzIgdG1wID0gdmVjMih2YWx1ZXNbMF0sIHZhbHVlc1sxXSkgKiB2ZWMyKHZhbHVlc1syXSwgdmFsdWVzWzNdKTsKICAgICAgICBwcm9kVmFsdWUgKj0gdG1wWzBdICogdG1wWzFdOwogICAgICB9IGVsc2UgewogICAgICAgIG1pbk1heFZhbHVlID0gJHtrYX0odmFsdWVzLCBtaW5NYXhWYWx1ZSk7CiAgICAgICAgaWYgKCR7eGE9PT0ibWluIn0gfHwgJHt4YT09PSJtYXgifSkgewogICAgICAgICAgbWluTWF4VmFsdWUgPSAke2thfSh2YWx1ZXMsIG1pbk1heFZhbHVlKTsKICAgICAgICAgIGJ2ZWM0IGlzTmFOID0gaXNuYW4odmFsdWVzKTsKICAgICAgICAgIGlmIChpc05hTi5yIHx8IGlzTmFOLmcgfHwgaXNOYU4uYiB8fCBpc05hTi5hKSB7CiAgICAgICAgICAgIG1pbk1heFZhbHVlID0gdmVjNChOQU4pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgYCx0bD0idmVjNCI7eGE9PT0iYWxsIj8oRWE9IjEuMCIsZWw9YAogICAgICAgIGJvb2wgcmVkdWNlZEFsbFZhbHVlID0gYWxsKHZhbHVlcyk7CiAgICAgICAgZmxvYXQgZmxvYXRlZFJlZHVjZWRBbGxWYWx1ZSA9IGZsb2F0KHJlZHVjZWRBbGxWYWx1ZSk7CiAgICAgICAgYWxsVmFsdWUgPSBmbG9hdChhbGxWYWx1ZSA+PSAxLjAgJiYgZmxvYXRlZFJlZHVjZWRBbGxWYWx1ZSA+PSAxLjApOwogICAgICBgLHRsPSJidmVjNCIpOnhhPT09ImFueSImJihFYT0iMC4wIixlbD1gCiAgICAgICAgYm9vbCByZWR1Y2VkQW55VmFsdWUgPSBhbnkodmFsdWVzKTsKICAgICAgICBmbG9hdCBmbG9hdGVkUmVkdWNlZEFueVZhbHVlID0gZmxvYXQocmVkdWNlZEFueVZhbHVlKTsKICAgICAgICBhbnlWYWx1ZSA9IGZsb2F0KGFueVZhbHVlID49IDEuMCB8fCBmbG9hdGVkUmVkdWNlZEFueVZhbHVlID49IDEuMCk7CiAgICAgIGAsdGw9ImJ2ZWM0Iik7bGV0IG5sPSIiO1RhJWJhPjAmJihubD1gCiAgICAgICAgaWYgKGluSWR4IDwgMCB8fCBpbklkeCA+PSAke1RhfSkgewogICAgICAgICAgcmV0dXJuIGluaXRpYWxpemF0aW9uVmFsdWU7CiAgICAgICAgfQogICAgICBgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgZmxvYXQgaW5pdGlhbGl6YXRpb25WYWx1ZSA9ICR7RWF9OwogICAgICBjb25zdCB2ZWM0IG9uZXMgPSB2ZWM0KDEuMCwgMS4wLCAxLjAsIDEuMCk7CgogICAgICBmbG9hdCBnZXRWYWx1ZShpbnQgYmF0Y2gsIGludCBpbklkeCkgewogICAgICAgICR7bmx9CiAgICAgICAgcmV0dXJuIGdldFgoYmF0Y2gsIGluSWR4KTsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMyIGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgb3V0SWR4ID0gY29vcmRzWzFdOwogICAgICAgIGludCBpbk9mZnNldCA9IG91dElkeCAqICR7YmF9OwoKICAgICAgICB2ZWM0IG1pbk1heFZhbHVlID0gdmVjNCgke0VhfSk7CiAgICAgICAgZmxvYXQgcHJvZFZhbHVlID0gMS4wOwogICAgICAgIGZsb2F0IHN1bVZhbHVlID0gMC4wOwogICAgICAgIGZsb2F0IGFsbFZhbHVlID0gMS4wOwogICAgICAgIGZsb2F0IGFueVZhbHVlID0gMC4wOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7RmF9OyBpICs9IDQpIHsKICAgICAgICAgIGludCBpbklkeCA9IGluT2Zmc2V0ICsgaTsKICAgICAgICAgICR7dGx9IHZhbHVlcyA9ICR7dGx9KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAxKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMiksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDMpCiAgICAgICAgICApOwoKICAgICAgICAgICR7ZWx9CiAgICAgICAgfQoKICAgICAgICBpbnQgaW5JZHggPSBpbk9mZnNldCArICR7RmF9OwogICAgICAgIGlmICgke0xhPT09MX0pIHsKICAgICAgICAgICR7dGx9IHZhbHVlcyA9ICR7dGx9KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlLAogICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlLAogICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlCiAgICAgICAgICApOwoKICAgICAgICAgICR7ZWx9CiAgICAgICAgfSBlbHNlIGlmICgke0xhPT09Mn0pIHsKICAgICAgICAgICR7dGx9IHZhbHVlcyA9ICR7dGx9KAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHgpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAxKSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0gZWxzZSBpZiAoJHtMYT09PTN9KSB7CiAgICAgICAgICAke3RsfSB2YWx1ZXMgPSAke3RsfSgKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4KSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMSksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDIpLAogICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlCiAgICAgICAgICApOwoKICAgICAgICAgICR7ZWx9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dCgke0FhfSk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdldFJlZHVjdGlvblN0YWdlcyhoYSl7Y29uc3QgYWE9W107Zm9yKDthYS5sZW5ndGg9PT0wfHxhYVthYS5sZW5ndGgtMV0ub3V0U2l6ZSE9PTE7KXtjb25zdCB4YT1hYS5sZW5ndGg/YWFbYWEubGVuZ3RoLTFdLm91dFNpemU6aGFbMV0sYmE9Y29tcHV0ZU9wdGltYWxXaW5kb3dTaXplKHhhKTthYS5wdXNoKHtpblNpemU6eGEsd2luZG93U2l6ZTpiYSxvdXRTaXplOk1hdGguY2VpbCh4YS9iYSl9KX1yZXR1cm4gYWF9ZnVuY3Rpb24gcmVkdWNlKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1nZXRSZWR1Y3Rpb25TdGFnZXMoaGEuc2hhcGUpO2xldCBUYT1oYTtmb3IobGV0IHdhPTA7d2E8U2EubGVuZ3RoO3dhKyspe2NvbnN0e2luU2l6ZTpFYSx3aW5kb3dTaXplOmthLG91dFNpemU6QWF9PVNhW3dhXTtsZXQgRmEsTGE7eGE9PT0ibWVhbiI/RmE9d2E9PT0wP25ldyBNZWFuUHJvZ3JhbSh7d2luZG93U2l6ZTprYSxpblNpemU6RWEsYmF0Y2hTaXplOmhhLnNoYXBlWzBdLG91dFNpemU6QWF9LEVhKTpuZXcgTWVhblByb2dyYW0oe3dpbmRvd1NpemU6a2EsaW5TaXplOkVhLGJhdGNoU2l6ZTpoYS5zaGFwZVswXSxvdXRTaXplOkFhfSk6RmE9bmV3IFJlZHVjZVByb2dyYW0oe3dpbmRvd1NpemU6a2EsaW5TaXplOkVhLGJhdGNoU2l6ZTpoYS5zaGFwZVswXSxvdXRTaXplOkFhfSx4YSksTGE9VGEsVGE9YmEucnVuV2ViR0xQcm9ncmFtKEZhLFtUYV0sYWEpLExhLmRhdGFJZCE9PWhhLmRhdGFJZCYmYmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpfXJldHVybiBUYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBUcmFuc3Bvc2VQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl07Y29uc3QgYmE9bmV3IEFycmF5KGFhLmxlbmd0aCk7Zm9yKGxldCB3YT0wO3dhPGJhLmxlbmd0aDt3YSsrKWJhW3dhXT1hYVt4YVt3YV1dO3RoaXMub3V0cHV0U2hhcGU9YmEsdGhpcy5yYW5rPWJhLmxlbmd0aDtjb25zdCBTYT1nZXRDb29yZHNEYXRhVHlwZSh0aGlzLnJhbmspLFRhPWdldFN3aXRjaGVkQ29vcmRzKHhhKTt0aGlzLnVzZXJDb2RlPWAKICAgIHZvaWQgbWFpbigpIHsKICAgICAgJHtTYX0gcmVzUkMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgc2V0T3V0cHV0KGdldEEoJHtUYX0pKTsKICAgIH0KICAgIGB9fWZ1bmN0aW9uIGdldFN3aXRjaGVkQ29vcmRzKGhhKXtjb25zdCBhYT1oYS5sZW5ndGg7aWYoYWE+Nil0aHJvdyBFcnJvcihgVHJhbnNwb3NlIGZvciByYW5rICR7YWF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7Y29uc3QgeGE9WyJyZXNSQy54IiwicmVzUkMueSIsInJlc1JDLnoiLCJyZXNSQy53IiwicmVzUkMudSIsInJlc1JDLnYiXSxiYT1uZXcgQXJyYXkoYWEpO2ZvcihsZXQgU2E9MDtTYTxoYS5sZW5ndGg7U2ErKyliYVtoYVtTYV1dPXhhW1NhXTtyZXR1cm4gYmEuam9pbigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFRyYW5zcG9zZVBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMDtjb25zdCBiYT1uZXcgQXJyYXkoYWEubGVuZ3RoKTtmb3IobGV0IEZhPTA7RmE8YmEubGVuZ3RoO0ZhKyspYmFbRmFdPWFhW3hhW0ZhXV07aWYodGhpcy5vdXRwdXRTaGFwZT1iYSx0aGlzLnJhbms9YmEubGVuZ3RoLHRoaXMucmFuaz42KXRocm93IEVycm9yKGBQYWNrZWQgdHJhbnNwb3NlIGZvciByYW5rICR7dGhpcy5yYW5rfSBpcyBub3QgeWV0IHN1cHBvcnRlZC5gKTtjb25zdCBTYT1nZXRDb29yZHNEYXRhVHlwZSh0aGlzLnJhbmspLFRhPWdldFZlY0NoYW5uZWxzKCJyYyIsdGhpcy5yYW5rKSx3YT1uZXcgQXJyYXkodGhpcy5yYW5rKTtmb3IobGV0IEZhPTA7RmE8eGEubGVuZ3RoO0ZhKyspd2FbeGFbRmFdXT1UYVtGYV07Y29uc3QgRWE9YHZlYzIoJHt3YS5zbGljZSgtMikuam9pbigpfSlgLGthPWArKyR7VGFbdGhpcy5yYW5rLTFdfSA8ICR7YmFbdGhpcy5yYW5rLTFdfWAsQWE9YGdldENoYW5uZWwoZ2V0QSgke3dhLmpvaW4oKX0pLCAke0VhfSlgO3RoaXMudXNlckNvZGU9YAogICAgdm9pZCBtYWluKCkgewogICAgICAke1NhfSByYyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwogICAgICByZXN1bHRbMF0gPSAke0FhfTsKICAgICAgaWYoJHtrYX0pIHsKICAgICAgICByZXN1bHRbMV0gPSAke0FhfTsKICAgICAgfQogICAgICAtLSR7VGFbdGhpcy5yYW5rLTFdfTsKICAgICAgaWYoKyske1RhW3RoaXMucmFuay0yXX0gPCAke2JhW3RoaXMucmFuay0yXX0pIHsKICAgICAgICByZXN1bHRbMl0gPSAke0FhfTsKICAgICAgICBpZigke2thfSkgewogICAgICAgICAgcmVzdWx0WzNdID0gJHtBYX07CiAgICAgICAgfQogICAgICB9CiAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdHJhbnNwb3NlSW1wbChoYSxhYSx4YSl7Y29uc3QgYmE9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19BUlJBWV9PUEVSQVRJT05TIik/bmV3IFRyYW5zcG9zZVBhY2tlZFByb2dyYW0oaGEuc2hhcGUsYWEpOm5ldyBUcmFuc3Bvc2VQcm9ncmFtKGhhLnNoYXBlLGFhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKGJhLFtoYV0saGEuZHR5cGUpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN1bUltcGwoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWFhLFRhPWhhLnNoYXBlLmxlbmd0aCx3YT1wYXJzZUF4aXNQYXJhbShTYSxoYS5zaGFwZSk7bGV0IEVhPXdhO2NvbnN0IGthPWdldEF4ZXNQZXJtdXRhdGlvbihFYSxUYSksQWE9a2EhPW51bGw7bGV0IEZhPWhhO0FhJiYoRmE9dHJhbnNwb3NlSW1wbChoYSxrYSxiYSksRWE9Z2V0SW5uZXJNb3N0QXhlcyhFYS5sZW5ndGgsVGEpKSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcygic3VtIixFYSxUYSk7Y29uc3RbTGEsZWxdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoRmEuc2hhcGUsRWEpO2xldCB0bD1MYTt4YSYmKHRsPWV4cGFuZFNoYXBlVG9LZWVwRGltKExhLHdhKSk7Y29uc3Qgbmw9c2l6ZUZyb21TaGFwZShlbCkscmw9c2l6ZUZyb21TaGFwZShoYS5zaGFwZSkvbmwsb2w9cmVzaGFwZSh7aW5wdXRzOnt4OkZhfSxhdHRyczp7c2hhcGU6W3JsLG5sXX0sYmFja2VuZDpiYX0pLGFsPXN1bU91dFR5cGUoaGEuZHR5cGUpLGxsPXJlZHVjZShvbCxhbCwic3VtIixiYSksaWw9cmVzaGFwZSh7aW5wdXRzOnt4OmxsfSxhdHRyczp7c2hhcGU6dGx9LGJhY2tlbmQ6YmF9KTtyZXR1cm4gYmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpLGJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGxsKSxBYSYmYmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpLGlsfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN1bShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmE7cmV0dXJuIHN1bUltcGwoU2EsVGEsd2EseGEpfWNvbnN0IHN1bUNvbmZpZz17a2VybmVsTmFtZTpTdW0sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnN1bX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdHJhbnNwb3NlKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtwZXJtOlRhfT1iYSx3YT14YSxFYT1TYS5zaGFwZS5sZW5ndGgsa2E9bmV3IEFycmF5KEVhKTtmb3IobGV0IEZhPTA7RmE8a2EubGVuZ3RoO0ZhKyspa2FbRmFdPVNhLnNoYXBlW1RhW0ZhXV07bGV0IEFhO2lmKHdhLnNob3VsZEV4ZWN1dGVPbkNQVShbU2FdKSl7Y29uc3QgTGE9d2EudGV4RGF0YS5nZXQoU2EuZGF0YUlkKS52YWx1ZXMsZWw9dHJhbnNwb3NlSW1wbENQVShMYSxTYS5zaGFwZSxTYS5kdHlwZSxUYSxrYSk7QWE9d2EubWFrZVRlbnNvckluZm8oa2EsU2EuZHR5cGUpO2NvbnN0IHRsPXdhLnRleERhdGEuZ2V0KEFhLmRhdGFJZCk7dGwudmFsdWVzPWVsfWVsc2UgQWE9dHJhbnNwb3NlSW1wbChTYSxUYSx3YSk7cmV0dXJuIEFhfWNvbnN0IHRyYW5zcG9zZUNvbmZpZz17a2VybmVsTmFtZTpUcmFuc3Bvc2UsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRyYW5zcG9zZX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgTUFUTVVMX1NIQVJFRF9ESU1fVEhSRVNIT0xEPTFlMztmdW5jdGlvbiBiYXRjaE1hdE11bEltcGwoe2E6aGEsYjphYSx0cmFuc3Bvc2VBOnhhLHRyYW5zcG9zZUI6YmEsYmFja2VuZDpTYSxiaWFzOlRhPW51bGwscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czp3YT1udWxsLGxlYWt5cmVsdUFscGhhOkVhPTAsYWN0aXZhdGlvbjprYT1udWxsfSl7Y29uc3QgQWE9aGEuc2hhcGUubGVuZ3RoLEZhPWFhLnNoYXBlLmxlbmd0aCxMYT14YT9oYS5zaGFwZVtBYS0yXTpoYS5zaGFwZVtBYS0xXSxlbD1iYT9hYS5zaGFwZVtGYS0xXTphYS5zaGFwZVtGYS0yXSx0bD14YT9oYS5zaGFwZVtBYS0xXTpoYS5zaGFwZVtBYS0yXSxubD1iYT9hYS5zaGFwZVtGYS0yXTphYS5zaGFwZVtGYS0xXSxzbD1oYS5zaGFwZS5zbGljZSgwLC0yKSxybD1hYS5zaGFwZS5zbGljZSgwLC0yKSxvbD1zaXplRnJvbVNoYXBlKHNsKSxhbD1zaXplRnJvbVNoYXBlKHJsKSxpbD1hc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZShoYS5zaGFwZS5zbGljZSgwLC0yKSxhYS5zaGFwZS5zbGljZSgwLC0yKSkuY29uY2F0KFt0bCxubF0pO2Fzc2VydChMYT09PWVsLCgpPT5gRXJyb3IgaW4gbWF0TXVsOiBpbm5lciBzaGFwZXMgKCR7TGF9KSBhbmQgKCR7ZWx9KSBvZiBUZW5zb3JzIHdpdGggc2hhcGVzICR7aGEuc2hhcGV9IGFuZCAke2FhLnNoYXBlfSBhbmQgdHJhbnNwb3NlQT0ke3hhfSBhbmQgdHJhbnNwb3NlQj0ke2JhfSBtdXN0IG1hdGNoLmApO2NvbnN0IGNsPXhhP1tvbCxMYSx0bF06W29sLHRsLExhXSx1bD1iYT9bYWwsbmwsZWxdOlthbCxlbCxubF0sZGw9cmVzaGFwZSh7aW5wdXRzOnt4OmhhfSxiYWNrZW5kOlNhLGF0dHJzOntzaGFwZTpjbH19KSxobD1yZXNoYXBlKHtpbnB1dHM6e3g6YWF9LGJhY2tlbmQ6U2EsYXR0cnM6e3NoYXBlOnVsfX0pLHBsPVtkbCxobF0sZmw9TWF0aC5tYXgob2wsYWwpLG1sPXhhP2RsLnNoYXBlWzFdOmRsLnNoYXBlWzJdLGdsPVRhIT1udWxsLCRsPXdhIT1udWxsLHhsPWthPT09ImxlYWt5cmVsdSIseWw9a2EhPW51bGw/bWFwQWN0aXZhdGlvblRvU2hhZGVyUHJvZ3JhbShrYSwhMCk6bnVsbCxibD1nbHx8JGx8fHhsfHx5bCE9bnVsbDtsZXQgU2w7aWYoKHRsPT09MXx8bmw9PT0xKSYmbWw+TUFUTVVMX1NIQVJFRF9ESU1fVEhSRVNIT0xEJiZibD09PSExKXtsZXQgVGw9ZGwsd2w9aGw7eGEmJihUbD10cmFuc3Bvc2Uoe2lucHV0czp7eDpkbH0sYmFja2VuZDpTYSxhdHRyczp7cGVybTpbMCwyLDFdfX0pLHBsLnB1c2goVGwpKSxiYSYmKHdsPXRyYW5zcG9zZSh7aW5wdXRzOnt4OmhsfSxiYWNrZW5kOlNhLGF0dHJzOntwZXJtOlswLDIsMV19fSkscGwucHVzaCh3bCkpO2NvbnN0IElsPW5sIT09MSxObD1ubD09PTE7bGV0IHZsPVRsO0lsJiYodmw9cmVzaGFwZSh7aW5wdXRzOnt4OlRsfSxiYWNrZW5kOlNhLGF0dHJzOntzaGFwZTpbZmwsbWwsMV19fSkscGwucHVzaCh2bCkpO2NvbnN0IGtsPW5sPT09MT8yOjE7bGV0IEVsPXdsO05sJiYoRWw9cmVzaGFwZSh7aW5wdXRzOnt4OndsfSxiYWNrZW5kOlNhLGF0dHJzOntzaGFwZTpbZmwsMSxtbF19fSkscGwucHVzaChFbCkpO2NvbnN0IEFsPW11bHRpcGx5KHtpbnB1dHM6e2E6dmwsYjpFbH0sYmFja2VuZDpTYX0pO1NsPXN1bSh7aW5wdXRzOnt4OkFsfSxiYWNrZW5kOlNhLGF0dHJzOntheGlzOmtsLGtlZXBEaW1zOiEwfX0pLHBsLnB1c2goQWwpfWVsc2V7Y29uc3QgVGw9dXBjYXN0VHlwZShoYS5kdHlwZSxhYS5kdHlwZSksd2w9bmV3IE1hdE11bFBhY2tlZFByb2dyYW0oY2wsdWwsW2ZsLHRsLG5sXSx4YSxiYSxnbCx5bCwkbCx4bCksSWw9W2RsLGhsXTtpZihUYSE9bnVsbCYmSWwucHVzaChUYSksJGwmJklsLnB1c2god2EpLHhsKXtjb25zdCBObD1TYS5tYWtlVGVuc29ySW5mbyhbXSwiZmxvYXQzMiIsY3JlYXRlU2NhbGFyVmFsdWUoRWEsImZsb2F0MzIiKSk7SWwucHVzaChObCkscGwucHVzaChObCl9U2w9U2EucnVuV2ViR0xQcm9ncmFtKHdsLElsLFRsKX1jb25zdCBDbD1yZXNoYXBlKHtpbnB1dHM6e3g6U2x9LGJhY2tlbmQ6U2EsYXR0cnM6e3NoYXBlOmlsfX0pO3BsLnB1c2goU2wpO2Zvcihjb25zdCBUbCBvZiBwbClTYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhUbCk7cmV0dXJuIENsfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gX2Z1c2VkTWF0TXVsKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2E6U2EsYjpUYSxiaWFzOndhLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWF9PWFhLHt0cmFuc3Bvc2VBOmthLHRyYW5zcG9zZUI6QWEsYWN0aXZhdGlvbjpGYSxsZWFreXJlbHVBbHBoYTpMYX09YmE7cmV0dXJuIGJhdGNoTWF0TXVsSW1wbCh7YTpTYSxiOlRhLHRyYW5zcG9zZUE6a2EsdHJhbnNwb3NlQjpBYSxiYWNrZW5kOnhhLGJpYXM6d2EscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpFYSxsZWFreXJlbHVBbHBoYTpMYSxhY3RpdmF0aW9uOkZhfSl9Y29uc3QgX2Z1c2VkTWF0TXVsQ29uZmlnPXtrZXJuZWxOYW1lOl9GdXNlZE1hdE11bCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6X2Z1c2VkTWF0TXVsfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBQlM9InJldHVybiBhYnMoeCk7IjtmdW5jdGlvbiBhYnMoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWE7aWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtiYV0pJiZiYS5kdHlwZSE9PSJjb21wbGV4NjQiKXtjb25zdCBUYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpLHdhPXNpbXBsZUFic0ltcGxDUFUoVGEudmFsdWVzKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oYmEuc2hhcGUsYmEuZHR5cGUsd2EpfWxldCBTYTtyZXR1cm4gZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19VTkFSWV9PUEVSQVRJT05TIik/U2E9bmV3IFVuYXJ5T3BQYWNrZWRQcm9ncmFtKGJhLnNoYXBlLEFCUyk6U2E9bmV3IFVuYXJ5T3BQcm9ncmFtKGJhLnNoYXBlLEFCUykseGEucnVuV2ViR0xQcm9ncmFtKFNhLFtiYV0sYmEuZHR5cGUpfWNvbnN0IGFic0NvbmZpZz17a2VybmVsTmFtZTpBYnMsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFic307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQUNPUz1DSEVDS19OQU5fU05JUFBFVCQxK2AKICBpZiAoYWJzKHgpID4gMS4pIHsKICAgIHJldHVybiBOQU47CiAgfQogIHJldHVybiBhY29zKHgpOwpgLGFjb3M9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6QUNPU30pLGFjb3NDb25maWc9e2tlcm5lbE5hbWU6QWNvcyxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YWNvc307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQUNPU0g9Q0hFQ0tfTkFOX1NOSVBQRVQkMStgCiAgaWYgKHggPCAxLjApIHJldHVybiBOQU47CnJldHVybiBsb2coeCArIHNxcnQoeCAqIHggLSAxLjApKTtgLGFjb3NoPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkFDT1NIfSksYWNvc2hDb25maWc9e2tlcm5lbE5hbWU6QWNvc2gsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFjb3NofTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBREQ9InJldHVybiBhICsgYjsiLGFkZEtlcm5lbEZ1bmM9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkFERCxwYWNrZWRPcFNuaXBwZXQ6QURELHN1cHBvcnRzQ29tcGxleDohMCxjcHVLZXJuZWxJbXBsOmFkZEltcGxDUFV9KSxhZGRDb25maWc9e2tlcm5lbE5hbWU6QWRkLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphZGRLZXJuZWxGdW5jfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBBZGROUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudmFyaWFibGVOYW1lcz14YS5tYXAoKFRhLHdhKT0+YFQke3dhfWApO2NvbnN0IGJhPVtdO3RoaXMudmFyaWFibGVOYW1lcy5mb3JFYWNoKFRhPT57YmEucHVzaChgZmxvYXQgdiR7VGF9ID0gZ2V0JHtUYX1BdE91dENvb3JkcygpO2ApfSk7Y29uc3QgU2E9dGhpcy52YXJpYWJsZU5hbWVzLm1hcChUYT0+YHYke1RhfWApLmpvaW4oIiArICIpO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtiYS5qb2luKGAKICAgICAgICBgKX0KCiAgICAgICAgZmxvYXQgcmVzdWx0ID0gJHtTYX07CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEFkZE5QYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy52YXJpYWJsZU5hbWVzPXhhLm1hcCgoVGEsd2EpPT5gVCR7d2F9YCk7Y29uc3QgYmE9W107dGhpcy52YXJpYWJsZU5hbWVzLmZvckVhY2goVGE9PntiYS5wdXNoKGB2ZWM0IHYke1RhfSA9IGdldCR7VGF9QXRPdXRDb29yZHMoKTtgKX0pO2NvbnN0IFNhPXRoaXMudmFyaWFibGVOYW1lcy5tYXAoVGE9PmB2JHtUYX1gKS5qb2luKCIgKyAiKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7YmEuam9pbihgCiAgICAgICAgYCl9CgogICAgICAgIHZlYzQgcmVzdWx0ID0gJHtTYX07CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFkZE4oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSxiYT1hYTtpZihiYS5sZW5ndGg9PT0xKXJldHVybiBpZGVudGl0eSh7aW5wdXRzOnt4OmJhWzBdfSxiYWNrZW5kOnhhfSk7aWYoYmEubGVuZ3RoPmVudigpLmdldE51bWJlcigiV0VCR0xfTUFYX1RFWFRVUkVTX0lOX1NIQURFUiIpKXtjb25zdCBrYT1NYXRoLmZsb29yKGJhLmxlbmd0aC8yKSxBYT1hZGROKHtpbnB1dHM6YmEuc2xpY2UoMCxrYSksYmFja2VuZDp4YX0pLEZhPWFkZE4oe2lucHV0czpiYS5zbGljZShrYSksYmFja2VuZDp4YX0pO3JldHVybiBhZGROKHtpbnB1dHM6W0FhLEZhXSxiYWNrZW5kOnhhfSl9Y29uc3QgU2E9YmEubWFwKGthPT5rYS5kdHlwZSkucmVkdWNlKChrYSxBYSk9PnVwY2FzdFR5cGUoa2EsQWEpKSxUYT1iYS5tYXAoa2E9PmthLnNoYXBlKSxFYT1lbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLIik/bmV3IEFkZE5QYWNrZWRQcm9ncmFtKGJhWzBdLnNoYXBlLFRhKTpuZXcgQWRkTlByb2dyYW0oYmFbMF0uc2hhcGUsVGEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRWEsYmEsU2EpfWNvbnN0IGFkZE5Db25maWc9e2tlcm5lbE5hbWU6QWRkTixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YWRkTn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYWxsKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGtlZXBEaW1zOndhfT1iYSxFYT1TYS5zaGFwZS5sZW5ndGgsa2E9cGFyc2VBeGlzUGFyYW0oVGEsU2Euc2hhcGUpO2xldCBBYT1rYTtjb25zdCBGYT1nZXRBeGVzUGVybXV0YXRpb24oQWEsRWEpO2xldCBMYT1TYTtGYSE9bnVsbCYmKExhPXRyYW5zcG9zZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkZhfX0pLEFhPWdldElubmVyTW9zdEF4ZXMoQWEubGVuZ3RoLEVhKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMoImFsbCIsQWEsRWEpO2NvbnN0W2VsLHRsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKExhLnNoYXBlLEFhKSxubD1zaXplRnJvbVNoYXBlKHRsKSxzbD1yZXNoYXBlKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSxubF19fSkscmw9cmVkdWNlKHNsLHNsLmR0eXBlLCJhbGwiLHhhKTtsZXQgb2w7aWYod2Epe2NvbnN0IGFsPWV4cGFuZFNoYXBlVG9LZWVwRGltKGVsLGthKTtvbD1yZXNoYXBlKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmFsfX0pfWVsc2Ugb2w9cmVzaGFwZSh7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTplbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKSxGYSE9bnVsbCYmeGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpLG9sfWNvbnN0IGFsbENvbmZpZz17a2VybmVsTmFtZTpBbGwsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFsbH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYW55KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGtlZXBEaW1zOndhfT1iYSxFYT1TYS5zaGFwZS5sZW5ndGgsa2E9cGFyc2VBeGlzUGFyYW0oVGEsU2Euc2hhcGUpO2xldCBBYT1rYTtjb25zdCBGYT1nZXRBeGVzUGVybXV0YXRpb24oQWEsRWEpO2xldCBMYT1TYTtGYSE9bnVsbCYmKExhPXRyYW5zcG9zZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkZhfX0pLEFhPWdldElubmVyTW9zdEF4ZXMoQWEubGVuZ3RoLEVhKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMoImFueSIsQWEsRWEpO2NvbnN0W2VsLHRsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKExhLnNoYXBlLEFhKSxubD1zaXplRnJvbVNoYXBlKHRsKSxzbD1yZXNoYXBlKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSxubF19fSkscmw9cmVkdWNlKHNsLHNsLmR0eXBlLCJhbnkiLHhhKTtsZXQgb2w7aWYod2Epe2NvbnN0IGFsPWV4cGFuZFNoYXBlVG9LZWVwRGltKGVsLGthKTtvbD1yZXNoYXBlKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmFsfX0pfWVsc2Ugb2w9cmVzaGFwZSh7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTplbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKSxGYSE9bnVsbCYmeGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpLG9sfWNvbnN0IGFueUNvbmZpZz17a2VybmVsTmFtZTpBbnksYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFueX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgQXJnTWluTWF4UHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdO2NvbnN0e3dpbmRvd1NpemU6U2EsYmF0Y2hTaXplOlRhLG91dFNpemU6d2F9PWFhO2JhfHx0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgiYmVzdEluZGljZXNBIiksdGhpcy5vdXRwdXRTaGFwZT1bVGEsd2FdO2NvbnN0IEVhPXhhPT09Im1heCI/Ij4iOiI8IixrYT1iYT8iaW5PZmZzZXQgKyBpOyI6InJvdW5kKGdldEJlc3RJbmRpY2VzQShiYXRjaCwgaW5PZmZzZXQgKyBpKSk7Ijt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMyIGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgb3V0SWR4ID0gY29vcmRzWzFdOwogICAgICAgIGludCBpbk9mZnNldCA9IG91dElkeCAqICR7U2F9OwoKICAgICAgICBpbnQgYmVzdEluZGV4ID0gaW5PZmZzZXQ7CiAgICAgICAgZmxvYXQgYmVzdFZhbHVlID0gZ2V0QShiYXRjaCwgYmVzdEluZGV4KTsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke1NhfTsgaSsrKSB7CiAgICAgICAgICBpbnQgaW5JZHggPSAke2thfTsKICAgICAgICAgIGZsb2F0IGNhbmRpZGF0ZSA9IGdldEEoYmF0Y2gsIGluSWR4KTsKICAgICAgICAgIGlmIChjYW5kaWRhdGUgJHtFYX0gYmVzdFZhbHVlKSB7CiAgICAgICAgICAgIGJlc3RWYWx1ZSA9IGNhbmRpZGF0ZTsKICAgICAgICAgICAgYmVzdEluZGV4ID0gaW5JZHg7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChmbG9hdChiZXN0SW5kZXgpKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgQXJnTWluTWF4UGFja2VkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLGFzc2VydChhYS5sZW5ndGg+MiwoKT0+YFBhY2tlZCBhcmcke2JhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2JhLnNsaWNlKDEpfSBzdXBwb3J0cyBvbmx5IGlucHV0cyB3aXRoIHJhbmsgYWJvdmUgMi5gKTtjb25zdCBUYT1hYVthYS5sZW5ndGgtMV0sd2E9TWF0aC5jZWlsKFRhL3hhKTt0aGlzLm91dHB1dFNoYXBlPWFhLnNsaWNlKDAsLTEpLHdhPjEmJnRoaXMub3V0cHV0U2hhcGUucHVzaCh3YSksU2F8fHRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJiZXN0SW5kaWNlc0EiKTtjb25zdCBFYT10aGlzLm91dHB1dFNoYXBlLGthPUVhLmxlbmd0aCxBYT1nZXRDb29yZHNEYXRhVHlwZShrYSksRmE9Z2V0Q2hhbm5lbHMoImNvb3JkcyIsa2EpO2xldCBMYSxlbDtpZih3YT09PTEpe2VsPWthKzE7Y29uc3QgaGw9Z2V0Q29vcmRzRGF0YVR5cGUoZWwpO0xhPWAKICAgICAgICAke2hsfSBzb3VyY2VMb2NSID0gJHtobH0oJHtGYS5qb2luKCl9LCAwKTsKICAgICAgICArKyR7RmFba2EtMV19OwogICAgICAgICR7aGx9IHNvdXJjZUxvY0cgPSAke2hsfSgke0ZhLmpvaW4oKX0sIDApOwogICAgICAgICsrJHtGYVtrYS0yXX07CiAgICAgICAgJHtobH0gc291cmNlTG9jQSA9ICR7aGx9KCR7RmEuam9pbigpfSwgMCk7CiAgICAgICAgLS0ke0ZhW2thLTFdfTsKICAgICAgICAke2hsfSBzb3VyY2VMb2NCID0gJHtobH0oJHtGYS5qb2luKCl9LCAwKTsKICAgICAgICAtLSR7RmFba2EtMl19O2B9ZWxzZSBlbD1rYSxMYT1gCiAgICAgICAgJHtBYX0gc291cmNlTG9jUiA9IGNvb3JkczsKICAgICAgICArKyR7RmFba2EtMV19OwogICAgICAgICR7QWF9IHNvdXJjZUxvY0cgPSBjb29yZHM7CiAgICAgICAgKyske0ZhW2thLTJdfTsKICAgICAgICAke0FhfSBzb3VyY2VMb2NBID0gY29vcmRzOwogICAgICAgIC0tJHtGYVtrYS0xXX07CiAgICAgICAgJHtBYX0gc291cmNlTG9jQiA9IGNvb3JkczsKICAgICAgICAtLSR7RmFba2EtMl19O2A7Y29uc3QgdGw9WyJ4IiwieSIsInoiLCJ3IiwidSIsInYiXS5zbGljZSgwLGVsKSxubD0iLiIrdGxbZWwtMV0sc2w9dGwubWFwKGhsPT4iaW50ICIraGwpLHJsPWdldENoYW5uZWxzKCJzb3VyY2VMb2NSIixlbC0xKS5jb25jYXQoImluSWR4LnIiKSxvbD1nZXRDaGFubmVscygic291cmNlTG9jRyIsZWwtMSkuY29uY2F0KCJpbklkeC5nIiksYWw9Z2V0Q2hhbm5lbHMoInNvdXJjZUxvY0IiLGVsLTEpLmNvbmNhdCgiaW5JZHguYiIpLGxsPWdldENoYW5uZWxzKCJzb3VyY2VMb2NBIixlbC0xKS5jb25jYXQoImluSWR4LmEiKSxpbD1iYT09PSJtYXgiPyJncmVhdGVyVGhhbiI6Imxlc3NUaGFuIixjbD1TYT8iIjpgCiAgICAgICAgICBpbklkeCA9IHJvdW5kKHZlYzQoZ2V0QmVzdEluZGljZXNBQ2hhbm5lbCgke3JsLmpvaW4oKX0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEJlc3RJbmRpY2VzQUNoYW5uZWwoJHtvbC5qb2luKCl9KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRCZXN0SW5kaWNlc0FDaGFubmVsKCR7YWwuam9pbigpfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QmVzdEluZGljZXNBQ2hhbm5lbCgke2xsLmpvaW4oKX0pKSk7YCx1bD1gdmVjNCgKICAgICAgICAgICAgZ2V0QUNoYW5uZWwoJHtybC5qb2luKCl9KSwKICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFDaGFubmVsKCR7b2wuam9pbigpfSkgOiAwLiwKICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFDaGFubmVsKCR7YWwuam9pbigpfSkgOiAwLiwKICAgICAgICAgICAgaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sID8gZ2V0QUNoYW5uZWwoJHtsbC5qb2luKCl9KSA6IDAuKWAsZGw9U2E/IiI6YAogICAgICBmbG9hdCBnZXRCZXN0SW5kaWNlc0FDaGFubmVsKCR7c2wuam9pbigpfSkgewogICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEJlc3RJbmRpY2VzQSgke3RsLmpvaW4oKX0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGwuc2xpY2UoLTIpLmpvaW4oKX0pKTsKICAgICAgfWA7dGhpcy51c2VyQ29kZT1gCiAgICAgIGZsb2F0IGdldEFDaGFubmVsKCR7c2wuam9pbigpfSkgewogICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoJHt0bC5qb2luKCl9KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0bC5zbGljZSgtMikuam9pbigpfSkpOwogICAgICB9CiAgICAgICR7ZGx9CiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke0FhfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBib29sIGhhc05leHRDb2wgPSAke0ZhW2thLTFdfSA8ICR7RWFba2EtMV0tMX07CiAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gJHtGYVtrYS0yXX0gPCAke0VhW2thLTJdLTF9OwogICAgICAgICR7TGF9CiAgICAgICAgaXZlYzQgc3JjSWR4ID0gaXZlYzQoc291cmNlTG9jUiR7bmx9LCBzb3VyY2VMb2NHJHtubH0sCiAgICAgICAgICBzb3VyY2VMb2NCJHtubH0sIHNvdXJjZUxvY0Eke25sfSkgKiAke3hhfTsKICAgICAgICBpdmVjNCBpbklkeCA9IHNyY0lkeDsKICAgICAgICB2ZWM0IGJlc3RJbmRleCA9IHZlYzQoaW5JZHgpOwogICAgICAgIHZlYzQgYmVzdFZhbHVlID0gJHt1bH07CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHt4YX07IGkrKykgewogICAgICAgICAgaW5JZHggPSBzcmNJZHg7CiAgICAgICAgICAke2NsfQogICAgICAgICAgdmVjNCBjYW5kaWRhdGUgPSAke3VsfTsKICAgICAgICAgIGJ2ZWM0IG5hbiA9IGlzbmFuKGNhbmRpZGF0ZSk7CiAgICAgICAgICBidmVjNCByZXBsYWNlID0gYnZlYzQoCiAgICAgICAgICAgIHZlYzQoJHtpbH0oY2FuZGlkYXRlLCBiZXN0VmFsdWUpKSAqICh2ZWM0KDEuMCkgLSB2ZWM0KG5hbikpKTsKCiAgICAgICAgICBiZXN0VmFsdWUgPSB2ZWM0KHJlcGxhY2UueCAgPyBjYW5kaWRhdGUueCA6IGJlc3RWYWx1ZS54LAogICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlLnkgID8gY2FuZGlkYXRlLnkgOiBiZXN0VmFsdWUueSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZS56ICA/IGNhbmRpZGF0ZS56IDogYmVzdFZhbHVlLnosCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2UudyAgPyBjYW5kaWRhdGUudyA6IGJlc3RWYWx1ZS53KTsKICAgICAgICAgIGJlc3RJbmRleCA9IG1peChiZXN0SW5kZXgsIHZlYzQoaW5JZHgpLCB2ZWM0KHJlcGxhY2UpKTsKICAgICAgICAgIHNyY0lkeCsrOwogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoYmVzdEluZGV4KTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXJnUmVkdWNlKGhhLGFhLHhhLGJhPW51bGwpe2xldCBTYT1hYS5zaGFwZVswXSxUYT1hYS5zaGFwZVsxXTtiYSE9bnVsbCYmKFNhPWJhLnNoYXBlWzBdLFRhPWJhLnNoYXBlWzFdKTtjb25zdCB3YT1jb21wdXRlT3B0aW1hbFdpbmRvd1NpemUoVGEpLEVhPXt3aW5kb3dTaXplOndhLGluU2l6ZTpUYSxiYXRjaFNpemU6U2Esb3V0U2l6ZTpNYXRoLmNlaWwoVGEvd2EpfSxrYT1uZXcgQXJnTWluTWF4UHJvZ3JhbShFYSx4YSxiYT09bnVsbCksQWE9W2FhXTtiYSE9bnVsbCYmQWEucHVzaChiYSk7Y29uc3QgRmE9aGEucnVuV2ViR0xQcm9ncmFtKGthLEFhLCJpbnQzMiIpO2lmKEZhLnNoYXBlWzFdPT09MSlyZXR1cm4gRmE7Y29uc3QgTGE9YXJnUmVkdWNlKGhhLGFhLHhhLEZhKTtyZXR1cm4gaGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpLExhfWZ1bmN0aW9uIGFyZ1JlZHVjZVBhY2tlZChoYSxhYSx4YSxiYT1udWxsKXtjb25zdCBTYT1iYSE9bnVsbD9iYS5zaGFwZTphYS5zaGFwZSxUYT1TYVtTYS5sZW5ndGgtMV0sd2E9Y29tcHV0ZU9wdGltYWxXaW5kb3dTaXplKFRhKSxFYT1uZXcgQXJnTWluTWF4UGFja2VkUHJvZ3JhbShTYSx3YSx4YSxiYT09bnVsbCksa2E9YmE9PW51bGw/W2FhXTpbYWEsYmFdLEFhPWhhLnJ1bldlYkdMUHJvZ3JhbShFYSxrYSwiaW50MzIiKTtpZihBYS5zaGFwZS5sZW5ndGg9PT1hYS5zaGFwZS5sZW5ndGgpe2NvbnN0IEZhPWFyZ1JlZHVjZVBhY2tlZChoYSxhYSx4YSxBYSk7cmV0dXJuIGhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEFhKSxGYX1yZXR1cm4gQWF9ZnVuY3Rpb24gYXJnTWluTWF4UmVkdWNlKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1beGFdO2lmKGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zKCJhcmciK2JhLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2JhLnNsaWNlKDEpLFNhLGFhLnNoYXBlLmxlbmd0aCksIWVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfUkVEVUNFIil8fGFhLnNoYXBlLmxlbmd0aDw9Mil7Y29uc3QgVGE9W10sd2E9aGEudGV4RGF0YS5nZXQoYWEuZGF0YUlkKSxFYT13YSE9PW51bGwmJndhLmlzUGFja2VkO2xldCBrYT1hYTtFYSYmKGthPWhhLnVucGFja1RlbnNvcihhYSksVGEucHVzaChrYSkpO2NvbnN0W0FhLEZhXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKGthLnNoYXBlLFNhKSxMYT1zaXplRnJvbVNoYXBlKEZhKSxlbD1yZXNoYXBlKHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6aGEsYXR0cnM6e3NoYXBlOlstMSxMYV19fSk7VGEucHVzaChlbCk7Y29uc3QgdGw9YXJnUmVkdWNlKGhhLGVsLGJhKTtUYS5wdXNoKHRsKTtjb25zdCBubD1yZXNoYXBlKHtpbnB1dHM6e3g6dGx9LGJhY2tlbmQ6aGEsYXR0cnM6e3NoYXBlOkFhfX0pO3JldHVybiBUYS5mb3JFYWNoKHNsPT5oYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkpLG5sfXJldHVybiBhcmdSZWR1Y2VQYWNrZWQoaGEsYWEsYmEpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFyZ01heChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYX09YmE7bGV0IHdhPXBhcnNlQXhpc1BhcmFtKFRhLFNhLnNoYXBlKTtjb25zdCBFYT1nZXRBeGVzUGVybXV0YXRpb24od2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQga2E9U2E7Y29uc3QgQWE9W107RWEhPW51bGwmJihrYT10cmFuc3Bvc2Uoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpFYX19KSxBYS5wdXNoKGthKSx3YT1nZXRJbm5lck1vc3RBeGVzKHdhLmxlbmd0aCxrYS5zaGFwZS5sZW5ndGgpKSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcygiYXJnTWF4Iixbd2FbMF1dLGthLnNoYXBlLmxlbmd0aCk7Y29uc3QgRmE9YXJnTWluTWF4UmVkdWNlKHhhLGthLHdhWzBdLCJtYXgiKTtyZXR1cm4gQWEuZm9yRWFjaChMYT0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpKSxGYX1jb25zdCBhcmdNYXhDb25maWc9e2tlcm5lbE5hbWU6QXJnTWF4LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphcmdNYXh9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGFyZ01pbihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYX09YmE7bGV0IHdhPXBhcnNlQXhpc1BhcmFtKFRhLFNhLnNoYXBlKTtjb25zdCBFYT1nZXRBeGVzUGVybXV0YXRpb24od2EsU2Euc2hhcGUubGVuZ3RoKTtsZXQga2E9U2E7Y29uc3QgQWE9W107RWEhPW51bGwmJihrYT10cmFuc3Bvc2Uoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpFYX19KSxBYS5wdXNoKGthKSx3YT1nZXRJbm5lck1vc3RBeGVzKHdhLmxlbmd0aCxrYS5zaGFwZS5sZW5ndGgpKSxhc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcygiYXJnTWluIixbd2FbMF1dLGthLnNoYXBlLmxlbmd0aCk7Y29uc3QgRmE9YXJnTWluTWF4UmVkdWNlKHhhLGthLHdhWzBdLCJtaW4iKTtyZXR1cm4gQWEuZm9yRWFjaChMYT0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpKSxGYX1jb25zdCBhcmdNaW5Db25maWc9e2tlcm5lbE5hbWU6QXJnTWluLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphcmdNaW59Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFTSU49Q0hFQ0tfTkFOX1NOSVBQRVQkMStgCiAgaWYgKGFicyh4KSA+IDEuKSB7CiAgICByZXR1cm4gTkFOOwogIH0KICByZXR1cm4gYXNpbih4KTsKYCxhc2luPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkFTSU59KSxhc2luQ29uZmlnPXtrZXJuZWxOYW1lOkFzaW4sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFzaW59Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEFTSU5IPUNIRUNLX05BTl9TTklQUEVUJDErInJldHVybiBsb2coeCArIHNxcnQoeCAqIHggKyAxLjApKTsiLGFzaW5oPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkFTSU5IfSksYXNpbmhDb25maWc9e2tlcm5lbE5hbWU6QXNpbmgsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmFzaW5ofTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBVEFOPUNIRUNLX05BTl9TTklQUEVUJDErYAogIHJldHVybiBhdGFuKHgpOwpgLGF0YW49dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6QVRBTn0pLGF0YW5Db25maWc9e2tlcm5lbE5hbWU6QXRhbixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YXRhbn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQVRBTjI9Q0hFQ0tfTkFOX1NOSVBQRVQrYAogIHJldHVybiBhdGFuKGEsIGIpOwpgLEFUQU4yX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSBhdGFuKGEsIGIpOwogIGJ2ZWM0IGlzTmFOQSA9IGlzbmFuKGEpOwogIGJ2ZWM0IGlzTmFOQiA9IGlzbmFuKGIpOwogIGJ2ZWM0IGlzTmFOID0gYnZlYzQoaXNOYU5BLnggfHwgaXNOYU5CLngsIGlzTmFOQS55IHx8IGlzTmFOQi55LCBpc05hTkEueiB8fCBpc05hTkIueiwgaXNOYU5BLncgfHwgaXNOYU5CLncpOwogIGArQ0hFQ0tfTkFOX1NOSVBQRVRfUEFDS0VEK2AKICByZXR1cm4gcmVzdWx0OwpgLGF0YW4yPWJpbmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpBVEFOMixwYWNrZWRPcFNuaXBwZXQ6QVRBTjJfUEFDS0VEfSksYXRhbjJDb25maWc9e2tlcm5lbE5hbWU6QXRhbjIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmF0YW4yfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBBVEFOSD1DSEVDS19OQU5fU05JUFBFVCQxK2AKICBpZiAoKHggPCAtMS4wKSB8fCAoeCA+IDEuMCkpIHJldHVybiBOQU47CnJldHVybiAobG9nKDEuMCArIHgpIC0gbG9nKDEuMCAtIHgpKSAvIDIuMDtgLGF0YW5oPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkFUQU5IfSksYXRhbmhDb25maWc9e2tlcm5lbE5hbWU6QXRhbmgsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmF0YW5ofTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBQb29sMkRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhPSExLFRhPSExKXtpZih0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0seGE9PT0iYXZnIiYmYmEpdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgY29tcHV0ZSBwb3NpdGlvbnMgZm9yIGF2ZXJhZ2UgcG9vbC4iKTtjb25zdCB3YT1hYS5maWx0ZXJXaWR0aCxFYT1hYS5zdHJpZGVIZWlnaHQsa2E9YWEuc3RyaWRlV2lkdGgsQWE9YWEuZGlsYXRpb25IZWlnaHQsRmE9YWEuZGlsYXRpb25XaWR0aCxMYT1hYS5lZmZlY3RpdmVGaWx0ZXJIZWlnaHQsZWw9YWEuZWZmZWN0aXZlRmlsdGVyV2lkdGgsdGw9YWEucGFkSW5mby50b3Asbmw9YWEucGFkSW5mby5sZWZ0O3RoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGU7Y29uc3Qgc2w9eGE9PT0iYXZnIixybD1gKChiYXRjaCAgKiAke2FhLmluSGVpZ2h0fSArIHhSKSAqICR7YWEuaW5XaWR0aH0gKyB4QykgKiAke2FhLmluQ2hhbm5lbHN9ICsgZGAsb2w9YCh4UiAqICR7YWEuaW5XaWR0aH0gKyB4QykgKiAke2FhLmluQ2hhbm5lbHN9ICsgZGA7bGV0IGFsPSIwLjAiO2lmKHNsfHwoYWw9Ii0xLjAgLyAxZS0yMCIpLGJhKXtjb25zdCBobD0iPj0iO3RoaXMudXNlckNvZGU9YAogICAgICAgIGNvbnN0IGl2ZWMyIHN0cmlkZXMgPSBpdmVjMigke0VhfSwgJHtrYX0pOwogICAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke3RsfSwgJHtubH0pOwoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICAgIGludCBkID0gY29vcmRzWzNdOwoKICAgICAgICAgIGl2ZWMyIHhSQ0Nvcm5lciA9IGNvb3Jkcy55eiAqIHN0cmlkZXMgLSBwYWRzOwogICAgICAgICAgaW50IHhSQ29ybmVyID0geFJDQ29ybmVyLng7CiAgICAgICAgICBpbnQgeENDb3JuZXIgPSB4UkNDb3JuZXIueTsKCiAgICAgICAgICAvLyBtYXgvbWluIHgoPywgPywgZCkgdG8gZ2V0IHkoeVIsIHlDLCBkKS4KICAgICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkCiAgICAgICAgICBmbG9hdCBtaW5NYXhWYWx1ZSA9IDAuMDsKICAgICAgICAgIGZsb2F0IG1pbk1heFZhbHVlRm91bmQgPSAwLjA7CiAgICAgICAgICBpbnQgbWluTWF4UG9zaXRpb24gPSAwOwogICAgICAgICAgZmxvYXQgYXZnVmFsdWUgPSAwLjA7CgogICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7TGF9OwogICAgICAgICAgICAgIHdSICs9ICR7QWF9KSB7CiAgICAgICAgICAgIGludCB4UiA9IHhSQ29ybmVyICsgd1I7CgogICAgICAgICAgICBpZiAoeFIgPCAwIHx8IHhSID49ICR7YWEuaW5IZWlnaHR9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke2VsfTsKICAgICAgICAgICAgICAgIHdDICs9ICR7RmF9KSB7CiAgICAgICAgICAgICAgaW50IHhDID0geENDb3JuZXIgKyB3QzsKCiAgICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0WChiYXRjaCwgeFIsIHhDLCBkKTsKCiAgICAgICAgICAgICAgLy8gSWYgYSBtaW4gLyBtYXggdmFsdWUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdXNlIGl0LiBJZiBub3QsCiAgICAgICAgICAgICAgLy8gdXNlIHRoZSBjdXJyZW50IHZhbHVlLgogICAgICAgICAgICAgIGZsb2F0IGN1cnJNaW5NYXhWYWx1ZSA9IG1peCgKICAgICAgICAgICAgICAgICAgdmFsdWUsIG1pbk1heFZhbHVlLCBtaW5NYXhWYWx1ZUZvdW5kKTsKICAgICAgICAgICAgICBpZiAodmFsdWUgJHtobH0gY3Vyck1pbk1heFZhbHVlKSB7CiAgICAgICAgICAgICAgICBtaW5NYXhWYWx1ZSA9IHZhbHVlOwogICAgICAgICAgICAgICAgbWluTWF4VmFsdWVGb3VuZCA9IDEuMDsKICAgICAgICAgICAgICAgIG1pbk1heFBvc2l0aW9uID0gJHtTYT9UYT9ybDpvbDpgd1IgKiAke2VsfSArIHdDYH07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBzZXRPdXRwdXQoZmxvYXQobWluTWF4UG9zaXRpb24pKTsKICAgICAgICB9CiAgICAgIGA7cmV0dXJufWNvbnN0IGxsPSJtYXgiO2xldCBpbD1gJHt4YX0oJHt4YX0oJHt4YX0obWluTWF4VmFsdWVbMF0sIG1pbk1heFZhbHVlWzFdKSwgbWluTWF4VmFsdWVbMl0pLCBtaW5NYXhWYWx1ZVszXSlgO3hhPT09ImF2ZyImJihpbD0iYXZnVmFsdWUgLyBtYXgoY291bnQsIDEuMCkiKTtjb25zdCBjbD1NYXRoLmZsb29yKHdhLzQpKjQsdWw9d2ElNCxkbD1gCiAgICAgIGlmICgke3NsfSkgewogICAgICAgIGF2Z1ZhbHVlICs9IGRvdCh2YWx1ZXMsIG9uZXMpOwogICAgICB9IGVsc2UgewogICAgICAgIG1pbk1heFZhbHVlID0gJHtsbH0odmFsdWVzLCBtaW5NYXhWYWx1ZSk7CiAgICAgIH0KICAgIGA7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMyIHN0cmlkZXMgPSBpdmVjMigke0VhfSwgJHtrYX0pOwogICAgICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHt0bH0sICR7bmx9KTsKICAgICAgY29uc3QgZmxvYXQgaW5pdGlhbGl6YXRpb25WYWx1ZSA9ICR7YWx9OwogICAgICBjb25zdCB2ZWM0IG9uZXMgPSB2ZWM0KDEuMCwgMS4wLCAxLjAsIDEuMCk7CgogICAgICBmbG9hdCBjb3VudCA9IDAuMDsKCiAgICAgIGZsb2F0IGdldFZhbHVlKGludCBiYXRjaCwgaW50IHhSLCBpbnQgeEMsIGludCBkKSB7CiAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICByZXR1cm4gaW5pdGlhbGl6YXRpb25WYWx1ZTsKICAgICAgICB9CiAgICAgICAgY291bnQgKz0gMS4wOwogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCB4UiwgeEMsIGQpOwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwoKICAgICAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMueXogKiBzdHJpZGVzIC0gcGFkczsKICAgICAgICBpbnQgeFJDb3JuZXIgPSB4UkNDb3JuZXIueDsKICAgICAgICBpbnQgeENDb3JuZXIgPSB4UkNDb3JuZXIueTsKCiAgICAgICAgLy8gbWF4L21pbiB4KD8sID8sIGQpIHRvIGdldCB5KHlSLCB5QywgZCkuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQKICAgICAgICB2ZWM0IG1pbk1heFZhbHVlID0gdmVjNCgke2FsfSk7CiAgICAgICAgZmxvYXQgYXZnVmFsdWUgPSAwLjA7CiAgICAgICAgY291bnQgPSAwLjA7CgogICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke0xhfTsKICAgICAgICAgICAgd1IgKz0gJHtBYX0pIHsKICAgICAgICAgIGludCB4UiA9IHhSQ29ybmVyICsgd1I7CgogICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtjbH07IHdDICs9IDQpIHsKICAgICAgICAgICAgaW50IHhDID0geENDb3JuZXIgKyB3QyAqICR7RmF9OwoKICAgICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMsIGQpLAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMgKyAke0ZhfSwgZCksCiAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhSLCB4QyArIDIgKiAke0ZhfSwgZCksCiAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhSLCB4QyArIDMgKiAke0ZhfSwgZCkKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICR7ZGx9CiAgICAgICAgICB9CgogICAgICAgICAgaW50IHhDID0geENDb3JuZXIgKyAke2NsfTsKICAgICAgICAgIGlmICgke3VsPT09MX0pIHsKICAgICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMsIGQpLAogICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAke2RsfQogICAgICAgICAgfSBlbHNlIGlmICgke3VsPT09Mn0pIHsKICAgICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMsIGQpLAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMgKyAke0ZhfSwgZCksCiAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAke2RsfQogICAgICAgICAgfSBlbHNlIGlmICgke3VsPT09M30pIHsKICAgICAgICAgICAgdmVjNCB2YWx1ZXMgPSB2ZWM0KAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMsIGQpLAogICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4UiwgeEMgKyAke0ZhfSwgZCksCiAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhSLCB4QyArIDIgKiAke0ZhfSwgZCksCiAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgICApOwoKICAgICAgICAgICAgJHtkbH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KCR7aWx9KTsKICAgICAgfQogICAgYH19Y2xhc3MgUG9vbDNEUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYT0hMSxUYT0hMSl7aWYodGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHhhPT09ImF2ZyImJmJhKXRocm93IG5ldyBFcnJvcigiQ2Fubm90IGNvbXB1dGUgcG9zaXRpb25zIGZvciBhdmVyYWdlIHBvb2wuIik7Y29uc3Qgd2E9YWEuZmlsdGVyV2lkdGgsRWE9YWEuc3RyaWRlRGVwdGgsa2E9YWEuc3RyaWRlSGVpZ2h0LEFhPWFhLnN0cmlkZVdpZHRoLEZhPWFhLmRpbGF0aW9uRGVwdGgsTGE9YWEuZGlsYXRpb25IZWlnaHQsZWw9YWEuZGlsYXRpb25XaWR0aCx0bD1hYS5lZmZlY3RpdmVGaWx0ZXJEZXB0aCxubD1hYS5lZmZlY3RpdmVGaWx0ZXJIZWlnaHQsc2w9YWEuZWZmZWN0aXZlRmlsdGVyV2lkdGgscmw9YWEucGFkSW5mby5mcm9udCxvbD1hYS5wYWRJbmZvLnRvcCxhbD1hYS5wYWRJbmZvLmxlZnQ7dGhpcy5vdXRwdXRTaGFwZT1hYS5vdXRTaGFwZTtjb25zdCBsbD14YT09PSJhdmciO2xldCBpbD0iMC4wIjtpZihsbHx8KGlsPSItMS4wIC8gMWUtMjAiKSxiYSl7Y29uc3QgZmw9Ij49Ijt0aGlzLnVzZXJDb2RlPWAKICAgICAgICBjb25zdCBpdmVjMyBzdHJpZGVzID0KICAgICAgICAgICAgaXZlYzMoJHtFYX0sICR7a2F9LCAke0FhfSk7CiAgICAgICAgY29uc3QgaXZlYzMgcGFkcyA9IGl2ZWMzKCR7cmx9LCAke29sfSwgJHthbH0pOwoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICBpdmVjNSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgICAgaW50IGNoID0gY29vcmRzLnU7CgogICAgICAgICAgaXZlYzMgeENvcm5lciA9IGl2ZWMzKGNvb3Jkcy55LCBjb29yZHMueiwgY29vcmRzLncpICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgICBpbnQgeERDb3JuZXIgPSB4Q29ybmVyLng7CiAgICAgICAgICBpbnQgeFJDb3JuZXIgPSB4Q29ybmVyLnk7CiAgICAgICAgICBpbnQgeENDb3JuZXIgPSB4Q29ybmVyLno7CgogICAgICAgICAgLy8gbWF4L21pbiB4KD8sID8sID8sIGNoKSB0byBnZXQgeSh5RCwgeVIsIHlDLCBjaCkuCiAgICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZAogICAgICAgICAgZmxvYXQgbWluTWF4VmFsdWUgPSAwLjA7CiAgICAgICAgICBmbG9hdCBtaW5NYXhWYWx1ZUZvdW5kID0gMC4wOwogICAgICAgICAgaW50IG1pbk1heFBvc2l0aW9uID0gMDsKCiAgICAgICAgICBmb3IgKGludCB3RCA9IDA7IHdEIDwgJHt0bH07CiAgICAgICAgICAgICAgd0QgKz0gJHtGYX0pIHsKICAgICAgICAgICAgaW50IHhEID0geERDb3JuZXIgKyB3RDsKCiAgICAgICAgICAgIGlmICh4RCA8IDAgfHwgeEQgPj0gJHthYS5pbkRlcHRofSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHtubH07CiAgICAgICAgICAgICAgICB3UiArPSAke0xhfSkgewogICAgICAgICAgICAgIGludCB4UiA9IHhSQ29ybmVyICsgd1I7CgogICAgICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gJHthYS5pbkhlaWdodH0pIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7c2x9OwogICAgICAgICAgICAgICAgICB3QyArPSAke2VsfSkgewogICAgICAgICAgICAgICAgaW50IHhDID0geENDb3JuZXIgKyB3QzsKCiAgICAgICAgICAgICAgICBpZiAoeEMgPCAwIHx8IHhDID49ICR7YWEuaW5XaWR0aH0pIHsKICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRYKGJhdGNoLCB4RCwgeFIsIHhDLCBjaCk7CgogICAgICAgICAgICAgICAgLy8gSWYgYSBtaW4gLyBtYXggdmFsdWUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdXNlIGl0LiBJZiBub3QsCiAgICAgICAgICAgICAgICAvLyB1c2UgdGhlIGN1cnJlbnQgdmFsdWUuCiAgICAgICAgICAgICAgICBmbG9hdCBjdXJyTWluTWF4VmFsdWUgPSBtaXgoCiAgICAgICAgICAgICAgICAgICAgdmFsdWUsIG1pbk1heFZhbHVlLCBtaW5NYXhWYWx1ZUZvdW5kKTsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAke2ZsfSBjdXJyTWluTWF4VmFsdWUpIHsKICAgICAgICAgICAgICAgICAgbWluTWF4VmFsdWUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgbWluTWF4VmFsdWVGb3VuZCA9IDEuMDsKICAgICAgICAgICAgICAgICAgbWluTWF4UG9zaXRpb24gPSAke1NhP1RhP2AoKChiYXRjaCAqICR7YWEuaW5EZXB0aH0gKyB4RCkgKiAke2FhLmluSGVpZ2h0fSArIHhSKSAqICR7YWEuaW5XaWR0aH0gKyB4QykgKiAke2FhLmluQ2hhbm5lbHN9ICsgY2hgOmAoKHhEICogJHthYS5pbkhlaWdodH0gKyB4UikgKiAke2FhLmluV2lkdGh9ICsgeEMpICogJHthYS5pbkNoYW5uZWxzfSArIGNoYDpgd0QgKiAke25sfSAqICR7c2x9ICsKICAgICAgICAgICAgICAgICAgICAgIHdSICogJHtzbH0gKyB3Q2B9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KGZsb2F0KG1pbk1heFBvc2l0aW9uKSk7CiAgICAgICAgfQogICAgICBgO3JldHVybn1jb25zdCBjbD0ibWF4IjtsZXQgdWw9YCR7eGF9KCR7eGF9KCR7eGF9KG1pbk1heFZhbHVlWzBdLCBtaW5NYXhWYWx1ZVsxXSksIG1pbk1heFZhbHVlWzJdKSwgbWluTWF4VmFsdWVbM10pYDt4YT09PSJhdmciJiYodWw9ImF2Z1ZhbHVlIC8gbWF4KGNvdW50LCAxLjApIik7Y29uc3QgZGw9TWF0aC5mbG9vcih3YS80KSo0LGhsPXdhJTQscGw9YAogICAgICBpZiAoJHtsbH0pIHsKICAgICAgICBhdmdWYWx1ZSArPSBkb3QodmFsdWVzLCBvbmVzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBtaW5NYXhWYWx1ZSA9ICR7Y2x9KHZhbHVlcywgbWluTWF4VmFsdWUpOwogICAgICB9CiAgICBgO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMyBzdHJpZGVzID0KICAgICAgICBpdmVjMygke0VhfSwgJHtrYX0sICR7QWF9KTsKICAgICAgY29uc3QgaXZlYzMgcGFkcyA9IGl2ZWMzKCR7cmx9LCAke29sfSwgJHthbH0pOwogICAgICBjb25zdCBmbG9hdCBpbml0aWFsaXphdGlvblZhbHVlID0gJHtpbH07CiAgICAgIGNvbnN0IHZlYzQgb25lcyA9IHZlYzQoMS4wLCAxLjAsIDEuMCwgMS4wKTsKCiAgICAgIGZsb2F0IGNvdW50ID0gMC4wOwoKICAgICAgZmxvYXQgZ2V0VmFsdWUoaW50IGJhdGNoLCBpbnQgeEQsIGludCB4UiwgaW50IHhDLCBpbnQgY2gpIHsKICAgICAgICBpZiAoeEMgPCAwIHx8IHhDID49ICR7YWEuaW5XaWR0aH0pIHsKICAgICAgICAgIHJldHVybiBpbml0aWFsaXphdGlvblZhbHVlOwogICAgICAgIH0KICAgICAgICBjb3VudCArPSAxLjA7CiAgICAgICAgcmV0dXJuIGdldFgoYmF0Y2gsIHhELCB4UiwgeEMsIGNoKTsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM1IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgIGludCBjaCA9IGNvb3Jkcy51OwoKICAgICAgICBpdmVjMyB4Q29ybmVyID0gaXZlYzMoY29vcmRzLnksIGNvb3Jkcy56LCBjb29yZHMudykgKiBzdHJpZGVzIC0gcGFkczsKICAgICAgICBpbnQgeERDb3JuZXIgPSB4Q29ybmVyLng7CiAgICAgICAgaW50IHhSQ29ybmVyID0geENvcm5lci55OwogICAgICAgIGludCB4Q0Nvcm5lciA9IHhDb3JuZXIuejsKCiAgICAgICAgLy8gbWF4L21pbiB4KD8sID8sID8sIGQpIHRvIGdldCB5KHlELCB5UiwgeUMsIGNoKS4KICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZAogICAgICAgIHZlYzQgbWluTWF4VmFsdWUgPSB2ZWM0KCR7aWx9KTsKICAgICAgICBmbG9hdCBhdmdWYWx1ZSA9IDAuMDsKICAgICAgICBjb3VudCA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgd0QgPSAwOyB3RCA8ICR7dGx9OwogICAgICAgICAgICB3RCArPSAke0ZhfSkgewogICAgICAgICAgaW50IHhEID0geERDb3JuZXIgKyB3RDsKCiAgICAgICAgICBpZiAoeEQgPCAwIHx8IHhEID49ICR7YWEuaW5EZXB0aH0pIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CgogICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7bmx9OwogICAgICAgICAgICB3UiArPSAke0xhfSkgewogICAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSOwoKICAgICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtkbH07IHdDICs9IDQpIHsKICAgICAgICAgICAgICBpbnQgeEMgPSB4Q0Nvcm5lciArIHdDICogJHtlbH07CgogICAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4RCwgeFIsIHhDLCBjaCksCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QyArICR7ZWx9LCBjaCksCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QyArIDIgKiAke2VsfSwgY2gpLAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMgKyAzICogJHtlbH0sIGNoKQogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICR7cGx9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgJHtkbH07CiAgICAgICAgICAgIGlmICgke2hsPT09MX0pIHsKICAgICAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QywgY2gpLAogICAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgICAgICBpbml0aWFsaXphdGlvblZhbHVlCiAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgJHtwbH0KICAgICAgICAgICAgfSBlbHNlIGlmICgke2hsPT09Mn0pIHsKICAgICAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QywgY2gpLAogICAgICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIHhELCB4UiwgeEMgKyAke2VsfSwgY2gpLAogICAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZSwKICAgICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAke3BsfQogICAgICAgICAgICB9IGVsc2UgaWYgKCR7aGw9PT0zfSkgewogICAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCB4RCwgeFIsIHhDLCBjaCksCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QyArICR7ZWx9LCBjaCksCiAgICAgICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgeEQsIHhSLCB4QyArIDIgKiAke2VsfSwgY2gpLAogICAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICR7cGx9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KCR7dWx9KTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXZnUG9vbChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYTthc3NlcnROb3RDb21wbGV4KFNhLCJhdmdQb29sIik7Y29uc3R7ZmlsdGVyU2l6ZTpUYSxzdHJpZGVzOndhLHBhZDpFYSxkaW1Sb3VuZGluZ01vZGU6a2F9PWJhLEFhPTE7YXNzZXJ0KGVpdGhlclN0cmlkZXNPckRpbGF0aW9uc0FyZU9uZSh3YSxBYSksKCk9PmBFcnJvciBpbiBhdmdQb29sOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke3dhfSBhbmQgZGlsYXRpb25zICcke0FhfSdgKTtjb25zdCBGYT1jb21wdXRlUG9vbDJESW5mbyhTYS5zaGFwZSxUYSx3YSxBYSxFYSxrYSk7aWYoRmEuZmlsdGVyV2lkdGg9PT0xJiZGYS5maWx0ZXJIZWlnaHQ9PT0xJiZhcnJheXNFcXVhbChGYS5pblNoYXBlLEZhLm91dFNoYXBlKSlyZXR1cm4gaWRlbnRpdHkoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2NvbnN0IExhPW5ldyBQb29sMkRQcm9ncmFtKEZhLCJhdmciLCExKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sImZsb2F0MzIiKX1jb25zdCBhdmdQb29sQ29uZmlnPXtrZXJuZWxOYW1lOkF2Z1Bvb2wsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmF2Z1Bvb2x9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGF2Z1Bvb2wzRChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7ZmlsdGVyU2l6ZTpUYSxzdHJpZGVzOndhLHBhZDpFYSxkaW1Sb3VuZGluZ01vZGU6a2EsZGF0YUZvcm1hdDpBYX09YmEsRmE9WzEsMSwxXSxMYT1jb21wdXRlUG9vbDNESW5mbyhTYS5zaGFwZSxUYSx3YSxGYSxFYSxrYSxBYSksZWw9bmV3IFBvb2wzRFByb2dyYW0oTGEsImF2ZyIsITEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oZWwsW1NhXSwiZmxvYXQzMiIpfWNvbnN0IGF2Z1Bvb2wzRENvbmZpZz17a2VybmVsTmFtZTpBdmdQb29sM0QsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmF2Z1Bvb2wzRH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgQXZnUG9vbDJEQmFja3Byb3BQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSJdLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZTtjb25zdCB4YT1hYS5maWx0ZXJIZWlnaHQsYmE9YWEuZmlsdGVyV2lkdGgsU2E9YWEuc3RyaWRlSGVpZ2h0LFRhPWFhLnN0cmlkZVdpZHRoLHdhPWFhLmRpbGF0aW9uSGVpZ2h0LEVhPWFhLmRpbGF0aW9uV2lkdGgsa2E9YWEuZWZmZWN0aXZlRmlsdGVySGVpZ2h0LEFhPWFhLmVmZmVjdGl2ZUZpbHRlcldpZHRoLEZhPWthLTEtYWEucGFkSW5mby50b3AsTGE9QWEtMS1hYS5wYWRJbmZvLmxlZnQsZWw9MS8oeGEqYmEpO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHtGYX0sICR7TGF9KTsKICAgICAgY29uc3QgZmxvYXQgYXZnTXVsdGlwbGllciA9IGZsb2F0KCR7ZWx9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKCiAgICAgICAgaXZlYzIgZHlSQ0Nvcm5lciA9IGNvb3Jkcy55eiAtIHBhZHM7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5UkNDb3JuZXIueDsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlSQ0Nvcm5lci55OwoKICAgICAgICAvLyBDb252b2x2ZSBkeSg/LCA/LCBkKSB3aXRoIHBvcyBtYXNrKDosIDosIGQpIHRvIGdldCBkeCh4UiwgeEMsIGQpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7a2F9OwogICAgICAgICAgICB3UiArPSAke3dhfSkgewogICAgICAgICAgZmxvYXQgZHlSID0gZmxvYXQoZHlSQ29ybmVyICsgd1IpIC8gJHtTYX0uMDsKCiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtBYX07CiAgICAgICAgICAgIHdDKz0gJHtFYX0pIHsKICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gJHtUYX0uMDsKCiAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgIGZyYWN0KGR5QykgPiAwLjApIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWR5QyA9IGludChkeUMpOwoKICAgICAgICAgICAgZmxvYXQgZHlWYWx1ZSA9IGdldER5KGIsIGlkeVIsIGlkeUMsIGQpOwoKICAgICAgICAgICAgZG90UHJvZCArPSBkeVZhbHVlICogYXZnTXVsdGlwbGllcjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX1jbGFzcyBBdmdQb29sM0RCYWNrcHJvcFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5Il0sdGhpcy5vdXRwdXRTaGFwZT1hYS5pblNoYXBlO2NvbnN0IHhhPWFhLmZpbHRlckRlcHRoLGJhPWFhLmZpbHRlckhlaWdodCxTYT1hYS5maWx0ZXJXaWR0aCxUYT1hYS5zdHJpZGVEZXB0aCx3YT1hYS5zdHJpZGVIZWlnaHQsRWE9YWEuc3RyaWRlV2lkdGgsa2E9YWEuZGlsYXRpb25EZXB0aCxBYT1hYS5kaWxhdGlvbkhlaWdodCxGYT1hYS5kaWxhdGlvbldpZHRoLExhPWFhLmVmZmVjdGl2ZUZpbHRlckRlcHRoLGVsPWFhLmVmZmVjdGl2ZUZpbHRlckhlaWdodCx0bD1hYS5lZmZlY3RpdmVGaWx0ZXJXaWR0aCxubD1MYS0xLWFhLnBhZEluZm8uZnJvbnQsc2w9ZWwtMS1hYS5wYWRJbmZvLnRvcCxybD10bC0xLWFhLnBhZEluZm8ubGVmdCxvbD0xLyh4YSpiYSpTYSk7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMzIHBhZHMgPSBpdmVjMygke25sfSwgJHtzbH0sICR7cmx9KTsKICAgICAgY29uc3QgZmxvYXQgYXZnTXVsdGlwbGllciA9IGZsb2F0KCR7b2x9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDsKICAgICAgICBpbnQgY2ggPSBjb29yZHMudTsKCiAgICAgICAgaXZlYzMgZHlDb3JuZXIgPSBpdmVjMyhjb29yZHMueSwgY29vcmRzLnosIGNvb3Jkcy53KSAtIHBhZHM7CiAgICAgICAgaW50IGR5RENvcm5lciA9IGR5Q29ybmVyLng7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5Q29ybmVyLnk7CiAgICAgICAgaW50IGR5Q0Nvcm5lciA9IGR5Q29ybmVyLno7CgogICAgICAgIC8vIENvbnZvbHZlIGR5KD8sID8sID8sIGQpIHdpdGggcG9zIG1hc2soOiwgOiwgOiwgY2gpIHRvIGdldAogICAgICAgIC8vIGR4KHhELCB4UiwgeEMsIGNoKS4KICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZC4gOiA9IGFjcm9zcyBhbGwgdmFsdWVzIGluIHRoYXQgYXhpcy4KICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwoKICAgICAgICBmb3IgKGludCB3RCA9IDA7IHdEIDwgJHtMYX07CiAgICAgICAgICAgIHdEICs9ICR7a2F9KSB7CiAgICAgICAgICBmbG9hdCBkeUQgPSBmbG9hdChkeURDb3JuZXIgKyB3RCkgLyAke1RhfS4wOwoKICAgICAgICAgIGlmIChkeUQgPCAwLjAgfHwgZHlEID49ICR7YWEub3V0RGVwdGh9LjAgfHwgZnJhY3QoZHlEKSA+IDAuMCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBpZHlEID0gaW50KGR5RCk7CgogICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7ZWx9OwogICAgICAgICAgICAgIHdSICs9ICR7QWF9KSB7CiAgICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvICR7d2F9LjA7CgogICAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fAogICAgICAgICAgICAgICAgZnJhY3QoZHlSKSA+IDAuMCkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBpZHlSID0gaW50KGR5Uik7CgogICAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHt0bH07CiAgICAgICAgICAgICAgICB3QyArPSAke0ZhfSkgewogICAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7RWF9LjA7CgogICAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgICAgZnJhY3QoZHlDKSA+IDAuMCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICAgIGZsb2F0IGR5VmFsdWUgPSBnZXREeShiYXRjaCwgaWR5RCwgaWR5UiwgaWR5QywgY2gpOwoKICAgICAgICAgICAgICBkb3RQcm9kICs9IGR5VmFsdWUgKiBhdmdNdWx0aXBsaWVyOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXZnUG9vbDNER3JhZChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxpbnB1dDpUYX09YWEsd2E9VGEse2ZpbHRlclNpemU6RWEsc3RyaWRlczprYSxwYWQ6QWEsZGltUm91bmRpbmdNb2RlOkZhfT1iYSxMYT1bMSwxLDFdLGVsPWNvbXB1dGVQb29sM0RJbmZvKHdhLnNoYXBlLEVhLGthLExhLEFhLEZhKSx0bD1uZXcgQXZnUG9vbDNEQmFja3Byb3BQcm9ncmFtKGVsKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKHRsLFtTYV0sd2EuZHR5cGUpfWNvbnN0IGF2Z1Bvb2wzREdyYWRDb25maWc9e2tlcm5lbE5hbWU6QXZnUG9vbDNER3JhZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YXZnUG9vbDNER3JhZH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYXZnUG9vbEdyYWQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsaW5wdXQ6VGF9PWFhLHdhPVRhO2Fzc2VydE5vdENvbXBsZXgoW1NhLFRhXSwiYXZnUG9vbEdyYWQiKTtjb25zdHtmaWx0ZXJTaXplOkVhLHN0cmlkZXM6a2EscGFkOkFhfT1iYSxGYT1jb21wdXRlUG9vbDJESW5mbyh3YS5zaGFwZSxFYSxrYSwxLEFhKSxMYT1uZXcgQXZnUG9vbDJEQmFja3Byb3BQcm9ncmFtKEZhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sd2EuZHR5cGUpfWNvbnN0IGF2Z1Bvb2xHcmFkQ29uZmlnPXtrZXJuZWxOYW1lOkF2Z1Bvb2xHcmFkLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzphdmdQb29sR3JhZH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gYmF0Y2hNYXRNdWwoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7YTpTYSxiOlRhfT1hYSx7dHJhbnNwb3NlQTp3YSx0cmFuc3Bvc2VCOkVhfT1iYTtyZXR1cm4gYmF0Y2hNYXRNdWxJbXBsKHthOlNhLGI6VGEsdHJhbnNwb3NlQTp3YSx0cmFuc3Bvc2VCOkVhLGJhY2tlbmQ6eGF9KX1jb25zdCBiYXRjaE1hdE11bENvbmZpZz17a2VybmVsTmFtZTpCYXRjaE1hdE11bCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6YmF0Y2hNYXRNdWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEJhdGNoTm9ybVByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEsd2Epe3RoaXMub3V0cHV0U2hhcGU9W10sdGhpcy52YXJpYWJsZU5hbWVzPVsieCIsIm1lYW4iLCJ2YXJpYW5jZSJdLGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlKGFhLHhhKSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZShhYSxiYSk7bGV0IEVhPSIwLjAiO1NhIT1udWxsJiYoYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUoYWEsU2EpLHRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJvZmZzZXQiKSxFYT0iZ2V0T2Zmc2V0QXRPdXRDb29yZHMoKSIpO2xldCBrYT0iMS4wIjtUYSE9bnVsbCYmKGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlKGFhLFRhKSx0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgic2NhbGUiKSxrYT0iZ2V0U2NhbGVBdE91dENvb3JkcygpIiksdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IHggPSBnZXRYQXRPdXRDb29yZHMoKTsKICAgICAgICBmbG9hdCBtZWFuID0gZ2V0TWVhbkF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgdmFyaWFuY2UgPSBnZXRWYXJpYW5jZUF0T3V0Q29vcmRzKCk7CiAgICAgICAgZmxvYXQgb2Zmc2V0ID0gJHtFYX07CiAgICAgICAgZmxvYXQgc2NhbGUgPSAke2thfTsKICAgICAgICBmbG9hdCBpbnYgPSBzY2FsZSAqIGludmVyc2VzcXJ0KHZhcmlhbmNlICsgZmxvYXQoJHt3YX0pKTsKICAgICAgICBzZXRPdXRwdXQoZG90KHZlYzMoeCwgLW1lYW4sIG9mZnNldCksIHZlYzMoaW52LCBpbnYsIDEpKSk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEJhdGNoTm9ybVBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEsd2Epe3RoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMudmFyaWFibGVOYW1lcz1bIngiLCJtZWFuIiwidmFyaWFuY2UiXSxhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZShhYSx4YSksYXNzZXJ0QW5kR2V0QnJvYWRjYXN0U2hhcGUoYWEsYmEpO2xldCBFYT0idmVjNCgwLjApIjtTYSE9bnVsbCYmKGFzc2VydEFuZEdldEJyb2FkY2FzdFNoYXBlKGFhLFNhKSx0aGlzLnZhcmlhYmxlTmFtZXMucHVzaCgib2Zmc2V0IiksRWE9ImdldE9mZnNldEF0T3V0Q29vcmRzKCkiKTtsZXQga2E9InZlYzQoMS4wKSI7VGEhPW51bGwmJihhc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZShhYSxUYSksdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInNjYWxlIiksa2E9ImdldFNjYWxlQXRPdXRDb29yZHMoKSIpLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICB2ZWM0IG9mZnNldCA9ICR7RWF9OwogICAgICAgIHZlYzQgc2NhbGUgPSAke2thfTsKCiAgICAgICAgdmVjNCB4ID0gZ2V0WEF0T3V0Q29vcmRzKCk7CiAgICAgICAgdmVjNCBtZWFuID0gZ2V0TWVhbkF0T3V0Q29vcmRzKCk7CiAgICAgICAgdmVjNCB2YXJpYW5jZSA9IGdldFZhcmlhbmNlQXRPdXRDb29yZHMoKTsKCiAgICAgICAgdmVjNCBpbnYgPSBzY2FsZSAqIGludmVyc2VzcXJ0KHZhcmlhbmNlICsgdmVjNCgke3dhfSkpOwoKICAgICAgICBzZXRPdXRwdXQoKHggLSBtZWFuKSAqIGludiArIG9mZnNldCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGJhdGNoTm9ybT0oe2lucHV0czpoYSxiYWNrZW5kOmFhLGF0dHJzOnhhfSk9Pntjb25zdHt4OmJhLG1lYW46U2EsdmFyaWFuY2U6VGEsb2Zmc2V0OndhLHNjYWxlOkVhfT1oYTthc3NlcnQoU2Euc2hhcGUubGVuZ3RoPT09VGEuc2hhcGUubGVuZ3RoLCgpPT4iQmF0Y2ggbm9ybWFsaXphdGlvbiBncmFkaWVudCByZXF1aXJlcyBtZWFuIGFuZCB2YXJpYW5jZSB0byBoYXZlIGVxdWFsIHJhbmtzLiIpLGFzc2VydCh3YT09bnVsbHx8U2Euc2hhcGUubGVuZ3RoPT09d2Euc2hhcGUubGVuZ3RoLCgpPT4iQmF0Y2ggbm9ybWFsaXphdGlvbiBncmFkaWVudCByZXF1aXJlcyBtZWFuIGFuZCBvZmZzZXQgdG8gaGF2ZSBlcXVhbCByYW5rcy4iKSxhc3NlcnQoRWE9PW51bGx8fFNhLnNoYXBlLmxlbmd0aD09PUVhLnNoYXBlLmxlbmd0aCwoKT0+IkJhdGNoIG5vcm1hbGl6YXRpb24gZ3JhZGllbnQgcmVxdWlyZXMgbWVhbiBhbmQgc2NhbGUgdG8gaGF2ZSBlcXVhbCByYW5rcy4iKTtsZXR7dmFyaWFuY2VFcHNpbG9uOmthfT14YTtrYT09bnVsbCYmKGthPS4wMDEpO2NvbnN0IEFhPVtiYSxTYSxUYV07bGV0IEZhPW51bGw7d2EhPW51bGwmJihGYT13YS5zaGFwZSxBYS5wdXNoKHdhKSk7bGV0IExhPW51bGw7RWEhPW51bGwmJihMYT1FYS5zaGFwZSxBYS5wdXNoKEVhKSk7Y29uc3QgZWw9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19OT1JNQUxJWkFUSU9OIik/bmV3IEJhdGNoTm9ybVBhY2tlZFByb2dyYW0oYmEuc2hhcGUsU2Euc2hhcGUsVGEuc2hhcGUsRmEsTGEsa2EpOm5ldyBCYXRjaE5vcm1Qcm9ncmFtKGJhLnNoYXBlLFNhLnNoYXBlLFRhLnNoYXBlLEZhLExhLGthKTtyZXR1cm4gYWEucnVuV2ViR0xQcm9ncmFtKGVsLEFhLEFhWzBdLmR0eXBlKX0sYmF0Y2hOb3JtQ29uZmlnPXtrZXJuZWxOYW1lOkZ1c2VkQmF0Y2hOb3JtLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpiYXRjaE5vcm19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFNsaWNlUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsic291cmNlIl0sdGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnJhbms9YWEubGVuZ3RoO2NvbnN0IHhhPWdldENvb3Jkc0RhdGFUeXBlKHRoaXMucmFuayk7dGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InN0YXJ0IixhcnJheUluZGV4OnRoaXMucmFuayx0eXBlOiJpbnQifV07Y29uc3QgYmE9Z2V0Q29vcmRzJDEodGhpcy5yYW5rKTtsZXQgU2E7Y29uc3QgVGE9YWEubWFwKCh3YSxFYSk9PmBzb3VyY2VMb2MuJHtjb29yZHNbRWFdfSA9IHN0YXJ0WyR7RWF9XSArIGNvb3Jkcy4ke2Nvb3Jkc1tFYV19O2ApO1NhPWAKICAgICAgICAke3hhfSBzb3VyY2VMb2M7CiAgICAgICAgJHt4YX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgJHtUYS5qb2luKGAKYCl9CiAgICAgIGAsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke1NhfQogICAgICAgIHNldE91dHB1dChnZXRTb3VyY2UoJHtiYX0pKTsKICAgICAgfQogICAgYH19Y29uc3QgY29vcmRzPVsieCIsInkiLCJ6IiwidyIsInUiLCJ2Il07ZnVuY3Rpb24gZ2V0Q29vcmRzJDEoaGEpe2lmKGhhPT09MSlyZXR1cm4ic291cmNlTG9jIjtpZihoYTw9NilyZXR1cm4gY29vcmRzLnNsaWNlKDAsaGEpLm1hcChhYT0+InNvdXJjZUxvYy4iK2FhKS5qb2luKCIsIik7dGhyb3cgRXJyb3IoYFNsaWNpbmcgZm9yIHJhbmsgJHtoYX0gaXMgbm90IHlldCBzdXBwb3J0ZWRgKX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBTbGljZVBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bInNvdXJjZSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5yYW5rPWFhLmxlbmd0aCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToic3RhcnQiLGFycmF5SW5kZXg6dGhpcy5yYW5rLHR5cGU6ImludCJ9XTtjb25zdCB4YT1nZXRDb29yZHNEYXRhVHlwZSh0aGlzLnJhbmspLGJhPWdldENoYW5uZWxzKCJjb29yZHMiLHRoaXMucmFuayksU2E9Z2V0Q2hhbm5lbHMoInNvdXJjZUxvYyIsdGhpcy5yYW5rKSxUYT10aGlzLnJhbms9PT0xPyJzb3VyY2VMb2MiOmB2ZWMyKCR7U2Euc2xpY2UoLTIpLmpvaW4oKX0pYCx3YT1gZ2V0Q2hhbm5lbChnZXRTb3VyY2UoJHtTYS5qb2luKCl9KSwgJHtUYX0pYCxFYT1gCiAgICAgIHJlc3VsdC54ID0gJHt3YX07CiAgICAgIGlmICgrKyR7YmFbdGhpcy5yYW5rLTFdfSA8ICR7YWFbdGhpcy5yYW5rLTFdfSkgewogICAgICAgICsrJHtTYVt0aGlzLnJhbmstMV19OwogICAgICAgIHJlc3VsdC55ID0gJHt3YX07CiAgICAgICAgLS0ke1NhW3RoaXMucmFuay0xXX07CiAgICAgIH0KICAgIGAsa2E9dGhpcy5yYW5rPT09MT8iIjpgCiAgICAgIC0tJHtiYVt0aGlzLnJhbmstMV19OwogICAgICBpZiAoKyske2JhW3RoaXMucmFuay0yXX0gPCAke2FhW3RoaXMucmFuay0yXX0pIHsKICAgICAgICArKyR7U2FbdGhpcy5yYW5rLTJdfTsKICAgICAgICByZXN1bHQueiA9ICR7d2F9OwogICAgICAgIGlmICgrKyR7YmFbdGhpcy5yYW5rLTFdfSA8ICR7YWFbdGhpcy5yYW5rLTFdfSkgewogICAgICAgICAgKyske1NhW3RoaXMucmFuay0xXX07CiAgICAgICAgICByZXN1bHQudyA9ICR7d2F9OwogICAgICAgIH0KICAgICAgfQogICAgYCxBYT10aGlzLnJhbms8PTQ/YHNvdXJjZUxvYyA9IGNvb3JkcyArCiAgICAgICAgICAgICR7eGF9KCR7YWEubWFwKChGYSxMYSk9PmBzdGFydFske0xhfV1gKS5qb2luKCl9KTtgOmFhLm1hcCgoRmEsTGEpPT5gJHtTYVtMYV19ID0gJHtiYVtMYV19ICsgc3RhcnRbJHtMYX1dO2ApLmpvaW4oYApgKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7eGF9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICR7eGF9IHNvdXJjZUxvYzsKICAgICAgICAke0FhfQogICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLik7CiAgICAgICAgJHtFYX0KICAgICAgICAke2thfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzaGFsbG93U2xpY2UoaGEsYWEseGEsYmEpe2NvbnN0IFNhPWJhLnRleERhdGEuZ2V0KGhhLmRhdGFJZCksVGE9YmEubWFrZVRlbnNvckluZm8oeGEsaGEuZHR5cGUpLHdhPWJhLnRleERhdGEuZ2V0KFRhLmRhdGFJZCk7T2JqZWN0LmFzc2lnbih3YSxTYSksd2EucmVmQ291bnQ9MSx3YS5zaGFwZT14YSx3YS5kdHlwZT1oYS5kdHlwZTtsZXQgRWE9Y29tcHV0ZUZsYXRPZmZzZXQoYWEsY29tcHV0ZVN0cmlkZXMoaGEuc2hhcGUpKTtTYS5zbGljZSYmKEVhKz1TYS5zbGljZS5mbGF0T2Zmc2V0KSx3YS5zbGljZT17ZmxhdE9mZnNldDpFYSxvcmlnRGF0YUlkOlNhLnNsaWNlJiZTYS5zbGljZS5vcmlnRGF0YUlkfHxoYS5kYXRhSWR9O2NvbnN0IGthPWJhLmRhdGFSZWZDb3VudC5nZXQod2Euc2xpY2Uub3JpZ0RhdGFJZCl8fDE7cmV0dXJuIGJhLmRhdGFSZWZDb3VudC5zZXQod2Euc2xpY2Uub3JpZ0RhdGFJZCxrYSsxKSxUYX1mdW5jdGlvbiBzbGljZShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YmVnaW46VGEsc2l6ZTp3YX09YmEsW0VhLGthXT1wYXJzZVNsaWNlUGFyYW1zKFNhLFRhLHdhKTtpZihhc3NlcnRQYXJhbXNWYWxpZChTYSxFYSxrYSksc2l6ZUZyb21TaGFwZShrYSk9PT0wKXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSxTYS5kdHlwZSxbXSk7aWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtTYV0pfHxTYS5kdHlwZT09PSJzdHJpbmciKXtjb25zdCBMYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLGVsPXNsaWNlSW1wbENQVShMYS52YWx1ZXMsRWEsa2EsU2Euc2hhcGUsU2EuZHR5cGUpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhrYSxTYS5kdHlwZSxlbCl9Y29uc3R7aXNQYWNrZWQ6QWF9PXhhLnRleERhdGEuZ2V0KFNhLmRhdGFJZCksRmE9aXNTbGljZUNvbnRpbm91cyhTYS5zaGFwZSxFYSxrYSk7aWYoQWF8fCFGYSl7Y29uc3QgTGE9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19BUlJBWV9PUEVSQVRJT05TIik/bmV3IFNsaWNlUGFja2VkUHJvZ3JhbShrYSk6bmV3IFNsaWNlUHJvZ3JhbShrYSksZWw9W0VhXTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKExhLFtTYV0sU2EuZHR5cGUsZWwpfXJldHVybiB4YS51cGxvYWRUb0dQVShTYS5kYXRhSWQpLHNoYWxsb3dTbGljZShTYSxFYSxrYSx4YSl9Y29uc3Qgc2xpY2VDb25maWc9e2tlcm5lbE5hbWU6U2xpY2UsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNsaWNlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBiYXRjaFRvU3BhY2VORD1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2Jsb2NrU2hhcGU6VGEsY3JvcHM6d2F9PWJhO2Fzc2VydChTYS5zaGFwZS5sZW5ndGg8PTQsKCk9PiJiYXRjaFRvU3BhY2VORCBmb3IgcmFuayA+IDQgd2l0aCBhIFdlYkdMIGJhY2tlbmQgbm90IGltcGxlbWVudGVkIHlldCIpO2NvbnN0IEVhPVRhLnJlZHVjZSgoYWwsbGwpPT5hbCpsbCksa2E9Z2V0UmVzaGFwZWQoU2Euc2hhcGUsVGEsRWEpLEFhPWdldFBlcm11dGVkKGthLmxlbmd0aCxUYS5sZW5ndGgpLEZhPWdldFJlc2hhcGVkUGVybXV0ZWQoU2Euc2hhcGUsVGEsRWEpLExhPWdldFNsaWNlQmVnaW5Db29yZHMod2EsVGEubGVuZ3RoKSxlbD1nZXRTbGljZVNpemUoRmEsd2EsVGEubGVuZ3RoKSx0bD1bXSxubD1yZXNoYXBlKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmthfX0pLHNsPXRyYW5zcG9zZSh7aW5wdXRzOnt4Om5sfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOkFhfX0pLHJsPXJlc2hhcGUoe2lucHV0czp7eDpzbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6RmF9fSksb2w9c2xpY2Uoe2lucHV0czp7eDpybH0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46TGEsc2l6ZTplbH19KTtyZXR1cm4gdGwucHVzaChubCksdGwucHVzaChzbCksdGwucHVzaChybCksdGwuZm9yRWFjaChhbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpKSxvbH0sYmF0Y2hUb1NwYWNlTkRDb25maWc9e2tlcm5lbE5hbWU6QmF0Y2hUb1NwYWNlTkQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmJhdGNoVG9TcGFjZU5EfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBiaW5jb3VudChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLHdlaWdodHM6VGF9PWFhLHtzaXplOndhfT1iYSxFYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksQWE9YmluY291bnRJbXBsQ1BVKEVhLGthLFRhLmR0eXBlLFRhLnNoYXBlLHdhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oW3dhXSxUYS5kdHlwZSxBYSl9Y29uc3QgYmluY291bnRDb25maWc9e2tlcm5lbE5hbWU6QmluY291bnQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmJpbmNvdW50fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBCSVRXSVNFQU5EPWAKICBpbnQgciA9IGludChhLnIpICYgaW50KGIucik7CiAgaW50IGcgPSBpbnQoYS5nKSAmIGludChiLmcpOwogIGludCByYiA9IGludChhLmIpICYgaW50KGIuYik7CiAgaW50IHJhID0gaW50KGEuYSkgJiBpbnQoYi5hKTsKICByZXR1cm4gdmVjNChyLCBnLCByYiwgcmEpOwpgLEJJVFdJU0VBTkRfVU5QQUNLRUQ9YAogIHJldHVybiBmbG9hdChpbnQoYS5yKSAmIGludChiLnIpKTsKYDtmdW5jdGlvbiBiaXR3aXNlQW5kKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2E6YmEsYjpTYX09YWEsVGE9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19CSU5BUllfT1BFUkFUSU9OUyIpLHdhPWVudigpLmdldE51bWJlcigiV0VCR0xfVkVSU0lPTiIpO2lmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbYmEsU2FdKXx8d2E9PT0xKXtjb25zdCBrYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpLnZhbHVlcyxBYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxbRmEsTGFdPWJpdHdpc2VBbmRJbXBsQ1BVKGJhLnNoYXBlLFNhLnNoYXBlLGthLEFhLGJhLmR0eXBlKSxlbD14YS5tYWtlVGVuc29ySW5mbyhMYSxiYS5kdHlwZSksdGw9eGEudGV4RGF0YS5nZXQoZWwuZGF0YUlkKTtyZXR1cm4gdGwudmFsdWVzPUZhLGVsfWxldCBFYTtyZXR1cm4gVGE/RWE9bmV3IEJpbmFyeU9wUGFja2VkUHJvZ3JhbShCSVRXSVNFQU5ELGJhLnNoYXBlLFNhLnNoYXBlLCExKTpFYT1uZXcgQmluYXJ5T3BQcm9ncmFtKEJJVFdJU0VBTkRfVU5QQUNLRUQsYmEuc2hhcGUsU2Euc2hhcGUpLHhhLnJ1bldlYkdMUHJvZ3JhbShFYSxbYmEsU2FdLGJhLmR0eXBlKX1jb25zdCBiaXR3aXNlQW5kQ29uZmlnPXtrZXJuZWxOYW1lOkJpdHdpc2VBbmQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmJpdHdpc2VBbmR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGJyb2FkY2FzdEFyZ3MoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7czA6YmEsczE6U2F9PWFhLFRhPXhhLnJlYWRTeW5jKGJhLmRhdGFJZCksd2E9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxFYT1hc3NlcnRBbmRHZXRCcm9hZGNhc3RTaGFwZShBcnJheS5mcm9tKFRhKSxBcnJheS5mcm9tKHdhKSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFtFYS5sZW5ndGhdLCJpbnQzMiIsSW50MzJBcnJheS5mcm9tKEVhKSl9Y29uc3QgYnJvYWRjYXN0QXJnc0NvbmZpZz17a2VybmVsTmFtZTpCcm9hZGNhc3RBcmdzLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpicm9hZGNhc3RBcmdzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBOT1RfRVFVQUw9InJldHVybiBmbG9hdChhICE9IGIpOyIsbm90RXF1YWw9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0Ok5PVF9FUVVBTCxjcHVLZXJuZWxJbXBsOm5vdEVxdWFsSW1wbENQVSxkdHlwZToiYm9vbCJ9KSxub3RFcXVhbENvbmZpZz17a2VybmVsTmFtZTpOb3RFcXVhbCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bm90RXF1YWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJlYWwoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7aW5wdXQ6YmF9PWFhLFNhPXhhLnRleERhdGEuZ2V0KGJhLmRhdGFJZCk7cmV0dXJuIGlkZW50aXR5KHtpbnB1dHM6e3g6U2EuY29tcGxleFRlbnNvckluZm9zLnJlYWx9LGJhY2tlbmQ6eGF9KX1jb25zdCByZWFsQ29uZmlnPXtrZXJuZWxOYW1lOlJlYWwsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlYWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFRPX0lOVD0icmV0dXJuIGZsb2F0KGludCh4KSk7IjtmdW5jdGlvbiBpbnQoaGEsYWEpe2NvbnN0IHhhPW5ldyBVbmFyeU9wUHJvZ3JhbShoYS5zaGFwZSxUT19JTlQpLGJhPWFhLnJ1bldlYkdMUHJvZ3JhbSh4YSxbaGFdLCJpbnQzMiIpO3JldHVybntkYXRhSWQ6YmEuZGF0YUlkLHNoYXBlOmJhLnNoYXBlLGR0eXBlOmJhLmR0eXBlfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjYXN0KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtkdHlwZTpUYX09YmE7aWYoVGE9PT0iY29tcGxleDY0Iil7aWYoU2EuZHR5cGU9PT0iY29tcGxleDY0IilyZXR1cm4gaWRlbnRpdHkoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2NvbnN0IHdhPXplcm9zKFNhLnNoYXBlKSxFYT1jYXN0KHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2R0eXBlOiJmbG9hdDMyIn19KSxrYT1jb21wbGV4KHtpbnB1dHM6e3JlYWw6RWEsaW1hZzp3YX0sYmFja2VuZDp4YX0pO3JldHVybiB3YS5kaXNwb3NlKCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLGthfWlmKFNhLmR0eXBlPT09ImNvbXBsZXg2NCIpe2NvbnN0IHdhPXJlYWwoe2lucHV0czp7aW5wdXQ6U2F9LGJhY2tlbmQ6eGF9KSxFYT1jYXN0KHtpbnB1dHM6e3g6d2F9LGJhY2tlbmQ6eGEsYXR0cnM6e2R0eXBlOlRhfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh3YSksRWF9aWYoIWhhc0VuY29kaW5nTG9zcyhTYS5kdHlwZSxUYSkpe2NvbnN0IHdhPWlkZW50aXR5KHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtyZXR1cm57ZGF0YUlkOndhLmRhdGFJZCxzaGFwZTp3YS5zaGFwZSxkdHlwZTpUYX19aWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtTYV0pKXtjb25zdCB3YT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLnZhbHVlcyxbRWEsa2EsQWFdPWNhc3RJbXBsQ1BVKHdhLFNhLnNoYXBlLFNhLmR0eXBlLFRhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRWEsa2EsQWEpfWlmKFRhPT09ImludDMyIilyZXR1cm4gaW50KFNhLHhhKTtpZihUYT09PSJib29sIil7Y29uc3Qgd2E9eGEubWFrZVRlbnNvckluZm8oW10sImJvb2wiLGdldFR5cGVkQXJyYXlGcm9tRFR5cGUoImJvb2wiLDEpKSxrYT1ub3RFcXVhbCh7aW5wdXRzOnthOlNhLGI6d2F9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLGthfXRocm93IG5ldyBFcnJvcihgRXJyb3IgaW4gQ2FzdDogZmFpbGVkIHRvIGNhc3QgJHtTYS5kdHlwZX0gdG8gJHtUYX1gKX1jb25zdCBjYXN0Q29uZmlnPXtrZXJuZWxOYW1lOkNhc3QsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNhc3R9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IENFSUw9InJldHVybiBjZWlsKHgpOyIsY2VpbD11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpDRUlMLHBhY2tlZE9wU25pcHBldDpDRUlMLGNwdUtlcm5lbEltcGw6Y2VpbEltcGxDUFV9KSxjZWlsQ29uZmlnPXtrZXJuZWxOYW1lOkNlaWwsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNlaWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIENsaXBQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl0sdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6Im1pblZhbCIsdHlwZToiZmxvYXQifSx7bmFtZToibWF4VmFsIix0eXBlOiJmbG9hdCJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudXNlckNvZGU9YAoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0QUF0T3V0Q29vcmRzKCk7CiAgICAgICAgaWYgKGlzbmFuKHZhbHVlKSkgewogICAgICAgICAgc2V0T3V0cHV0KHZhbHVlKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHNldE91dHB1dChjbGFtcCh2YWx1ZSwgbWluVmFsLCBtYXhWYWwpKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgQ2xpcFBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToibWluVmFsIix0eXBlOiJmbG9hdCJ9LHtuYW1lOiJtYXhWYWwiLHR5cGU6ImZsb2F0In1dLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICB2ZWM0IHZhbHVlID0gZ2V0QUF0T3V0Q29vcmRzKCk7CgogICAgICAgIGlmIChhbnkoaXNuYW4odmFsdWUpKSkgewogICAgICAgICAgc2V0T3V0cHV0KHZhbHVlKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHNldE91dHB1dChjbGFtcCh2YWx1ZSwgdmVjNChtaW5WYWwpLCB2ZWM0KG1heFZhbCkpKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY2xpcEJ5VmFsdWUoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2NsaXBWYWx1ZU1pbjpUYSxjbGlwVmFsdWVNYXg6d2F9PWJhO2xldCBFYTtlbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0NMSVAiKT9FYT1uZXcgQ2xpcFBhY2tlZFByb2dyYW0oU2Euc2hhcGUpOkVhPW5ldyBDbGlwUHJvZ3JhbShTYS5zaGFwZSk7Y29uc3Qga2E9W1tUYV0sW3dhXV07cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShFYSxbU2FdLFNhLmR0eXBlLGthKX1jb25zdCBjbGlwQnlWYWx1ZUNvbmZpZz17a2VybmVsTmFtZTpDbGlwQnlWYWx1ZSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y2xpcEJ5VmFsdWV9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIENvbXBsZXhBYnNQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJyZWFsIiwiaW1hZyJdLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBmbG9hdCByZSA9IGFicyhnZXRSZWFsQXRPdXRDb29yZHMoKSk7CiAgICAgICAgZmxvYXQgaW0gPSBhYnMoZ2V0SW1hZ0F0T3V0Q29vcmRzKCkpOwogICAgICAgIGZsb2F0IG14ID0gbWF4KHJlLCBpbSk7CgogICAgICAgIC8vIHNhZGx5IHRoZSBsZW5ndGggZnVuY3Rpb24gaW4gZ2xzbCBpcyBub3QgdW5kZXJmbG93LXNhZmUKICAgICAgICAvLyAoYXQgbGVhc3Qgbm90IG9uIEludGVsIEdQVXMpLiBTbyB0aGUgc2FmZSBzb2x1dGlvbiBpcwogICAgICAgIC8vIHRvIGVuc3VyZSB1bmRlcmZsb3ctc2FmZXR5IGluIGFsbCBjYXNlcy4KICAgICAgICBzZXRPdXRwdXQoCiAgICAgICAgICBteCA9PSAwLjAgPyAwLjAgOiBteCAqIGxlbmd0aCh2ZWMyKDEsIG1pbihyZSwgaW0pL214KSkKICAgICAgICApOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYWtlQ29tcGxleENvbXBvbmVudFRlbnNvckluZm8oaGEsYWEpe3JldHVybntkYXRhSWQ6YWEuZGF0YUlkLGR0eXBlOmFhLmR0eXBlLHNoYXBlOmhhLnNoYXBlfX1mdW5jdGlvbiBjb21wbGV4QWJzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3g6YmF9PWFhLFNhPXhhLnRleERhdGEuZ2V0KGJhLmRhdGFJZCksVGE9bmV3IENvbXBsZXhBYnNQcm9ncmFtKGJhLnNoYXBlKSx3YT1bbWFrZUNvbXBsZXhDb21wb25lbnRUZW5zb3JJbmZvKGJhLFNhLmNvbXBsZXhUZW5zb3JJbmZvcy5yZWFsKSxtYWtlQ29tcGxleENvbXBvbmVudFRlbnNvckluZm8oYmEsU2EuY29tcGxleFRlbnNvckluZm9zLmltYWcpXTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKFRhLHdhLHdhWzBdLmR0eXBlKX1jb25zdCBjb21wbGV4QWJzQ29uZmlnPXtrZXJuZWxOYW1lOkNvbXBsZXhBYnMsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbXBsZXhBYnN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIENvbmNhdFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMub3V0cHV0U2hhcGU9W10sdGhpcy5vdXRwdXRTaGFwZT1jb21wdXRlT3V0U2hhcGUkMShhYSwxKSx0aGlzLnZhcmlhYmxlTmFtZXM9YWEubWFwKCh3YSxFYSk9PmBUJHtFYX1gKTtjb25zdCB4YT1uZXcgQXJyYXkoYWEubGVuZ3RoLTEpO3hhWzBdPWFhWzBdWzFdO2ZvcihsZXQgd2E9MTt3YTx4YS5sZW5ndGg7d2ErKyl4YVt3YV09eGFbd2EtMV0rYWFbd2FdWzFdO2NvbnN0IGJhPVtgaWYgKHlDIDwgJHt4YVswXX0pIHNldE91dHB1dChnZXRUMCh5UiwgeUMpKTtgXTtmb3IobGV0IHdhPTE7d2E8eGEubGVuZ3RoO3dhKyspe2NvbnN0IEVhPXhhW3dhLTFdO2JhLnB1c2goYGVsc2UgaWYgKHlDIDwgJHt4YVt3YV19KSBzZXRPdXRwdXQoZ2V0VCR7d2F9KHlSLCB5Qy0ke0VhfSkpO2ApfWNvbnN0IFNhPXhhLmxlbmd0aCxUYT14YVt4YS5sZW5ndGgtMV07YmEucHVzaChgZWxzZSBzZXRPdXRwdXQoZ2V0VCR7U2F9KHlSLCB5Qy0ke1RhfSkpO2ApLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IHlSID0gY29vcmRzLng7CiAgICAgICAgaW50IHlDID0gY29vcmRzLnk7CgogICAgICAgICR7YmEuam9pbihgCiAgICAgICAgYCl9CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIENvbmNhdFBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9W10sdGhpcy5vdXRwdXRTaGFwZT1jb21wdXRlT3V0U2hhcGUkMShhYSx4YSk7Y29uc3QgYmE9dGhpcy5vdXRwdXRTaGFwZSxTYT1iYS5sZW5ndGgsVGE9Z2V0Q29vcmRzRGF0YVR5cGUoU2EpLHdhPWdldENoYW5uZWxzKCJjb29yZHMiLFNhKSxFYT1bIngiLCJ5IiwieiIsInciLCJ1IiwidiJdLnNsaWNlKDAsU2EpO3RoaXMudmFyaWFibGVOYW1lcz1hYS5tYXAoKHNsLHJsKT0+YFQke3JsfWApO2NvbnN0IGthPW5ldyBBcnJheShhYS5sZW5ndGgtMSk7a2FbMF09YWFbMF1beGFdO2ZvcihsZXQgc2w9MTtzbDxrYS5sZW5ndGg7c2wrKylrYVtzbF09a2Fbc2wtMV0rYWFbc2xdW3hhXTtjb25zdCBBYT1FYVt4YV0sRmE9RWEuc2xpY2UoLTIpLExhPUVhLmpvaW4oKTtsZXQgZWw9YGlmICgke0FhfSA8ICR7a2FbMF19KSB7CiAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoCiAgICAgICAgICAgIGdldFQwKCR7TGF9KSwgdmVjMigke0ZhLmpvaW4oKX0pKTsKICAgICAgICB9YDtmb3IobGV0IHNsPTE7c2w8a2EubGVuZ3RoO3NsKyspe2NvbnN0IHJsPWthW3NsLTFdO2VsKz1gCiAgICAgICAgaWYgKCR7QWF9IDwgJHtrYVtzbF19ICAmJiAke0FhfSA+PSAke2thW3NsLTFdfSkgewogICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoCiAgICAgICAgICAgIGdldFQke3NsfSgke3NoaWZ0ZWRDaGFubmVscyhFYSxBYSxybCl9KSwKICAgICAgICAgICAgdmVjMigke3NoaWZ0ZWRDaGFubmVscyhGYSxBYSxybCl9KSk7CiAgICAgICAgfWB9Y29uc3QgdGw9a2EubGVuZ3RoLG5sPWthW2thLmxlbmd0aC0xXTtlbCs9YAogICAgICAgIHJldHVybiBnZXRDaGFubmVsKAogICAgICAgICAgZ2V0VCR7dGx9KCR7c2hpZnRlZENoYW5uZWxzKEVhLEFhLG5sKX0pLAogICAgICAgICAgdmVjMigke3NoaWZ0ZWRDaGFubmVscyhGYSxBYSxubCl9KSk7YCx0aGlzLnVzZXJDb2RlPWAKICAgICAgZmxvYXQgZ2V0VmFsdWUoJHtFYS5tYXAoc2w9PiJpbnQgIitzbCl9KSB7CiAgICAgICAgJHtlbH0KICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7VGF9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNChnZXRWYWx1ZSgke3dhfSksIDAuLCAwLiwgMC4pOwoKICAgICAgICAke3dhW1NhLTFdfSA9ICR7d2FbU2EtMV19ICsgMTsKICAgICAgICBpZiAoJHt3YVtTYS0xXX0gPCAke2JhW1NhLTFdfSkgewogICAgICAgICAgcmVzdWx0LmcgPSBnZXRWYWx1ZSgke3dhfSk7CiAgICAgICAgfQoKICAgICAgICAke3dhW1NhLTJdfSA9ICR7d2FbU2EtMl19ICsgMTsKICAgICAgICBpZiAoJHt3YVtTYS0yXX0gPCAke2JhW1NhLTJdfSkgewogICAgICAgICAgcmVzdWx0LmEgPSBnZXRWYWx1ZSgke3dhfSk7CiAgICAgICAgfQoKICAgICAgICAke3dhW1NhLTFdfSA9ICR7d2FbU2EtMV19IC0gMTsKICAgICAgICBpZiAoJHt3YVtTYS0yXX0gPCAke2JhW1NhLTJdfSAmJgogICAgICAgICAgICAke3dhW1NhLTFdfSA8ICR7YmFbU2EtMV19KSB7CiAgICAgICAgICByZXN1bHQuYiA9IGdldFZhbHVlKCR7d2F9KTsKICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fWZ1bmN0aW9uIHNoaWZ0ZWRDaGFubmVscyhoYSxhYSx4YSl7Y29uc3QgYmE9aGEuaW5kZXhPZihhYSk7cmV0dXJuIGhhLm1hcCgoVGEsd2EpPT53YT09PWJhP2Ake1RhfSAtICR7eGF9YDpUYSkuam9pbigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGltYWcoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7aW5wdXQ6YmF9PWFhLFNhPXhhLnRleERhdGEuZ2V0KGJhLmRhdGFJZCk7cmV0dXJuIGlkZW50aXR5KHtpbnB1dHM6e3g6U2EuY29tcGxleFRlbnNvckluZm9zLmltYWd9LGJhY2tlbmQ6eGF9KX1jb25zdCBpbWFnQ29uZmlnPXtrZXJuZWxOYW1lOkltYWcsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmltYWd9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbmNhdEltcGwoaGEsYWEseGEpe2NvbnN0IGJhPWhhWzBdLmR0eXBlO2lmKGJhPT09ImNvbXBsZXg2NCIpe2NvbnN0IHRsPWhhLm1hcChhbD0+cmVhbCh7aW5wdXRzOntpbnB1dDphbH0sYmFja2VuZDp4YX0pKSxubD1oYS5tYXAoYWw9PmltYWcoe2lucHV0czp7aW5wdXQ6YWx9LGJhY2tlbmQ6eGF9KSksc2w9Y29uY2F0SW1wbCh0bCxhYSx4YSkscmw9Y29uY2F0SW1wbChubCxhYSx4YSksb2w9Y29tcGxleCh7aW5wdXRzOntyZWFsOnNsLGltYWc6cmx9LGJhY2tlbmQ6eGF9KTtyZXR1cm4gdGwuZm9yRWFjaChhbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oYWwpKSxubC5mb3JFYWNoKGFsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhbCkpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhybCksb2x9bGV0IFNhPXhhLnNob3VsZEV4ZWN1dGVPbkNQVShoYSk7aWYoYmE9PT0ic3RyaW5nIiYmKFNhPSEwKSxTYSl7Y29uc3QgdGw9aGEubWFwKGlsPT57Y29uc3QgdWw9Wy0xLHNpemVGcm9tU2hhcGUoaWwuc2hhcGUuc2xpY2UoYWEpKV07cmV0dXJuIHJlc2hhcGUoe2lucHV0czp7eDppbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6dWx9fSl9KSxubD10bC5tYXAoaWw9Pih7dmFsczp4YS5yZWFkU3luYyhpbC5kYXRhSWQpLHNoYXBlOmlsLnNoYXBlfSkpLHNsPWNvbXB1dGVPdXRTaGFwZSQxKHRsLm1hcChpbD0+aWwuc2hhcGUpLDEpLHJsPXRsWzBdLnNoYXBlWzBdPT09MSxvbD1jb25jYXRJbXBsQ1BVKG5sLHNsLGJhLHJsKSxhbD1jb21wdXRlT3V0U2hhcGUkMShoYS5tYXAoaWw9PmlsLnNoYXBlKSxhYSksbGw9eGEubWFrZVRlbnNvckluZm8oYWwsYmEsb2wpO3JldHVybiB0bC5mb3JFYWNoKGlsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhpbCkpLGxsfWNvbnN0IFRhPWhhLmZpbHRlcih0bD0+c2l6ZUZyb21TaGFwZSh0bC5zaGFwZSk+MCksd2E9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19BUlJBWV9PUEVSQVRJT05TIikmJlRhWzBdLnNoYXBlLmxlbmd0aD4xO2lmKFRhLmxlbmd0aD09PTEpe2NvbnN0IHRsPXdhP25ldyBVbmFyeU9wUHJvZ3JhbShoYVswXS5zaGFwZSxDTE9ORSk6bmV3IFVuYXJ5T3BQYWNrZWRQcm9ncmFtKGhhWzBdLnNoYXBlLENMT05FKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKHRsLGhhLGJhKX1jb25zdCBFYT1lbnYoKS5nZXROdW1iZXIoIldFQkdMX01BWF9URVhUVVJFU19JTl9TSEFERVIiKTtpZihUYS5sZW5ndGg+RWEpe2NvbnN0IHRsPVtdO2ZvcihsZXQgc2w9MDtzbDxUYS5sZW5ndGg7c2wrPUVhKXtjb25zdCBybD1UYS5zbGljZShzbCxzbCtFYSk7dGwucHVzaChjb25jYXRJbXBsKHJsLGFhLHhhKSl9Y29uc3Qgbmw9Y29uY2F0SW1wbCh0bCxhYSx4YSk7Zm9yKGNvbnN0IHNsIG9mIHRsKXhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKTtyZXR1cm4gbmx9aWYod2Epe2NvbnN0IHRsPW5ldyBDb25jYXRQYWNrZWRQcm9ncmFtKFRhLm1hcChubD0+bmwuc2hhcGUpLGFhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKHRsLFRhLGJhKX1jb25zdHt0ZW5zb3JzMkQ6a2Esb3V0U2hhcGU6QWF9PWNvbXB1dGVUZW5zb3JzMkQoVGEsYWEseGEpLEZhPW5ldyBDb25jYXRQcm9ncmFtKGthLm1hcCh0bD0+dGwuc2hhcGUpKSxMYT14YS5ydW5XZWJHTFByb2dyYW0oRmEsa2EsYmEpO2thLmZvckVhY2godGw9PnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSk7Y29uc3QgZWw9cmVzaGFwZSh7aW5wdXRzOnt4OkxhfSxhdHRyczp7c2hhcGU6QWF9LGJhY2tlbmQ6eGF9KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpLGVsfWZ1bmN0aW9uIGNvbXB1dGVUZW5zb3JzMkQoaGEsYWEseGEpe2NvbnN0IGJhPWNvbXB1dGVPdXRTaGFwZSQxKGhhLm1hcChUYT0+VGEuc2hhcGUpLGFhKTtyZXR1cm57dGVuc29yczJEOmhhLm1hcChUYT0+cmVzaGFwZSh7aW5wdXRzOnt4OlRhfSxhdHRyczp7c2hhcGU6Wy0xLHNpemVGcm9tU2hhcGUoVGEuc2hhcGUuc2xpY2UoYWEpKV19LGJhY2tlbmQ6eGF9KSksb3V0U2hhcGU6YmF9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbmNhdChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtheGlzOlNhfT1iYSxUYT1wYXJzZUF4aXNQYXJhbShTYSxhYVswXS5zaGFwZSlbMF0sd2E9YWEubWFwKEFhPT5BYS5zaGFwZSk7YXNzZXJ0UGFyYW1zQ29uc2lzdGVudCh3YSxUYSk7Y29uc3QgRWE9Y29tcHV0ZU91dFNoYXBlJDEoYWEubWFwKEFhPT5BYS5zaGFwZSksVGEpO2lmKHNpemVGcm9tU2hhcGUoRWEpPT09MClyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRWEsYWFbMF0uZHR5cGUsW10pO2NvbnN0IGthPWFhLmZpbHRlcihBYT0+c2l6ZUZyb21TaGFwZShBYS5zaGFwZSk+MCk7cmV0dXJuIGthLmxlbmd0aD09PTE/aWRlbnRpdHkoe2lucHV0czp7eDprYVswXX0sYmFja2VuZDp4YX0pOmNvbmNhdEltcGwoa2EsVGEseGEpfWNvbnN0IGNvbmNhdENvbmZpZz17a2VybmVsTmFtZTpDb25jYXQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbmNhdH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgQ29udjJEUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YT0hMSxiYT1udWxsLFNhPSExLFRhPSExKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiVyJdLHRoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGU7Y29uc3Qgd2E9YWEucGFkSW5mby50b3AsRWE9YWEucGFkSW5mby5sZWZ0LGthPWFhLnN0cmlkZUhlaWdodCxBYT1hYS5zdHJpZGVXaWR0aCxGYT1hYS5kaWxhdGlvbkhlaWdodCxMYT1hYS5kaWxhdGlvbldpZHRoLGVsPWFhLmZpbHRlckhlaWdodCx0bD1hYS5maWx0ZXJXaWR0aCxubD1NYXRoLmZsb29yKGFhLmluQ2hhbm5lbHMvNCkqNCxzbD1hYS5pbkNoYW5uZWxzJTQscmw9YWEuZGF0YUZvcm1hdD09PSJjaGFubmVsc0xhc3QiLG9sPXJsPzE6MixhbD1ybD8yOjMsbGw9cmw/MzoxO2xldCBpbD0iIixjbD0iIjtiYSYmKFNhP2lsPWBmbG9hdCBhY3RpdmF0aW9uKGZsb2F0IGEpIHsKICAgICAgICAgIGZsb2F0IGIgPSBnZXRQcmVsdUFjdGl2YXRpb25XZWlnaHRzQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6VGE/aWw9YGZsb2F0IGFjdGl2YXRpb24oZmxvYXQgYSkgewogICAgICAgICAgZmxvYXQgYiA9IGdldExlYWt5cmVsdUFscGhhQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6aWw9YAogICAgICAgICAgZmxvYXQgYWN0aXZhdGlvbihmbG9hdCB4KSB7CiAgICAgICAgICAgICR7YmF9CiAgICAgICAgICB9CiAgICAgICAgYCxjbD0icmVzdWx0ID0gYWN0aXZhdGlvbihyZXN1bHQpOyIpO2NvbnN0IHVsPXhhPyJyZXN1bHQgKz0gZ2V0Qmlhc0F0T3V0Q29vcmRzKCk7IjoiIjt4YSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJpYXMiKSxTYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInByZWx1QWN0aXZhdGlvbldlaWdodHMiKSxUYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImxlYWt5cmVsdUFscGhhIiksdGhpcy51c2VyQ29kZT1gCiAgICAgICR7aWx9CgogICAgICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHtrYX0sICR7QWF9KTsKICAgICAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7d2F9LCAke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgIGludCBkMiA9IGNvb3Jkc1ske2xsfV07CgogICAgICAgIGl2ZWMyIHhSQ0Nvcm5lciA9CiAgICAgICAgICAgIGl2ZWMyKGNvb3Jkc1ske29sfV0sIGNvb3Jkc1ske2FsfV0pICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IHhSQ29ybmVyID0geFJDQ29ybmVyLng7CiAgICAgICAgaW50IHhDQ29ybmVyID0geFJDQ29ybmVyLnk7CgogICAgICAgIC8vIENvbnZvbHZlIHgoPywgPywgZDEpIHdpdGggdyg6LCA6LCBkMSwgZDIpIHRvIGdldCB5KHlSLCB5QywgZDIpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7ZWx9OyB3UisrKSB7CiAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSICogJHtGYX07CgogICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHt0bH07IHdDKyspIHsKICAgICAgICAgICAgaW50IHhDID0geENDb3JuZXIgKyB3QyAqICR7TGF9OwoKICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaW50IGQxID0gMDsgZDEgPCAke25sfTsgZDEgKz0gNCkgewogICAgICAgICAgICAgIHZlYzQgd1ZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgZDEsIGQyKSwKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCBkMSArIDEsIGQyKSwKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCBkMSArIDIsIGQyKSwKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCBkMSArIDMsIGQyKQogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGlmICgke3JsfSkgewogICAgICAgICAgICAgICAgdmVjNCB4VmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgZDEgKyAxKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSArIDIpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4UiwgeEMsIGQxICsgMykKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmVjNCB4VmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgZDEsIHhSLCB4QyksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGQxICsgMSwgeFIsIHhDKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgZDEgKyAyLCB4UiwgeEMpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBkMSArIDMsIHhSLCB4QykKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgke3NsPT09MX0pIHsKCiAgICAgICAgICAgICAgaWYgKCR7cmx9KSB7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9CiAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCAke25sfSkgKgogICAgICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCAke25sfSwgZDIpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9CiAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgJHtubH0sIHhSLCB4QykgKgogICAgICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCAke25sfSwgZDIpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0gZWxzZSBpZiAoJHtzbD09PTJ9KSB7CiAgICAgICAgICAgICAgdmVjMiB3VmFsdWVzID0gdmVjMigKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCAke25sfSwgZDIpLAogICAgICAgICAgICAgICAgZ2V0Vyh3Uiwgd0MsICR7bmx9ICsgMSwgZDIpCiAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgaWYgKCR7cmx9KSB7CiAgICAgICAgICAgICAgICB2ZWMyIHhWYWx1ZXMgPSB2ZWMyKAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4UiwgeEMsICR7bmx9KSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCAke25sfSArIDEpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZlYzIgeFZhbHVlcyA9IHZlYzIoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsICR7bmx9LCB4UiwgeEMpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCAke25sfSArIDEsIHhSLCB4QykKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9IGVsc2UgaWYgKCR7c2w9PT0zfSkgewogICAgICAgICAgICAgIHZlYzMgd1ZhbHVlcyA9IHZlYzMoCiAgICAgICAgICAgICAgICBnZXRXKHdSLCB3QywgJHtubH0sIGQyKSwKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCAke25sfSArIDEsIGQyKSwKICAgICAgICAgICAgICAgIGdldFcod1IsIHdDLCAke25sfSArIDIsIGQyKQogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGlmICgke3JsfSkgewogICAgICAgICAgICAgICAgdmVjMyB4VmFsdWVzID0gdmVjMygKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCAke25sfSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhSLCB4QywgJHtubH0gKyAxKSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeFIsIHhDLCAke25sfSArIDIpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgZG90UHJvZCArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZlYzMgeFZhbHVlcyA9IHZlYzMoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsICR7bmx9LCB4UiwgeEMpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCAke25sfSArIDEsIHhSLCB4QyksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsICR7bmx9ICsgMiwgeFIsIHhDKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGRvdFByb2QgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZsb2F0IHJlc3VsdCA9IGRvdFByb2Q7CiAgICAgICAgJHt1bH0KICAgICAgICAke2NsfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX1jbGFzcyBDb252M0RQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiVyJdLHRoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGU7Y29uc3QgeGE9YWEucGFkSW5mby5mcm9udCxiYT1hYS5wYWRJbmZvLnRvcCxTYT1hYS5wYWRJbmZvLmxlZnQsVGE9YWEuc3RyaWRlRGVwdGgsd2E9YWEuc3RyaWRlSGVpZ2h0LEVhPWFhLnN0cmlkZVdpZHRoLGthPWFhLmRpbGF0aW9uRGVwdGgsQWE9YWEuZGlsYXRpb25IZWlnaHQsRmE9YWEuZGlsYXRpb25XaWR0aCxMYT1hYS5maWx0ZXJEZXB0aCxlbD1hYS5maWx0ZXJIZWlnaHQsdGw9YWEuZmlsdGVyV2lkdGgsbmw9TWF0aC5mbG9vcihhYS5pbkNoYW5uZWxzLzQpKjQsc2w9YWEuaW5DaGFubmVscyU0O3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMyBzdHJpZGVzID0gaXZlYzMoJHtUYX0sICR7d2F9LCAke0VhfSk7CiAgICAgIGNvbnN0IGl2ZWMzIHBhZHMgPSBpdmVjMygke3hhfSwgJHtiYX0sICR7U2F9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDsKICAgICAgICBpbnQgZDIgPSBjb29yZHMudTsKCiAgICAgICAgaXZlYzMgeEZSQ0Nvcm5lciA9IGl2ZWMzKGNvb3Jkcy55LCBjb29yZHMueiwgY29vcmRzLncpICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IHhGQ29ybmVyID0geEZSQ0Nvcm5lci54OwogICAgICAgIGludCB4UkNvcm5lciA9IHhGUkNDb3JuZXIueTsKICAgICAgICBpbnQgeENDb3JuZXIgPSB4RlJDQ29ybmVyLno7CgogICAgICAgIC8vIENvbnZvbHZlIHgoPywgPywgPywgZDEpIHdpdGggdyg6LCA6LCA6LCBkMSwgZDIpIHRvIGdldAogICAgICAgIC8vIHkoeUYsIHlSLCB5QywgZDIpLiA/ID0gdG8gYmUgZGV0ZXJtaW5lZC4gOiA9IGFjcm9zcyBhbGwKICAgICAgICAvLyB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd0YgPSAwOyB3RiA8ICR7TGF9OyB3RisrKSB7CiAgICAgICAgICBpbnQgeEYgPSB4RkNvcm5lciArIHdGICogJHtrYX07CgogICAgICAgICAgaWYgKHhGIDwgMCB8fCB4RiA+PSAke2FhLmluRGVwdGh9KSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke2VsfTsgd1IrKykgewogICAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSICogJHtBYX07CgogICAgICAgICAgICBpZiAoeFIgPCAwIHx8IHhSID49ICR7YWEuaW5IZWlnaHR9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke3RsfTsgd0MrKykgewogICAgICAgICAgICAgIGludCB4QyA9IHhDQ29ybmVyICsgd0MgKiAke0ZhfTsKCiAgICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGZvciAoaW50IGQxID0gMDsgZDEgPCAke25sfTsgZDEgKz0gNCkgewogICAgICAgICAgICAgICAgdmVjNCB4VmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBkMSArIDEpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBkMSArIDIpLAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBkMSArIDMpCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgdmVjNCB3VmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCBkMSwgZDIpLAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsIGQxICsgMSwgZDIpLAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsIGQxICsgMiwgZDIpLAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsIGQxICsgMywgZDIpCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGRvdFByb2QgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgaWYgKCR7c2w9PT0xfSkgewogICAgICAgICAgICAgICAgZG90UHJvZCArPQogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCAke25sfSkgKgogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsICR7bmx9LCBkMik7CiAgICAgICAgICAgICAgfSBlbHNlIGlmICgke3NsPT09Mn0pIHsKICAgICAgICAgICAgICAgIHZlYzIgeFZhbHVlcyA9IHZlYzIoCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsICR7bmx9KSwKICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgJHtubH0gKyAxKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHZlYzIgd1ZhbHVlcyA9IHZlYzIoCiAgICAgICAgICAgICAgICAgIGdldFcod0YsIHdSLCB3QywgJHtubH0sIGQyKSwKICAgICAgICAgICAgICAgICAgZ2V0Vyh3Riwgd1IsIHdDLCAke25sfSArIDEsIGQyKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGRvdFByb2QgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpOwogICAgICAgICAgICAgIH0gZWxzZSBpZiAoJHtzbD09PTN9KSB7CiAgICAgICAgICAgICAgICB2ZWMzIHhWYWx1ZXMgPSB2ZWMzKAogICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCAke25sfSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsICR7bmx9ICsgMSksCiAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsICR7bmx9ICsgMikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB2ZWMzIHdWYWx1ZXMgPSB2ZWMzKAogICAgICAgICAgICAgICAgICBnZXRXKHdGLCB3Uiwgd0MsICR7bmx9LCBkMiksCiAgICAgICAgICAgICAgICAgIGdldFcod0YsIHdSLCB3QywgJHtubH0gKyAxLCBkMiksCiAgICAgICAgICAgICAgICAgIGdldFcod0YsIHdSLCB3QywgJHtubH0gKyAyLCBkMikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBDb252MkRQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhPSExLGJhPW51bGwsU2E9ITEsVGE9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJXIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InBhZHMiLHR5cGU6Iml2ZWMyIn0se25hbWU6InN0cmlkZXMiLHR5cGU6Iml2ZWMyIn0se25hbWU6ImRpbGF0aW9ucyIsdHlwZToiaXZlYzIifSx7bmFtZToiaW5EaW1zIix0eXBlOiJpdmVjMiJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLm91dFNoYXBlLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdCB3YT1hYS5wYWRJbmZvLmxlZnQsRWE9YWEuc3RyaWRlV2lkdGgsa2E9YWEuZGlsYXRpb25XaWR0aCxBYT1hYS5maWx0ZXJIZWlnaHQsRmE9YWEuZmlsdGVyV2lkdGgsTGE9RmE7bGV0IGVsPWAKICAgICAgIGludCB4UjsgaW50IHhDOyBpbnQgeENPZmZzZXQ7CiAgICAgICB2ZWM0IHdUZXhlbDsgdmVjNCBwcmV2aW91czsgdmVjNCBmaW5hbDtgO2ZvcihsZXQgcmw9MDtybDxGYTtybCsrKWVsKz1gCiAgICAgICAgICAgdmVjNCB4VGV4ZWxDJHtybCoyfTsKICAgICAgICAgICBpbnQgeFRleGVsQyR7cmwqMn1SZWFkeTsKICAgICAgICAgICB2ZWM0IHhUZXhlbEMke3JsKjIrMX07CiAgICAgICAgICAgaW50IHhUZXhlbEMke3JsKjIrMX1SZWFkeTsKICAgICAgICAgICB2ZWM0IHhDJHtybH07YDtlbCs9YAogICAgIGZvciAoaW50IHIgPSAwOyByIDwgJHtBYX07IHIrKykgewogICAgICBmb3IgKGludCBkMSA9IDA7IGQxIDwgJHthYS5pbkNoYW5uZWxzfTsgZDEgKz0gMikgewogICAgICAgYDtmb3IobGV0IHJsPTA7cmw8RmE7cmwrKyllbCs9YAogICAgICAgICAgIHhUZXhlbEMke3JsKjJ9ID0gdmVjNCgwLjApOwogICAgICAgICAgIHhUZXhlbEMke3JsKjJ9UmVhZHkgPSAwOwogICAgICAgICAgIHhUZXhlbEMke3JsKjIrMX0gPSB2ZWM0KDAuMCk7CiAgICAgICAgICAgeFRleGVsQyR7cmwqMisxfVJlYWR5ID0gMDsKICAgICAgICAgICB4QyR7cmx9ID0gdmVjNCgwLjApO2A7ZWwrPWAKICAgICAgICAgeFIgPSB4UkNvcm5lciArIHIgKiBkaWxhdGlvbnNbMF07CiAgICAgICAgIGlmICh4UiA+PTAgJiYgeFIgPCBpbkRpbXNbMF0pIHsKICAgICAgIGA7Zm9yKGxldCBybD0wO3JsPChMYSsxKS8yO3JsKyspe2NvbnN0IG9sPXJsKjI7aWYoZWwrPWAKICAgICAgICAgICB4QyA9IHhDQ29ybmVyICsgJHtvbCprYX07CiAgICAgICAgICAgYCxFYT09PTEpe2lmKG9sPEZhJiYod2ElMj09PTE/KGVsKz1gCiAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDE7CiAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2x9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CgogICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBgLGthPT09MSYmb2w+MD9lbCs9YAogICAgICAgICAgICAgICAgIHhDJHtvbH0gPSB2ZWM0KHhUZXhlbEMke29sLTJ9Lnp3LCB4VGV4ZWxDJHtvbH0ueHkpOwogICAgICAgICAgICAgICAgIGA6ZWwrPWAKICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAxIC0gMjsKCiAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91cy56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgeEMke29sfSA9IHZlYzQocHJldmlvdXMuencsIHhUZXhlbEMke29sfS54eSk7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICB4QyR7b2x9ID0gdmVjNCgwLjAsIDAuMCwgeFRleGVsQyR7b2x9Lnh5KTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIGApOmVsKz1gCiAgICAgICAgICAgICAgICAgaWYgKHhDID49IDAgJiYgeEMgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2x9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9ID0gZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSk7CiAgICAgICAgICAgICAgICAgICBpZiAoeEMgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICB4QyR7b2x9ID0geFRleGVsQyR7b2x9OwogICAgICAgICAgICAgICAgIGAsb2wrMTxGYSkpe2NvbnN0IGFsPXdhJTI9PT0wP25lYXJlc3RMYXJnZXJFdmVuKGthKTprYTtrYSUyPT09MCYmd2ElMj09PTF8fGthJTIhPT0wJiZ3YSUyIT09MT8oZWwrPWAKICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyBpbW9kKHBhZHNbMV0sIDIpICsgJHthbH07CgogICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2wrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CgogICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAgIC8vIHdlJ3JlIHJlYWRpbmcgZnJvbSByZWN5Y2xlZCB0ZXh0dXJlLgogICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgYCxrYT4xP2VsKz1gCiAgICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0IC09IDI7CiAgICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCA+PSAwICYmIHhDT2Zmc2V0IDwgaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgICAgeEMke29sKzF9ID0gdmVjNChwcmV2aW91cy56dywgeFRleGVsQyR7b2wrMX0ueHkpOwogICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgeEMke29sKzF9ID0gdmVjNCgwLjAsIDAuMCwgeFRleGVsQyR7b2wrMX0ueHkpOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGA6ZWwrPWAKICAgICAgICAgICAgICAgICAgICAgeEMke29sKzF9ID0gdmVjNCh4VGV4ZWxDJHtvbH0uencsIHhUZXhlbEMke29sKzF9Lnh5KTsKICAgICAgICAgICAgICAgICAgICAgYCk6YWw9PT0xP2VsKz1gCiAgICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHhUZXhlbEMke29sfTsKICAgICAgICAgICAgICAgICAgICAgYDplbCs9YAogICAgICAgICAgICAgICAgICAgICB4Q09mZnNldCA9IHhDICsgJHthbH07CgogICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHtvbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2wrMX1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHhUZXhlbEMke29sKzF9OwogICAgICAgICAgICAgICAgICAgICBgfX1lbHNlIG9sPEZhJiYod2ElMj09PTE/KGVsKz1gCiAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDEgLSBzdHJpZGVzWzFdOwogICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2x9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2x9ID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CiAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIGlmKHhDICsgMSA+PSAwICYmIHhDICsgMSA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHtvbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9ID0gZ2V0WChiYXRjaCwgeFIsIHhDICsgMSwgZDEpOwogICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICBpZiAoeEMgKyAyID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgeEMke29sfSA9IHZlYzQoeFRleGVsQyR7b2x9Lnp3LCB4VGV4ZWxDJHtvbCsxfS56dyk7CiAgICAgICAgICAgICAgIGAsb2wrMTxGYSYmKGVsKz1gCiAgICAgICAgICAgICAgICAgICBmaW5hbCA9IHZlYzQoMC4wKTsKICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAxICsgc3RyaWRlc1sxXTsKICAgICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgZmluYWwgPSBnZXRYKGJhdGNoLCB4UiwgeENPZmZzZXQsIGQxKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHZlYzQoeFRleGVsQyR7b2wrMX0ueHksIGZpbmFsLnh5KTsKICAgICAgICAgICAgICAgICBgKSk6KGVsKz1gCiAgICAgICAgICAgICAgICAgaWYoeEMgPj0gMCAmJiB4QyA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHtvbH1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH0gPSBnZXRYKGJhdGNoLCB4UiwgeEMsIGQxKTsKICAgICAgICAgICAgICAgICAgIGlmICh4QyArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyBzdHJpZGVzWzFdOwogICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7b2wrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7b2wrMX0uencgPSB2ZWMyKDAuKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke29sKzF9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgeEMke29sfSA9IHZlYzQoCiAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHtvbH0ueHksIHhUZXhlbEMke29sKzF9Lnh5KTsKICAgICAgICAgICAgICAgYCxvbCsxPEZhJiYoZWwrPWAKICAgICAgICAgICAgICAgICAgIHhDJHtvbCsxfSA9IHZlYzQoeFRleGVsQyR7b2x9Lnp3LCB4VGV4ZWxDJHtvbCsxfS56dyk7CiAgICAgICAgICAgICAgICAgYCkpKTtvbDxGYSYmKGVsKz1gCiAgICAgICAgICAgICB3VGV4ZWwgPSBnZXRXKHIsICR7b2x9LCBkMSwgZDIpOwogICAgICAgICAgICAgZG90UHJvZCArPSB4QyR7b2x9Lnh4enogKiB2ZWM0KHdUZXhlbC54eSwgd1RleGVsLnh5KTsKICAgICAgICAgICAgIGlmKGQxICsgMSA8ICR7YWEuaW5DaGFubmVsc30pIHsKICAgICAgICAgICAgICAgZG90UHJvZCArPSB4QyR7b2x9Lnl5d3cgKiB2ZWM0KHdUZXhlbC56dywgd1RleGVsLnp3KTsKICAgICAgICAgICAgIH0KICAgICAgICAgICBgLG9sKzE8RmEmJihlbCs9YAogICAgICAgICAgICAgICB3VGV4ZWwgPSBnZXRXKHIsICR7b2wrMX0sIGQxLCBkMik7CiAgICAgICAgICAgICAgIGRvdFByb2QgKz0geEMke29sKzF9Lnh4enogKiB2ZWM0KHdUZXhlbC54eSwgd1RleGVsLnh5KTsKICAgICAgICAgICAgICAgaWYoZDEgKyAxIDwgJHthYS5pbkNoYW5uZWxzfSkgewogICAgICAgICAgICAgICAgIGRvdFByb2QgKz0geEMke29sKzF9Lnl5d3cgKiB2ZWM0KHdUZXhlbC56dywgd1RleGVsLnp3KTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgYCkpfWVsKz1gCiAgICAgfQogICBgLGVsKz1gCiAgICAgfQogICBgLGVsKz1gCiAgICAgfQogICBgO2xldCB0bD0iIixubD0iIjtiYSYmKFNhP3RsPWB2ZWM0IGFjdGl2YXRpb24odmVjNCBhKSB7CiAgICAgICAgICAgdmVjNCBiID0gZ2V0UHJlbHVBY3RpdmF0aW9uV2VpZ2h0c0F0T3V0Q29vcmRzKCk7CiAgICAgICAgICAgJHtiYX0KICAgICAgICAgfWA6VGE/dGw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IGEpIHsKICAgICAgICAgICB2ZWM0IGIgPSBnZXRMZWFreXJlbHVBbHBoYUF0T3V0Q29vcmRzKCk7CiAgICAgICAgICAgJHtiYX0KICAgICAgICAgfWA6dGw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IHgpIHsKICAgICAgICAgICAke2JhfQogICAgICAgICB9YCxubD0icmVzdWx0ID0gYWN0aXZhdGlvbihyZXN1bHQpOyIpO2NvbnN0IHNsPXhhPyJyZXN1bHQgKz0gZ2V0Qmlhc0F0T3V0Q29vcmRzKCk7IjoiIjt4YSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJpYXMiKSxTYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInByZWx1QWN0aXZhdGlvbldlaWdodHMiKSxUYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImxlYWt5cmVsdUFscGhhIiksdGhpcy51c2VyQ29kZT1gCiAgICAgICAke3RsfQoKICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMueXogKiBzdHJpZGVzIC0gcGFkczsKICAgICAgICAgaW50IGQyID0gY29vcmRzLnc7CiAgICAgICAgIGludCB4UkNvcm5lciA9IHhSQ0Nvcm5lci54OwogICAgICAgICBpbnQgeENDb3JuZXIgPSB4UkNDb3JuZXIueTsKCiAgICAgICAgIC8vaW50aWFsaXplIGRvdFByb2Qgd2l0aCBhIHNtYWxsIGVwc2lsb24gc2VlbXMgdG8gcmVkdWNlIEdQVSBhY2N1cmFjeSBsb3NzLgogICAgICAgICB2ZWM0IGRvdFByb2QgPSB2ZWM0KDAuMDAwMDAwMDAwMDAwMDAxKTsKCiAgICAgICAgICR7ZWx9CgogICAgICAgICB2ZWM0IHJlc3VsdCA9IGRvdFByb2QgLSB2ZWM0KDAuMDAwMDAwMDAwMDAwMDAxKTsKICAgICAgICAgJHtzbH0KICAgICAgICAgJHtubH0KICAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgICB9CiAgICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgSW0yQ29sUGFja2VkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJpbnB1dFNoYXBlIix0eXBlOiJpdmVjNCJ9LHtuYW1lOiJwYWQiLHR5cGU6Iml2ZWMyIn0se25hbWU6InN0cmlkZSIsdHlwZToiaXZlYzIifSx7bmFtZToiZGlsYXRpb24iLHR5cGU6Iml2ZWMyIn0se25hbWU6ImluQ2hhbm5lbHMiLHR5cGU6ImludCJ9LHtuYW1lOiJpdGVtc1BlckJsb2NrUm93Iix0eXBlOiJpbnQifSx7bmFtZToib3V0V2lkdGgiLHR5cGU6ImludCJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdHtkYXRhRm9ybWF0OmJhfT14YSxTYT1nZXRHbHNsRGlmZmVyZW5jZXMoKSxUYT1iYT09PSJjaGFubmVsc0xhc3QiLHdhPVRhPzE6MixFYT1UYT8yOjMsa2E9dGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPyJpZihibG9ja0luZGV4IDwgb3V0U2hhcGVbMl0gJiYgcG9zIDwgb3V0U2hhcGVbMV0pIHsiOmBpZihibG9ja0luZGV4IDwgJHthYVsyXX0gJiYgcG9zIDwgJHthYVsxXX0pIHtgO2xldCBBYT0iIjtmb3IobGV0IEZhPTA7RmE8PTE7RmErKylmb3IobGV0IExhPTA7TGE8PTE7TGErKylBYSs9YAogICAgICAgICAgYmxvY2tJbmRleCA9IHJjLnogKyAke0xhfTsKICAgICAgICAgIHBvcyA9IHJjLnkgKyAke0ZhfTsKCiAgICAgICAgICAke2thfQogICAgICAgICAgICBvZmZzZXRZID0gaW50KGJsb2NrSW5kZXggLyBvdXRXaWR0aCkgKiBzdHJpZGVbMF0gLSBwYWRbMF07CiAgICAgICAgICAgIGQwID0gb2Zmc2V0WSArIGRpbGF0aW9uWzBdICogKHBvcyAvIGl0ZW1zUGVyQmxvY2tSb3cpOwoKICAgICAgICAgICAgaWYoZDAgPCBpbnB1dFNoYXBlWyR7d2F9XSAmJiBkMCA+PSAwKSB7CiAgICAgICAgICAgICAgLy8gVXNlIGN1c3RvbSBpbW9kIGluc3RlYWQgbW9kLiBPbiBJbnRlbCBHUFUsIG1vZCBtYXkgZ2VuZXJhdGUKICAgICAgICAgICAgICAvLyB1bmV4cGVjdGVkIHZhbHVlLgogICAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS90ZW5zb3JmbG93L3RmanMvaXNzdWVzLzU0NDcKICAgICAgICAgICAgICBvZmZzZXRYID0gaW1vZChibG9ja0luZGV4LCBvdXRXaWR0aCkgKiBzdHJpZGVbMV0gLSBwYWRbMV07CiAgICAgICAgICAgICAgZDEgPSBvZmZzZXRYICsgZGlsYXRpb25bMV0gKiAoaW1vZChwb3MsIGl0ZW1zUGVyQmxvY2tSb3cpIC8KICAgICAgICAgICAgICAgICAgaW5DaGFubmVscyk7CgogICAgICAgICAgICAgIGlmKGQxIDwgaW5wdXRTaGFwZVske0VhfV0gJiYgZDEgPj0gMCkgewoKICAgICAgICAgICAgICAgIGNoID0gaW1vZChwb3MsIGluQ2hhbm5lbHMpOwoKICAgICAgICAgICAgICAgIGlmICgke1RhfSkgewogICAgICAgICAgICAgICAgICBpbm5lckRpbXMgPSB2ZWMyKGQxLCBjaCk7CiAgICAgICAgICAgICAgICAgIHJlc3VsdFske0ZhKjIrTGF9XSA9IGdldENoYW5uZWwoCiAgICAgICAgICAgICAgICAgICAgZ2V0QShyYy54LCBkMCwgaW50KGlubmVyRGltcy54KSwKICAgICAgICAgICAgICAgICAgICBpbnQoaW5uZXJEaW1zLnkpKSwgaW5uZXJEaW1zKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGlubmVyRGltcyA9IHZlYzIoZDAsIGQxKTsKICAgICAgICAgICAgICAgICAgcmVzdWx0WyR7RmEqMitMYX1dID0gZ2V0Q2hhbm5lbCgKICAgICAgICAgICAgICAgICAgICBnZXRBKHJjLngsIGNoLCBpbnQoaW5uZXJEaW1zLngpLAogICAgICAgICAgICAgICAgICAgIGludChpbm5lckRpbXMueSkpLCBpbm5lckRpbXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIGA7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMyByYyA9IGdldE91dHB1dENvb3JkcygpOwoKICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMCk7CgogICAgICAgIGludCBibG9ja0luZGV4LCBwb3MsIG9mZnNldFksIGQwLCBvZmZzZXRYLCBkMSwgY2g7CiAgICAgICAgdmVjMiBpbm5lckRpbXM7CgogICAgICAgICR7QWF9CgogICAgICAgICR7U2Eub3V0cHV0fSA9IHJlc3VsdDsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2V0U2hhcGVGb3JCYXRjaE1hdE11bChoYSxhYSl7Y29uc3QgeGE9aGEubGVuZ3RoO3JldHVybiB4YT49Mz9hYT9bLi4uaGEuc2xpY2UoMCwtMyksaGFbeGEtM10qaGFbeGEtMl0saGFbeGEtMV1dOlsuLi5oYS5zbGljZSgwLC0zKSxoYVt4YS0zXSxoYVt4YS0yXSpoYVt4YS0xXV06IWFhJiZ4YT09PTEmJmhhWzBdPjE/W2hhWzBdLDFdOm51bGx9ZnVuY3Rpb24gY29udjJkQnlNYXRNdWwoe3g6aGEsZmlsdGVyOmFhLGNvbnZJbmZvOnhhLGJhY2tlbmQ6YmEsYmlhczpTYT1udWxsLHByZWx1QWN0aXZhdGlvbldlaWdodHM6VGE9bnVsbCxsZWFreXJlbHVBbHBoYTp3YT0wLGFjdGl2YXRpb246RWE9bnVsbH0pe2NvbnN0IGthPWhhLnNoYXBlLEFhPWJhLnRleERhdGEuZ2V0KGhhLmRhdGFJZCksRmE9eGEuaW5DaGFubmVscyxMYT1rYVswXSprYVsxXSprYVsyXSxlbD14YS5vdXRDaGFubmVscyx0bD14YS5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCIsbmw9ITEsc2w9ITE7bGV0IHJsO2NvbnN0IG9sPVtdO2lmKFRhIT1udWxsKXtjb25zdCBpbD1nZXRTaGFwZUZvckJhdGNoTWF0TXVsKFRhLnNoYXBlLHRsKTtpbCE9bnVsbCYmKFRhPXJlc2hhcGUoe2lucHV0czp7eDpUYX0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6aWx9fSksb2wucHVzaChUYSkpfWlmKFNhIT1udWxsKXtjb25zdCBpbD1nZXRTaGFwZUZvckJhdGNoTWF0TXVsKFNhLnNoYXBlLHRsKTtpbCE9bnVsbCYmKFNhPXJlc2hhcGUoe2lucHV0czp7eDpTYX0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6aWx9fSksb2wucHVzaChTYSkpfWlmKCEoKExhPT09MXx8ZWw9PT0xKSYmRmE+TUFUTVVMX1NIQVJFRF9ESU1fVEhSRVNIT0xEKSYmQWEuaXNQYWNrZWQmJnRsJiZBYS50ZXh0dXJlIT1udWxsJiZrYVsyXSUyIT09MCYmYXJyYXlzRXF1YWwoQWEuc2hhcGUuc2xpY2UoLTMpLGthLnNsaWNlKC0zKSkpe2NvbnN0IGlsPWthWzBdKmthWzFdKihrYVsyXSsxKSxjbD17ZGF0YUlkOmhhLmRhdGFJZCxzaGFwZTpbMSxpbCx4YS5pbkNoYW5uZWxzXSxkdHlwZTpoYS5kdHlwZX0sdWw9QWEuc2hhcGU7QWEuc2hhcGU9QWEuc2hhcGUuc2xpY2UoKSxBYS5zaGFwZVtBYS5zaGFwZS5sZW5ndGgtMl0rKyxhc3NlcnQoaXNSZXNoYXBlRnJlZShBYS5zaGFwZSxjbC5zaGFwZSksKCk9PmBwYWNrZWQgcmVzaGFwZSAke0FhLnNoYXBlfSB0byAke2NsLnNoYXBlfSBpc24ndCBmcmVlYCk7Y29uc3QgZGw9cmVzaGFwZSh7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpbMSx4YS5pbkNoYW5uZWxzLHhhLm91dENoYW5uZWxzXX19KTtvbC5wdXNoKGRsKTtjb25zdCBobD1iYXRjaE1hdE11bEltcGwoe2E6Y2wsYjpkbCxiYWNrZW5kOmJhLHRyYW5zcG9zZUE6bmwsdHJhbnNwb3NlQjpzbCxiaWFzOlNhLGFjdGl2YXRpb246RWEscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpUYSxsZWFreXJlbHVBbHBoYTp3YX0pLHBsPWJhLnRleERhdGEuZ2V0KGhsLmRhdGFJZCk7YXNzZXJ0KHBsLmlzUGFja2VkLCgpPT4iYmF0Y2hNYXRNdWwgcmVzdWx0IGlzIGV4cGVjdGVkIHRvIGJlIHBhY2tlZCIpLEFhLnNoYXBlPXVsLHBsLnNoYXBlPXhhLm91dFNoYXBlLHJsPWlkZW50aXR5KHtpbnB1dHM6e3g6aGx9LGJhY2tlbmQ6YmF9KSxybC5zaGFwZT14YS5vdXRTaGFwZSxvbC5wdXNoKGhsKX1lbHNle2NvbnN0IGlsPXhhLm91dEhlaWdodCp4YS5vdXRXaWR0aCxjbD1yZXNoYXBlKHtpbnB1dHM6e3g6aGF9LGJhY2tlbmQ6YmEsYXR0cnM6e3NoYXBlOnRsP1t4YS5iYXRjaFNpemUsaWwseGEuaW5DaGFubmVsc106W3hhLmJhdGNoU2l6ZSx4YS5pbkNoYW5uZWxzLGlsXX19KSx1bD1yZXNoYXBlKHtpbnB1dHM6e3g6YWF9LGJhY2tlbmQ6YmEsYXR0cnM6e3NoYXBlOlsxLHhhLmluQ2hhbm5lbHMseGEub3V0Q2hhbm5lbHNdfX0pLGRsPWJhdGNoTWF0TXVsSW1wbCh7YTp0bD9jbDp1bCxiOnRsP3VsOmNsLHRyYW5zcG9zZUE6IXRsLHRyYW5zcG9zZUI6c2wsYmFja2VuZDpiYSxiaWFzOlNhLGFjdGl2YXRpb246RWEscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpUYSxsZWFreXJlbHVBbHBoYTp3YX0pO3JsPXJlc2hhcGUoe2lucHV0czp7eDpkbH0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6eGEub3V0U2hhcGV9fSksb2wucHVzaChjbCksb2wucHVzaCh1bCksb2wucHVzaChkbCl9Zm9yKGNvbnN0IGlsIG9mIG9sKWJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGlsKTtyZXR1cm4gcmx9ZnVuY3Rpb24gY29udjJkV2l0aEltMlJvdyh7eDpoYSxmaWx0ZXI6YWEsY29udkluZm86eGEsYmFja2VuZDpiYSxiaWFzOlNhPW51bGwscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpUYT1udWxsLGxlYWt5cmVsdUFscGhhOndhPTAsYWN0aXZhdGlvbjpFYT1udWxsfSl7Y29uc3R7ZmlsdGVyV2lkdGg6a2EsZmlsdGVySGVpZ2h0OkFhLGluQ2hhbm5lbHM6RmEsb3V0V2lkdGg6TGEsb3V0SGVpZ2h0OmVsLGRhdGFGb3JtYXQ6dGx9PXhhLG5sPXRsPT09ImNoYW5uZWxzTGFzdCIsc2w9a2EqQWEqRmEscmw9ZWwqTGEsb2w9W3hhLmJhdGNoU2l6ZSxzbCxybF0sYWw9ITAsbGw9ITEsaWw9W107aWYoVGEhPW51bGwpe2NvbnN0IENsPWdldFNoYXBlRm9yQmF0Y2hNYXRNdWwoVGEuc2hhcGUsbmwpO0NsIT1udWxsJiYoVGE9cmVzaGFwZSh7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpDbH19KSxpbC5wdXNoKFRhKSl9aWYoU2EhPW51bGwpe2NvbnN0IENsPWdldFNoYXBlRm9yQmF0Y2hNYXRNdWwoU2Euc2hhcGUsbmwpO0NsIT1udWxsJiYoU2E9cmVzaGFwZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpDbH19KSxpbC5wdXNoKFNhKSl9Y29uc3QgY2w9cmVzaGFwZSh7aW5wdXRzOnt4OmFhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpbMSxzbCxzaXplRnJvbVNoYXBlKGFhLnNoYXBlKS9zbF19fSk7aWwucHVzaChjbCk7Y29uc3QgdWw9bmV3IEltMkNvbFBhY2tlZFByb2dyYW0ob2wseGEpLGRsPVtoYS5zaGFwZSxbeGEucGFkSW5mby50b3AseGEucGFkSW5mby5sZWZ0XSxbeGEuc3RyaWRlSGVpZ2h0LHhhLnN0cmlkZVdpZHRoXSxbeGEuZGlsYXRpb25IZWlnaHQseGEuZGlsYXRpb25XaWR0aF0sW3hhLmluQ2hhbm5lbHNdLFt4YS5maWx0ZXJXaWR0aCp4YS5pbkNoYW5uZWxzXSxbeGEub3V0V2lkdGhdXSxobD1iYS5ydW5XZWJHTFByb2dyYW0odWwsW2hhXSwiZmxvYXQzMiIsZGwpLHBsPXJlc2hhcGUoe2lucHV0czp7eDpobH0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6b2x9fSk7aWwucHVzaChobCksaWwucHVzaChwbCk7Y29uc3QgZmw9U2EhPW51bGwsbWw9VGEhPW51bGwsZ2w9RWE9PT0ibGVha3lyZWx1IiwkbD1FYT9tYXBBY3RpdmF0aW9uVG9TaGFkZXJQcm9ncmFtKEVhLCEwKTpudWxsLHhsPW5ldyBNYXRNdWxQYWNrZWRQcm9ncmFtKG5sP3BsLnNoYXBlOmNsLnNoYXBlLG5sP2NsLnNoYXBlOnBsLnNoYXBlLG5sP1t4YS5iYXRjaFNpemUscmwseGEub3V0Q2hhbm5lbHNdOlt4YS5iYXRjaFNpemUseGEub3V0Q2hhbm5lbHMscmxdLGFsLGxsLGZsLCRsLG1sLGdsKSx5bD1ubD9bcGwsY2xdOltjbCxwbF07aWYoU2EmJnlsLnB1c2goU2EpLG1sJiZ5bC5wdXNoKFRhKSxnbCl7Y29uc3QgQ2w9YmEubWFrZVRlbnNvckluZm8oW10sImZsb2F0MzIiLGNyZWF0ZVNjYWxhclZhbHVlKHdhLCJmbG9hdDMyIikpO3lsLnB1c2goQ2wpLGlsLnB1c2goQ2wpfWNvbnN0IGJsPWJhLnJ1bldlYkdMUHJvZ3JhbSh4bCx5bCwiZmxvYXQzMiIpLFNsPXJlc2hhcGUoe2lucHV0czp7eDpibH0sYmFja2VuZDpiYSxhdHRyczp7c2hhcGU6eGEub3V0U2hhcGV9fSk7aWwucHVzaChibCk7Zm9yKGNvbnN0IENsIG9mIGlsKWJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKENsKTtyZXR1cm4gU2x9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjJkKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGF0YUZvcm1hdDprYSxkaWxhdGlvbnM6QWEsZGltUm91bmRpbmdNb2RlOkZhfT1iYSxMYT1jb252ZXJ0Q29udjJERGF0YUZvcm1hdChrYSksZWw9Y29tcHV0ZUNvbnYyREluZm8oU2Euc2hhcGUsVGEuc2hhcGUsd2EsQWEsRWEsRmEsITEsTGEpO2xldCB0bDtpZihlbC5maWx0ZXJIZWlnaHQ9PT0xJiZlbC5maWx0ZXJXaWR0aD09PTEmJmVsLmRpbGF0aW9uSGVpZ2h0PT09MSYmZWwuZGlsYXRpb25XaWR0aD09PTEmJmVsLnN0cmlkZUhlaWdodD09PTEmJmVsLnN0cmlkZVdpZHRoPT09MSYmKGVsLnBhZEluZm8udHlwZT09PSJTQU1FInx8ZWwucGFkSW5mby50eXBlPT09IlZBTElEIikpdGw9Y29udjJkQnlNYXRNdWwoe3g6U2EsZmlsdGVyOlRhLGNvbnZJbmZvOmVsLGJhY2tlbmQ6eGF9KTtlbHNlIGlmKGVsLnN0cmlkZVdpZHRoPD0yJiZMYT09PSJjaGFubmVsc0xhc3QiJiZlbnYoKS5nZXRCb29sKCJXRUJHTF9FWFBfQ09OViIpKXtjb25zdCBzbD1uZXcgQ29udjJEUGFja2VkUHJvZ3JhbShlbCkscmw9W1tlbC5wYWRJbmZvLnRvcCxlbC5wYWRJbmZvLmxlZnRdLFtlbC5zdHJpZGVIZWlnaHQsZWwuc3RyaWRlV2lkdGhdLFtlbC5kaWxhdGlvbkhlaWdodCxlbC5kaWxhdGlvbldpZHRoXSxbZWwuaW5IZWlnaHQsZWwuaW5XaWR0aF1dO3RsPXhhLnJ1bldlYkdMUHJvZ3JhbShzbCxbU2EsVGFdLCJmbG9hdDMyIixybCl9ZWxzZSBpZihlbnYoKS5nZXRCb29sKCJXRUJHTF9DT05WX0lNMkNPTCIpKXRsPWNvbnYyZFdpdGhJbTJSb3coe3g6U2EsZmlsdGVyOlRhLGNvbnZJbmZvOmVsLGJhY2tlbmQ6eGF9KTtlbHNle2NvbnN0IHNsPW5ldyBDb252MkRQcm9ncmFtKGVsKTt0bD14YS5ydW5XZWJHTFByb2dyYW0oc2wsW1NhLFRhXSwiZmxvYXQzMiIpfWNvbnN0IG5sPXJlc2hhcGUoe2lucHV0czp7eDp0bH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6ZWwub3V0U2hhcGV9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSxubH1jb25zdCBjb252MkRDb25maWc9e2tlcm5lbE5hbWU6Q29udjJELGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpjb252MmR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIENvbnYyRERlckZpbHRlclByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJkeSJdLHRoaXMub3V0cHV0U2hhcGU9YWEuZmlsdGVyU2hhcGU7Y29uc3QgeGE9YWEuc3RyaWRlSGVpZ2h0LGJhPWFhLnN0cmlkZVdpZHRoLFNhPWFhLnBhZEluZm8udG9wLFRhPWFhLnBhZEluZm8ubGVmdCx3YT1hYS5kYXRhRm9ybWF0PT09ImNoYW5uZWxzTGFzdCI7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgd1IgPSBjb29yZHMueDsKICAgICAgICBpbnQgd0MgPSBjb29yZHMueTsKICAgICAgICBpbnQgZDEgPSBjb29yZHMuejsKICAgICAgICBpbnQgZDIgPSBjb29yZHMudzsKCiAgICAgICAgLy8gQ29udm9sdmUgeCg/LCA/LCBkMSkgd2l0aCBkeSg6LCA6LCBkMikgdG8gZ2V0IGR3KHdSLCB3QywgZDEsIGQyKS4KICAgICAgICAvLyA/ID0gdG8gYmUgZGV0ZXJtaW5lZC4gOiA9IGFjcm9zcyBhbGwgdmFsdWVzIGluIHRoYXQgYXhpcy4KICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwoKICAgICAgICBmb3IgKGludCBiID0gMDsgYiA8ICR7YWEuYmF0Y2hTaXplfTsgYisrKSB7CiAgICAgICAgICBmb3IgKGludCB5UiA9IDA7IHlSIDwgJHthYS5vdXRIZWlnaHR9OyB5UisrKSB7CiAgICAgICAgICAgIGludCB4UiA9IHdSICsgeVIgKiAke3hhfSAtICR7U2F9OwoKICAgICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB5QyA9IDA7IHlDIDwgJHthYS5vdXRXaWR0aH07IHlDKyspIHsKICAgICAgICAgICAgICBpbnQgeEMgPSB3QyArIHlDICogJHtiYX0gLSAke1RhfTsKCiAgICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICR7d2E/YGZsb2F0IGR5VmFsdWUgPSBnZXREeShiLCB5UiwgeUMsIGQyKTsKICAgICAgICAgICAgICBmbG9hdCB4VmFsdWUgPSBnZXRYKGIsIHhSLCB4QywgZDEpOwogICAgICAgICAgICAgIGRvdFByb2QgKz0gKHhWYWx1ZSAqIGR5VmFsdWUpO2A6YGZsb2F0IGR5VmFsdWUgPSBnZXREeShiLCBkMiwgeVIsIHlDKTsKICAgICAgICAgICAgICBmbG9hdCB4VmFsdWUgPSBnZXRYKGIsIGQxLCB4UiwgeEMpOwogICAgICAgICAgICAgIGRvdFByb2QgKz0gKHhWYWx1ZSAqIGR5VmFsdWUpO2B9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX1jbGFzcyBDb252MkREZXJJbnB1dFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5IiwiVyJdLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZTtjb25zdCB4YT1hYS5maWx0ZXJIZWlnaHQsYmE9YWEuZmlsdGVyV2lkdGgsU2E9YWEuc3RyaWRlSGVpZ2h0LFRhPWFhLnN0cmlkZVdpZHRoLHdhPWFhLmRhdGFGb3JtYXQ9PT0iY2hhbm5lbHNMYXN0IixFYT14YS0xLWFhLnBhZEluZm8udG9wLGthPWJhLTEtYWEucGFkSW5mby5sZWZ0LEFhPXdhPzE6MixGYT13YT8yOjMsTGE9d2E/MzoxO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHtFYX0sICR7a2F9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQxID0gY29vcmRzWyR7TGF9XTsKCiAgICAgICAgaXZlYzIgZHlDb3JuZXIgPSBpdmVjMihjb29yZHNbJHtBYX1dLCBjb29yZHNbJHtGYX1dKSAtIHBhZHM7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5Q29ybmVyLng7CiAgICAgICAgaW50IGR5Q0Nvcm5lciA9IGR5Q29ybmVyLnk7CgogICAgICAgIC8vIENvbnZvbHZlIGR5KD8sID8sIGQyKSB3aXRoIHcoOiwgOiwgZDEsIGQyKSB0byBjb21wdXRlIGR4KHhSLCB4QywgZDEpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7eGF9OyB3UisrKSB7CiAgICAgICAgICBmbG9hdCBkeVIgPSBmbG9hdChkeVJDb3JuZXIgKyB3UikgLyAke1NhfS4wOwoKICAgICAgICAgIGlmIChkeVIgPCAwLjAgfHwgZHlSID49ICR7YWEub3V0SGVpZ2h0fS4wIHx8IGZyYWN0KGR5UikgPiAwLjApIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CiAgICAgICAgICBpbnQgaWR5UiA9IGludChkeVIpOwoKICAgICAgICAgIGludCB3UlBlcm0gPSAke3hhfSAtIDEgLSB3UjsKCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtiYX07IHdDKyspIHsKICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gJHtUYX0uMDsKCiAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7YWEub3V0V2lkdGh9LjAgfHwKICAgICAgICAgICAgICAgIGZyYWN0KGR5QykgPiAwLjApIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWR5QyA9IGludChkeUMpOwoKICAgICAgICAgICAgaW50IHdDUGVybSA9ICR7YmF9IC0gMSAtIHdDOwoKICAgICAgICAgICAgZm9yIChpbnQgZDIgPSAwOyBkMiA8ICR7YWEub3V0Q2hhbm5lbHN9OyBkMisrKSB7CgogICAgICAgICAgICAgIGlmICgke3dhfSkgewogICAgICAgICAgICAgICAgZmxvYXQgeFZhbHVlID0gZ2V0RHkoYmF0Y2gsIGlkeVIsIGlkeUMsIGQyKTsKICAgICAgICAgICAgICAgIGZsb2F0IHdWYWx1ZSA9IGdldFcod1JQZXJtLCB3Q1Blcm0sIGQxLCBkMik7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IHhWYWx1ZSAqIHdWYWx1ZTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZmxvYXQgeFZhbHVlID0gZ2V0RHkoYmF0Y2gsIGQyLCBpZHlSLCBpZHlDKTsKICAgICAgICAgICAgICAgIGZsb2F0IHdWYWx1ZSA9IGdldFcod1JQZXJtLCB3Q1Blcm0sIGQxLCBkMik7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IHhWYWx1ZSAqIHdWYWx1ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19Y2xhc3MgQ29udjNERGVyRmlsdGVyUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsImR5Il0sdGhpcy5vdXRwdXRTaGFwZT1hYS5maWx0ZXJTaGFwZTtjb25zdCB4YT1hYS5zdHJpZGVEZXB0aCxiYT1hYS5zdHJpZGVIZWlnaHQsU2E9YWEuc3RyaWRlV2lkdGgsVGE9YWEucGFkSW5mby5mcm9udCx3YT1hYS5wYWRJbmZvLnRvcCxFYT1hYS5wYWRJbmZvLmxlZnQ7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgd0YgPSBjb29yZHMueDsKICAgICAgICBpbnQgd1IgPSBjb29yZHMueTsKICAgICAgICBpbnQgd0MgPSBjb29yZHMuejsKICAgICAgICBpbnQgZDEgPSBjb29yZHMudzsKICAgICAgICBpbnQgZDIgPSBjb29yZHMudTsKCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCAke2FhLmJhdGNoU2l6ZX07IGIrKykgewogICAgICAgICAgZm9yIChpbnQgeUYgPSAwOyB5RiA8ICR7YWEub3V0RGVwdGh9OyB5RisrKSB7CiAgICAgICAgICAgIGludCB4RiA9IHdGICsgeUYgKiAke3hhfSAtICR7VGF9OwoKICAgICAgICAgICAgaWYgKHhGIDwgMCB8fCB4RiA+PSAke2FhLmluRGVwdGh9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaW50IHlSID0gMDsgeVIgPCAke2FhLm91dEhlaWdodH07IHlSKyspIHsKICAgICAgICAgICAgICBpbnQgeFIgPSB3UiArIHlSICogJHtiYX0gLSAke3dhfTsKCiAgICAgICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBmb3IgKGludCB5QyA9IDA7IHlDIDwgJHthYS5vdXRXaWR0aH07IHlDKyspIHsKICAgICAgICAgICAgICAgIGludCB4QyA9IHdDICsgeUMgKiAke1NhfSAtICR7RWF9OwoKICAgICAgICAgICAgICAgIGlmICh4QyA8IDAgfHwgeEMgPj0gJHthYS5pbldpZHRofSkgewogICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmbG9hdCBkeVZhbHVlID0gZ2V0RHkoYiwgeUYsIHlSLCB5QywgZDIpOwogICAgICAgICAgICAgICAgZmxvYXQgeFZhbHVlID0gZ2V0WChiLCB4RiwgeFIsIHhDLCBkMSk7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9ICh4VmFsdWUgKiBkeVZhbHVlKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX1jbGFzcyBDb252M0REZXJJbnB1dFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5IiwiVyJdLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZTtjb25zdCB4YT1hYS5maWx0ZXJEZXB0aCxiYT1hYS5maWx0ZXJIZWlnaHQsU2E9YWEuZmlsdGVyV2lkdGgsVGE9YWEuc3RyaWRlRGVwdGgsd2E9YWEuc3RyaWRlSGVpZ2h0LEVhPWFhLnN0cmlkZVdpZHRoLGthPXhhLTEtYWEucGFkSW5mby5mcm9udCxBYT1iYS0xLWFhLnBhZEluZm8udG9wLEZhPVNhLTEtYWEucGFkSW5mby5sZWZ0O3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMyBwYWRzID0gaXZlYzMoJHtrYX0sICR7QWF9LCAke0ZhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzUgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaW50IGQxID0gY29vcmRzLnU7CgoKICAgICAgICBpdmVjMyBkeUNvcm5lciA9IGl2ZWMzKGNvb3Jkcy55LCBjb29yZHMueiwgY29vcmRzLncpIC0gcGFkczsKICAgICAgICBpbnQgZHlGQ29ybmVyID0gZHlDb3JuZXIueDsKICAgICAgICBpbnQgZHlSQ29ybmVyID0gZHlDb3JuZXIueTsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlDb3JuZXIuejsKCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKICAgICAgICBmb3IgKGludCB3RiA9IDA7IHdGIDwgJHt4YX07IHdGKyspIHsKICAgICAgICAgIGZsb2F0IGR5RiA9IGZsb2F0KGR5RkNvcm5lciArIHdGKSAvICR7VGF9LjA7CgogICAgICAgICAgaWYgKGR5RiA8IDAuMCB8fCBkeUYgPj0gJHthYS5vdXREZXB0aH0uMCB8fCBmcmFjdChkeUYpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeUYgPSBpbnQoZHlGKTsKCiAgICAgICAgICBpbnQgd0ZQZXJtID0gJHt4YX0gLSAxIC0gd0Y7CgogICAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7YmF9OyB3UisrKSB7CiAgICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvICR7d2F9LjA7CgogICAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fAogICAgICAgICAgICAgIGZyYWN0KGR5UikgPiAwLjApIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWR5UiA9IGludChkeVIpOwoKICAgICAgICAgICAgaW50IHdSUGVybSA9ICR7YmF9IC0gMSAtIHdSOwoKICAgICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7U2F9OyB3QysrKSB7CiAgICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gJHtFYX0uMDsKCiAgICAgICAgICAgICAgaWYgKGR5QyA8IDAuMCB8fCBkeUMgPj0gJHthYS5vdXRXaWR0aH0uMCB8fAogICAgICAgICAgICAgICAgICBmcmFjdChkeUMpID4gMC4wKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaW50IGlkeUMgPSBpbnQoZHlDKTsKCiAgICAgICAgICAgICAgaW50IHdDUGVybSA9ICR7U2F9IC0gMSAtIHdDOwoKICAgICAgICAgICAgICBmb3IgKGludCBkMiA9IDA7IGQyIDwgJHthYS5vdXRDaGFubmVsc307IGQyKyspIHsKICAgICAgICAgICAgICAgIGZsb2F0IHhWYWx1ZSA9IGdldER5KGJhdGNoLCBpZHlGLCBpZHlSLCBpZHlDLCBkMik7CiAgICAgICAgICAgICAgICBmbG9hdCB3VmFsdWUgPSBnZXRXKHdGUGVybSwgd1JQZXJtLCB3Q1Blcm0sIGQxLCBkMik7CiAgICAgICAgICAgICAgICBkb3RQcm9kICs9IHhWYWx1ZSAqIHdWYWx1ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252MkRCYWNrcHJvcEZpbHRlcihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGF0YUZvcm1hdDprYSxkaW1Sb3VuZGluZ01vZGU6QWEsZmlsdGVyU2hhcGU6RmF9PWJhLExhPWNvbnZlcnRDb252MkREYXRhRm9ybWF0KGthKSxlbD1jb21wdXRlQ29udjJESW5mbyhTYS5zaGFwZSxGYSx3YSwxLEVhLEFhLCExLExhKSx0bD1uZXcgQ29udjJERGVyRmlsdGVyUHJvZ3JhbShlbCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbSh0bCxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgY29udjJEQmFja3Byb3BGaWx0ZXJDb25maWc9e2tlcm5lbE5hbWU6Q29udjJEQmFja3Byb3BGaWx0ZXIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbnYyREJhY2twcm9wRmlsdGVyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBDb252MkREZXJJbnB1dFBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5IiwiVyJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJzdHJpZGVzIix0eXBlOiJ2ZWMyIn1dLHRoaXMub3V0cHV0U2hhcGU9YWEuaW5TaGFwZSx0aGlzLmVuYWJsZVNoYXBlVW5pZm9ybXM9dXNlU2hhcGVVbmlmb3Jtcyh0aGlzLm91dHB1dFNoYXBlLmxlbmd0aCk7Y29uc3QgeGE9YWEuZmlsdGVySGVpZ2h0LGJhPWFhLmZpbHRlcldpZHRoLFNhPXhhLTEtYWEucGFkSW5mby50b3AsVGE9YmEtMS1hYS5wYWRJbmZvLmxlZnQ7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke1NhfSwgJHtUYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZDEgPSBjb29yZHNbM107CgogICAgICAgIGl2ZWMyIGR5Q29ybmVyID0gaXZlYzIoY29vcmRzWzFdLCBjb29yZHNbMl0pIC0gcGFkczsKICAgICAgICBpbnQgZHlSQ29ybmVyID0gZHlDb3JuZXIueDsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlDb3JuZXIueTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHt4YX07IHdSKyspIHsKICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvIHN0cmlkZXNbMF07CiAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2FhLm91dEhlaWdodH0uMCB8fCBmcmFjdChkeVIpID4gMC4wKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGlkeVIgPSBpbnQoZHlSKTsKICAgICAgICAgIGludCB3UlBlcm0gPSAke3hhfSAtIDEgLSB3UjsKCiAgICAgICAgICBmb3IgKGludCB3QyA9IDA7IHdDIDwgJHtiYX07IHdDKyspIHsKICAgICAgICAgICAgaW50IHdDUGVybSA9ICR7YmF9IC0gMSAtIHdDOwoKICAgICAgICAgICAgZmxvYXQgZHlDID0gZmxvYXQoZHlDQ29ybmVyICsgd0MpIC8gc3RyaWRlc1sxXTsKICAgICAgICAgICAgYm9vbCBpZHlDVmFsID0gKGR5QyA+PSAwLjApICYmIChkeUMgPCAke2FhLm91dFdpZHRofS4wKQogICAgICAgICAgICAgICYmIChmcmFjdChkeUMpID09IDAuMCk7CiAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICBmbG9hdCBkeUMyID0gZmxvYXQoZHlDQ29ybmVyICsgd0MgKyAxKSAvIHN0cmlkZXNbMV07CiAgICAgICAgICAgIGJvb2wgaWR5Q1ZhbDIgPSAoZHlDMiA+PSAwLjApICYmIChkeUMyIDwgJHthYS5vdXRXaWR0aH0uMCkKICAgICAgICAgICAgICAmJiAoZnJhY3QoZHlDMikgPT0gMC4wKTsKICAgICAgICAgICAgaW50IGlkeUMyID0gaW50KGR5QzIpOwoKICAgICAgICAgICAgaWYgKGlkeUNWYWwgJiYgaWR5Q1ZhbDIpIHsKICAgICAgICAgICAgICBmb3IgKGludCBkMiA9IDA7IGQyIDwgJHthYS5vdXRDaGFubmVsc307IGQyICs9IDIpIHsKICAgICAgICAgICAgICAgIHZlYzQgd1ZhbHVlID0gZ2V0Vyh3UlBlcm0sIHdDUGVybSwgZDEsIGQyKTsKICAgICAgICAgICAgICAgIHZlYzQgZHlTYW1wbGUgPSBnZXREeShiYXRjaCwgaWR5UiwgaWR5QywgZDIpOwogICAgICAgICAgICAgICAgdmVjNCBkeVNhbXBsZTIgPSAoaWR5QyAvIDIgPT0gaWR5QzIgLyAyKSA/CiAgICAgICAgICAgICAgICAgIGR5U2FtcGxlIDogZ2V0RHkoYmF0Y2gsIGlkeVIsIGlkeUMyLCBkMik7CgogICAgICAgICAgICAgICAgdmVjMiBkeVZhbHVlID0gbW9kKGZsb2F0KGlkeUMpLCAyLikgPT0gMC4gPwogICAgICAgICAgICAgICAgICBkeVNhbXBsZS54eSA6IGR5U2FtcGxlLnp3OwogICAgICAgICAgICAgICAgcmVzdWx0Lnh5ICs9IHZlYzIoZG90KGR5VmFsdWUsIHdWYWx1ZS54eSksCiAgICAgICAgICAgICAgICAgIGRvdChkeVZhbHVlLCB3VmFsdWUuencpKTsKCiAgICAgICAgICAgICAgICBkeVZhbHVlID0gbW9kKGZsb2F0KGlkeUMyKSwgMi4pID09IDAuID8KICAgICAgICAgICAgICAgICAgZHlTYW1wbGUyLnh5IDogZHlTYW1wbGUyLnp3OwogICAgICAgICAgICAgICAgcmVzdWx0Lnp3ICs9IHZlYzIoZG90KGR5VmFsdWUsIHdWYWx1ZS54eSksCiAgICAgICAgICAgICAgICAgIGRvdChkeVZhbHVlLCB3VmFsdWUuencpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaWR5Q1ZhbCkgewogICAgICAgICAgICAgIGZvciAoaW50IGQyID0gMDsgZDIgPCAke2FhLm91dENoYW5uZWxzfTsgZDIgKz0gMikgewogICAgICAgICAgICAgICAgdmVjNCB3VmFsdWUgPSBnZXRXKHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgdmVjNCBkeVNhbXBsZSA9IGdldER5KGJhdGNoLCBpZHlSLCBpZHlDLCBkMik7CiAgICAgICAgICAgICAgICB2ZWMyIGR5VmFsdWUgPSBtb2QoZmxvYXQoaWR5QyksIDIuKSA9PSAwLiA/CiAgICAgICAgICAgICAgICAgIGR5U2FtcGxlLnh5IDogZHlTYW1wbGUuenc7CiAgICAgICAgICAgICAgICByZXN1bHQueHkgKz0gdmVjMihkb3QoZHlWYWx1ZSwgd1ZhbHVlLnh5KSwKICAgICAgICAgICAgICAgICAgZG90KGR5VmFsdWUsIHdWYWx1ZS56dykpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChpZHlDVmFsMikgewogICAgICAgICAgICAgIGZvciAoaW50IGQyID0gMDsgZDIgPCAke2FhLm91dENoYW5uZWxzfTsgZDIgKz0gMikgewogICAgICAgICAgICAgICAgdmVjNCB3VmFsdWUgPSBnZXRXKHdSUGVybSwgd0NQZXJtLCBkMSwgZDIpOwogICAgICAgICAgICAgICAgdmVjNCBkeVNhbXBsZSA9IGdldER5KGJhdGNoLCBpZHlSLCBpZHlDMiwgZDIpOwogICAgICAgICAgICAgICAgdmVjMiBkeVZhbHVlID0gbW9kKGZsb2F0KGlkeUMyKSwgMi4pID09IDAuID8KICAgICAgICAgICAgICAgICAgZHlTYW1wbGUueHkgOiBkeVNhbXBsZS56dzsKICAgICAgICAgICAgICAgIHJlc3VsdC56dyArPSB2ZWMyKGRvdChkeVZhbHVlLCB3VmFsdWUueHkpLAogICAgICAgICAgICAgICAgICBkb3QoZHlWYWx1ZSwgd1ZhbHVlLnp3KSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjb252MkRCYWNrcHJvcElucHV0KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2R5OlNhLGZpbHRlcjpUYX09YWEse2lucHV0U2hhcGU6d2Esc3RyaWRlczpFYSxwYWQ6a2EsZGF0YUZvcm1hdDpBYSxkaW1Sb3VuZGluZ01vZGU6RmF9PWJhLExhPWNvbnZlcnRDb252MkREYXRhRm9ybWF0KEFhKSxlbD1jb21wdXRlQ29udjJESW5mbyh3YSxUYS5zaGFwZSxFYSwxLGthLEZhLCExLExhKTtpZihlbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0NPTlYyRFRSQU5TUE9TRSIpJiZMYT09PSJjaGFubmVsc0xhc3QiKXtjb25zdCB0bD1bW2VsLnN0cmlkZUhlaWdodCxlbC5zdHJpZGVXaWR0aF1dLG5sPW5ldyBDb252MkREZXJJbnB1dFBhY2tlZFByb2dyYW0oZWwpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0obmwsW1NhLFRhXSwiZmxvYXQzMiIsdGwpfWVsc2V7Y29uc3QgdGw9bmV3IENvbnYyRERlcklucHV0UHJvZ3JhbShlbCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbSh0bCxbU2EsVGFdLCJmbG9hdDMyIil9fWNvbnN0IGNvbnYyREJhY2twcm9wSW5wdXRDb25maWc9e2tlcm5lbE5hbWU6Q29udjJEQmFja3Byb3BJbnB1dCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Y29udjJEQmFja3Byb3BJbnB1dH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjNEKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZGlsYXRpb25zOmthfT1iYSxBYT1jb21wdXRlQ29udjNESW5mbyhTYS5zaGFwZSxUYS5zaGFwZSx3YSxrYSxFYSksRmE9bmV3IENvbnYzRFByb2dyYW0oQWEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRmEsW1NhLFRhXSwiZmxvYXQzMiIpfWNvbnN0IGNvbnYzRENvbmZpZz17a2VybmVsTmFtZTpDb252M0QsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbnYzRH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY29udjNEQmFja3Byb3BGaWx0ZXJWMihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxwYWQ6RWEsZmlsdGVyU2hhcGU6a2F9PWJhLEFhPWNvbXB1dGVDb252M0RJbmZvKFNhLnNoYXBlLGthLHdhLDEsRWEpLEZhPW5ldyBDb252M0REZXJGaWx0ZXJQcm9ncmFtKEFhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEZhLFtTYSxUYV0sImZsb2F0MzIiKX1jb25zdCBjb252M0RCYWNrcHJvcEZpbHRlclYyQ29uZmlnPXtrZXJuZWxOYW1lOkNvbnYzREJhY2twcm9wRmlsdGVyVjIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbnYzREJhY2twcm9wRmlsdGVyVjJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGNvbnYzREJhY2twcm9wSW5wdXQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsZmlsdGVyOlRhfT1hYSx7cGFkOndhLHN0cmlkZXM6RWEsaW5wdXRTaGFwZTprYX09YmEsQWE9Y29tcHV0ZUNvbnYzREluZm8oa2EsVGEuc2hhcGUsRWEsMSx3YSksRmE9bmV3IENvbnYzRERlcklucHV0UHJvZ3JhbShBYSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShGYSxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgY29udjNEQmFja3Byb3BJbnB1dENvbmZpZz17a2VybmVsTmFtZTpDb252M0RCYWNrcHJvcElucHV0VjIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvbnYzREJhY2twcm9wSW5wdXR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IENPUz1DSEVDS19OQU5fU05JUFBFVF9VTkFSWStgCiAgcmV0dXJuIGNvcyh4KTsKYCxDT1NfUEFDS0VEPWAKICB2ZWM0IHJlc3VsdCA9IGNvcyh4KTsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwogICR7Q0hFQ0tfTkFOX1NOSVBQRVRfUEFDS0VEfQogIHJldHVybiByZXN1bHQ7CmAsY29zPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkNPUyxwYWNrZWRPcFNuaXBwZXQ6Q09TX1BBQ0tFRH0pLGNvc0NvbmZpZz17a2VybmVsTmFtZTpDb3MsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNvc307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgQ09TSD1gCiAgZmxvYXQgZTJ4ID0gZXhwKC14KTsKICByZXR1cm4gKGUyeCArIDEuMCAvIGUyeCkgLyAyLjA7CmAsY29zaD11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpDT1NIfSksY29zaENvbmZpZz17a2VybmVsTmFtZTpDb3NoLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpjb3NofTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBDcm9wQW5kUmVzaXplUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiSW1hZ2UiLCJCb3hlcyIsIkJveEluZCJdLHRoaXMub3V0cHV0U2hhcGU9W107Y29uc3Rbd2EsRWEsa2EsQWFdPWFhLFtGYV09eGEsW0xhLGVsXT1iYTt0aGlzLm91dHB1dFNoYXBlPVtGYSxMYSxlbCxBYV07Y29uc3QgdGw9U2E9PT0iYmlsaW5lYXIiPzE6MCxbbmwsc2xdPVtgJHtFYS0xfS4wYCxgJHtrYS0xfS4wYF0sW3JsLG9sLGFsXT1MYT4xP1tgJHsoRWEtMSkvKExhLTEpfWAsIih5Mi15MSkgKiBoZWlnaHRfcmF0aW8iLGB5MSoke25sfSArIGZsb2F0KHkpKihoZWlnaHRfc2NhbGUpYF06WyIwLjAiLCIwLjAiLGAwLjUgKiAoeTEreTIpICogJHtubH1gXSxbbGwsaWwsY2xdPWVsPjE/W2AkeyhrYS0xKS8oZWwtMSl9YCwiKHgyLXgxKSAqIHdpZHRoX3JhdGlvIixgeDEqJHtzbH0gKyBmbG9hdCh4KSood2lkdGhfc2NhbGUpYF06WyIwLjAiLCIwLjAiLGAwLjUgKiAoeDEreDIpICogJHtzbH1gXTt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgZmxvYXQgaGVpZ2h0X3JhdGlvID0gZmxvYXQoJHtybH0pOwogICAgICBjb25zdCBmbG9hdCB3aWR0aF9yYXRpbyA9IGZsb2F0KCR7bGx9KTsKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCB5ID0gY29vcmRzWzFdOwogICAgICAgIGludCB4ID0gY29vcmRzWzJdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwoKICAgICAgICAvLyBnZXQgYm94IHZhbHMKICAgICAgICBmbG9hdCB5MSA9IGdldEJveGVzKGIsMCk7CiAgICAgICAgZmxvYXQgeDEgPSBnZXRCb3hlcyhiLDEpOwogICAgICAgIGZsb2F0IHkyID0gZ2V0Qm94ZXMoYiwyKTsKICAgICAgICBmbG9hdCB4MiA9IGdldEJveGVzKGIsMyk7CgogICAgICAgIC8vIGdldCBpbWFnZSBpbiBiYXRjaCBpbmRleAogICAgICAgIGludCBiSW5kID0gcm91bmQoZ2V0Qm94SW5kKGIpKTsKICAgICAgICBpZihiSW5kIDwgMCB8fCBiSW5kID49ICR7d2F9KSB7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmbG9hdCBoZWlnaHRfc2NhbGUgPSAke29sfTsKICAgICAgICBmbG9hdCB3aWR0aF9zY2FsZSA9ICR7aWx9OwoKICAgICAgICBmbG9hdCBpbl95ID0gJHthbH07CiAgICAgICAgaWYoIGluX3kgPCAwLjAgfHwgaW5feSA+ICR7bmx9ICkgewogICAgICAgICAgc2V0T3V0cHV0KGZsb2F0KCR7VGF9KSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGZsb2F0IGluX3ggPSAke2NsfTsKICAgICAgICBpZiggaW5feCA8IDAuMCB8fCBpbl94ID4gJHtzbH0gKSB7CiAgICAgICAgICBzZXRPdXRwdXQoZmxvYXQoJHtUYX0pKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHZlYzIgc291cmNlRnJhY0luZGV4Q1IgPSB2ZWMyKGluX3gsaW5feSk7CiAgICAgICAgaWYoJHt0bH0gPT0gMSkgewogICAgICAgICAgLy8gQ29tcHV0ZSB0aGUgZm91ciBpbnRlZ2VyIGluZGljZXMuCiAgICAgICAgICBpdmVjMiBzb3VyY2VGbG9vckNSID0gaXZlYzIoc291cmNlRnJhY0luZGV4Q1IpOwogICAgICAgICAgaXZlYzIgc291cmNlQ2VpbENSID0gaXZlYzIoY2VpbChzb3VyY2VGcmFjSW5kZXhDUikpOwoKICAgICAgICAgIGZsb2F0IHRvcExlZnQgPSBnZXRJbWFnZShiLCBzb3VyY2VGbG9vckNSLnksIHNvdXJjZUZsb29yQ1IueCwgZCk7CiAgICAgICAgICBmbG9hdCBib3R0b21MZWZ0ID0gZ2V0SW1hZ2UoYiwgc291cmNlQ2VpbENSLnksIHNvdXJjZUZsb29yQ1IueCwgZCk7CiAgICAgICAgICBmbG9hdCB0b3BSaWdodCA9IGdldEltYWdlKGIsIHNvdXJjZUZsb29yQ1IueSwgc291cmNlQ2VpbENSLngsIGQpOwogICAgICAgICAgZmxvYXQgYm90dG9tUmlnaHQgPSBnZXRJbWFnZShiLCBzb3VyY2VDZWlsQ1IueSwgc291cmNlQ2VpbENSLngsIGQpOwoKICAgICAgICAgIHZlYzIgZnJhY0NSID0gc291cmNlRnJhY0luZGV4Q1IgLSB2ZWMyKHNvdXJjZUZsb29yQ1IpOwoKICAgICAgICAgIGZsb2F0IHRvcCA9IHRvcExlZnQgKyAodG9wUmlnaHQgLSB0b3BMZWZ0KSAqIGZyYWNDUi54OwogICAgICAgICAgZmxvYXQgYm90dG9tID0gYm90dG9tTGVmdCArIChib3R0b21SaWdodCAtIGJvdHRvbUxlZnQpICogZnJhY0NSLng7CiAgICAgICAgICBmbG9hdCBuZXdWYWx1ZSA9IHRvcCArIChib3R0b20gLSB0b3ApICogZnJhY0NSLnk7CiAgICAgICAgICBzZXRPdXRwdXQobmV3VmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBDb21wdXRlIHRoZSBjb29yZGluYXRvcnMgb2YgbmVhcmVzdCBuZWlnaGJvciBwb2ludC4KICAgICAgICAgIGl2ZWMyIHNvdXJjZU5lYXJlc3RDUiA9IGl2ZWMyKGZsb29yKAogICAgICAgICAgICBzb3VyY2VGcmFjSW5kZXhDUiArIHZlYzIoMC41LDAuNSkpKTsKICAgICAgICAgIGZsb2F0IG5ld1ZhbHVlID0gZ2V0SW1hZ2UoYiwgc291cmNlTmVhcmVzdENSLnksIHNvdXJjZU5lYXJlc3RDUi54LCBkKTsKICAgICAgICAgIHNldE91dHB1dChuZXdWYWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBjcm9wQW5kUmVzaXplPWhhPT57Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtpbWFnZTpTYSxib3hlczpUYSxib3hJbmQ6d2F9PWFhLHtjcm9wU2l6ZTpFYSxtZXRob2Q6a2EsZXh0cmFwb2xhdGlvblZhbHVlOkFhfT1iYSxGYT1uZXcgQ3JvcEFuZFJlc2l6ZVByb2dyYW0oU2Euc2hhcGUsVGEuc2hhcGUsRWEsa2EsQWEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRmEsW1NhLFRhLHdhXSwiZmxvYXQzMiIpfSxjcm9wQW5kUmVzaXplQ29uZmlnPXtrZXJuZWxOYW1lOkNyb3BBbmRSZXNpemUsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmNyb3BBbmRSZXNpemV9O3ZhciBDdW1PcFR5cGU7KGZ1bmN0aW9uKGhhKXtoYS5Qcm9kPSIqIixoYS5TdW09IisifSkoQ3VtT3BUeXBlfHwoQ3VtT3BUeXBlPXt9KSk7Y2xhc3MgQ3VtUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSl7dGhpcy5vcD1hYSx0aGlzLm91dHB1dFNoYXBlPXhhLHRoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToiaW5kZXgiLHR5cGU6ImZsb2F0In1dO2NvbnN0IFRhPXRoaXMub3V0cHV0U2hhcGUubGVuZ3RoLHdhPXRoaXMub3A9PT1DdW1PcFR5cGUuUHJvZD8iMS4wIjoiMC4wIixFYT1iYT93YTpgZ2V0WCgke2dldENvb3JkcyhUYSwiY29vcmRzIix0aGlzLm9wKX0pYCxrYT10aGlzLm91dHB1dFNoYXBlW3RoaXMub3V0cHV0U2hhcGUubGVuZ3RoLTFdO2xldCBBYT0iIixGYT0iIjtiYT8oQWE9U2E/YGVuZCAhPSAke2thLTF9YDoiZW5kICE9IDAiLEZhPVNhPyJlbmQgKyAxIjoiZW5kIC0gMSIpOihBYT1TYT9gZW5kICsgcG93MiA8ICR7a2F9YDoiZW5kID49IHBvdzIiLEZhPVNhPyJlbmQgKyBwb3cyIjoiZW5kIC0gcG93MiIpLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtnZXRDb29yZHNEYXRhVHlwZShUYSl9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBlbmQgPSAke2dldEZpbmFsQ29vcmQoVGEsImNvb3JkcyIsdGhpcy5vcCl9OwogICAgICAgIGZsb2F0IHZhbCA9ICR7RWF9OwogICAgICAgIGludCBwb3cyID0gaW50KHBvdygyLjAsIGluZGV4KSk7CiAgICAgICAgaWYgKCR7QWF9KSB7CiAgICAgICAgICBpbnQgaWR4ID0gJHtGYX07CiAgICAgICAgICAke2dldEZpbmFsQ29vcmQoVGEsImNvb3JkcyIsdGhpcy5vcCl9ID0gaWR4OwogICAgICAgICAgdmFsICR7dGhpcy5vcH09IGdldFgoJHtnZXRDb29yZHMoVGEsImNvb3JkcyIsdGhpcy5vcCl9KTsKICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KHZhbCk7CiAgICAgIH0KICAgIGB9fWZ1bmN0aW9uIGdldENvb3JkcyhoYSxhYSx4YSl7aWYoaGE9PT0xKXJldHVybmAke2FhfWA7aWYoaGE9PT0yKXJldHVybmAke2FhfS54LCAke2FhfS55YDtpZihoYT09PTMpcmV0dXJuYCR7YWF9LngsICR7YWF9LnksICR7YWF9LnpgO2lmKGhhPT09NClyZXR1cm5gJHthYX0ueCwgJHthYX0ueSwgJHthYX0ueiwgJHthYX0ud2A7dGhyb3cgbmV3IEVycm9yKGBDdW11bGF0aXZlICR7eGF9IGZvciByYW5rICR7aGF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCl9ZnVuY3Rpb24gZ2V0RmluYWxDb29yZChoYSxhYSx4YSl7aWYoaGE9PT0xKXJldHVybmAke2FhfWA7aWYoaGE9PT0yKXJldHVybmAke2FhfS55YDtpZihoYT09PTMpcmV0dXJuYCR7YWF9LnpgO2lmKGhhPT09NClyZXR1cm5gJHthYX0ud2A7dGhyb3cgbmV3IEVycm9yKGBDdW11bGF0aXZlICR7eGF9IGZvciByYW5rICR7aGF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCl9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gY3VtSW1wbChoYSxhYSx4YSxiYSxTYSxUYSl7Y29uc3Qgd2E9YWEuc2hhcGUubGVuZ3RoLEVhPWdldEF4ZXNQZXJtdXRhdGlvbihbYmFdLHdhKTtsZXQga2E9YWE7RWEhPW51bGwmJihrYT10cmFuc3Bvc2Uoe2lucHV0czp7eDphYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpFYX19KSk7Y29uc3QgQWE9Z2V0SW5uZXJNb3N0QXhlcygxLHdhKVswXTtpZihBYSE9PXdhLTEpdGhyb3cgbmV3IEVycm9yKGBXZWJHTCBjdW1wcm9kIHNoYWRlciBleHBlY3RzIGFuIGlubmVyLW1vc3QgYXhpcz0ke2FhLnNoYXBlLmxlbmd0aC0xfSBidXQgZ290IGF4aXM9JHtiYX1gKTtjb25zdCBGYT1rYS5zaGFwZVtBYV07bGV0IExhPWlkZW50aXR5KHtpbnB1dHM6e3g6a2F9LGJhY2tlbmQ6eGF9KTtmb3IobGV0IGVsPTA7ZWw8PU1hdGguY2VpbChNYXRoLmxvZzIoRmEpKS0xO2VsKyspe2NvbnN0IHRsPW5ldyBDdW1Qcm9ncmFtKGhhLGthLnNoYXBlLCExLFRhKSxubD1bW2VsXV0sc2w9TGE7TGE9eGEucnVuV2ViR0xQcm9ncmFtKHRsLFtMYV0sTGEuZHR5cGUsbmwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKX1pZihTYSl7Y29uc3QgZWw9bmV3IEN1bVByb2dyYW0oaGEsa2Euc2hhcGUsU2EsVGEpLHRsPUxhO0xhPXhhLnJ1bldlYkdMUHJvZ3JhbShlbCxbTGFdLExhLmR0eXBlKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh0bCl9aWYoRWEhPW51bGwpe2NvbnN0IGVsPWdldFVuZG9BeGVzUGVybXV0YXRpb24oRWEpLHRsPXRyYW5zcG9zZSh7aW5wdXRzOnt4OkxhfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOmVsfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oa2EpLHRsfXJldHVybiBMYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjdW1wcm9kKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtheGlzOlRhLGV4Y2x1c2l2ZTp3YSxyZXZlcnNlOkVhfT1iYTtyZXR1cm4gY3VtSW1wbChDdW1PcFR5cGUuUHJvZCxTYSx4YSxUYSx3YSxFYSl9Y29uc3QgY3VtcHJvZENvbmZpZz17a2VybmVsTmFtZTpDdW1wcm9kLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpjdW1wcm9kfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBjdW1zdW0oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGEsZXhjbHVzaXZlOndhLHJldmVyc2U6RWF9PWJhO3JldHVybiBjdW1JbXBsKEN1bU9wVHlwZS5TdW0sU2EseGEsVGEsd2EsRWEpfWNvbnN0IGN1bXN1bUNvbmZpZz17a2VybmVsTmFtZTpDdW1zdW0sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmN1bXN1bX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZGVuc2VCaW5jb3VudChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLHdlaWdodHM6VGF9PWFhLHtzaXplOndhLGJpbmFyeU91dHB1dDpFYX09YmE7aWYoU2Euc2hhcGUubGVuZ3RoPT09MSl7Y29uc3Qga2E9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxBYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLEZhPWJpbmNvdW50SW1wbENQVShrYSxBYSxUYS5kdHlwZSxUYS5zaGFwZSx3YSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFt3YV0sVGEuZHR5cGUsRmEpfWVsc2UgaWYoU2Euc2hhcGUubGVuZ3RoPT09Mil7Y29uc3Qga2E9eGEuYnVmZmVyU3luYyhTYSksQWE9eGEuYnVmZmVyU3luYyhUYSksRmE9YmluY291bnRSZWR1Y2VJbXBsQ1BVKGthLEFhLHdhLEVhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRmEuc2hhcGUsVGEuZHR5cGUsRmEudmFsdWVzKX10aHJvdyBuZXcgRXJyb3IoYEVycm9yIGluIGRlbnNlQmluY291bnQ6IGlucHV0IG11c3QgYmUgYXQgbW9zdCByYW5rIDIsIGJ1dCBnb3QgcmFuayR7U2Euc2hhcGUubGVuZ3RofS5gKX1jb25zdCBkZW5zZUJpbmNvdW50Q29uZmlnPXtrZXJuZWxOYW1lOkRlbnNlQmluY291bnQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRlbnNlQmluY291bnR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIERlcHRoVG9TcGFjZVByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5ibG9ja1NpemU9eGEsdGhpcy5kYXRhRm9ybWF0PWJhLHRoaXMudXNlckNvZGU9YAogICAgdm9pZCBtYWluKCkgewogICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgIGludCBoID0gJHt0aGlzLmdldEhlaWdodENvb3JkU3RyaW5nKCl9OwogICAgICBpbnQgdyA9ICR7dGhpcy5nZXRXaWR0aENvb3JkU3RyaW5nKCl9OwogICAgICBpbnQgZCA9ICR7dGhpcy5nZXREZXB0aENvb3JkU3RyaW5nKCl9OwoKICAgICAgaW50IGluX2ggPSBoIC8gJHt4YX07CiAgICAgIGludCBvZmZzZXRfaCA9IGltb2QoaCwgJHt4YX0pOwogICAgICBpbnQgaW5fdyA9IHcgLyAke3hhfTsKICAgICAgaW50IG9mZnNldF93ID0gaW1vZCh3LCAke3hhfSk7CiAgICAgIGludCBvZmZzZXRfZCA9IChvZmZzZXRfaCAqICR7eGF9ICsgb2Zmc2V0X3cpICoKICAgICAgICAke3RoaXMuZ2V0T3V0cHV0RGVwdGhTaXplKCl9OwogICAgICBpbnQgaW5fZCA9IGQgKyBvZmZzZXRfZDsKCiAgICAgIGZsb2F0IHJlc3VsdCA9ICR7dGhpcy5nZXRJbnB1dFNhbXBsaW5nU3RyaW5nKCl9OwogICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgIH0KICBgfWdldEhlaWdodENvb3JkU3RyaW5nKCl7cmV0dXJuIHRoaXMuZGF0YUZvcm1hdD09PSJOSFdDIj8iY29vcmRzWzFdIjoiY29vcmRzWzJdIn1nZXRXaWR0aENvb3JkU3RyaW5nKCl7cmV0dXJuIHRoaXMuZGF0YUZvcm1hdD09PSJOSFdDIj8iY29vcmRzWzJdIjoiY29vcmRzWzNdIn1nZXREZXB0aENvb3JkU3RyaW5nKCl7cmV0dXJuIHRoaXMuZGF0YUZvcm1hdD09PSJOSFdDIj8iY29vcmRzWzNdIjoiY29vcmRzWzFdIn1nZXRPdXRwdXREZXB0aFNpemUoKXtyZXR1cm4gdGhpcy5kYXRhRm9ybWF0PT09Ik5IV0MiP3RoaXMub3V0cHV0U2hhcGVbM106dGhpcy5vdXRwdXRTaGFwZVsxXX1nZXRJbnB1dFNhbXBsaW5nU3RyaW5nKCl7cmV0dXJuIHRoaXMuZGF0YUZvcm1hdD09PSJOSFdDIj8iZ2V0WChiLCBpbl9oLCBpbl93LCBpbl9kKSI6ImdldFgoYiwgaW5fZCwgaW5faCwgaW5fdykifX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZXB0aFRvU3BhY2UoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2Jsb2NrU2l6ZTpUYSxkYXRhRm9ybWF0OndhfT1iYSxFYT1TYS5zaGFwZVswXSxrYT13YT09PSJOSFdDIj9TYS5zaGFwZVsxXTpTYS5zaGFwZVsyXSxBYT13YT09PSJOSFdDIj9TYS5zaGFwZVsyXTpTYS5zaGFwZVszXSxGYT13YT09PSJOSFdDIj9TYS5zaGFwZVszXTpTYS5zaGFwZVsxXSxMYT1rYSpUYSxlbD1BYSpUYSx0bD1GYS8oVGEqVGEpLG5sPXdhPT09Ik5IV0MiP1tFYSxMYSxlbCx0bF06W0VhLHRsLExhLGVsXSxzbD1uZXcgRGVwdGhUb1NwYWNlUHJvZ3JhbShubCxUYSx3YSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShzbCxbU2FdLFNhLmR0eXBlKX1jb25zdCBkZXB0aFRvU3BhY2VDb25maWc9e2tlcm5lbE5hbWU6RGVwdGhUb1NwYWNlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpkZXB0aFRvU3BhY2V9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIERlcHRod2lzZUNvbnYyRFByb2dyYW17Y29uc3RydWN0b3IoYWEseGE9ITEsYmE9bnVsbCxTYT0hMSxUYT0hMSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsIlciXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToicGFkcyIsdHlwZToiaXZlYzIifSx7bmFtZToic3RyaWRlcyIsdHlwZToiaXZlYzIifSx7bmFtZToiZGlsYXRpb25zIix0eXBlOiJpdmVjMiJ9LHtuYW1lOiJpbkRpbXMiLHR5cGU6Iml2ZWMyIn1dLHRoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGUsdGhpcy5lbmFibGVTaGFwZVVuaWZvcm1zPXVzZVNoYXBlVW5pZm9ybXModGhpcy5vdXRwdXRTaGFwZS5sZW5ndGgpO2NvbnN0IHdhPWFhLmZpbHRlckhlaWdodCxFYT1hYS5maWx0ZXJXaWR0aCxrYT1hYS5vdXRDaGFubmVscy9hYS5pbkNoYW5uZWxzO2xldCBBYT0iIixGYT0iIjtiYSYmKFNhP0FhPWBmbG9hdCBhY3RpdmF0aW9uKGZsb2F0IGEpIHsKICAgICAgICAgIGZsb2F0IGIgPSBnZXRQcmVsdUFjdGl2YXRpb25XZWlnaHRzQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6VGE/QWE9YGZsb2F0IGFjdGl2YXRpb24oZmxvYXQgYSkgewogICAgICAgICAgZmxvYXQgYiA9IGdldExlYWt5cmVsdUFscGhhQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6QWE9YAogICAgICAgICAgZmxvYXQgYWN0aXZhdGlvbihmbG9hdCB4KSB7CiAgICAgICAgICAgICR7YmF9CiAgICAgICAgICB9CiAgICAgICAgYCxGYT0icmVzdWx0ID0gYWN0aXZhdGlvbihyZXN1bHQpOyIpO2NvbnN0IExhPXhhPyJyZXN1bHQgKz0gZ2V0Qmlhc0F0T3V0Q29vcmRzKCk7IjoiIjt4YSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImJpYXMiKSxTYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goInByZWx1QWN0aXZhdGlvbldlaWdodHMiKSxUYSYmdGhpcy52YXJpYWJsZU5hbWVzLnB1c2goImxlYWt5cmVsdUFscGhhIiksdGhpcy51c2VyQ29kZT1gCiAgICAgICR7QWF9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGJhdGNoID0gY29vcmRzLng7CiAgICAgICAgaXZlYzIgeFJDQ29ybmVyID0gY29vcmRzLnl6ICogc3RyaWRlcyAtIHBhZHM7CiAgICAgICAgaW50IGQyID0gY29vcmRzLnc7CiAgICAgICAgaW50IGQxID0gZDIgLyAke2thfTsKICAgICAgICBpbnQgcSA9IGQyIC0gZDEgKiAke2thfTsKCiAgICAgICAgaW50IHhSQ29ybmVyID0geFJDQ29ybmVyLng7CiAgICAgICAgaW50IHhDQ29ybmVyID0geFJDQ29ybmVyLnk7CgogICAgICAgIC8vIENvbnZvbHZlIHgoPywgPywgZDEpIHdpdGggdyg6LCA6LCBkMSwgcSkgdG8gZ2V0IHkoeVIsIHlDLCBkMikuCiAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsIHZhbHVlcyBpbiB0aGF0IGF4aXMuCiAgICAgICAgZmxvYXQgZG90UHJvZCA9IDAuMDsKICAgICAgICAvLyBUTyBETyhkc21pbGtvdik6IEZsYXR0ZW4gdGhlIHR3byBmb3IgbG9vcHMgYW5kIHZlYzQgdGhlIG9wZXJhdGlvbnMuCiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7d2F9OyB3UisrKSB7CiAgICAgICAgICBpbnQgeFIgPSB4UkNvcm5lciArIHdSICogZGlsYXRpb25zWzBdOwoKICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0gaW5EaW1zWzBdKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke0VhfTsgd0MrKykgewogICAgICAgICAgICBpbnQgeEMgPSB4Q0Nvcm5lciArIHdDICogZGlsYXRpb25zWzFdOwoKICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIHhSLCB4QywgZDEpOwogICAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0Vyh3Uiwgd0MsIGQxLCBxKTsKICAgICAgICAgICAgZG90UHJvZCArPSB4VmFsICogd1ZhbDsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZsb2F0IHJlc3VsdCA9IGRvdFByb2Q7CiAgICAgICAgJHtMYX0KICAgICAgICAke0ZhfQogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBEZXB0aHdpc2VDb252UGFja2VkMkRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhPSExLGJhPW51bGwsU2E9ITEsVGE9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJXIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InBhZHMiLHR5cGU6Iml2ZWMyIn0se25hbWU6InN0cmlkZXMiLHR5cGU6Iml2ZWMyIn0se25hbWU6ImRpbGF0aW9ucyIsdHlwZToiaXZlYzIifSx7bmFtZToiaW5EaW1zIix0eXBlOiJpdmVjMiJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLm91dFNoYXBlLHRoaXMuZW5hYmxlU2hhcGVVbmlmb3Jtcz11c2VTaGFwZVVuaWZvcm1zKHRoaXMub3V0cHV0U2hhcGUubGVuZ3RoKTtjb25zdCB3YT1hYS5vdXRDaGFubmVscy9hYS5pbkNoYW5uZWxzLEVhPWFhLnBhZEluZm8ubGVmdCxrYT1hYS5zdHJpZGVXaWR0aCxBYT1hYS5kaWxhdGlvbldpZHRoLEZhPWFhLmZpbHRlckhlaWdodCxMYT1hYS5maWx0ZXJXaWR0aCxlbD1MYTtsZXQgdGw9YAogICAgICBpbnQgeFI7IGludCB4QzsgaW50IHhDT2Zmc2V0OwogICAgICB2ZWM0IHdUZXhlbDsgdmVjNCBwcmV2aW91czsgdmVjNCBmaW5hbDtgO2ZvcihsZXQgb2w9MDtvbDxMYTtvbCsrKXRsKz1gCiAgICAgICAgICB2ZWM0IHhUZXhlbEMke29sKjJ9OwogICAgICAgICAgaW50IHhUZXhlbEMke29sKjJ9UmVhZHk7CiAgICAgICAgICB2ZWM0IHhUZXhlbEMke29sKjIrMX07CiAgICAgICAgICBpbnQgeFRleGVsQyR7b2wqMisxfVJlYWR5OwogICAgICAgICAgdmVjNCB4QyR7b2x9O2A7dGwrPWAKICAgIGZvciAoaW50IHIgPSAwOyByIDwgJHtGYX07IHIrKykgewogICAgICBgO2ZvcihsZXQgb2w9MDtvbDxMYTtvbCsrKXRsKz1gCiAgICAgICAgICB4VGV4ZWxDJHtvbCoyfSA9IHZlYzQoMC4wKTsKICAgICAgICAgIHhUZXhlbEMke29sKjJ9UmVhZHkgPSAwOwogICAgICAgICAgeFRleGVsQyR7b2wqMisxfSA9IHZlYzQoMC4wKTsKICAgICAgICAgIHhUZXhlbEMke29sKjIrMX1SZWFkeSA9IDA7CiAgICAgICAgICB4QyR7b2x9ID0gdmVjNCgwLjApO2A7dGwrPWAKICAgICAgICB4UiA9IHhSQ29ybmVyICsgciAqIGRpbGF0aW9uc1swXTsKICAgICAgICBpZiAoeFIgPj0wICYmIHhSIDwgaW5EaW1zWzBdKSB7CiAgICAgIGA7Zm9yKGxldCBvbD0wO29sPChlbCsxKS8yO29sKyspe2NvbnN0IGFsPW9sKjI7aWYodGwrPWAKICAgICAgICAgIHhDID0geENDb3JuZXIgKyAke2FsKkFhfTsKICAgICAgICAgIGAsa2E9PT0xKXtpZihhbDxMYSYmKEVhJTI9PT0xPyh0bCs9YAogICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDE7CiAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbH1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbH0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGAsQWE9PT0xJiZhbD4wP3RsKz1gCiAgICAgICAgICAgICAgICB4QyR7YWx9ID0gdmVjNCh4VGV4ZWxDJHthbC0yfS56dywgeFRleGVsQyR7YWx9Lnh5KTsKICAgICAgICAgICAgICAgIGA6dGwrPWAKICAgICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIDEgLSAyOwoKICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwoKICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIG1hbnVhbGx5IGNsZWFyIHVudXNlZCBjaGFubmVscyBpbiBjYXNlCiAgICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzLnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeEMke2FsfSA9IHZlYzQocHJldmlvdXMuencsIHhUZXhlbEMke2FsfS54eSk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgeEMke2FsfSA9IHZlYzQoMC4wLCAwLjAsIHhUZXhlbEMke2FsfS54eSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYCk6dGwrPWAKICAgICAgICAgICAgICAgIGlmICh4QyA+PSAwICYmIHhDIDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke2FsfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9ID0gZ2V0WChiYXRjaCwgeFIsIHhDLCBkMSk7CiAgICAgICAgICAgICAgICAgIGlmICh4QyArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9Lnp3ID0gdmVjMigwLjApOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB4QyR7YWx9ID0geFRleGVsQyR7YWx9OwogICAgICAgICAgICAgICAgYCxhbCsxPExhKSl7Y29uc3QgbGw9RWElMj09PTA/bmVhcmVzdExhcmdlckV2ZW4oQWEpOkFhO0FhJTI9PT0wJiZFYSUyPT09MXx8QWElMiE9PTAmJkVhJTIhPT0xPyh0bCs9YAogICAgICAgICAgICAgICAgICB4Q09mZnNldCA9IHhDICsgaW1vZChwYWRzWzFdLCAyKSArICR7bGx9OwoKICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7YWwrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX0gPSBnZXRYKGJhdGNoLCB4UiwgeENPZmZzZXQsIGQxKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAgIC8vIHdlJ3JlIHJlYWRpbmcgZnJvbSByZWN5Y2xlZCB0ZXh0dXJlLgogICAgICAgICAgICAgICAgICAgIGlmICh4Q09mZnNldCArIDEgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYCxBYT4xP3RsKz1gCiAgICAgICAgICAgICAgICAgICAgeENPZmZzZXQgLT0gMjsKICAgICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgICB4QyR7YWwrMX0gPSB2ZWM0KHByZXZpb3VzLnp3LCB4VGV4ZWxDJHthbCsxfS54eSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgeEMke2FsKzF9ID0gdmVjNCgwLjAsIDAuMCwgeFRleGVsQyR7YWwrMX0ueHkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBgOnRsKz1gCiAgICAgICAgICAgICAgICAgICAgeEMke2FsKzF9ID0gdmVjNCh4VGV4ZWxDJHthbH0uencsIHhUZXhlbEMke2FsKzF9Lnh5KTsKICAgICAgICAgICAgICAgICAgICBgKTpsbD09PTE/dGwrPWAKICAgICAgICAgICAgICAgICAgICB4QyR7YWwrMX0gPSB4VGV4ZWxDJHthbH07CiAgICAgICAgICAgICAgICAgICAgYDp0bCs9YAogICAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAke2xsfTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7YWwrMX1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfVJlYWR5ID0gMTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHhDJHthbCsxfSA9IHhUZXhlbEMke2FsKzF9OwogICAgICAgICAgICAgICAgICAgIGB9fWVsc2UgYWw8TGEmJihFYSUyPT09MT8odGwrPWAKICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAxIC0gc3RyaWRlc1sxXTsKICAgICAgICAgICAgICAgIGlmKHhDT2Zmc2V0ID49IDAgJiYgeENPZmZzZXQgPCBpbkRpbXNbMV0gJiYgeFRleGVsQyR7YWx9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbH0gPSBnZXRYKGJhdGNoLCB4UiwgeENPZmZzZXQsIGQxKTsKICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBtYW51YWxseSBjbGVhciB1bnVzZWQgY2hhbm5lbHMgaW4gY2FzZQogICAgICAgICAgICAgICAgICAvLyB3ZSdyZSByZWFkaW5nIGZyb20gcmVjeWNsZWQgdGV4dHVyZS4KICAgICAgICAgICAgICAgICAgaWYgKHhDT2Zmc2V0ICsgMSA+PSBpbkRpbXNbMV0pIHsKICAgICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbH0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWx9UmVhZHkgPSAxOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKHhDICsgMSA+PSAwICYmIHhDICsgMSA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbCsxfVJlYWR5ID09IDApIHsKICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX0gPSBnZXRYKGJhdGNoLCB4UiwgeEMgKyAxLCBkMSk7CiAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gbWFudWFsbHkgY2xlYXIgdW51c2VkIGNoYW5uZWxzIGluIGNhc2UKICAgICAgICAgICAgICAgICAgLy8gd2UncmUgcmVhZGluZyBmcm9tIHJlY3ljbGVkIHRleHR1cmUuCiAgICAgICAgICAgICAgICAgIGlmICh4QyArIDIgPj0gaW5EaW1zWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX0uencgPSB2ZWMyKDAuMCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeEMke2FsfSA9IHZlYzQoeFRleGVsQyR7YWx9Lnp3LCB4VGV4ZWxDJHthbCsxfS56dyk7CiAgICAgICAgICAgICAgYCxhbCsxPExhJiYodGwrPWAKICAgICAgICAgICAgICAgICAgZmluYWwgPSB2ZWM0KDAuMCk7CiAgICAgICAgICAgICAgICAgIHhDT2Zmc2V0ID0geEMgKyAxICsgc3RyaWRlc1sxXTsKICAgICAgICAgICAgICAgICAgaWYoeENPZmZzZXQgPj0gMCAmJiB4Q09mZnNldCA8IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsID0gZ2V0WChiYXRjaCwgeFIsIHhDT2Zmc2V0LCBkMSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgeEMke2FsKzF9ID0gdmVjNCh4VGV4ZWxDJHthbCsxfS54eSwgZmluYWwueHkpOwogICAgICAgICAgICAgICAgYCkpOih0bCs9YAogICAgICAgICAgICAgICAgaWYoeEMgPj0gMCAmJiB4QyA8IGluRGltc1sxXSAmJiB4VGV4ZWxDJHthbH1SZWFkeSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfSA9IGdldFgoYmF0Y2gsIHhSLCB4QywgZDEpOwogICAgICAgICAgICAgICAgICBpZiAoeEMgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfS56dyA9IHZlYzIoMC4wKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbH1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeENPZmZzZXQgPSB4QyArIHN0cmlkZXNbMV07CiAgICAgICAgICAgICAgICBpZih4Q09mZnNldCA+PSAwICYmIHhDT2Zmc2V0IDwgaW5EaW1zWzFdICYmIHhUZXhlbEMke2FsKzF9UmVhZHkgPT0gMCkgewogICAgICAgICAgICAgICAgICB4VGV4ZWxDJHthbCsxfSA9IGdldFgoYmF0Y2gsIHhSLCB4Q09mZnNldCwgZDEpOwogICAgICAgICAgICAgICAgICBpZiAoeENPZmZzZXQgKyAxID49IGluRGltc1sxXSkgewogICAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsKzF9Lnp3ID0gdmVjMigwLik7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgeFRleGVsQyR7YWwrMX1SZWFkeSA9IDE7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeEMke2FsfSA9IHZlYzQoCiAgICAgICAgICAgICAgICAgIHhUZXhlbEMke2FsfS54eSwgeFRleGVsQyR7YWwrMX0ueHkpOwogICAgICAgICAgICAgIGAsYWwrMTxMYSYmKHRsKz1gCiAgICAgICAgICAgICAgICAgIHhDJHthbCsxfSA9IHZlYzQoeFRleGVsQyR7YWx9Lnp3LCB4VGV4ZWxDJHthbCsxfS56dyk7CiAgICAgICAgICAgICAgICBgKSkpO2FsPExhJiYodGwrPWAKICAgICAgICAgICAgd1RleGVsID0gZ2V0VyhyLCAke2FsfSwgZDEsIHEpOwogICAgICAgICAgICBkb3RQcm9kICs9IHhDJHthbH0gKiB2ZWM0KHdUZXhlbC54eiwgd1RleGVsLnh6KTsKICAgICAgICAgIGAsYWwrMTxMYSYmKHRsKz1gCiAgICAgICAgICAgICAgd1RleGVsID0gZ2V0VyhyLCAke2FsKzF9LCBkMSwgcSk7CiAgICAgICAgICAgICAgZG90UHJvZCArPSB4QyR7YWwrMX0gKiB2ZWM0KHdUZXhlbC54eiwgd1RleGVsLnh6KTsKICAgICAgICAgICAgYCkpfXRsKz1gCiAgICB9CiAgYCx0bCs9YAogICAgICB9CiAgICBgO2xldCBubD0iIixzbD0iIjtiYSYmKFNhP25sPWB2ZWM0IGFjdGl2YXRpb24odmVjNCBhKSB7CiAgICAgICAgICB2ZWM0IGIgPSBnZXRQcmVsdUFjdGl2YXRpb25XZWlnaHRzQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6VGE/bmw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IGEpIHsKICAgICAgICAgIHZlYzQgYiA9IGdldExlYWt5cmVsdUFscGhhQXRPdXRDb29yZHMoKTsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWA6bmw9YHZlYzQgYWN0aXZhdGlvbih2ZWM0IHgpIHsKICAgICAgICAgICR7YmF9CiAgICAgICAgfWAsc2w9InJlc3VsdCA9IGFjdGl2YXRpb24ocmVzdWx0KTsiKTtjb25zdCBybD14YT8icmVzdWx0ICs9IGdldEJpYXNBdE91dENvb3JkcygpOyI6IiI7eGEmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJiaWFzIiksU2EmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJwcmVsdUFjdGl2YXRpb25XZWlnaHRzIiksVGEmJnRoaXMudmFyaWFibGVOYW1lcy5wdXNoKCJsZWFreXJlbHVBbHBoYSIpLHRoaXMudXNlckNvZGU9YAogICAgICAke25sfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgIGl2ZWMyIHhSQ0Nvcm5lciA9IGNvb3Jkcy55eiAqIHN0cmlkZXMgLSBwYWRzOwogICAgICAgIGludCBkMiA9IGNvb3Jkcy53OwogICAgICAgIGludCBkMSA9IGQyIC8gJHt3YX07CiAgICAgICAgaW50IHEgPSBkMiAtIGQxICogJHt3YX07CiAgICAgICAgaW50IHhSQ29ybmVyID0geFJDQ29ybmVyLng7CiAgICAgICAgaW50IHhDQ29ybmVyID0geFJDQ29ybmVyLnk7CgogICAgICAgIC8vaW50aWFsaXplIGRvdFByb2Qgd2l0aCBhIHNtYWxsIGVwc2lsb24gc2VlbXMgdG8gcmVkdWNlIEdQVSBhY2N1cmFjeSBsb3NzLgogICAgICAgIHZlYzQgZG90UHJvZCA9IHZlYzQoMC4wMDAwMDAwMDAwMDAwMDEpOwoKICAgICAgICAke3RsfQoKICAgICAgICB2ZWM0IHJlc3VsdCA9IGRvdFByb2QgLSB2ZWM0KDAuMDAwMDAwMDAwMDAwMDAxKTsKICAgICAgICAke3JsfQogICAgICAgICR7c2x9CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZE5hdGl2ZShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGZpbHRlcjpUYX09YWEse3N0cmlkZXM6d2EscGFkOkVhLGRpbGF0aW9uczprYSxkaW1Sb3VuZGluZ01vZGU6QWF9PWJhO2xldCBGYT1rYTtGYT09bnVsbCYmKEZhPVsxLDFdKSxhc3NlcnQoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lKHdhLEZhKSwoKT0+YEVycm9yIGluIGRlcHRod2lzZUNvbnYyZDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt3YX0gYW5kIGRpbGF0aW9ucyAnJHtGYX0nYCk7Y29uc3QgTGE9Y29tcHV0ZUNvbnYyREluZm8oU2Euc2hhcGUsVGEuc2hhcGUsd2EsRmEsRWEsQWEsITApO2xldCBlbDtlbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0RFUFRIV0lTRUNPTlYiKSYmTGEuc3RyaWRlV2lkdGg8PTImJkxhLm91dENoYW5uZWxzL0xhLmluQ2hhbm5lbHM9PT0xP2VsPW5ldyBEZXB0aHdpc2VDb252UGFja2VkMkRQcm9ncmFtKExhKTplbD1uZXcgRGVwdGh3aXNlQ29udjJEUHJvZ3JhbShMYSk7Y29uc3QgdGw9W1tMYS5wYWRJbmZvLnRvcCxMYS5wYWRJbmZvLmxlZnRdLFtMYS5zdHJpZGVIZWlnaHQsTGEuc3RyaWRlV2lkdGhdLFtMYS5kaWxhdGlvbkhlaWdodCxMYS5kaWxhdGlvbldpZHRoXSxbTGEuaW5IZWlnaHQsTGEuaW5XaWR0aF1dO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oZWwsW1NhLFRhXSwiZmxvYXQzMiIsdGwpfWNvbnN0IGRlcHRod2lzZUNvbnYyZE5hdGl2ZUNvbmZpZz17a2VybmVsTmFtZTpEZXB0aHdpc2VDb252MmROYXRpdmUsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRlcHRod2lzZUNvbnYyZE5hdGl2ZX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgRGVwdGh3aXNlQ29udjJERGVyRmlsdGVyUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsImR5Il0sdGhpcy5vdXRwdXRTaGFwZT1hYS5maWx0ZXJTaGFwZTtjb25zdCB4YT1hYS5zdHJpZGVIZWlnaHQsYmE9YWEuc3RyaWRlV2lkdGgsU2E9YWEucGFkSW5mby50b3AsVGE9YWEucGFkSW5mby5sZWZ0LHdhPWFhLm91dENoYW5uZWxzL2FhLmluQ2hhbm5lbHM7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgd1IgPSBjb29yZHMueDsKICAgICAgICBpbnQgd0MgPSBjb29yZHMueTsKICAgICAgICBpbnQgZDEgPSBjb29yZHMuejsKICAgICAgICBpbnQgZG0gPSBjb29yZHMudzsKICAgICAgICBpbnQgZDIgPSBkMSAqICR7d2F9ICsgZG07CgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CgogICAgICAgIC8vIFRPIERPOiBWZWM0IG92ZXIgdGhlIGJhdGNoIHNpemUKICAgICAgICBmb3IgKGludCBiID0gMDsgYiA8ICR7YWEuYmF0Y2hTaXplfTsgYisrKSB7CiAgICAgICAgICBmb3IgKGludCB5UiA9IDA7IHlSIDwgJHthYS5vdXRIZWlnaHR9OyB5UisrKSB7CiAgICAgICAgICAgIGludCB4UiA9IHdSICsgeVIgKiAke3hhfSAtICR7U2F9OwoKICAgICAgICAgICAgaWYgKHhSIDwgMCB8fCB4UiA+PSAke2FhLmluSGVpZ2h0fSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB5QyA9IDA7IHlDIDwgJHthYS5vdXRXaWR0aH07IHlDKyspIHsKICAgICAgICAgICAgICBpbnQgeEMgPSB3QyArIHlDICogJHtiYX0gLSAke1RhfTsKCiAgICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSAke2FhLmluV2lkdGh9KSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGZsb2F0IGR5VmFsdWUgPSBnZXREeShiLCB5UiwgeUMsIGQyKTsKICAgICAgICAgICAgICBmbG9hdCB4VmFsdWUgPSBnZXRYKGIsIHhSLCB4QywgZDEpOwogICAgICAgICAgICAgIGRvdFByb2QgKz0gKHhWYWx1ZSAqIGR5VmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNldE91dHB1dChkb3RQcm9kKTsKICAgICAgfQogICAgYH19Y2xhc3MgRGVwdGh3aXNlQ29udjJERGVySW5wdXRQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSIsIlciXSx0aGlzLm91dHB1dFNoYXBlPWFhLmluU2hhcGU7Y29uc3QgeGE9YWEuZmlsdGVySGVpZ2h0LGJhPWFhLmZpbHRlcldpZHRoLFNhPWFhLnN0cmlkZUhlaWdodCxUYT1hYS5zdHJpZGVXaWR0aCx3YT14YS0xLWFhLnBhZEluZm8udG9wLEVhPWJhLTEtYWEucGFkSW5mby5sZWZ0LGthPWFhLm91dENoYW5uZWxzL2FhLmluQ2hhbm5lbHM7dGhpcy51c2VyQ29kZT1gCiAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke3dhfSwgJHtFYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZDEgPSBjb29yZHNbM107CiAgICAgICAgaXZlYzIgZHlDb3JuZXIgPSBjb29yZHMueXogLSBwYWRzOwogICAgICAgIGludCBkeVJDb3JuZXIgPSBkeUNvcm5lci54OwogICAgICAgIGludCBkeUNDb3JuZXIgPSBkeUNvcm5lci55OwoKICAgICAgICBmbG9hdCBkb3RQcm9kID0gMC4wOwoKICAgICAgICBmb3IgKGludCB3UiA9IDA7IHdSIDwgJHt4YX07IHdSKyspIHsKICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvICR7U2F9LjA7CgogICAgICAgICAgaWYgKGR5UiA8IDAuMCB8fCBkeVIgPj0gJHthYS5vdXRIZWlnaHR9LjAgfHwgZnJhY3QoZHlSKSA+IDAuMCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBpZHlSID0gaW50KGR5Uik7CgogICAgICAgICAgaW50IHdSUGVybSA9ICR7eGF9IC0gMSAtIHdSOwoKICAgICAgICAgIGZvciAoaW50IHdDID0gMDsgd0MgPCAke2JhfTsgd0MrKykgewogICAgICAgICAgICBmbG9hdCBkeUMgPSBmbG9hdChkeUNDb3JuZXIgKyB3QykgLyAke1RhfS4wOwoKICAgICAgICAgICAgaWYgKGR5QyA8IDAuMCB8fCBkeUMgPj0gJHthYS5vdXRXaWR0aH0uMCB8fAogICAgICAgICAgICAgICAgZnJhY3QoZHlDKSA+IDAuMCkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBpZHlDID0gaW50KGR5Qyk7CgogICAgICAgICAgICBpbnQgd0NQZXJtID0gJHtiYX0gLSAxIC0gd0M7CgogICAgICAgICAgICAvLyBUTyBETzogVmVjNCBvdmVyIHRoZSBjaGFubmVsTXVsCiAgICAgICAgICAgIGZvciAoaW50IGRtID0gMDsgZG0gPCAke2thfTsgZG0rKykgewogICAgICAgICAgICAgIGludCBkMiA9IGQxICogJHtrYX0gKyBkbTsKICAgICAgICAgICAgICBmbG9hdCB4VmFsdWUgPSBnZXREeShiYXRjaCwgaWR5UiwgaWR5QywgZDIpOwogICAgICAgICAgICAgIGZsb2F0IHdWYWx1ZSA9IGdldFcod1JQZXJtLCB3Q1Blcm0sIGQxLCBkbSk7CiAgICAgICAgICAgICAgZG90UHJvZCArPSB4VmFsdWUgKiB3VmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlcihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhLGR5OlRhfT1hYSx7c3RyaWRlczp3YSxkaWxhdGlvbnM6RWEscGFkOmthLGRpbVJvdW5kaW5nTW9kZTpBYSxmaWx0ZXJTaGFwZTpGYX09YmEsTGE9Y29tcHV0ZUNvbnYyREluZm8oU2Euc2hhcGUsRmEsd2EsRWEsa2EsQWEsITApLGVsPW5ldyBEZXB0aHdpc2VDb252MkREZXJGaWx0ZXJQcm9ncmFtKExhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKGVsLFtTYSxUYV0sImZsb2F0MzIiKX1jb25zdCBkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlckNvbmZpZz17a2VybmVsTmFtZTpEZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcEZpbHRlcixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BGaWx0ZXJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7ZHk6U2EsZmlsdGVyOlRhfT1hYSx7c3RyaWRlczp3YSxkaWxhdGlvbnM6RWEscGFkOmthLGRpbVJvdW5kaW5nTW9kZTpBYSxpbnB1dFNoYXBlOkZhfT1iYSxMYT1jb21wdXRlQ29udjJESW5mbyhGYSxUYS5zaGFwZSx3YSxFYSxrYSxBYSwhMCksZWw9bmV3IERlcHRod2lzZUNvbnYyRERlcklucHV0UHJvZ3JhbShMYSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShlbCxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgZGVwdGh3aXNlQ29udjJkTmF0aXZlQmFja3Byb3BJbnB1dENvbmZpZz17a2VybmVsTmFtZTpEZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcElucHV0LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpkZXB0aHdpc2VDb252MmROYXRpdmVCYWNrcHJvcElucHV0fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBEaWFnUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiWCJdLHRoaXMub3V0cHV0U2hhcGU9W2FhLGFhXSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBmbG9hdCB2YWwgPSBjb29yZHNbMF0gPT0gY29vcmRzWzFdID8gZ2V0WChjb29yZHNbMF0pIDogMC4wOwogICAgICAgICAgc2V0T3V0cHV0KHZhbCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRpYWcoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWEsU2E9Wy4uLmJhLnNoYXBlLC4uLmJhLnNoYXBlXSxUYT1zaXplRnJvbVNoYXBlKGJhLnNoYXBlKSx3YT1yZXNoYXBlKHtpbnB1dHM6e3g6YmF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltUYV19fSksRWE9bmV3IERpYWdQcm9ncmFtKFRhKSxrYT14YS5ydW5XZWJHTFByb2dyYW0oRWEsW3dhXSx3YS5kdHlwZSksQWE9cmVzaGFwZSh7aW5wdXRzOnt4OmthfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpTYX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGthKSxBYX1jb25zdCBkaWFnQ29uZmlnPXtrZXJuZWxOYW1lOkRpYWcsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmRpYWd9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIERpbGF0aW9uMkRQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiVyJdLHRoaXMub3V0cHV0U2hhcGU9YWEub3V0U2hhcGU7Y29uc3R7aW5IZWlnaHQ6eGEsaW5XaWR0aDpiYSxwYWRJbmZvOlNhLHN0cmlkZUhlaWdodDpUYSxzdHJpZGVXaWR0aDp3YSxmaWx0ZXJIZWlnaHQ6RWEsZmlsdGVyV2lkdGg6a2EsZGlsYXRpb25IZWlnaHQ6QWEsZGlsYXRpb25XaWR0aDpGYX09YWEse3RvcDpMYSxsZWZ0OmVsfT1TYTt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7VGF9LCAke3dhfSk7CiAgICAgIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke0xhfSwgJHtlbH0pOwogICAgICBjb25zdCBmbG9hdCBuZWdfaW5maW5pdHkgPSAtMy40ZTM4OwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgIGludCBkMSA9IGNvb3Jkcy53OwogICAgICAgIGl2ZWMyIG91dFRvcExlZnRDb3JuZXIgPQogICAgICAgICAgICBjb29yZHMueXogKiBzdHJpZGVzIC0gcGFkczsKICAgICAgICBpbnQgaEJlZyA9IG91dFRvcExlZnRDb3JuZXIueDsKICAgICAgICBpbnQgd0JlZyA9IG91dFRvcExlZnRDb3JuZXIueTsKCiAgICAgICAgZmxvYXQgY3VyVmFsID0gbmVnX2luZmluaXR5OwogICAgICAgIGZvciAoaW50IGggPSAwOyBoIDwgJHtFYX07IGgrKykgewogICAgICAgICAgaW50IGhJbiA9IGhCZWcgKyBoICogJHtBYX07CgogICAgICAgICAgaWYgKGhJbiA+PSAwICYmIGhJbiA8ICR7eGF9KSB7CiAgICAgICAgICAgIGZvciAoaW50IHcgPSAwOyB3IDwgJHtrYX07IHcrKykgewogICAgICAgICAgICAgIGludCB3SW4gPSB3QmVnICsgdyAqICR7RmF9OwoKICAgICAgICAgICAgICBpZiAod0luID49IDAgJiYgd0luIDwgJHtiYX0pIHsKICAgICAgICAgICAgICAgIGZsb2F0IHhWYWwgPSBnZXRYKGJhdGNoLCBoSW4sIHdJbiwgZDEpOwogICAgICAgICAgICAgICAgZmxvYXQgd1ZhbCA9IGdldFcoaCwgdywgZDEpOwoKICAgICAgICAgICAgICAgIGZsb2F0IHZhbCA9IHhWYWwgKyB3VmFsOwogICAgICAgICAgICAgICAgaWYgKHZhbCA+IGN1clZhbCkgewogICAgICAgICAgICAgICAgICBjdXJWYWwgPSB2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmbG9hdCByZXN1bHQgPSBjdXJWYWw7CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRpbGF0aW9uMkQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxmaWx0ZXI6VGF9PWFhLHtzdHJpZGVzOndhLHBhZDpFYSxkaWxhdGlvbnM6a2F9PWJhLEFhPWNvbXB1dGVEaWxhdGlvbjJESW5mbyhTYS5zaGFwZSxUYS5zaGFwZSx3YSxFYSwiTkhXQyIsa2EpO2xldCBGYTtjb25zdCBMYT1uZXcgRGlsYXRpb24yRFByb2dyYW0oQWEpO0ZhPXhhLnJ1bldlYkdMUHJvZ3JhbShMYSxbU2EsVGFdLCJmbG9hdDMyIik7Y29uc3QgZWw9cmVzaGFwZSh7aW5wdXRzOnt4OkZhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpBYS5vdXRTaGFwZX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRmEpLGVsfWNvbnN0IGRpbGF0aW9uMkRDb25maWc9e2tlcm5lbE5hbWU6RGlsYXRpb24yRCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZGlsYXRpb24yRH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZWluc3VtKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2VxdWF0aW9uOlNhfT1iYSxUYT1hYSx7YWxsRGltczp3YSxzdW1tZWREaW1zOkVhLGlkRGltczprYX09ZGVjb2RlRWluc3VtRXF1YXRpb24oU2EsVGEubGVuZ3RoKTtjaGVja0VpbnN1bURpbVNpemVzKHdhLmxlbmd0aCxrYSxUYSk7Y29uc3R7cGF0aDpBYSxzdGVwczpGYX09Z2V0RWluc3VtQ29tcHV0ZVBhdGgoRWEsa2EpLExhPUZhLmxlbmd0aDtsZXQgZWw9bnVsbCx0bD13YS5sZW5ndGg7Y29uc3Qgbmw9W107Zm9yKGxldCBzbD0wO3NsPExhOysrc2wpe2Zvcihjb25zdCBybCBvZiBGYVtzbF0pe2NvbnN0e3Blcm11dGF0aW9uSW5kaWNlczpvbCxleHBhbmREaW1zOmFsfT1nZXRFaW5zdW1QZXJtdXRhdGlvbih0bCxrYVtybF0pO2xldCBsbDtpc0lkZW50aXR5UGVybXV0YXRpb24ob2wpP2xsPVRhW3JsXToobGw9dHJhbnNwb3NlKHtpbnB1dHM6e3g6VGFbcmxdfSxiYWNrZW5kOnhhLGF0dHJzOntwZXJtOm9sfX0pLG5sLnB1c2gobGwpKTtjb25zdCBpbD1sbC5zaGFwZS5zbGljZSgpO2ZvcihsZXQgY2w9MDtjbDxhbC5sZW5ndGg7KytjbClpbC5zcGxpY2UoYWxbY2xdLDAsMSk7YXJyYXlzRXF1YWwobGwuc2hhcGUsaWwpfHwobGw9cmVzaGFwZSh7aW5wdXRzOnt4OmxsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTppbH19KSxubC5wdXNoKGxsKSksZWw9PT1udWxsP2VsPWxsOihlbD1tdWx0aXBseSh7aW5wdXRzOnthOmxsLGI6ZWx9LGJhY2tlbmQ6eGF9KSxubC5wdXNoKGVsKSl9c2w8TGEtMSYmKEFhW3NsXT49MCYmKGVsPXN1bSh7aW5wdXRzOnt4OmVsfSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOkFhW3NsXS0od2EubGVuZ3RoLXRsKSxrZWVwRGltczohMX19KSxubC5wdXNoKGVsKSksdGwtLSl9Zm9yKGNvbnN0IHNsIG9mIG5sKXNsIT09ZWwmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKTtyZXR1cm4gZWx9Y29uc3QgZWluc3VtQ29uZmlnPXtrZXJuZWxOYW1lOkVpbnN1bSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZWluc3VtfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBFTFU9InJldHVybiAoeCA+PSAwLjApID8geCA6IChleHAoeCkgLSAxLjApOyIsRUxVX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQ7CgogIHJlc3VsdC5yID0gKHguciA+PSAwLjApID8geC5yIDogKGV4cCh4LnIpIC0gMS4wKTsKICByZXN1bHQuZyA9ICh4LmcgPj0gMC4wKSA/IHguZyA6IChleHAoeC5nKSAtIDEuMCk7CiAgcmVzdWx0LmIgPSAoeC5iID49IDAuMCkgPyB4LmIgOiAoZXhwKHguYikgLSAxLjApOwogIHJlc3VsdC5hID0gKHguYSA+PSAwLjApID8geC5hIDogKGV4cCh4LmEpIC0gMS4wKTsKCiAgcmV0dXJuIHJlc3VsdDsKYCxlbHU9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RUxVLHBhY2tlZE9wU25pcHBldDpFTFVfUEFDS0VEfSksZWx1Q29uZmlnPXtrZXJuZWxOYW1lOkVsdSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZWx1fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBFTFVfREVSPSJyZXR1cm4gKGIgPj0gMC4wKSA/IGEgOiBhICogKGIgKyAxLjApOyIsRUxVX0RFUl9QQUNLRUQ9YAogIHZlYzQgYkdURVplcm8gPSB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoYiwgdmVjNCgwLikpKTsKICByZXR1cm4gKGJHVEVaZXJvICogYSkgKyAoKHZlYzQoMS4wKSAtIGJHVEVaZXJvKSAqIChhICogKGIgKyB2ZWM0KDEuMCkpKSk7CmAsZWx1R3JhZD1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7ZHk6YmEseTpTYX09YWEsVGE9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19CSU5BUllfT1BFUkFUSU9OUyIpP25ldyBCaW5hcnlPcFBhY2tlZFByb2dyYW0oRUxVX0RFUl9QQUNLRUQsYmEuc2hhcGUsU2Euc2hhcGUpOm5ldyBCaW5hcnlPcFByb2dyYW0oRUxVX0RFUixiYS5zaGFwZSxTYS5zaGFwZSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShUYSxbYmEsU2FdLGJhLmR0eXBlKX0sZWx1R3JhZENvbmZpZz17a2VybmVsTmFtZTpFbHVHcmFkLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzplbHVHcmFkfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBQQUNLRURfRVFVQUw9YAogIHJldHVybiB2ZWM0KGVxdWFsKGEsIGIpKTsKYCxFUVVBTD0icmV0dXJuIGZsb2F0KGEgPT0gYik7IixlcXVhbD1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RVFVQUwscGFja2VkT3BTbmlwcGV0OlBBQ0tFRF9FUVVBTCxkdHlwZToiYm9vbCIsY3B1S2VybmVsSW1wbDplcXVhbEltcGxDUFV9KSxlcXVhbENvbmZpZz17a2VybmVsTmFtZTpFcXVhbCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZXF1YWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVSRj1gCiAgLy8gRXJyb3IgZnVuY3Rpb24gaXMgY2FsY3VsYXRlZCBhcHByb3hpbWF0ZWx5IHdpdGggZWxlbWVudGFyeSBmdW5jdGlvbi4KICAvLyBTZWUgIkhhbmRib29rIG9mIE1hdGhlbWF0aWNhbCBGdW5jdGlvbnMgd2l0aCBGb3JtdWxhcywKICAvLyBHcmFwaHMsIGFuZCBNYXRoZW1hdGljYWwgVGFibGVzIiwgQWJyYW1vd2l0eiBhbmQgU3RlZ3VuLgogIGZsb2F0IHAgPSAke0VSRl9QfTsKICBmbG9hdCBhMSA9ICR7RVJGX0ExfTsKICBmbG9hdCBhMiA9ICR7RVJGX0EyfTsKICBmbG9hdCBhMyA9ICR7RVJGX0EzfTsKICBmbG9hdCBhNCA9ICR7RVJGX0E0fTsKICBmbG9hdCBhNSA9ICR7RVJGX0E1fTsKCiAgZmxvYXQgc2lnbiA9IHNpZ24oeCk7CiAgeCA9IGFicyh4KTsKICBmbG9hdCB0ID0gMS4wIC8gKDEuMCArIHAgKiB4KTsKICByZXR1cm4gc2lnbiAqICgxLjAgLSAoKCgoKGE1KnQgKyBhNCkqdCkgKyBhMykqdCArIGEyKSp0ICsgYTEpKnQqZXhwKC14KngpKTsKYCxlcmY9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RVJGfSksZXJmQ29uZmlnPXtrZXJuZWxOYW1lOkVyZixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZXJmfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBFWFA9Q0hFQ0tfTkFOX1NOSVBQRVRfVU5BUlkrYAogIHJldHVybiBleHAoeCk7CmAsRVhQX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSBleHAoeCk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyB4LmcgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyB4LmIgOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiByZXN1bHQuYTsKCiAgcmV0dXJuIHJlc3VsdDsKYCxleHA9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RVhQLHBhY2tlZE9wU25pcHBldDpFWFBfUEFDS0VELGNwdUtlcm5lbEltcGw6ZXhwSW1wbENQVSxkdHlwZToiZmxvYXQzMiJ9KSxleHBDb25maWc9e2tlcm5lbE5hbWU6RXhwLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpleHB9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgTGljZW5zZSk7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIEFTIElTIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZXhwYW5kRGltcyhoYSl7Y29uc3R7aW5wdXRzOmFhLGF0dHJzOnhhLGJhY2tlbmQ6YmF9PWhhLHtkaW06U2F9PXhhLHtpbnB1dDpUYX09YWEsd2E9VGEuc2hhcGUubGVuZ3RoLEVhPVRhLnNoYXBlLnNsaWNlKCk7bGV0IGthPVNhO3JldHVybiBTYTwwJiYoYXNzZXJ0KC0od2ErMSk8PVNhLCgpPT5gQXhpcyBtdXN0IGJlIGluIHRoZSBpbnRlcnZhbCBbJHstKHdhKzEpfSwgJHt3YX1dYCksa2E9d2ErU2ErMSksRWEuc3BsaWNlKGthLDAsMSkscmVzaGFwZSh7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOmJhLGF0dHJzOntzaGFwZTpFYX19KX1jb25zdCBleHBhbmREaW1zQ29uZmlnPXtrZXJuZWxOYW1lOkV4cGFuZERpbXMsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmV4cGFuZERpbXN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEVYUE0xPSJyZXR1cm4gZXhwKHgpIC0gMS4wOyIsZXhwbTE9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RVhQTTEscGFja2VkT3BTbmlwcGV0OkVYUE0xLGNwdUtlcm5lbEltcGw6ZXhwbTFJbXBsQ1BVfSksZXhwbTFDb25maWc9e2tlcm5lbE5hbWU6RXhwbTEsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmV4cG0xfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBGRlRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJyZWFsIiwiaW1hZyJdO2NvbnN0IFNhPXhhWzFdO3RoaXMub3V0cHV0U2hhcGU9eGE7Y29uc3QgVGE9YmE/YDIuMCAqICR7TWF0aC5QSX1gOmAtMi4wICogJHtNYXRoLlBJfWAsd2E9YmE/YCR7U2F9LjBgOiIxLjAiO2xldCBFYTtpZihhYT09PSJyZWFsIilFYT0icmV0dXJuIHJlYWwgKiBleHBSIC0gaW1hZyAqIGV4cEk7IjtlbHNlIGlmKGFhPT09ImltYWciKUVhPSJyZXR1cm4gcmVhbCAqIGV4cEkgKyBpbWFnICogZXhwUjsiO2Vsc2UgdGhyb3cgbmV3IEVycm9yKGBGRlQgY29tcG9uZW50IG11c3QgYmUgZWl0aGVyICJyZWFsIiBvciAiaW1hZyIsIGdvdCAke2FhfS5gKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgZmxvYXQgZXhwb25lbnRNdWx0aXBsaWVyID0gJHtUYX07CgogICAgICBmbG9hdCB1bmFyeU9wQ29tcGxleChmbG9hdCByZWFsLCBmbG9hdCBleHBSLCBmbG9hdCBpbWFnLCBmbG9hdCBleHBJKSB7CiAgICAgICAgJHtFYX0KICAgICAgfQoKICAgICAgZmxvYXQgbXVsTWF0REZUKGludCBiYXRjaCwgaW50IGluZGV4KSB7CiAgICAgICAgZmxvYXQgaW5kZXhSYXRpbyA9IGZsb2F0KGluZGV4KSAvIGZsb2F0KCR7U2F9KTsKICAgICAgICBmbG9hdCBleHBvbmVudE11bHRpcGxpZXJUaW1lc0luZGV4UmF0aW8gPQogICAgICAgICAgICBleHBvbmVudE11bHRpcGxpZXIgKiBpbmRleFJhdGlvOwoKICAgICAgICBmbG9hdCByZXN1bHQgPSAwLjA7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtTYX07IGkrKykgewogICAgICAgICAgLy8geCA9ICgtMnwyICogUEkgLyBOKSAqIGluZGV4ICogaTsKICAgICAgICAgIGZsb2F0IHggPSBleHBvbmVudE11bHRpcGxpZXJUaW1lc0luZGV4UmF0aW8gKiBmbG9hdChpKTsKICAgICAgICAgIGZsb2F0IGV4cFIgPSBjb3MoeCk7CiAgICAgICAgICBmbG9hdCBleHBJID0gc2luKHgpOwogICAgICAgICAgZmxvYXQgcmVhbCA9IGdldFJlYWwoYmF0Y2gsIGkpOwogICAgICAgICAgZmxvYXQgaW1hZyA9IGdldEltYWcoYmF0Y2gsIGkpOwoKICAgICAgICAgIHJlc3VsdCArPQogICAgICAgICAgICAgIHVuYXJ5T3BDb21wbGV4KHJlYWwsIGV4cFIsIGltYWcsIGV4cEkpIC8gJHt3YX07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgc2V0T3V0cHV0KG11bE1hdERGVChjb29yZHNbMF0sIGNvb3Jkc1sxXSkpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmZnRJbXBsKGhhLGFhLHhhKXtjb25zdCBiYT14YS50ZXhEYXRhLmdldChoYS5kYXRhSWQpLFNhPXNpemVGcm9tU2hhcGUoaGEuc2hhcGUpLFRhPWhhLnNoYXBlW2hhLnNoYXBlLmxlbmd0aC0xXSx3YT1TYS9UYSxFYT1yZXNoYXBlKHtpbnB1dHM6e3g6aGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlt3YSxUYV19fSksa2E9RWEuc2hhcGUsQWE9bmV3IEZGVFByb2dyYW0oInJlYWwiLGthLGFhKSxGYT1uZXcgRkZUUHJvZ3JhbSgiaW1hZyIsa2EsYWEpLExhPVt7ZGF0YUlkOmJhLmNvbXBsZXhUZW5zb3JJbmZvcy5yZWFsLmRhdGFJZCxkdHlwZTpiYS5jb21wbGV4VGVuc29ySW5mb3MucmVhbC5kdHlwZSxzaGFwZTprYX0se2RhdGFJZDpiYS5jb21wbGV4VGVuc29ySW5mb3MuaW1hZy5kYXRhSWQsZHR5cGU6YmEuY29tcGxleFRlbnNvckluZm9zLmltYWcuZHR5cGUsc2hhcGU6a2F9XSxlbD14YS5ydW5XZWJHTFByb2dyYW0oQWEsTGEsImZsb2F0MzIiKSx0bD14YS5ydW5XZWJHTFByb2dyYW0oRmEsTGEsImZsb2F0MzIiKSxubD1jb21wbGV4KHtpbnB1dHM6e3JlYWw6ZWwsaW1hZzp0bH0sYmFja2VuZDp4YX0pO3hhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGVsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh0bCk7Y29uc3Qgc2w9cmVzaGFwZSh7aW5wdXRzOnt4Om5sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpoYS5zaGFwZX19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKG5sKSxzbH0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBmZnQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7aW5wdXQ6YmF9PWFhO3JldHVybiBmZnRJbXBsKGJhLCExLHhhKX1jb25zdCBmZnRDb25maWc9e2tlcm5lbE5hbWU6RkZULGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpmZnR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEZpbGxQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJ2YWx1ZSIsdHlwZToiZmxvYXQifV0sdGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAvLyBJbnB1dCBjYW4gYmUgb2J0YWluZWQgZnJvbSB1bmlmb3JtIHZhbHVlLgogICAgICAgIHNldE91dHB1dCh2YWx1ZSk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZpbGwoaGEpe2NvbnN0e2JhY2tlbmQ6YWEsYXR0cnM6eGF9PWhhLHtzaGFwZTpiYSx2YWx1ZTpTYX09eGE7bGV0e2R0eXBlOlRhfT14YTtpZihUYT1UYXx8aW5mZXJEdHlwZShTYSksVGE9PT0ic3RyaW5nIil7Y29uc3Qgd2E9Z2V0QXJyYXlGcm9tRFR5cGUoVGEsc2l6ZUZyb21TaGFwZShiYSkpO3JldHVybiB3YS5maWxsKFNhKSxhYS5tYWtlVGVuc29ySW5mbyhiYSxUYSx3YSl9ZWxzZXtjb25zdCB3YT1uZXcgRmlsbFByb2dyYW0oYmEsU2EpLEVhPVtbU2FdXTtyZXR1cm4gYWEucnVuV2ViR0xQcm9ncmFtKHdhLFtdLFRhLEVhKX19Y29uc3QgZmlsbENvbmZpZz17a2VybmVsTmFtZTpGaWxsLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpmaWxsfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBGbGlwTGVmdFJpZ2h0UHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiSW1hZ2UiXSx0aGlzLm91dHB1dFNoYXBlPVtdO2NvbnN0IHhhPWFhWzJdO3RoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBpbnQgeCA9IGNvb3Jkc1syXTsKCiAgICAgICAgICBpbnQgY29vcmRYID0gJHt4YX0gLSB4IC0gMTsKICAgICAgICAgIGZsb2F0IG91dHB1dFZhbHVlOwogICAgICAgICAgaWYoY29vcmRYID49IDAgJiYgY29vcmRYIDwgJHt4YX0pIHsKICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSBnZXRJbWFnZShjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRYLCBjb29yZHNbM10pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3V0cHV0VmFsdWUgPSBnZXRJbWFnZShjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10pOwogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KG91dHB1dFZhbHVlKTsKICAgICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBmbGlwTGVmdFJpZ2h0Q29uZmlnPXtrZXJuZWxOYW1lOkZsaXBMZWZ0UmlnaHQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOih7aW5wdXRzOmhhLGJhY2tlbmQ6YWF9KT0+e2NvbnN0e2ltYWdlOnhhfT1oYSxiYT1hYSxTYT1uZXcgRmxpcExlZnRSaWdodFByb2dyYW0oeGEuc2hhcGUpO3JldHVybiBiYS5ydW5XZWJHTFByb2dyYW0oU2EsW3hhXSx4YS5kdHlwZSl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBGTE9PUj0icmV0dXJuIGZsb29yKHgpOyIsZmxvb3I9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RkxPT1IscGFja2VkT3BTbmlwcGV0OkZMT09SLGNwdUtlcm5lbEltcGw6Zmxvb3JJbXBsQ1BVfSksZmxvb3JDb25maWc9e2tlcm5lbE5hbWU6Rmxvb3IsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmZsb29yfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBJTlRfRElWPWAKICBmbG9hdCBzID0gc2lnbihhKSAqIHNpZ24oYik7CiAgaW50IGlhID0gcm91bmQoYSk7CiAgaW50IGliID0gcm91bmQoYik7CiAgaWYgKGliICE9IDApIHsKICAgIC8vIFdpbmRvd3MgKEQzRCkgd2FudHMgZ3VhcmFudGVlZCBub24temVybyBpbnQgZGl2aXNpb24gYXQgY29tcGlsZS10aW1lLgogICAgcmV0dXJuIGZsb2F0KGlkaXYoaWEsIGliLCBzKSk7CiAgfSBlbHNlIHsKICAgIHJldHVybiBOQU47CiAgfQpgLElOVF9ESVZfUEFDS0VEPWAKICBpdmVjNCBpYSA9IHJvdW5kKGEpOwogIGl2ZWM0IGliID0gcm91bmQoYik7CiAgYnZlYzQgY29uZCA9IG5vdEVxdWFsKGliLCBpdmVjNCgwKSk7CiAgaXZlYzQgcmVzdWx0ID0gaXZlYzQoMCk7CiAgdmVjNCBzID0gc2lnbihhKSAqIHNpZ24oYik7CgogIC8vIFdpbmRvd3MgKEQzRCkgd2FudHMgZ3VhcmFudGVlZCBub24temVybyBpbnQgZGl2aXNpb24gYXQgY29tcGlsZS10aW1lLgogIGlmIChjb25kWzBdKSB7CiAgICByZXN1bHRbMF0gPSBpZGl2KGlhWzBdLCBpYlswXSwgc1swXSk7CiAgfQogIGlmIChjb25kWzFdKSB7CiAgICByZXN1bHRbMV0gPSBpZGl2KGlhWzFdLCBpYlsxXSwgc1sxXSk7CiAgfQogIGlmIChjb25kWzJdKSB7CiAgICByZXN1bHRbMl0gPSBpZGl2KGlhWzJdLCBpYlsyXSwgc1syXSk7CiAgfQogIGlmIChjb25kWzNdKSB7CiAgICByZXN1bHRbM10gPSBpZGl2KGlhWzNdLCBpYlszXSwgc1szXSk7CiAgfQogIHJldHVybiB2ZWM0KHJlc3VsdCk7CmAsZmxvb3JEaXY9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OklOVF9ESVYscGFja2VkT3BTbmlwcGV0OklOVF9ESVZfUEFDS0VELGR0eXBlOiJpbnQzMiJ9KSxmbG9vckRpdkNvbmZpZz17a2VybmVsTmFtZTpGbG9vckRpdixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Zmxvb3JEaXZ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEZyb21QaXhlbHNQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJBIl07Y29uc3QgeGE9Z2V0R2xzbERpZmZlcmVuY2VzKCksW2JhLFNhXT1hYTt0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzMgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IHRleFIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IHRleEMgPSBjb29yZHNbMV07CiAgICAgICAgaW50IGRlcHRoID0gY29vcmRzWzJdOwogICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKCR7U2F9LjAsICR7YmF9LjApOwoKICAgICAgICB2ZWM0IHZhbHVlcyA9ICR7eGEudGV4dHVyZTJEfShBLCB1dik7CiAgICAgICAgZmxvYXQgdmFsdWU7CiAgICAgICAgaWYgKGRlcHRoID09IDApIHsKICAgICAgICAgIHZhbHVlID0gdmFsdWVzLnI7CiAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAxKSB7CiAgICAgICAgICB2YWx1ZSA9IHZhbHVlcy5nOwogICAgICAgIH0gZWxzZSBpZiAoZGVwdGggPT0gMikgewogICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuYjsKICAgICAgICB9IGVsc2UgaWYgKGRlcHRoID09IDMpIHsKICAgICAgICAgIHZhbHVlID0gdmFsdWVzLmE7CiAgICAgICAgfQoKICAgICAgICBzZXRPdXRwdXQoZmxvb3IodmFsdWUgKiAyNTUuMCArIDAuNSkpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBGcm9tUGl4ZWxzUGFja2VkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSExLHRoaXMucGFja2VkT3V0cHV0PSEwO2NvbnN0IHhhPWdldEdsc2xEaWZmZXJlbmNlcygpLFtiYSxTYV09YWE7dGhpcy5vdXRwdXRTaGFwZT1hYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMzIGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCB0ZXhSID0gY29vcmRzWzBdOwogICAgICAgIGludCB0ZXhDID0gY29vcmRzWzFdOwogICAgICAgIGludCBkZXB0aCA9IGNvb3Jkc1syXTsKCiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKCiAgICAgICAgZm9yKGludCByb3c9MDsgcm93PD0xOyByb3crKykgewogICAgICAgICAgZm9yKGludCBjb2w9MDsgY29sPD0xOyBjb2wrKykgewogICAgICAgICAgICB0ZXhDID0gY29vcmRzWzFdICsgcm93OwogICAgICAgICAgICBkZXB0aCA9IGNvb3Jkc1syXSArIGNvbDsKCiAgICAgICAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLwogICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtTYX0uMCwgJHtiYX0uMCk7CiAgICAgICAgICAgIHZlYzQgdmFsdWVzID0gJHt4YS50ZXh0dXJlMkR9KEEsIHV2KTsKICAgICAgICAgICAgZmxvYXQgdmFsdWU7CiAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMucjsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAxKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuZzsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAyKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuYjsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZXB0aCA9PSAzKSB7CiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXMuYTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVzdWx0W3JvdyAqIDIgKyBjb2xdID0gZmxvb3IodmFsdWUgKiAyNTUuMCArIDAuNSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAke3hhLm91dHB1dH0gPSByZXN1bHQ7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGZyb21QaXhlbHNDb25maWc9e2tlcm5lbE5hbWU6RnJvbVBpeGVscyxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZnJvbVBpeGVsc307bGV0IGZyb21QaXhlbHMyRENvbnRleHQsd2lsbFJlYWRGcmVxdWVudGx5PWVudigpLmdldEJvb2woIkNBTlZBUzJEX1dJTExfUkVBRF9GUkVRVUVOVExZX0ZPUl9HUFUiKTtmdW5jdGlvbiBmcm9tUGl4ZWxzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGE7bGV0e3BpeGVsczpTYX09YWE7Y29uc3R7bnVtQ2hhbm5lbHM6VGF9PWJhLHdhPXR5cGVvZiBIVE1MVmlkZW9FbGVtZW50PCJ1IiYmU2EgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50LEVhPXR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50PCJ1IiYmU2EgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50LFtrYSxBYV09d2E/W1NhLnZpZGVvV2lkdGgsU2EudmlkZW9IZWlnaHRdOltTYS53aWR0aCxTYS5oZWlnaHRdLEZhPVtBYSxrYV0sTGE9W0FhLGthLFRhXTtpZihFYXx8d2Epe2NvbnN0IHNsPWVudigpLmdldEJvb2woIkNBTlZBUzJEX1dJTExfUkVBRF9GUkVRVUVOVExZX0ZPUl9HUFUiKTsoZnJvbVBpeGVsczJEQ29udGV4dD09bnVsbHx8c2whPT13aWxsUmVhZEZyZXF1ZW50bHkpJiYod2lsbFJlYWRGcmVxdWVudGx5PXNsLGZyb21QaXhlbHMyRENvbnRleHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2FudmFzIikuZ2V0Q29udGV4dCgiMmQiLHt3aWxsUmVhZEZyZXF1ZW50bHl9KSksZnJvbVBpeGVsczJEQ29udGV4dC5jYW52YXMud2lkdGg9a2EsZnJvbVBpeGVsczJEQ29udGV4dC5jYW52YXMuaGVpZ2h0PUFhLGZyb21QaXhlbHMyRENvbnRleHQuZHJhd0ltYWdlKFNhLDAsMCxrYSxBYSksU2E9ZnJvbVBpeGVsczJEQ29udGV4dC5jYW52YXN9Y29uc3QgZWw9eGEubWFrZVRlbnNvckluZm8oRmEsImludDMyIik7eGEudGV4RGF0YS5nZXQoZWwuZGF0YUlkKS51c2FnZT1UZXh0dXJlVXNhZ2UuUElYRUxTLHhhLmdwZ3B1LnVwbG9hZFBpeGVsRGF0YVRvVGV4dHVyZSh4YS5nZXRUZXh0dXJlKGVsLmRhdGFJZCksU2EpO2NvbnN0IHRsPWVudigpLmdldEJvb2woIldFQkdMX1BBQ0siKT9uZXcgRnJvbVBpeGVsc1BhY2tlZFByb2dyYW0oTGEpOm5ldyBGcm9tUGl4ZWxzUHJvZ3JhbShMYSksbmw9eGEucnVuV2ViR0xQcm9ncmFtKHRsLFtlbF0sImludDMyIik7cmV0dXJuIHhhLmRpc3Bvc2VEYXRhKGVsLmRhdGFJZCksbmx9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZnVzZWRDb252MmQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxmaWx0ZXI6VGEsYmlhczp3YSxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOkVhfT1hYSx7c3RyaWRlczprYSxwYWQ6QWEsZGF0YUZvcm1hdDpGYSxkaWxhdGlvbnM6TGEsZGltUm91bmRpbmdNb2RlOmVsLGFjdGl2YXRpb246dGwsbGVha3lyZWx1QWxwaGE6bmx9PWJhLHNsPWNvbnZlcnRDb252MkREYXRhRm9ybWF0KEZhKSxybD1jb21wdXRlQ29udjJESW5mbyhTYS5zaGFwZSxUYS5zaGFwZSxrYSxMYSxBYSxlbCwhMSxzbCk7bGV0IG9sO2NvbnN0IGFsPVtdLGxsPXdhIT1udWxsLGlsPUVhIT1udWxsLGNsPXRsPT09ImxlYWt5cmVsdSIsdWw9KCk9Pntjb25zdCBobD1bU2EsVGFdLHBsPShmbCxtbCk9PntpZihtbD09PSJOQ0hXIiYmZmwuc2hhcGUubGVuZ3RoPT09MSYmZmwuc2hhcGVbMF0hPT0xKXtjb25zdCBnbD1yZXNoYXBlKHtpbnB1dHM6e3g6Zmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltmbC5zaGFwZVswXSwxLDFdfX0pO3JldHVybiBhbC5wdXNoKGdsKSxnbH1yZXR1cm4gZmx9O2lmKGxsJiZobC5wdXNoKHBsKHdhLEZhKSksaWwmJmhsLnB1c2gocGwoRWEsRmEpKSxjbCl7Y29uc3QgZmw9eGEubWFrZVRlbnNvckluZm8oW10sImZsb2F0MzIiLGNyZWF0ZVNjYWxhclZhbHVlKG5sLCJmbG9hdDMyIikpO2hsLnB1c2goZmwpLGFsLnB1c2goZmwpfXJldHVybiBobH07aWYocmwuZmlsdGVySGVpZ2h0PT09MSYmcmwuZmlsdGVyV2lkdGg9PT0xJiZybC5kaWxhdGlvbkhlaWdodD09PTEmJnJsLmRpbGF0aW9uV2lkdGg9PT0xJiZybC5zdHJpZGVIZWlnaHQ9PT0xJiZybC5zdHJpZGVXaWR0aD09PTEmJihybC5wYWRJbmZvLnR5cGU9PT0iU0FNRSJ8fHJsLnBhZEluZm8udHlwZT09PSJWQUxJRCIpKW9sPWNvbnYyZEJ5TWF0TXVsKHt4OlNhLGZpbHRlcjpUYSxjb252SW5mbzpybCxiYWNrZW5kOnhhLGJpYXM6d2EsYWN0aXZhdGlvbjp0bCxwcmVsdUFjdGl2YXRpb25XZWlnaHRzOkVhLGxlYWt5cmVsdUFscGhhOm5sfSk7ZWxzZSBpZihybC5zdHJpZGVXaWR0aDw9MiYmc2w9PT0iY2hhbm5lbHNMYXN0IiYmZW52KCkuZ2V0Qm9vbCgiV0VCR0xfRVhQX0NPTlYiKSl7Y29uc3QgaGw9dGw/bWFwQWN0aXZhdGlvblRvU2hhZGVyUHJvZ3JhbSh0bCwhMCk6bnVsbCxwbD1uZXcgQ29udjJEUGFja2VkUHJvZ3JhbShybCxsbCxobCxpbCxjbCksZmw9W1tybC5wYWRJbmZvLnRvcCxybC5wYWRJbmZvLmxlZnRdLFtybC5zdHJpZGVIZWlnaHQscmwuc3RyaWRlV2lkdGhdLFtybC5kaWxhdGlvbkhlaWdodCxybC5kaWxhdGlvbldpZHRoXSxbcmwuaW5IZWlnaHQscmwuaW5XaWR0aF1dLG1sPXVsKCk7b2w9eGEucnVuV2ViR0xQcm9ncmFtKHBsLG1sLCJmbG9hdDMyIixmbCl9ZWxzZSBpZihlbnYoKS5nZXRCb29sKCJXRUJHTF9DT05WX0lNMkNPTCIpKW9sPWNvbnYyZFdpdGhJbTJSb3coe3g6U2EsZmlsdGVyOlRhLGNvbnZJbmZvOnJsLGJhY2tlbmQ6eGEsYmlhczp3YSxhY3RpdmF0aW9uOnRsLHByZWx1QWN0aXZhdGlvbldlaWdodHM6RWEsbGVha3lyZWx1QWxwaGE6bmx9KTtlbHNle2NvbnN0IGhsPXRsP21hcEFjdGl2YXRpb25Ub1NoYWRlclByb2dyYW0odGwsITEpOm51bGwscGw9bmV3IENvbnYyRFByb2dyYW0ocmwsbGwsaGwsaWwsY2wpLGZsPXVsKCk7b2w9eGEucnVuV2ViR0xQcm9ncmFtKHBsLGZsLCJmbG9hdDMyIil9Y29uc3QgZGw9cmVzaGFwZSh7aW5wdXRzOnt4Om9sfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpybC5vdXRTaGFwZX19KTtyZXR1cm4gYWwucHVzaChvbCksYWwuZm9yRWFjaChobD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oaGwpKSxkbH1jb25zdCBmdXNlZENvbnYyRENvbmZpZz17a2VybmVsTmFtZTpGdXNlZENvbnYyRCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6ZnVzZWRDb252MmR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGZ1c2VkRGVwdGh3aXNlQ29udjJEKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsZmlsdGVyOlRhLGJpYXM6d2EscHJlbHVBY3RpdmF0aW9uV2VpZ2h0czpFYX09YWEse3N0cmlkZXM6a2EscGFkOkFhLGRpbGF0aW9uczpGYSxkaW1Sb3VuZGluZ01vZGU6TGEsYWN0aXZhdGlvbjplbCxsZWFreXJlbHVBbHBoYTp0bH09YmEsbmw9W107bGV0IHNsPUZhO3NsPT1udWxsJiYoc2w9WzEsMV0pLGFzc2VydChlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUoa2Esc2wpLCgpPT5gRXJyb3IgaW4gZGVwdGh3aXNlQ29udjJkOiBFaXRoZXIgc3RyaWRlcyBvciBkaWxhdGlvbnMgbXVzdCBiZSAxLiBHb3Qgc3RyaWRlcyAke2thfSBhbmQgZGlsYXRpb25zICcke3NsfSdgKTtjb25zdCBybD1jb21wdXRlQ29udjJESW5mbyhTYS5zaGFwZSxUYS5zaGFwZSxrYSxzbCxBYSxMYSwhMCksb2w9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19ERVBUSFdJU0VDT05WIikmJnJsLnN0cmlkZVdpZHRoPD0yJiZybC5vdXRDaGFubmVscy9ybC5pbkNoYW5uZWxzPT09MSxhbD1lbD9tYXBBY3RpdmF0aW9uVG9TaGFkZXJQcm9ncmFtKGVsLG9sKTpudWxsLGxsPVtTYSxUYV0saWw9d2EhPW51bGwsY2w9RWEhPW51bGwsdWw9ZWw9PT0ibGVha3lyZWx1IjtpZihpbCYmbGwucHVzaCh3YSksY2wmJmxsLnB1c2goRWEpLHVsKXtjb25zdCBmbD14YS5tYWtlVGVuc29ySW5mbyhbXSwiZmxvYXQzMiIsY3JlYXRlU2NhbGFyVmFsdWUodGwsImZsb2F0MzIiKSk7bGwucHVzaChmbCksbmwucHVzaChmbCl9bGV0IGRsO29sP2RsPW5ldyBEZXB0aHdpc2VDb252UGFja2VkMkRQcm9ncmFtKHJsLGlsLGFsLGNsLHVsKTpkbD1uZXcgRGVwdGh3aXNlQ29udjJEUHJvZ3JhbShybCxpbCxhbCxjbCx1bCk7Y29uc3QgaGw9W1tybC5wYWRJbmZvLnRvcCxybC5wYWRJbmZvLmxlZnRdLFtybC5zdHJpZGVIZWlnaHQscmwuc3RyaWRlV2lkdGhdLFtybC5kaWxhdGlvbkhlaWdodCxybC5kaWxhdGlvbldpZHRoXSxbcmwuaW5IZWlnaHQscmwuaW5XaWR0aF1dLHBsPXhhLnJ1bldlYkdMUHJvZ3JhbShkbCxsbCwiZmxvYXQzMiIsaGwpO3JldHVybiBubC5mb3JFYWNoKGZsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhmbCkpLHBsfWNvbnN0IGZ1c2VkRGVwdGh3aXNlQ29udjJEQ29uZmlnPXtrZXJuZWxOYW1lOkZ1c2VkRGVwdGh3aXNlQ29udjJELGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpmdXNlZERlcHRod2lzZUNvbnYyRH07Y2xhc3MgR2F0aGVyTkRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhKXt0aGlzLnNsaWNlRGltPWFhLHRoaXMuc3RyaWRlcz14YSx0aGlzLnBhcmFtc1NoYXBlPVNhLHRoaXMudmFyaWFibGVOYW1lcz1bIngiLCJpbmRpY2VzIl0sdGhpcy5vdXRwdXRTaGFwZT1iYTtjb25zdCBUYT1nZXRDb29yZHNEYXRhVHlwZShiYS5sZW5ndGgpO2xldCB3YT1gCiAgICBpbnQgaW5kZXg7YDtmb3IobGV0IEVhPTA7RWE8dGhpcy5zbGljZURpbTtFYSsrKXdhKz1gCiAgICAgICAgICBpbmRleCA9IHJvdW5kKGdldEluZGljZXMoY29vcmRzWzBdLCAke0VhfSkpOwogICAgICAgICAgb3V0X29mX2JvdW5kcyA9IG91dF9vZl9ib3VuZHMgfHwgaW5kZXggPCAwOwogICAgICAgICAgb3V0X29mX2JvdW5kcyA9IG91dF9vZl9ib3VuZHMgfHwgaW5kZXggPj0gJHt0aGlzLnBhcmFtc1NoYXBlW0VhXX07CiAgICAgICAgICBmbGF0dGVuSW5kZXggKz0gaW5kZXggKiAke3RoaXMuc3RyaWRlc1tFYV19O2A7dGhpcy51c2VyQ29kZT1gCiAgICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgICR7VGF9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgaW50IGZsYXR0ZW5JbmRleCA9IDA7CiAgICAgICAgICBib29sIG91dF9vZl9ib3VuZHMgPSBmYWxzZTsKCiAgICAgICAgICAke3dhfQoKICAgICAgICAgIHNldE91dHB1dChvdXRfb2ZfYm91bmRzID8gMC4wIDogZ2V0WChmbGF0dGVuSW5kZXgsIGNvb3Jkc1sxXSkpOwogICAgICAgIH0KICAgICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gZ2F0aGVyTmQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7cGFyYW1zOmJhLGluZGljZXM6U2F9PWFhLFRhPVNhLnNoYXBlLHdhPVRhW1RhLmxlbmd0aC0xXSxFYT1zaXplRnJvbVNoYXBlKGJhLnNoYXBlKSxba2EsQWEsRmEsTGFdPXByZXBhcmVBbmRWYWxpZGF0ZShiYSxTYSksZWw9cmVzaGFwZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbQWEsd2FdfX0pLHRsPXJlc2hhcGUoe2lucHV0czp7eDpiYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W3NpemVGcm9tU2hhcGUoYmEuc2hhcGUpL0ZhLEZhXX19KTtpZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW2JhLFNhXSl8fGJhLmR0eXBlPT09InN0cmluZyIpe2NvbnN0IG9sPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksYWw9eGEuYnVmZmVyU3luYyhiYSksbGw9Z2F0aGVyTmRJbXBsQ1BVKG9sLGFsLGJhLmR0eXBlLEFhLHdhLEZhLExhLGJhLnNoYXBlLEVhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oa2EsYmEuZHR5cGUsbGwudmFsdWVzKX1jb25zdCBubD1uZXcgR2F0aGVyTkRQcm9ncmFtKHdhLExhLFtBYSxGYV0sYmEuc2hhcGUpLHNsPXhhLnJ1bldlYkdMUHJvZ3JhbShubCxbdGwsZWxdLHRsLmR0eXBlKSxybD1yZXNoYXBlKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmthfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8odGwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSxybH1jb25zdCBnYXRoZXJOZENvbmZpZz17a2VybmVsTmFtZTpHYXRoZXJOZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6Z2F0aGVyTmR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIEdhdGhlclByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiLCJpbmRpY2VzIl0sdGhpcy5vdXRwdXRTaGFwZT14YSx0aGlzLnJhbms9eGEubGVuZ3RoO2NvbnN0IGJhPWdldENvb3Jkc0RhdGFUeXBlKHRoaXMucmFuayksU2E9Z2V0U291cmNlQ29vcmRzJDEoYWEpO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtiYX0gcmVzUkMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgaW5kZXggPSBpbnQoZ2V0SW5kaWNlcyhyZXNSQy54LCByZXNSQy56KSk7CiAgICAgICAgZmxvYXQgaW5Cb3VuZHMgPSAoaW5kZXggPj0gMCkgJiYgKGluZGV4IDwgJHthYVsyXX0pID8gMS4wIDogMC4wOwogICAgICAgIHNldE91dHB1dChpbkJvdW5kcyAqIGdldEEoJHtTYX0pKTsKICAgICAgfQogICAgYH19ZnVuY3Rpb24gZ2V0U291cmNlQ29vcmRzJDEoaGEsYWEpe2NvbnN0IHhhPVsicmVzUkMueCIsInJlc1JDLnkiLCJyZXNSQy56IiwicmVzUkMudyJdLGJhPVtdO2ZvcihsZXQgU2E9MDtTYTxoYS5sZW5ndGg7U2ErKylTYT09PTI/YmEucHVzaCgiaW5kZXgiKTpiYS5wdXNoKGAke3hhW1NhXX1gKTtyZXR1cm4gYmEuam9pbigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGdhdGhlclYyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2EsaW5kaWNlczpUYX09YWEse2F4aXM6d2EsYmF0Y2hEaW1zOkVhfT1iYSxrYT1wYXJzZUF4aXNQYXJhbSh3YSxTYS5zaGFwZSlbMF07aWYoZW52KCkuZ2V0KCJERUJVRyIpKXtjb25zdCBhbD14YS5yZWFkU3luYyhUYS5kYXRhSWQpLGxsPVNhLnNoYXBlW2thXTtmb3IobGV0IGlsPTA7aWw8YWwubGVuZ3RoOysraWwpe2NvbnN0IGNsPWFsW2lsXTthc3NlcnQoY2w8PWxsLTEmJmNsPj0wLCgpPT5gR2F0aGVyVjI6IHRoZSBpbmRleCB2YWx1ZSAke2NsfSBpcyBub3QgaW4gWzAsICR7bGwtMX1dYCl9fWNvbnN0IEFhPWNvbGxlY3RHYXRoZXJPcFNoYXBlSW5mbyhTYSxUYSxrYSxFYSksRmE9c2l6ZUZyb21TaGFwZShUYS5zaGFwZSksTGE9W10sZWw9cmVzaGFwZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbQWEuYmF0Y2hTaXplLEFhLm91dGVyU2l6ZSxBYS5kaW1TaXplLEFhLnNsaWNlU2l6ZV19fSksdGw9cmVzaGFwZSh7aW5wdXRzOnt4OlRhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbQWEuYmF0Y2hTaXplLEZhL0FhLmJhdGNoU2l6ZV19fSk7TGEucHVzaChlbCksTGEucHVzaCh0bCk7Y29uc3Qgbmw9W0FhLmJhdGNoU2l6ZSxBYS5vdXRlclNpemUsRmEvQWEuYmF0Y2hTaXplLEFhLnNsaWNlU2l6ZV07aWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtTYSxUYV0pfHxTYS5kdHlwZT09PSJzdHJpbmciKXtjb25zdCBhbD14YS5idWZmZXJTeW5jKHRsKSxsbD14YS5idWZmZXJTeW5jKGVsKSxpbD1nYXRoZXJWMkltcGxDUFUobGwsYWwsbmwpO3JldHVybiBMYS5mb3JFYWNoKGNsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhjbCkpLHhhLm1ha2VUZW5zb3JJbmZvKEFhLm91dHB1dFNoYXBlLGlsLmR0eXBlLGlsLnZhbHVlcyl9Y29uc3Qgc2w9bmV3IEdhdGhlclByb2dyYW0oZWwuc2hhcGUsbmwpLHJsPXhhLnJ1bldlYkdMUHJvZ3JhbShzbCxbZWwsdGxdLGVsLmR0eXBlKTtMYS5wdXNoKHJsKTtjb25zdCBvbD1yZXNoYXBlKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkFhLm91dHB1dFNoYXBlfX0pO3JldHVybiBMYS5mb3JFYWNoKGFsPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhhbCkpLG9sfWNvbnN0IGdhdGhlclYyQ29uZmlnPXtrZXJuZWxOYW1lOkdhdGhlclYyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpnYXRoZXJWMn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgR1JFQVRFUj0icmV0dXJuIGZsb2F0KGEgPiBiKTsiLEdSRUFURVJfUEFDS0VEPWAKICByZXR1cm4gdmVjNChncmVhdGVyVGhhbihhLCBiKSk7CmAsZ3JlYXRlcj1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6R1JFQVRFUixwYWNrZWRPcFNuaXBwZXQ6R1JFQVRFUl9QQUNLRUQsY3B1S2VybmVsSW1wbDpncmVhdGVySW1wbENQVSxkdHlwZToiYm9vbCJ9KSxncmVhdGVyQ29uZmlnPXtrZXJuZWxOYW1lOkdyZWF0ZXIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmdyZWF0ZXJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IEdSRUFURVJfRVFVQUw9InJldHVybiBmbG9hdChhID49IGIpOyIsR1JFQVRFUl9FUVVBTF9QQUNLRUQ9YAogIHJldHVybiB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoYSwgYikpOwpgLGdyZWF0ZXJFcXVhbD1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6R1JFQVRFUl9FUVVBTCxwYWNrZWRPcFNuaXBwZXQ6R1JFQVRFUl9FUVVBTF9QQUNLRUQsZHR5cGU6ImJvb2wiLGNwdUtlcm5lbEltcGw6Z3JlYXRlckVxdWFsSW1wbENQVX0pLGdyZWF0ZXJFcXVhbENvbmZpZz17a2VybmVsTmFtZTpHcmVhdGVyRXF1YWwsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmdyZWF0ZXJFcXVhbH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gaWZmdChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtpbnB1dDpiYX09YWE7cmV0dXJuIGZmdEltcGwoYmEsITAseGEpfWNvbnN0IGlmZnRDb25maWc9e2tlcm5lbE5hbWU6SUZGVCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6aWZmdH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSVNfRklOSVRFPSJyZXR1cm4gZmxvYXQoIWlzbmFuKHgpICYmICFpc2luZih4KSk7Iixpc0Zpbml0ZSQxPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OklTX0ZJTklURSxkdHlwZToiYm9vbCJ9KSxpc0Zpbml0ZUNvbmZpZz17a2VybmVsTmFtZTpJc0Zpbml0ZSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6aXNGaW5pdGUkMX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSVNfSU5GPSJyZXR1cm4gZmxvYXQoaXNpbmYoeCkpOyIsaXNJbmY9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6SVNfSU5GLGR0eXBlOiJib29sIn0pLGlzSW5mQ29uZmlnPXtrZXJuZWxOYW1lOklzSW5mLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzppc0luZn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgSVNfTkFOPSJyZXR1cm4gZmxvYXQoaXNuYW4oeCkpOyIsaXNOYU4kMT11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpJU19OQU4sZHR5cGU6ImJvb2wifSksaXNOYU5Db25maWc9e2tlcm5lbE5hbWU6SXNOYW4sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmlzTmFOJDF9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExFU1M9InJldHVybiBmbG9hdChhIDwgYik7IixMRVNTX1BBQ0tFRD1gCiAgcmV0dXJuIHZlYzQobGVzc1RoYW4oYSwgYikpOwpgLGxlc3M9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkxFU1MscGFja2VkT3BTbmlwcGV0OkxFU1NfUEFDS0VELGNwdUtlcm5lbEltcGw6bGVzc0ltcGxDUFUsZHR5cGU6ImJvb2wifSksbGVzc0NvbmZpZz17a2VybmVsTmFtZTpMZXNzLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsZXNzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMRVNTX0VRVUFMPSJyZXR1cm4gZmxvYXQoYSA8PSBiKTsiLExFU1NfRVFVQUxfUEFDS0VEPWAKICByZXR1cm4gdmVjNChsZXNzVGhhbkVxdWFsKGEsIGIpKTsKYCxsZXNzRXF1YWw9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkxFU1NfRVFVQUwscGFja2VkT3BTbmlwcGV0OkxFU1NfRVFVQUxfUEFDS0VELGNwdUtlcm5lbEltcGw6bGVzc0VxdWFsSW1wbENQVSxkdHlwZToiYm9vbCJ9KSxsZXNzRXF1YWxDb25maWc9e2tlcm5lbE5hbWU6TGVzc0VxdWFsLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsZXNzRXF1YWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGxpblNwYWNlKGhhKXtjb25zdHtiYWNrZW5kOmFhLGF0dHJzOnhhfT1oYSx7c3RhcnQ6YmEsc3RvcDpTYSxudW06VGF9PXhhLHdhPWxpblNwYWNlSW1wbENQVShiYSxTYSxUYSk7cmV0dXJuIGFhLm1ha2VUZW5zb3JJbmZvKFt3YS5sZW5ndGhdLCJmbG9hdDMyIix3YSl9Y29uc3QgbGluU3BhY2VDb25maWc9e2tlcm5lbE5hbWU6TGluU3BhY2UsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmxpblNwYWNlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMT0c9Q0hFQ0tfTkFOX1NOSVBQRVRfVU5BUlkrYAogIHJldHVybiB4IDwgMC4wID8gMC4vMC4gOiBsb2coeCk7CmAsTE9HX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSBsb2coeCk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiAoeC5yIDwgMC4wID8gMC4vMC4gOiByZXN1bHQucik7CiAgcmVzdWx0LmcgPSBpc05hTi5nID8geC5nIDogKHguZyA8IDAuMCA/IDAuLzAuIDogcmVzdWx0LmcpOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6ICh4LmIgPCAwLjAgPyAwLi8wLiA6IHJlc3VsdC5iKTsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiAoeC5hIDwgMC4wID8gMC4vMC4gOiByZXN1bHQuYSk7CiAgcmV0dXJuIHJlc3VsdDsKYCxsb2c9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6TE9HLHBhY2tlZE9wU25pcHBldDpMT0dfUEFDS0VELGNwdUtlcm5lbEltcGw6bG9nSW1wbENQVX0pLGxvZ0NvbmZpZz17a2VybmVsTmFtZTpMb2csYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmxvZ307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgTE9HMVA9Q0hFQ0tfTkFOX1NOSVBQRVRfVU5BUlkrYAogIHJldHVybiBsb2coMS4wICsgeCk7CmAsbG9nMXA9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6TE9HMVB9KSxsb2cxcENvbmZpZz17a2VybmVsTmFtZTpMb2cxcCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bG9nMXB9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExPR0lDQUxfQU5EPSJyZXR1cm4gZmxvYXQoYSA+PSAxLjAgJiYgYiA+PSAxLjApOyIsTE9HSUNBTF9BTkRfUEFDS0VEPWAKICByZXR1cm4gdmVjNCgKICAgIHZlYzQoZ3JlYXRlclRoYW5FcXVhbChhLCB2ZWM0KDEuMCkpKSAqCiAgICB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoYiwgdmVjNCgxLjApKSkpOwpgLGxvZ2ljYWxBbmQ9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OkxPR0lDQUxfQU5ELHBhY2tlZE9wU25pcHBldDpMT0dJQ0FMX0FORF9QQUNLRUQsZHR5cGU6ImJvb2wifSksbG9naWNhbEFuZENvbmZpZz17a2VybmVsTmFtZTpMb2dpY2FsQW5kLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpsb2dpY2FsQW5kfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBMT0dJQ0FMX05PVD0icmV0dXJuIGZsb2F0KCEoeCA+PSAxLjApKTsiLGxvZ2ljYWxOb3Q9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6TE9HSUNBTF9OT1R9KSxsb2dpY2FsTm90Q29uZmlnPXtrZXJuZWxOYW1lOkxvZ2ljYWxOb3QsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOmxvZ2ljYWxOb3R9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IExPR0lDQUxfT1I9InJldHVybiBmbG9hdChhID49IDEuMCB8fCBiID49IDEuMCk7IixMT0dJQ0FMX09SX1BBQ0tFRD1gCiAgcmV0dXJuIG1pbigKICAgIHZlYzQoZ3JlYXRlclRoYW5FcXVhbChhLCB2ZWM0KDEuMCkpKSArCiAgICB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoYiwgdmVjNCgxLjApKSksCiAgICB2ZWM0KDEuMCkpOwpgLGxvZ2ljYWxPcj1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6TE9HSUNBTF9PUixwYWNrZWRPcFNuaXBwZXQ6TE9HSUNBTF9PUl9QQUNLRUQsZHR5cGU6ImJvb2wifSksbG9naWNhbE9yQ29uZmlnPXtrZXJuZWxOYW1lOkxvZ2ljYWxPcixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bG9naWNhbE9yfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBMUk5Qcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0sdGhpcy5vdXRwdXRTaGFwZT1bXTtjb25zdCB3YT14YSxFYT1hYVszXS0xO3RoaXMub3V0cHV0U2hhcGU9YWE7bGV0IGthO2NvbnN0IEFhPWBmbG9hdCgke2JhfSkgKyBmbG9hdCgke1NhfSkgKiBzdW1gO1RhPT09LjU/a2E9YGludmVyc2VzcXJ0KCR7QWF9KWA6VGE9PT0xP2thPWAxLjAvKCR7QWF9KWA6a2E9YGV4cChsb2coJHtBYX0pICogZmxvYXQoLSR7VGF9KSk7YCx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCByID0gY29vcmRzWzFdOwogICAgICAgIGludCBjID0gY29vcmRzWzJdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwogICAgICAgIGZsb2F0IHggPSBnZXRYKGIsIHIsIGMsIGQpOwogICAgICAgIGZsb2F0IHN1bSA9IDAuMDsKICAgICAgICBmb3IgKGludCBqID0gLSR7d2F9OyBqIDw9ICR7d2F9OyBqKyspIHsKICAgICAgICAgIGludCBpZHggPSBkICsgajsKICAgICAgICAgIGlmIChpZHggPj0gMCAmJiBpZHggPD0gICR7RWF9KSB7CiAgICAgICAgICAgIGZsb2F0IHogPSBnZXRYKGIsIHIsIGMsIGlkeCk7CiAgICAgICAgICAgIHN1bSArPSB6ICogejsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmxvYXQgdmFsID0geCAqICR7a2F9OwogICAgICAgIHNldE91dHB1dCh2YWwpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBMUk5QYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0sdGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMDtjb25zdCB3YT14YSxFYT1hYVszXS0xO3RoaXMub3V0cHV0U2hhcGU9YWE7bGV0IGthO2NvbnN0IEFhPWBmbG9hdCgke2JhfSkgKyBmbG9hdCgke1NhfSkgKiBzdW1gO1RhPT09LjU/a2E9YGludmVyc2VzcXJ0KCR7QWF9KWA6VGE9PT0xP2thPWAxLjAvKCR7QWF9KWA6a2E9YGV4cChsb2coJHtBYX0pICogZmxvYXQoLSR7VGF9KSk7YCx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzLng7CiAgICAgICAgaW50IHIgPSBjb29yZHMueTsKICAgICAgICBpbnQgYyA9IGNvb3Jkcy56OwogICAgICAgIGludCBkID0gY29vcmRzLnc7CgogICAgICAgIGJvb2wgaGFzTmV4dENvbCA9IGQgPCAke3RoaXMub3V0cHV0U2hhcGVbM119OwogICAgICAgIGJvb2wgaGFzTmV4dFJvdyA9IGMgPCAke3RoaXMub3V0cHV0U2hhcGVbMl19OwoKICAgICAgICB2ZWM0IHN1bSA9IHZlYzQoMC4pOwogICAgICAgIHZlYzQgeEZyYWdBdE91dHB1dENvb3JkcyA9IGdldFgoYiwgciwgYywgZCk7CgogICAgICAgIHZlYzQgeEF0T3V0cHV0Q29vcmRzID0gdmVjNCgKICAgICAgICAgIGdldENoYW5uZWwoeEZyYWdBdE91dHB1dENvb3JkcywgdmVjMihjLCBkKSksCiAgICAgICAgICBoYXNOZXh0Q29sID8KICAgICAgICAgICAgZ2V0Q2hhbm5lbCh4RnJhZ0F0T3V0cHV0Q29vcmRzLCB2ZWMyKGMsIGQgKyAxKSkgOiAwLjAsCiAgICAgICAgICBoYXNOZXh0Um93ID8KICAgICAgICAgICAgZ2V0Q2hhbm5lbCh4RnJhZ0F0T3V0cHV0Q29vcmRzICwgdmVjMihjICsgMSwgZCkpIDogMC4wLAogICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPwogICAgICAgICAgICBnZXRDaGFubmVsKHhGcmFnQXRPdXRwdXRDb29yZHMsIHZlYzIoYyArIDEsIGQgKyAxKSkgOiAwLjAKICAgICAgICApOwoKICAgICAgICBpbnQgZmlyc3RDaGFubmVsID0gZCAtICR7d2F9OwogICAgICAgIHZlYzIgY2FjaGUgPSB2ZWMyKDAuKTsKICAgICAgICBpZihmaXJzdENoYW5uZWwgPj0gMCl7CiAgICAgICAgICB2ZWM0IGZpcnN0Q2hhbm5lbEZyYWcgPSBnZXRYKGIsIHIsIGMsIGZpcnN0Q2hhbm5lbCk7CiAgICAgICAgICBjYWNoZS54ID0gZ2V0Q2hhbm5lbChmaXJzdENoYW5uZWxGcmFnLCB2ZWMyKGMsIGZpcnN0Q2hhbm5lbCkpOwogICAgICAgICAgICBpZihoYXNOZXh0Um93KXsKICAgICAgICAgICAgICBjYWNoZS55ID0gZ2V0Q2hhbm5lbChmaXJzdENoYW5uZWxGcmFnLCB2ZWMyKGMgKyAxLCBmaXJzdENoYW5uZWwpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaXZlYzIgZGVwdGggPSBpdmVjMihkLCBkICsgMSk7CiAgICAgICAgZm9yIChpbnQgaiA9IC0gJHt3YX07IGogPD0gJHt3YX07IGorKykgewogICAgICAgICAgaXZlYzIgaWR4ID0gZGVwdGggKyBqOwogICAgICAgICAgYnZlYzIgYWJvdmVMb3dlckJvdW5kID0gZ3JlYXRlclRoYW5FcXVhbChpZHgsIGl2ZWMyKDApKTsKICAgICAgICAgIGJ2ZWMyIGJlbG93VXBwZXJCb3VuZCA9IGxlc3NUaGFuRXF1YWwoaWR4LCBpdmVjMigke0VhfSkpOwoKICAgICAgICAgIGJvb2wgZGVwdGhJblJhbmdlID0gYWJvdmVMb3dlckJvdW5kLnggJiYgYmVsb3dVcHBlckJvdW5kLng7CiAgICAgICAgICBib29sIGRlcHRoUGx1c09uZUluUmFuZ2UgPSBhYm92ZUxvd2VyQm91bmQueSAmJiBiZWxvd1VwcGVyQm91bmQueTsKCiAgICAgICAgICBpZihkZXB0aEluUmFuZ2UgfHwgZGVwdGhQbHVzT25lSW5SYW5nZSl7CiAgICAgICAgICAgIHZlYzQgeiA9IHZlYzQoMC4pOwogICAgICAgICAgICB2ZWM0IHhGcmFnQXRDdXJyZW50RGVwdGg7CiAgICAgICAgICAgIHoueHogPSBjYWNoZS54eTsKICAgICAgICAgICAgaWYoZGVwdGhQbHVzT25lSW5SYW5nZSAmJiBoYXNOZXh0Q29sKXsKICAgICAgICAgICAgICB4RnJhZ0F0Q3VycmVudERlcHRoID0gaWR4LnkgIT0gZCA/CiAgICAgICAgICAgICAgICBnZXRYKGIsIHIsIGMsIGlkeC55KSA6IHhGcmFnQXRPdXRwdXRDb29yZHM7CiAgICAgICAgICAgICAgei55ID0gZ2V0Q2hhbm5lbCh4RnJhZ0F0Q3VycmVudERlcHRoLCB2ZWMyKGMsIGlkeC55KSk7CiAgICAgICAgICAgICAgaWYoaGFzTmV4dFJvdyl7CiAgICAgICAgICAgICAgICB6LncgPSBnZXRDaGFubmVsKHhGcmFnQXRDdXJyZW50RGVwdGgsIHZlYzIoYyArIDEsIGlkeC55KSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhY2hlLnh5ID0gei55dzsKICAgICAgICAgICAgc3VtICs9IHogKiB6OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB2ZWM0IHJlc3VsdCA9IHhBdE91dHB1dENvb3JkcyAqICR7a2F9OwogICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBscm49aGE9Pntjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtkZXB0aFJhZGl1czpUYSxiaWFzOndhLGFscGhhOkVhLGJldGE6a2F9PWJhLEFhPWVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfTk9STUFMSVpBVElPTiIpP25ldyBMUk5QYWNrZWRQcm9ncmFtKFNhLnNoYXBlLFRhLHdhLEVhLGthKTpuZXcgTFJOUHJvZ3JhbShTYS5zaGFwZSxUYSx3YSxFYSxrYSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShBYSxbU2FdLFNhLmR0eXBlKX0sTFJOQ29uZmlnPXtrZXJuZWxOYW1lOkxSTixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bHJufTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBMUk5HcmFkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiaW5wdXRJbWFnZSIsIm91dHB1dEltYWdlIiwiZHkiXSx0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy5kZXB0aD1hYVszXSx0aGlzLmRlcHRoUmFkaXVzPXhhLHRoaXMuYmlhcz1iYSx0aGlzLmFscGhhPVNhLHRoaXMuYmV0YT1UYSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCByID0gY29vcmRzWzFdOwogICAgICAgIGludCBjID0gY29vcmRzWzJdOwoKICAgICAgICBmbG9hdCByZXN1bHQgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgZCA9IDA7IGQgPCAke3RoaXMuZGVwdGh9OyArK2QpIHsKICAgICAgICAgIGludCBkZXB0aEJlZ2luID0gaW50KG1heCgwLjAsIGZsb2F0KGQgLSAke3hhfSkpKTsKICAgICAgICAgIGludCBkZXB0aEVuZCA9IGludChtaW4oZmxvYXQoJHt0aGlzLmRlcHRofSksCiAgICAgICAgICAgICAgZmxvYXQoZCArICR7eGF9ICsgMSkpKTsKCiAgICAgICAgICBjb25zdCBpbnQgTUlOX0RFUFRIX0JFR0lOID0gMDsKICAgICAgICAgIGNvbnN0IGludCBNQVhfREVQVEhfRU5EID0gJHt0aGlzLmRlcHRofTsKCiAgICAgICAgICBmbG9hdCBub3JtID0gMC4wOwogICAgICAgICAgZm9yIChpbnQgayA9IE1JTl9ERVBUSF9CRUdJTjsgayA8IE1BWF9ERVBUSF9FTkQ7ICsraykgewogICAgICAgICAgICBpZiAoayA8IGRlcHRoQmVnaW4pewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGsgPj0gZGVwdGhCZWdpbiAmJiBrIDwgZGVwdGhFbmQpIHsKICAgICAgICAgICAgICBub3JtICs9IGdldElucHV0SW1hZ2UoYiwgciwgYywgaykgKiBnZXRJbnB1dEltYWdlKGIsIHIsIGMsIGspOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgbm9ybSA9IGZsb2F0KCR7U2F9KSAqIG5vcm0gKyBmbG9hdCgke2JhfSk7CgogICAgICAgICAgZm9yKGludCBrID0gTUlOX0RFUFRIX0JFR0lOOyBrIDwgTUFYX0RFUFRIX0VORDsgKytrKXsKICAgICAgICAgICAgaWYgKGsgPCBkZXB0aEJlZ2luKXsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChrID49IGRlcHRoQmVnaW4gJiYgayA8IGRlcHRoRW5kKXsKICAgICAgICAgICAgICBmbG9hdCBkeWkgPSAtMi4wICogZmxvYXQoJHtTYX0pCiAgICAgICAgICAgICAgICAqIGZsb2F0KCR7VGF9KQogICAgICAgICAgICAgICAgKiBnZXRJbnB1dEltYWdlKGIsIHIsIGMsIGspICogZ2V0T3V0cHV0SW1hZ2UoYiwgciwgYywgZCkKICAgICAgICAgICAgICAgIC8gbm9ybTsKICAgICAgICAgICAgICBpZiAoayA9PSBkKSB7CiAgICAgICAgICAgICAgICBkeWkgKz0gcG93KG5vcm0sIC0xLjAgKiAke1RhfSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChrID09IGNvb3Jkc1szXSkgewogICAgICAgICAgICAgICAgZHlpICo9IGdldER5KGIsIHIsIGMsIGQpOwogICAgICAgICAgICAgICAgcmVzdWx0ICs9IGR5aTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgfQogICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbHJuR3JhZD1oYT0+e2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSx5OlRhLGR5OndhfT1hYSx7ZGVwdGhSYWRpdXM6RWEsYmlhczprYSxhbHBoYTpBYSxiZXRhOkZhfT1iYSxMYT1uZXcgTFJOR3JhZFByb2dyYW0oU2Euc2hhcGUsRWEsa2EsQWEsRmEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oTGEsW1NhLFRhLHdhXSxTYS5kdHlwZSl9LExSTkdyYWRDb25maWc9e2tlcm5lbE5hbWU6TFJOR3JhZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bHJuR3JhZH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gbWF4SW1wbChoYSxhYSx4YSxiYSl7Y29uc3QgU2E9c2l6ZUZyb21TaGFwZShhYSksd2E9c2l6ZUZyb21TaGFwZShoYS5zaGFwZSkvU2EsRWE9cmVzaGFwZSh7aW5wdXRzOnt4OmhhfSxhdHRyczp7c2hhcGU6W3dhLFNhXX0sYmFja2VuZDpiYX0pLGthPXJlZHVjZShFYSxoYS5kdHlwZSwibWF4IixiYSksQWE9cmVzaGFwZSh7aW5wdXRzOnt4OmthfSxhdHRyczp7c2hhcGU6eGF9LGJhY2tlbmQ6YmF9KTtyZXR1cm4gYmEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oRWEpLGJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGthKSxBYX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXgoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse3JlZHVjdGlvbkluZGljZXM6VGEsa2VlcERpbXM6d2F9PWJhLEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1wYXJzZUF4aXNQYXJhbShUYSxTYS5zaGFwZSk7bGV0IEFhPWthO2NvbnN0IEZhPWdldEF4ZXNQZXJtdXRhdGlvbihBYSxFYSksTGE9RmEhPW51bGwsZWw9eGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtTYV0pO2xldCB0bD1TYTtpZihMYSl7aWYoZWwpe2NvbnN0IGxsPXhhLnRleERhdGEuZ2V0KHRsLmRhdGFJZCkudmFsdWVzLGlsPW5ldyBBcnJheShFYSk7Zm9yKGxldCBkbD0wO2RsPGlsLmxlbmd0aDtkbCsrKWlsW2RsXT1TYS5zaGFwZVtGYVtkbF1dO2NvbnN0IGNsPXRyYW5zcG9zZUltcGxDUFUobGwsU2Euc2hhcGUsU2EuZHR5cGUsRmEsaWwpO3RsPXhhLm1ha2VUZW5zb3JJbmZvKGlsLFNhLmR0eXBlKTtjb25zdCB1bD14YS50ZXhEYXRhLmdldCh0bC5kYXRhSWQpO3VsLnZhbHVlcz1jbH1lbHNlIHRsPXRyYW5zcG9zZUltcGwoU2EsRmEseGEpO0FhPWdldElubmVyTW9zdEF4ZXMoQWEubGVuZ3RoLEVhKX1hc3NlcnRBeGVzQXJlSW5uZXJNb3N0RGltcygibWF4IixBYSxFYSk7Y29uc3Rbbmwsc2xdPWNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXModGwuc2hhcGUsQWEpO2xldCBybD1ubDt3YSYmKHJsPWV4cGFuZFNoYXBlVG9LZWVwRGltKG5sLGthKSk7bGV0IG9sO2lmKGVsKXtjb25zdCBsbD14YS50ZXhEYXRhLmdldCh0bC5kYXRhSWQpLnZhbHVlcyxpbD1tYXhJbXBsQ1BVKGxsLHNpemVGcm9tU2hhcGUoc2wpLHJsLFNhLmR0eXBlKTtvbD14YS5tYWtlVGVuc29ySW5mbyhybCxTYS5kdHlwZSk7Y29uc3QgY2w9eGEudGV4RGF0YS5nZXQob2wuZGF0YUlkKTtjbC52YWx1ZXM9aWx9ZWxzZSBvbD1tYXhJbXBsKHRsLHNsLHJsLHhhKTtyZXR1cm4gTGEmJnhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSxvbH1jb25zdCBtYXhDb25maWc9e2tlcm5lbE5hbWU6TWF4LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptYXh9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE1BWElNVU09Q0hFQ0tfTkFOX1NOSVBQRVQrYAogIHJldHVybiBtYXgoYSwgYik7CmAsTUFYSU1VTV9QQUNLRUQ9YAogIHZlYzQgcmVzdWx0ID0gdmVjNChtYXgoYSwgYikpOwogIGJ2ZWM0IGlzTmFOQSA9IGlzbmFuKGEpOwogIGJ2ZWM0IGlzTmFOQiA9IGlzbmFuKGIpOwogIGJ2ZWM0IGlzTmFOID0gYnZlYzQoaXNOYU5BLnggfHwgaXNOYU5CLngsIGlzTmFOQS55IHx8IGlzTmFOQi55LCBpc05hTkEueiB8fCBpc05hTkIueiwgaXNOYU5BLncgfHwgaXNOYU5CLncpOwogIGArQ0hFQ0tfTkFOX1NOSVBQRVRfUEFDS0VEK2AKICByZXR1cm4gcmVzdWx0OwpgLG1heGltdW09YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0Ok1BWElNVU0scGFja2VkT3BTbmlwcGV0Ok1BWElNVU1fUEFDS0VELGNwdUtlcm5lbEltcGw6bWF4aW11bUltcGxDUFV9KSxtYXhpbXVtQ29uZmlnPXtrZXJuZWxOYW1lOk1heGltdW0sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1heGltdW19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2woaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWE7YXNzZXJ0Tm90Q29tcGxleChTYSwibWF4UG9vbCIpO2NvbnN0e2ZpbHRlclNpemU6VGEsc3RyaWRlczp3YSxwYWQ6RWEsZGltUm91bmRpbmdNb2RlOmthfT1iYSxBYT0xO2Fzc2VydChlaXRoZXJTdHJpZGVzT3JEaWxhdGlvbnNBcmVPbmUod2EsQWEpLCgpPT5gRXJyb3IgaW4gbWF4UG9vbDogRWl0aGVyIHN0cmlkZXMgb3IgZGlsYXRpb25zIG11c3QgYmUgMS4gR290IHN0cmlkZXMgJHt3YX0gYW5kIGRpbGF0aW9ucyAnJHtBYX0nYCk7Y29uc3QgRmE9Y29tcHV0ZVBvb2wyREluZm8oU2Euc2hhcGUsVGEsd2EsQWEsRWEsa2EpO2lmKEZhLmZpbHRlcldpZHRoPT09MSYmRmEuZmlsdGVySGVpZ2h0PT09MSYmYXJyYXlzRXF1YWwoRmEuaW5TaGFwZSxGYS5vdXRTaGFwZSkpcmV0dXJuIGlkZW50aXR5KHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGF9KTtjb25zdCBMYT1uZXcgUG9vbDJEUHJvZ3JhbShGYSwibWF4IiwhMSk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShMYSxbU2FdLFNhLmR0eXBlKX1jb25zdCBtYXhQb29sQ29uZmlnPXtrZXJuZWxOYW1lOk1heFBvb2wsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1heFBvb2x9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2wzZChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7ZmlsdGVyU2l6ZTpUYSxzdHJpZGVzOndhLHBhZDpFYSxkYXRhRm9ybWF0OmthLGRpbVJvdW5kaW5nTW9kZTpBYX09YmEsRmE9WzEsMSwxXSxMYT1jb21wdXRlUG9vbDNESW5mbyhTYS5zaGFwZSxUYSx3YSxGYSxFYSxBYSxrYSksZWw9bmV3IFBvb2wzRFByb2dyYW0oTGEsIm1heCIsITEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oZWwsW1NhXSxTYS5kdHlwZSl9Y29uc3QgbWF4UG9vbDNEQ29uZmlnPXtrZXJuZWxOYW1lOk1heFBvb2wzRCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bWF4UG9vbDNkfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBNYXhQb29sMkRCYWNrcHJvcFByb2dyYW17Y29uc3RydWN0b3IoYWEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5IiwibWF4UG9zIl0sdGhpcy5vdXRwdXRTaGFwZT1hYS5pblNoYXBlO2NvbnN0IHhhPWFhLnN0cmlkZUhlaWdodCxiYT1hYS5zdHJpZGVXaWR0aCxTYT1hYS5kaWxhdGlvbkhlaWdodCxUYT1hYS5lZmZlY3RpdmVGaWx0ZXJIZWlnaHQsd2E9YWEuZWZmZWN0aXZlRmlsdGVyV2lkdGgsRWE9VGEtMS1hYS5wYWRJbmZvLnRvcCxrYT13YS0xLWFhLnBhZEluZm8ubGVmdCxBYT1UYSp3YS0xO3RoaXMudXNlckNvZGU9YAogICAgICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHtFYX0sICR7a2F9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKCiAgICAgICAgaXZlYzIgZHlSQ0Nvcm5lciA9IGNvb3Jkcy55eiAtIHBhZHM7CiAgICAgICAgaW50IGR5UkNvcm5lciA9IGR5UkNDb3JuZXIueDsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlSQ0Nvcm5lci55OwoKICAgICAgICAvLyBDb252b2x2ZSBkeSg/LCA/LCBkKSB3aXRoIHBvcyBtYXNrKDosIDosIGQpIHRvIGdldCBkeCh4UiwgeEMsIGQpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgd1IgPSAwOyB3UiA8ICR7VGF9OwogICAgICAgICAgd1IgKz0gJHtTYX0pIHsKICAgICAgICAgIGZsb2F0IGR5UiA9IGZsb2F0KGR5UkNvcm5lciArIHdSKSAvICR7eGF9LjA7CgogICAgICAgICAgaWYgKGR5UiA8IDAuMCB8fCBkeVIgPj0gJHthYS5vdXRIZWlnaHR9LjAgfHwgZnJhY3QoZHlSKSA+IDAuMCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBpZHlSID0gaW50KGR5Uik7CgogICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7d2F9OyB3QysrKSB7CiAgICAgICAgICAgIGZsb2F0IGR5QyA9IGZsb2F0KGR5Q0Nvcm5lciArIHdDKSAvICR7YmF9LjA7CgogICAgICAgICAgICBpZiAoZHlDIDwgMC4wIHx8IGR5QyA+PSAke2FhLm91dFdpZHRofS4wIHx8CiAgICAgICAgICAgICAgICBmcmFjdChkeUMpID4gMC4wKSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGlkeUMgPSBpbnQoZHlDKTsKCiAgICAgICAgICAgIGZsb2F0IGR5VmFsdWUgPSBnZXREeShiLCBpZHlSLCBpZHlDLCBkKTsKICAgICAgICAgICAgaW50IG1heFBvc1ZhbHVlID0gJHtBYX0gLSBpbnQoZ2V0TWF4UG9zKGIsIGlkeVIsIGlkeUMsIGQpKTsKCiAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCB2YWx1ZSwgY2hlY2sgaXQgYWdhaW5zdCB0aGUgdmFsdWUgZnJvbSB0aGUKICAgICAgICAgICAgLy8gcG9zaXRpb24gbWF0cml4LgogICAgICAgICAgICBpbnQgY3VyUG9zVmFsdWUgPSB3UiAqICR7d2F9ICsgd0M7CiAgICAgICAgICAgIGZsb2F0IG1hc2sgPSBmbG9hdChtYXhQb3NWYWx1ZSA9PSBjdXJQb3NWYWx1ZSA/IDEuMCA6IDAuMCk7CgogICAgICAgICAgICBkb3RQcm9kICs9IGR5VmFsdWUgKiBtYXNrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoZG90UHJvZCk7CiAgICAgIH0KICAgIGB9fWNsYXNzIE1heFBvb2wzREJhY2twcm9wUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiZHkiLCJtYXhQb3MiXSx0aGlzLm91dHB1dFNoYXBlPWFhLmluU2hhcGU7Y29uc3QgeGE9YWEuc3RyaWRlRGVwdGgsYmE9YWEuc3RyaWRlSGVpZ2h0LFNhPWFhLnN0cmlkZVdpZHRoLFRhPWFhLmRpbGF0aW9uRGVwdGgsd2E9YWEuZGlsYXRpb25IZWlnaHQsRWE9YWEuZGlsYXRpb25XaWR0aCxrYT1hYS5lZmZlY3RpdmVGaWx0ZXJEZXB0aCxBYT1hYS5lZmZlY3RpdmVGaWx0ZXJIZWlnaHQsRmE9YWEuZWZmZWN0aXZlRmlsdGVyV2lkdGgsTGE9a2EtMS1hYS5wYWRJbmZvLmZyb250LGVsPUFhLTEtYWEucGFkSW5mby50b3AsdGw9RmEtMS1hYS5wYWRJbmZvLmxlZnQsbmw9a2EqQWEqRmEtMTt0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgaXZlYzMgcGFkcyA9IGl2ZWMzKCR7TGF9LCAke2VsfSwgJHt0bH0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM1IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkcy54OwogICAgICAgIGludCBjaCA9IGNvb3Jkcy51OwoKICAgICAgICBpdmVjMyBkeUNvcm5lciA9IGl2ZWMzKGNvb3Jkcy55LCBjb29yZHMueiwgY29vcmRzLncpIC0gcGFkczsKICAgICAgICBpbnQgZHlEQ29ybmVyID0gZHlDb3JuZXIueDsKICAgICAgICBpbnQgZHlSQ29ybmVyID0gZHlDb3JuZXIueTsKICAgICAgICBpbnQgZHlDQ29ybmVyID0gZHlDb3JuZXIuejsKCiAgICAgICAgLy8gQ29udm9sdmUgZHkoPywgPywgPywgY2gpIHdpdGggcG9zIG1hc2soOiwgOiwgOiwgZCkgdG8gZ2V0CiAgICAgICAgLy8gZHgoeEQsIHhSLCB4QywgY2gpLgogICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLgogICAgICAgIGZsb2F0IGRvdFByb2QgPSAwLjA7CgogICAgICAgIGZvciAoaW50IHdEID0gMDsgd0QgPCAke2thfTsKICAgICAgICAgICB3RCArPSAke1RhfSkgewogICAgICAgICAgZmxvYXQgZHlEID0gZmxvYXQoZHlEQ29ybmVyICsgd0QpIC8gJHt4YX0uMDsKCiAgICAgICAgICBpZiAoZHlEIDwgMC4wIHx8IGR5RCA+PSAke2FhLm91dERlcHRofS4wIHx8IGZyYWN0KGR5RCkgPiAwLjApIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CiAgICAgICAgICBpbnQgaWR5RCA9IGludChkeUQpOwoKICAgICAgICAgIGZvciAoaW50IHdSID0gMDsgd1IgPCAke0FhfTsKICAgICAgICAgICAgICB3UiArPSAke3dhfSkgewogICAgICAgICAgICBmbG9hdCBkeVIgPSBmbG9hdChkeVJDb3JuZXIgKyB3UikgLyAke2JhfS4wOwoKICAgICAgICAgICAgaWYgKGR5UiA8IDAuMCB8fCBkeVIgPj0gJHthYS5vdXRIZWlnaHR9LjAgfHwKICAgICAgICAgICAgICAgIGZyYWN0KGR5UikgPiAwLjApIHsKICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWR5UiA9IGludChkeVIpOwoKICAgICAgICAgICAgZm9yIChpbnQgd0MgPSAwOyB3QyA8ICR7RmF9OwogICAgICAgICAgICAgICAgd0MgKz0gJHtFYX0pIHsKICAgICAgICAgICAgICBmbG9hdCBkeUMgPSBmbG9hdChkeUNDb3JuZXIgKyB3QykgLyAke1NhfS4wOwoKICAgICAgICAgICAgICBpZiAoZHlDIDwgMC4wIHx8IGR5QyA+PSAke2FhLm91dFdpZHRofS4wIHx8CiAgICAgICAgICAgICAgICAgIGZyYWN0KGR5QykgPiAwLjApIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpbnQgaWR5QyA9IGludChkeUMpOwoKICAgICAgICAgICAgICBmbG9hdCBkeVZhbHVlID0gZ2V0RHkoYmF0Y2gsIGlkeUQsIGlkeVIsIGlkeUMsIGNoKTsKICAgICAgICAgICAgICBpbnQgbWF4UG9zVmFsdWUgPSAke25sfSAtCiAgICAgICAgICAgICAgICAgIGludChnZXRNYXhQb3MoYmF0Y2gsIGlkeUQsIGlkeVIsIGlkeUMsIGNoKSk7CgogICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCB2YWx1ZSwgY2hlY2sgaXQgYWdhaW5zdCB0aGUgdmFsdWUgZnJvbSB0aGUKICAgICAgICAgICAgICAvLyBwb3NpdGlvbiBtYXRyaXguCiAgICAgICAgICAgICAgaW50IGN1clBvc1ZhbHVlID0KICAgICAgICAgICAgICAgICAgd0QgKiAke0FhfSAqICR7RmF9ICsKICAgICAgICAgICAgICAgICAgd1IgKiAke0ZhfSArIHdDOwogICAgICAgICAgICAgIGZsb2F0IG1hc2sgPSBmbG9hdChtYXhQb3NWYWx1ZSA9PSBjdXJQb3NWYWx1ZSA/IDEuMCA6IDAuMCk7CgogICAgICAgICAgICAgIGRvdFByb2QgKz0gZHlWYWx1ZSAqIG1hc2s7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0T3V0cHV0KGRvdFByb2QpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhQb29sM0RHcmFkKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2R5OlNhLGlucHV0OlRhfT1hYSx3YT1UYSx7ZmlsdGVyU2l6ZTpFYSxzdHJpZGVzOmthLHBhZDpBYSxkaW1Sb3VuZGluZ01vZGU6RmF9PWJhLExhPVsxLDEsMV0sZWw9Y29tcHV0ZVBvb2wzREluZm8od2Euc2hhcGUsRWEsa2EsTGEsQWEsRmEpLHRsPW5ldyBQb29sM0RQcm9ncmFtKGVsLCJtYXgiLCEwKSxubD14YS5ydW5XZWJHTFByb2dyYW0odGwsW3dhXSx3YS5kdHlwZSksc2w9bmV3IE1heFBvb2wzREJhY2twcm9wUHJvZ3JhbShlbCkscmw9eGEucnVuV2ViR0xQcm9ncmFtKHNsLFtTYSxubF0sd2EuZHR5cGUpO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhubCkscmx9Y29uc3QgbWF4UG9vbDNER3JhZENvbmZpZz17a2VybmVsTmFtZTpNYXhQb29sM0RHcmFkLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptYXhQb29sM0RHcmFkfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtYXhQb29sR3JhZChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtkeTpTYSxpbnB1dDpUYSxvdXRwdXQ6d2F9PWFhLEVhPVRhO2Fzc2VydE5vdENvbXBsZXgoW1RhLHdhXSwibWF4UG9vbEdyYWQiKTtjb25zdHtmaWx0ZXJTaXplOmthLHN0cmlkZXM6QWEscGFkOkZhLGRpbVJvdW5kaW5nTW9kZTpMYX09YmEsZWw9Y29tcHV0ZVBvb2wyREluZm8oRWEuc2hhcGUsa2EsQWEsMSxGYSxMYSksdGw9ITAsbmw9bmV3IFBvb2wyRFByb2dyYW0oZWwsIm1heCIsdGwpLHNsPXhhLnJ1bldlYkdMUHJvZ3JhbShubCxbRWFdLEVhLmR0eXBlKSxybD1uZXcgTWF4UG9vbDJEQmFja3Byb3BQcm9ncmFtKGVsKSxvbD14YS5ydW5XZWJHTFByb2dyYW0ocmwsW1NhLHNsXSxFYS5kdHlwZSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSxvbH1jb25zdCBtYXhQb29sR3JhZENvbmZpZz17a2VybmVsTmFtZTpNYXhQb29sR3JhZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bWF4UG9vbEdyYWR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1heFBvb2xXaXRoQXJnbWF4SW1wbChoYSxhYSx4YSxiYSl7bGV0IFNhPW5ldyBQb29sMkRQcm9ncmFtKHhhLCJtYXgiLCExKTtjb25zdCBUYT1iYS5ydW5XZWJHTFByb2dyYW0oU2EsW2hhXSwiZmxvYXQzMiIpO1NhPW5ldyBQb29sMkRQcm9ncmFtKHhhLCJtYXgiLCEwLCEwLGFhKTtjb25zdCB3YT1iYS5ydW5XZWJHTFByb2dyYW0oU2EsW2hhXSwiZmxvYXQzMiIpO3JldHVybltUYSx3YV19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWF4UG9vbFdpdGhBcmdtYXhDb25maWc9e2tlcm5lbE5hbWU6TWF4UG9vbFdpdGhBcmdtYXgsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOih7aW5wdXRzOmhhLGF0dHJzOmFhLGJhY2tlbmQ6eGF9KT0+e2NvbnN0e3g6YmF9PWhhLHtmaWx0ZXJTaXplOlNhLHN0cmlkZXM6VGEscGFkOndhLGluY2x1ZGVCYXRjaEluSW5kZXg6RWF9PWFhLGthPXhhO2Fzc2VydChiYS5zaGFwZS5sZW5ndGg9PT00LCgpPT5gRXJyb3IgaW4gbWF4UG9vbDogaW5wdXQgbXVzdCBiZSByYW5rIDQgYnV0IGdvdCByYW5rICR7YmEuc2hhcGUubGVuZ3RofS5gKTtjb25zdCBBYT1bMSwxXTthc3NlcnQoZWl0aGVyU3RyaWRlc09yRGlsYXRpb25zQXJlT25lKFRhLEFhKSwoKT0+YEVycm9yIGluIG1heFBvb2w6IEVpdGhlciBzdHJpZGVzIG9yIGRpbGF0aW9ucyBtdXN0IGJlIDEuIEdvdCBzdHJpZGVzICR7VGF9IGFuZCBkaWxhdGlvbnMgJyR7QWF9J2ApO2NvbnN0IEZhPWNvbXB1dGVQb29sMkRJbmZvKGJhLnNoYXBlLFNhLFRhLEFhLHdhKSxbTGEsZWxdPW1heFBvb2xXaXRoQXJnbWF4SW1wbChiYSxFYSxGYSxrYSk7cmV0dXJuW0xhLGVsXX19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG1lYW5JbXBsKGhhLGFhLHhhLGJhKXtjb25zdCBTYT1zaXplRnJvbVNoYXBlKGFhKSx3YT1zaXplRnJvbVNoYXBlKGhhLnNoYXBlKS9TYSxFYT1yZXNoYXBlKHtpbnB1dHM6e3g6aGF9LGF0dHJzOntzaGFwZTpbd2EsU2FdfSxiYWNrZW5kOmJhfSksa2E9cmVkdWNlKEVhLCJmbG9hdDMyIiwibWVhbiIsYmEpLEFhPXJlc2hhcGUoe2lucHV0czp7eDprYX0sYXR0cnM6e3NoYXBlOnhhfSxiYWNrZW5kOmJhfSk7cmV0dXJuIGJhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEVhKSxiYS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhrYSksQWF9LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWVhbkNvbmZpZz17a2VybmVsTmFtZTpNZWFuLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzooe2lucHV0czpoYSxhdHRyczphYSxiYWNrZW5kOnhhfSk9Pntjb25zdHt4OmJhfT1oYSx7a2VlcERpbXM6U2EsYXhpczpUYX09YWEsd2E9eGEsRWE9YmEuc2hhcGUubGVuZ3RoLGthPXBhcnNlQXhpc1BhcmFtKFRhLGJhLnNoYXBlKTtsZXQgQWE9a2E7Y29uc3QgRmE9Z2V0QXhlc1Blcm11dGF0aW9uKEFhLEVhKSxMYT1GYSE9bnVsbCxlbD13YS5zaG91bGRFeGVjdXRlT25DUFUoW2JhXSksdGw9W107bGV0IG5sPWJhO2lmKExhKXtpZihlbCl7Y29uc3QgaWw9d2EudGV4RGF0YS5nZXQobmwuZGF0YUlkKS52YWx1ZXMsY2w9bmV3IEFycmF5KEVhKTtmb3IobGV0IGhsPTA7aGw8Y2wubGVuZ3RoO2hsKyspY2xbaGxdPWJhLnNoYXBlW0ZhW2hsXV07Y29uc3QgdWw9dHJhbnNwb3NlSW1wbENQVShpbCxiYS5zaGFwZSxiYS5kdHlwZSxGYSxjbCk7bmw9d2EubWFrZVRlbnNvckluZm8oY2wsYmEuZHR5cGUpO2NvbnN0IGRsPXdhLnRleERhdGEuZ2V0KG5sLmRhdGFJZCk7ZGwudmFsdWVzPXVsfWVsc2Ugbmw9dHJhbnNwb3NlSW1wbChiYSxGYSx3YSk7dGwucHVzaChubCksQWE9Z2V0SW5uZXJNb3N0QXhlcyhBYS5sZW5ndGgsRWEpfWFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zKCJzdW0iLEFhLEVhKTtjb25zdFtzbCxybF09Y29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhubC5zaGFwZSxBYSk7bGV0IG9sPXNsO1NhJiYob2w9ZXhwYW5kU2hhcGVUb0tlZXBEaW0oc2wsa2EpKTtjb25zdCBhbD1tZWFuSW1wbChubCxybCxvbCx3YSk7Zm9yKGNvbnN0IGxsIG9mIHRsKXdhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGxsKTtyZXR1cm4gYWx9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBtaW4oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2F4aXM6VGEsa2VlcERpbXM6d2F9PWJhLEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1wYXJzZUF4aXNQYXJhbShUYSxTYS5zaGFwZSk7bGV0IEFhPWthO2NvbnN0IEZhPWdldEF4ZXNQZXJtdXRhdGlvbihBYSxFYSk7bGV0IExhPVNhO0ZhIT1udWxsJiYoTGE9dHJhbnNwb3NlKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06RmF9fSksQWE9Z2V0SW5uZXJNb3N0QXhlcyhBYS5sZW5ndGgsU2Euc2hhcGUubGVuZ3RoKSksYXNzZXJ0QXhlc0FyZUlubmVyTW9zdERpbXMoIm1pbiIsQWEsRWEpO2NvbnN0W2VsLHRsXT1jb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKExhLnNoYXBlLEFhKSxubD1zaXplRnJvbVNoYXBlKHRsKSxzbD1yZXNoYXBlKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSxubF19fSkscmw9cmVkdWNlKHNsLHNsLmR0eXBlLCJtaW4iLHhhKTtsZXQgb2w7aWYod2Epe2NvbnN0IGFsPWV4cGFuZFNoYXBlVG9LZWVwRGltKGVsLGthKTtvbD1yZXNoYXBlKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOmFsfX0pfWVsc2Ugb2w9cmVzaGFwZSh7aW5wdXRzOnt4OnJsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTplbH19KTtyZXR1cm4geGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHJsKSxGYSE9bnVsbCYmeGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oTGEpLG9sfWNvbnN0IG1pbkNvbmZpZz17a2VybmVsTmFtZTpNaW4sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm1pbn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgTUlOSU1VTT1DSEVDS19OQU5fU05JUFBFVCtgCiAgcmV0dXJuIG1pbihhLCBiKTsKYCxNSU5JTVVNX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSB2ZWM0KG1pbihhLCBiKSk7CiAgYnZlYzQgaXNOYU5BID0gaXNuYW4oYSk7CiAgYnZlYzQgaXNOYU5CID0gaXNuYW4oYik7CiAgYnZlYzQgaXNOYU4gPSBidmVjNChpc05hTkEueCB8fCBpc05hTkIueCwgaXNOYU5BLnkgfHwgaXNOYU5CLnksIGlzTmFOQS56IHx8IGlzTmFOQi56LCBpc05hTkEudyB8fCBpc05hTkIudyk7CiAgYCtDSEVDS19OQU5fU05JUFBFVF9QQUNLRUQrYAogIHJldHVybiByZXN1bHQ7CmAsbWluaW11bT1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6TUlOSU1VTSxwYWNrZWRPcFNuaXBwZXQ6TUlOSU1VTV9QQUNLRUQsY3B1S2VybmVsSW1wbDptaW5pbXVtSW1wbENQVX0pLG1pbmltdW1Db25maWc9e2tlcm5lbE5hbWU6TWluaW11bSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bWluaW11bX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgTWlycm9yUGFkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMub3V0cHV0U2hhcGU9eGEubWFwKChGYSxMYSk9PkZhWzBdK2FhW0xhXStGYVsxXSk7Y29uc3QgU2E9YWEubGVuZ3RoLFRhPWdldENvb3Jkc0RhdGFUeXBlKFNhKSx3YT14YS5tYXAoRmE9PkZhWzBdKS5qb2luKCIsIiksRWE9eGEubWFwKChGYSxMYSk9PkZhWzBdK2FhW0xhXSkuam9pbigiLCIpLGthPVsiY29vcmRzWzBdIiwiY29vcmRzWzFdIiwiY29vcmRzWzJdIiwiY29vcmRzWzNdIl0uc2xpY2UoMCxTYSksQWE9YmE9PT0icmVmbGVjdCI/MDoxO2lmKFNhPT09MSl7dGhpcy51c2VyQ29kZT1gCiAgICAgICAgaW50IHN0YXJ0ID0gJHt3YX07CiAgICAgICAgaW50IGVuZCA9ICR7RWF9OwoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICBpbnQgb3V0QyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgaWYgKG91dEMgPCBzdGFydCkgewogICAgICAgICAgICBvdXRDID0gc3RhcnQgKiAyIC0gb3V0QyAtICR7QWF9OwogICAgICAgICAgfSBlbHNlIGlmKG91dEMgPj0gZW5kKSB7CiAgICAgICAgICAgIG91dEMgPSAoZW5kIC0gMSkgKiAyIC0gb3V0QyArICR7QWF9OwogICAgICAgICAgfQogICAgICAgICAgc2V0T3V0cHV0KGdldFgob3V0QyAtIHN0YXJ0KSk7CiAgICAgICAgfQogICAgICBgO3JldHVybn10aGlzLnVzZXJDb2RlPWAKICAgICAgJHtUYX0gc3RhcnQgPSAke1RhfSgke3dhfSk7CiAgICAgICR7VGF9IGVuZCA9ICR7VGF9KCR7RWF9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke1RhfSBvdXRDID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke1NhfTsgaSsrKSB7CiAgICAgICAgICBpZiAob3V0Q1tpXSA8IHN0YXJ0W2ldKSB7CiAgICAgICAgICAgIG91dENbaV0gPSBzdGFydFtpXSAqIDIgLSBvdXRDW2ldIC0gJHtBYX07CiAgICAgICAgICB9IGVsc2UgaWYob3V0Q1tpXSA+PSBlbmRbaV0pIHsKICAgICAgICAgICAgb3V0Q1tpXSA9IChlbmRbaV0gLSAxKSAqIDIgLSBvdXRDW2ldICsgJHtBYX07CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR7VGF9IGNvb3JkcyA9IG91dEMgLSBzdGFydDsKICAgICAgICBzZXRPdXRwdXQoZ2V0WCgke2thfSkpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBNaXJyb3JQYWRQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT14YS5tYXAoKG5sLHNsKT0+bmxbMF0rYWFbc2xdK25sWzFdKTtjb25zdCBTYT1hYS5sZW5ndGgsVGE9Z2V0Q29vcmRzRGF0YVR5cGUoU2EpLHdhPXhhLm1hcChubD0+bmxbMF0pLmpvaW4oIiwiKSxFYT14YS5tYXAoKG5sLHNsKT0+bmxbMF0rYWFbc2xdKS5qb2luKCIsIiksa2E9Z2V0Q2hhbm5lbHMoInJjIixTYSksQWE9Z2V0Q2hhbm5lbHMoInNvdXJjZSIsU2EpLEZhPWAke2thW1NhLTFdfSA8ICR7dGhpcy5vdXRwdXRTaGFwZVtTYS0xXX1gLExhPVNhPT09MT8ic291cmNlIjpgdmVjMigke0FhLnNsaWNlKC0yKS5qb2luKCl9KWAsZWw9YmE9PT0icmVmbGVjdCI/MDoxO2xldCB0bD0iIjtpZihTYT09PTEpe2NvbnN0IG5sPWAKICAgICAgICAke1RhfSBzb3VyY2UgPSByYzsKICAgICAgICBpZiAoc291cmNlIDwgc3RhcnQpIHsKICAgICAgICAgIHNvdXJjZSA9IHN0YXJ0ICogMiAtIHNvdXJjZSAtICR7ZWx9OwogICAgICAgIH0gZWxzZSBpZiAoc291cmNlID49IGVuZCkgewogICAgICAgICAgc291cmNlID0gKGVuZCAtIDEpICogMiAtIHNvdXJjZSArICR7ZWx9OwogICAgICAgIH0KICAgICAgICBzb3VyY2UgLT0gc3RhcnQ7CiAgICAgIGA7dGw9YAogICAgICAgICR7VGF9IHJjID0gb3V0cHV0TG9jOwogICAgICAgICR7bmx9CiAgICAgICAgcmVzdWx0WzBdID0gZ2V0Q2hhbm5lbChnZXRYKCR7QWEuam9pbigpfSksICR7TGF9KTsKICAgICAgICAke2thW1NhLTFdfSArPSAxOwogICAgICAgIGlmKCR7RmF9KSB7CiAgICAgICAgICAke25sfQogICAgICAgICAgcmVzdWx0WzFdID0gZ2V0Q2hhbm5lbChnZXRYKCR7QWEuam9pbigpfSksICR7TGF9KTsKICAgICAgICB9CiAgICAgIGB9ZWxzZXtjb25zdCBubD1gCiAgICAgICAgJHtUYX0gc291cmNlID0gcmM7CiAgICAgICAgJHtUYX0gbHQgPSAke1RhfShsZXNzVGhhbihzb3VyY2UsIHN0YXJ0KSk7CiAgICAgICAgJHtUYX0gZ3RlID0gJHtUYX0oZ3JlYXRlclRoYW5FcXVhbChzb3VyY2UsIGVuZCkpOwogICAgICAgICR7VGF9IG9yaWcgPSAxIC0gKGx0ICsgZ3RlKTsKICAgICAgICBzb3VyY2UgPSBvcmlnICogc291cmNlICsKICAgICAgICAgICAgICAgIGx0ICogKHN0YXJ0ICogMiAtIHNvdXJjZSAtICR7ZWx9KSArCiAgICAgICAgICAgICAgICBndGUgKiAoKGVuZCAtIDEpICogMiAtIHNvdXJjZSArICR7ZWx9KTsKICAgICAgICBzb3VyY2UgLT0gc3RhcnQ7CiAgICAgIGA7dGw9YAogICAgICAgICR7VGF9IHJjID0gb3V0cHV0TG9jOwogICAgICAgICR7bmx9CiAgICAgICAgcmVzdWx0WzBdID0gZ2V0Q2hhbm5lbChnZXRYKCR7QWEuam9pbigpfSksICR7TGF9KTsKICAgICAgICAke2thW1NhLTFdfSArPSAxOwogICAgICAgIGlmKCR7RmF9KSB7CiAgICAgICAgICAke25sfQogICAgICAgICAgcmVzdWx0WzFdID0gZ2V0Q2hhbm5lbChnZXRYKCR7QWEuam9pbigpfSksICR7TGF9KTsKICAgICAgICB9CiAgICAgICAgcmMgPSBvdXRwdXRMb2M7CiAgICAgICAgJHtrYVtTYS0yXX0gKz0gMTsKICAgICAgICBpZigke2thW1NhLTJdfSA8ICR7dGhpcy5vdXRwdXRTaGFwZVtTYS0yXX0pIHsKICAgICAgICAgICR7bmx9CiAgICAgICAgICByZXN1bHRbMl0gPSBnZXRDaGFubmVsKGdldFgoJHtBYS5qb2luKCl9KSwgJHtMYX0pOwogICAgICAgICAgJHtrYVtTYS0xXX0gKz0gMTsKICAgICAgICAgIGlmKCR7RmF9KSB7CiAgICAgICAgICAgICR7bmx9CiAgICAgICAgICAgIHJlc3VsdFszXSA9IGdldENoYW5uZWwoZ2V0WCgke0FhLmpvaW4oKX0pLCAke0xhfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICBgfXRoaXMudXNlckNvZGU9YAogICAgICBjb25zdCAke1RhfSBzdGFydCA9ICR7VGF9KCR7d2F9KTsKICAgICAgY29uc3QgJHtUYX0gZW5kID0gJHtUYX0oJHtFYX0pOwoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7VGF9IG91dHB1dExvYyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLik7CiAgICAgICAgJHt0bH0KICAgICAgICBzZXRPdXRwdXQocmVzdWx0KTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgbWlycm9yUGFkS2VybmVsRnVuYz0oe2lucHV0czpoYSxiYWNrZW5kOmFhLGF0dHJzOnhhfSk9Pntjb25zdHt4OmJhfT1oYSx7cGFkZGluZ3M6U2EsbW9kZTpUYX09eGEsd2E9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19BUlJBWV9PUEVSQVRJT05TIik/bmV3IE1pcnJvclBhZFBhY2tlZFByb2dyYW0oYmEuc2hhcGUsU2EsVGEpOm5ldyBNaXJyb3JQYWRQcm9ncmFtKGJhLnNoYXBlLFNhLFRhKTtyZXR1cm4gYWEucnVuV2ViR0xQcm9ncmFtKHdhLFtiYV0sYmEuZHR5cGUpfSxtaXJyb3JQYWRDb25maWc9e2tlcm5lbE5hbWU6TWlycm9yUGFkLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzptaXJyb3JQYWRLZXJuZWxGdW5jfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBNT0Q9YGlmIChiID09IDAuMCkgcmV0dXJuIE5BTjsKICByZXR1cm4gbW9kKGEsIGIpO2AsTU9EX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSBtb2QoYSwgYik7CiAgYnZlYzQgaXNOYU4gPSBlcXVhbChiLCB2ZWM0KDAuMCkpOwogIGArQ0hFQ0tfTkFOX1NOSVBQRVRfUEFDS0VEK2AKICByZXR1cm4gcmVzdWx0OwpgLG1vZD1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6TU9ELHBhY2tlZE9wU25pcHBldDpNT0RfUEFDS0VEfSksbW9kQ29uZmlnPXtrZXJuZWxOYW1lOk1vZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bW9kfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBNdWx0aW5vbWlhbFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bInByb2JzIl0sdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6InNlZWQiLHR5cGU6ImZsb2F0In1dLHRoaXMub3V0cHV0U2hhcGU9W2FhLGJhXSx0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWMyIGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKCiAgICAgICAgZmxvYXQgciA9IHJhbmRvbShzZWVkKTsKICAgICAgICBmbG9hdCBjZGYgPSAwLjA7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHt4YS0xfTsgaSsrKSB7CiAgICAgICAgICBjZGYgKz0gZ2V0UHJvYnMoYmF0Y2gsIGkpOwoKICAgICAgICAgIGlmIChyIDwgY2RmKSB7CiAgICAgICAgICAgIHNldE91dHB1dChmbG9hdChpKSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIElmIG5vIG90aGVyIGV2ZW50IGhhcHBlbmVkLCBsYXN0IGV2ZW50IGhhcHBlbmVkLgogICAgICAgIHNldE91dHB1dChmbG9hdCgke3hhLTF9KSk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IERJVj1gCmlmIChhID09IGIpIHsKICByZXR1cm4gMS4wOwp9OwpyZXR1cm4gYSAvIGI7YCxESVZfUEFDS0VEPWAKICAvLyB2ZWM0IG9uZSA9IHZlYzQoZXF1YWwoYSwgYikpOwogIC8vIHJldHVybiBvbmUgKyAodmVjNCgxLjApIC0gb25lKSAqIGEgLyBiOwogIHZlYzQgcmVzdWx0ID0gYSAvIGI7CiAgaWYoYS54ID09IGIueCkgewogICAgcmVzdWx0LnggPSAxLjsKICB9CiAgaWYoYS55ID09IGIueSkgewogICAgcmVzdWx0LnkgPSAxLjsKICB9CiAgaWYoYS56ID09IGIueikgewogICAgcmVzdWx0LnogPSAxLjsKICB9CiAgaWYoYS53ID09IGIudykgewogICAgcmVzdWx0LncgPSAxLjsKICB9CgogIHJldHVybiByZXN1bHQ7CmAscmVhbERpdj1iaW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6RElWLHBhY2tlZE9wU25pcHBldDpESVZfUEFDS0VELGNoZWNrT3V0T2ZCb3VuZHM6ITB9KSxyZWFsRGl2Q29uZmlnPXtrZXJuZWxOYW1lOlJlYWxEaXYsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlYWxEaXZ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNVQj0icmV0dXJuIGEgLSBiOyIsc3ViPWJpbmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTVUIscGFja2VkT3BTbmlwcGV0OlNVQixzdXBwb3J0c0NvbXBsZXg6ITAsY3B1S2VybmVsSW1wbDpzdWJJbXBsQ1BVfSksc3ViQ29uZmlnPXtrZXJuZWxOYW1lOlN1YixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3VifTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzb2Z0bWF4KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2xvZ2l0czpTYX09YWEse2RpbTpUYX09YmEsd2E9cGFyc2VBeGlzUGFyYW0oW1RhXSxTYS5zaGFwZSksRWE9bWF4KHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3JlZHVjdGlvbkluZGljZXM6d2Esa2VlcERpbXM6ITF9fSksa2E9ZXhwYW5kU2hhcGVUb0tlZXBEaW0oRWEuc2hhcGUsd2EpLEFhPXJlc2hhcGUoe2lucHV0czp7eDpFYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6a2F9fSksRmE9c3ViKHtpbnB1dHM6e2E6U2EsYjpBYX0sYmFja2VuZDp4YX0pLExhPWV4cCh7aW5wdXRzOnt4OkZhfSxiYWNrZW5kOnhhfSksZWw9c3VtKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e2F4aXM6d2Esa2VlcERpbXM6ITF9fSksdGw9cmVzaGFwZSh7aW5wdXRzOnt4OmVsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTprYX19KSxubD1yZWFsRGl2KHtpbnB1dHM6e2E6TGEsYjp0bH0sYmFja2VuZDp4YX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhFYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oQWEpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEZhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oZWwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSxubH1jb25zdCBzb2Z0bWF4Q29uZmlnPXtrZXJuZWxOYW1lOlNvZnRtYXgsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNvZnRtYXh9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIG11bHRpbm9taWFsKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2xvZ2l0czpTYX09YWEse251bVNhbXBsZXM6VGEsc2VlZDp3YSxub3JtYWxpemVkOkVhfT1iYSxrYT1FYT9TYTpzb2Z0bWF4KHtpbnB1dHM6e2xvZ2l0czpTYX0sYmFja2VuZDp4YSxhdHRyczp7ZGltOlNhLnNoYXBlLmxlbmd0aC0xfX0pLEFhPWthLnNoYXBlWzBdLEZhPWthLnNoYXBlWzFdLExhPW5ldyBNdWx0aW5vbWlhbFByb2dyYW0oQWEsRmEsVGEpLGVsPVtbd2FdXSx0bD14YS5ydW5XZWJHTFByb2dyYW0oTGEsW2thXSwiaW50MzIiLGVsKTtyZXR1cm4gRWF8fHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGthKSx0bH1jb25zdCBtdWx0aW5vbWlhbENvbmZpZz17a2VybmVsTmFtZTpNdWx0aW5vbWlhbCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6bXVsdGlub21pYWx9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IE5FRz1DSEVDS19OQU5fU05JUFBFVCQxK2AKICByZXR1cm4gLXg7CmAsTkVHX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSAteDsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwoKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyB4LmcgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyB4LmIgOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiByZXN1bHQuYTsKCiAgcmV0dXJuIHJlc3VsdDsKYDtmdW5jdGlvbiBuZWcoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7eDpiYX09YWE7aWYoeGEuc2hvdWxkRXhlY3V0ZU9uQ1BVKFtiYV0pKXtjb25zdCBUYT14YS50ZXhEYXRhLmdldChiYS5kYXRhSWQpLFt3YSxFYV09bmVnSW1wbENQVShUYS52YWx1ZXMsYmEuc2hhcGUsYmEuZHR5cGUpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhFYSxiYS5kdHlwZSx3YSl9bGV0IFNhO3JldHVybiBlbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX1VOQVJZX09QRVJBVElPTlMiKT9TYT1uZXcgVW5hcnlPcFBhY2tlZFByb2dyYW0oYmEuc2hhcGUsTkVHX1BBQ0tFRCk6U2E9bmV3IFVuYXJ5T3BQcm9ncmFtKGJhLnNoYXBlLE5FRykseGEucnVuV2ViR0xQcm9ncmFtKFNhLFtiYV0sYmEuZHR5cGUpfWNvbnN0IG5lZ0NvbmZpZz17a2VybmVsTmFtZTpOZWcsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm5lZ307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgbm9uTWF4U3VwcHJlc3Npb25WM0ltcGw9bm9uTWF4U3VwcHJlc3Npb25WM0ltcGwkMTtmdW5jdGlvbiBub25NYXhTdXBwcmVzc2lvblYzKGhhKXt3YXJuKCJ0Zi5ub25NYXhTdXBwcmVzc2lvbigpIGluIHdlYmdsIGxvY2tzIHRoZSBVSSB0aHJlYWQuIENhbGwgdGYubm9uTWF4U3VwcHJlc3Npb25Bc3luYygpIGluc3RlYWQiKTtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2JveGVzOlNhLHNjb3JlczpUYX09YWEse21heE91dHB1dFNpemU6d2EsaW91VGhyZXNob2xkOkVhLHNjb3JlVGhyZXNob2xkOmthfT1iYSxBYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLEZhPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCkse3NlbGVjdGVkSW5kaWNlczpMYX09bm9uTWF4U3VwcHJlc3Npb25WM0ltcGwoQWEsRmEsd2EsRWEsa2EpO3JldHVybiB4YS5tYWtlVGVuc29ySW5mbyhbTGEubGVuZ3RoXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KExhKSl9Y29uc3Qgbm9uTWF4U3VwcHJlc3Npb25WM0NvbmZpZz17a2VybmVsTmFtZTpOb25NYXhTdXBwcmVzc2lvblYzLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpub25NYXhTdXBwcmVzc2lvblYzfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBub25NYXhTdXBwcmVzc2lvblY0SW1wbD1ub25NYXhTdXBwcmVzc2lvblY0SW1wbCQxO2Z1bmN0aW9uIG5vbk1heFN1cHByZXNzaW9uVjQoaGEpe3dhcm4oInRmLm5vbk1heFN1cHByZXNzaW9uKCkgaW4gd2ViZ2wgbG9ja3MgdGhlIFVJIHRocmVhZC4gQ2FsbCB0Zi5ub25NYXhTdXBwcmVzc2lvbkFzeW5jKCkgaW5zdGVhZCIpO2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7Ym94ZXM6U2Esc2NvcmVzOlRhfT1hYSx7bWF4T3V0cHV0U2l6ZTp3YSxpb3VUaHJlc2hvbGQ6RWEsc2NvcmVUaHJlc2hvbGQ6a2EscGFkVG9NYXhPdXRwdXRTaXplOkFhfT1iYSxGYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLExhPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCkse3NlbGVjdGVkSW5kaWNlczplbCx2YWxpZE91dHB1dHM6dGx9PW5vbk1heFN1cHByZXNzaW9uVjRJbXBsKEZhLExhLHdhLEVhLGthLEFhKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oW2VsLmxlbmd0aF0sImludDMyIixuZXcgSW50MzJBcnJheShlbCkpLHhhLm1ha2VUZW5zb3JJbmZvKFtdLCJpbnQzMiIsbmV3IEludDMyQXJyYXkoW3RsXSkpXX1jb25zdCBub25NYXhTdXBwcmVzc2lvblY0Q29uZmlnPXtrZXJuZWxOYW1lOk5vbk1heFN1cHByZXNzaW9uVjQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm5vbk1heFN1cHByZXNzaW9uVjR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IG5vbk1heFN1cHByZXNzaW9uVjVJbXBsPW5vbk1heFN1cHByZXNzaW9uVjVJbXBsJDE7ZnVuY3Rpb24gbm9uTWF4U3VwcHJlc3Npb25WNShoYSl7d2FybigidGYubm9uTWF4U3VwcHJlc3Npb24oKSBpbiB3ZWJnbCBsb2NrcyB0aGUgVUkgdGhyZWFkLiBDYWxsIHRmLm5vbk1heFN1cHByZXNzaW9uQXN5bmMoKSBpbnN0ZWFkIik7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtib3hlczpTYSxzY29yZXM6VGF9PWFhLHttYXhPdXRwdXRTaXplOndhLGlvdVRocmVzaG9sZDpFYSxzY29yZVRocmVzaG9sZDprYSxzb2Z0Tm1zU2lnbWE6QWF9PWJhLEZhPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksTGE9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxlbD13YSx0bD1FYSxubD1rYSxzbD1BYSx7c2VsZWN0ZWRJbmRpY2VzOnJsLHNlbGVjdGVkU2NvcmVzOm9sfT1ub25NYXhTdXBwcmVzc2lvblY1SW1wbChGYSxMYSxlbCx0bCxubCxzbCk7cmV0dXJuW3hhLm1ha2VUZW5zb3JJbmZvKFtybC5sZW5ndGhdLCJpbnQzMiIsbmV3IEludDMyQXJyYXkocmwpKSx4YS5tYWtlVGVuc29ySW5mbyhbb2wubGVuZ3RoXSwiZmxvYXQzMiIsbmV3IEZsb2F0MzJBcnJheShvbCkpXX1jb25zdCBub25NYXhTdXBwcmVzc2lvblY1Q29uZmlnPXtrZXJuZWxOYW1lOk5vbk1heFN1cHByZXNzaW9uVjUsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm5vbk1heFN1cHByZXNzaW9uVjV9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIE9uZUhvdFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2Epe3RoaXMudmFyaWFibGVOYW1lcz1bImluZGljZXMiXSx0aGlzLm91dHB1dFNoYXBlPVthYSx4YV0sdGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgaW5kZXggPSByb3VuZChnZXRJbmRpY2VzKGNvb3Jkcy54KSk7CiAgICAgICAgc2V0T3V0cHV0KG1peChmbG9hdCgke1NhfSksIGZsb2F0KCR7YmF9KSwKICAgICAgICAgICAgICAgICAgICAgIGZsb2F0KGluZGV4ID09IGNvb3Jkcy55KSkpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBvbmVIb3Q9aGE9Pntjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2luZGljZXM6U2F9PWFhLHtkdHlwZTpUYSxkZXB0aDp3YSxvblZhbHVlOkVhLG9mZlZhbHVlOmthfT1iYSxBYT1zaXplRnJvbVNoYXBlKFNhLnNoYXBlKSxGYT1uZXcgT25lSG90UHJvZ3JhbShBYSx3YSxFYSxrYSksTGE9cmVzaGFwZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbQWFdfX0pLGVsPXhhLnJ1bldlYkdMUHJvZ3JhbShGYSxbTGFdLFRhKTt4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhMYSk7Y29uc3QgdGw9Wy4uLlNhLnNoYXBlLHdhXSxubD1yZXNoYXBlKHtpbnB1dHM6e3g6ZWx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOnRsfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhlbCksbmx9LG9uZUhvdENvbmZpZz17a2VybmVsTmFtZTpPbmVIb3QsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOm9uZUhvdH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gemVyb3NMaWtlKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3g6YmF9PWFhO2lmKGJhLmR0eXBlPT09ImNvbXBsZXg2NCIpe2NvbnN0IFNhPXJlYWwoe2lucHV0czp7aW5wdXQ6YmF9LGJhY2tlbmQ6eGF9KSxUYT16ZXJvc0xpa2Uoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pLHdhPWltYWcoe2lucHV0czp7aW5wdXQ6YmF9LGJhY2tlbmQ6eGF9KSxFYT16ZXJvc0xpa2Uoe2lucHV0czp7eDp3YX0sYmFja2VuZDp4YX0pLGthPWNvbXBsZXgoe2lucHV0czp7cmVhbDpUYSxpbWFnOkVhfSxiYWNrZW5kOnhhfSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKFNhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhUYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEVhKSxrYX1lbHNlIHJldHVybiBmaWxsKHthdHRyczp7c2hhcGU6YmEuc2hhcGUsZHR5cGU6YmEuZHR5cGUsdmFsdWU6YmEuZHR5cGU9PT0ic3RyaW5nIj8iIjowfSxiYWNrZW5kOnhhfSl9Y29uc3QgemVyb3NMaWtlQ29uZmlnPXtrZXJuZWxOYW1lOlplcm9zTGlrZSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6emVyb3NMaWtlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBvbmVzTGlrZShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHt4OmJhfT1hYTtpZihiYS5kdHlwZT09PSJzdHJpbmciKXRocm93IG5ldyBFcnJvcigib25lc0xpa2UgaXMgbm90IHN1cHBvcnRlZCB1bmRlciBzdHJpbmcgZHR5cGUiKTtpZihiYS5kdHlwZT09PSJjb21wbGV4NjQiKXtjb25zdCBTYT1yZWFsKHtpbnB1dHM6e2lucHV0OmJhfSxiYWNrZW5kOnhhfSksVGE9b25lc0xpa2Uoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pLHdhPWltYWcoe2lucHV0czp7aW5wdXQ6YmF9LGJhY2tlbmQ6eGF9KSxFYT16ZXJvc0xpa2Uoe2lucHV0czp7eDp3YX0sYmFja2VuZDp4YX0pLGthPWNvbXBsZXgoe2lucHV0czp7cmVhbDpUYSxpbWFnOkVhfSxiYWNrZW5kOnhhfSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKFNhKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhUYSkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8od2EpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKEVhKSxrYX1lbHNlIHJldHVybiBmaWxsKHthdHRyczp7c2hhcGU6YmEuc2hhcGUsZHR5cGU6YmEuZHR5cGUsdmFsdWU6MX0sYmFja2VuZDp4YX0pfWNvbnN0IG9uZXNMaWtlQ29uZmlnPXtrZXJuZWxOYW1lOk9uZXNMaWtlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpvbmVzTGlrZX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcGFjayhoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtheGlzOlNhfT1iYTtpZihhYS5sZW5ndGg9PT0xKXJldHVybiBleHBhbmREaW1zKHtpbnB1dHM6e2lucHV0OmFhWzBdfSxiYWNrZW5kOnhhLGF0dHJzOntkaW06U2F9fSk7Y29uc3QgVGE9YWFbMF0uc2hhcGUsd2E9YWFbMF0uZHR5cGU7YWEuZm9yRWFjaChGYT0+e2Fzc2VydFNoYXBlc01hdGNoKFRhLEZhLnNoYXBlLCJBbGwgdGVuc29ycyBwYXNzZWQgdG8gc3RhY2sgbXVzdCBoYXZlIG1hdGNoaW5nIHNoYXBlcyIpLGFzc2VydCh3YT09PUZhLmR0eXBlLCgpPT4iQWxsIHRlbnNvcnMgcGFzc2VkIHRvIHN0YWNrIG11c3QgaGF2ZSBtYXRjaGluZyBkdHlwZXMiKX0pO2NvbnN0IEVhPVtdLGthPWFhLm1hcChGYT0+e2NvbnN0IExhPWV4cGFuZERpbXMoe2lucHV0czp7aW5wdXQ6RmF9LGJhY2tlbmQ6eGEsYXR0cnM6e2RpbTpTYX19KTtyZXR1cm4gRWEucHVzaChMYSksTGF9KSxBYT1jb25jYXQoe2lucHV0czprYSxiYWNrZW5kOnhhLGF0dHJzOntheGlzOlNhfX0pO3JldHVybiBFYS5mb3JFYWNoKEZhPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhGYSkpLEFhfWNvbnN0IHBhY2tDb25maWc9e2tlcm5lbE5hbWU6UGFjayxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cGFja307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUGFkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJ2YWx1ZSIsdHlwZToiZmxvYXQifV0sdGhpcy5vdXRwdXRTaGFwZT14YS5tYXAoKEFhLEZhKT0+QWFbMF0rYWFbRmFdK0FhWzFdKTtjb25zdCBTYT1hYS5sZW5ndGgsVGE9Z2V0Q29vcmRzRGF0YVR5cGUoU2EpLHdhPXhhLm1hcChBYT0+QWFbMF0pLmpvaW4oIiwiKSxFYT14YS5tYXAoKEFhLEZhKT0+QWFbMF0rYWFbRmFdKS5qb2luKCIsIiksa2E9WyJjb29yZHNbMF0iLCJjb29yZHNbMV0iLCJjb29yZHNbMl0iLCJjb29yZHNbM10iXS5zbGljZSgwLFNhKTtpZihTYT09PTEpe3RoaXMudXNlckNvZGU9YAogICAgICAgIGludCBzdGFydCA9ICR7d2F9OwogICAgICAgIGludCBlbmQgPSAke0VhfTsKCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaW50IG91dEMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIGlmIChvdXRDIDwgc3RhcnQgfHwgb3V0QyA+PSBlbmQpIHsKICAgICAgICAgICAgc2V0T3V0cHV0KHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNldE91dHB1dChnZXRYKG91dEMgLSBzdGFydCkpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgYDtyZXR1cm59dGhpcy51c2VyQ29kZT1gCiAgICAgICR7VGF9IHN0YXJ0ID0gJHtUYX0oJHt3YX0pOwogICAgICAke1RhfSBlbmQgPSAke1RhfSgke0VhfSk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtUYX0gb3V0QyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGlmIChhbnkobGVzc1RoYW4ob3V0Qywgc3RhcnQpKSB8fCBhbnkoZ3JlYXRlclRoYW5FcXVhbChvdXRDLCBlbmQpKSkgewogICAgICAgICAgc2V0T3V0cHV0KHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgJHtUYX0gY29vcmRzID0gb3V0QyAtIHN0YXJ0OwogICAgICAgICAgc2V0T3V0cHV0KGdldFgoJHtrYX0pKTsKICAgICAgICB9CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFBhZFBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToidmFsdWUiLHR5cGU6ImZsb2F0In1dLHRoaXMub3V0cHV0U2hhcGU9eGEubWFwKChzbCxybCk9PnNsWzBdK2FhW3JsXStzbFsxXSk7Y29uc3QgU2E9YWEubGVuZ3RoLFRhPWdldENvb3Jkc0RhdGFUeXBlKFNhKSx3YT14YS5tYXAoc2w9PnNsWzBdKS5qb2luKCIsIiksRWE9eGEubWFwKChzbCxybCk9PnNsWzBdK2FhW3JsXSkuam9pbigiLCIpLGthPWdldENoYW5uZWxzKCJyYyIsU2EpLEFhPWdldENoYW5uZWxzKCJzb3VyY2UiLFNhKSxGYT1gJHtrYVtTYS0xXX0gPCAke3RoaXMub3V0cHV0U2hhcGVbU2EtMV19YCxMYT1TYT09PTE/InNvdXJjZSI6YHZlYzIoJHtBYS5zbGljZSgtMikuam9pbigpfSlgLGVsPVtgJHtUYX0gcmMgPSBvdXRwdXRMb2M7YCxgJHtrYVtTYS0xXX0gKz0gMTsKICAgICAgIGlmKCR7RmF9KSB7CiAgICAgIGAsU2E9PT0xPyIiOmB9CiAgICAgICByYyA9IG91dHB1dExvYzsKICAgICAgICR7a2FbU2EtMl19ICs9IDE7CiAgICAgICBpZigke2thW1NhLTJdfSA8ICR7dGhpcy5vdXRwdXRTaGFwZVtTYS0yXX0pIHtgLFNhPT09MT8iIjpgICAke2thW1NhLTFdfSArPSAxOwogICAgICAgICBpZigke0ZhfSkge2BdLHRsPVNhPT09MT8icmMgPCBzdGFydCB8fCByYyA+PSBlbmQiOiJhbnkobGVzc1RoYW4ocmMsIHN0YXJ0KSkgfHwgYW55KGdyZWF0ZXJUaGFuRXF1YWwocmMsIGVuZCkpIjtsZXQgbmw9IiI7Zm9yKGxldCBzbD0wLHJsPVNhPT09MT8yOjQ7c2w8cmw7c2wrKylubCs9YAogICAgICAgICR7ZWxbc2xdfQogICAgICAgIGlmICgke3RsfSkgewogICAgICAgICAgcmVzdWx0WyR7c2x9XSA9IGZsb2F0KHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgJHtUYX0gc291cmNlID0gcmMgLSBzdGFydDsKICAgICAgICAgIHJlc3VsdFske3NsfV0gPSBnZXRDaGFubmVsKGdldFgoJHtBYS5qb2luKCl9KSwgJHtMYX0pOwogICAgICAgIH0KICAgICAgYDtubCs9U2E9PT0xPyJ9ICI6In19Iix0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgJHtUYX0gc3RhcnQgPSAke1RhfSgke3dhfSk7CiAgICAgIGNvbnN0ICR7VGF9IGVuZCA9ICR7VGF9KCR7RWF9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke1RhfSBvdXRwdXRMb2MgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4pOwogICAgICAgICR7bmx9CiAgICAgICAgc2V0T3V0cHV0KHJlc3VsdCk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHBhZFYyPWhhPT57Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7cGFkZGluZ3M6VGEsY29uc3RhbnRWYWx1ZTp3YX09YmE7aWYoc2l6ZUZyb21TaGFwZShTYS5zaGFwZSk9PT0wKXtjb25zdCBBYT1UYS5tYXAoKEZhLExhKT0+RmFbMF0rU2Euc2hhcGVbTGFdK0ZhWzFdKTtyZXR1cm4gZmlsbCh7YmFja2VuZDp4YSxhdHRyczp7c2hhcGU6QWEsdmFsdWU6d2EsZHR5cGU6U2EuZHR5cGV9fSl9Y29uc3QgRWE9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19BUlJBWV9PUEVSQVRJT05TIik/bmV3IFBhZFBhY2tlZFByb2dyYW0oU2Euc2hhcGUsVGEsd2EpOm5ldyBQYWRQcm9ncmFtKFNhLnNoYXBlLFRhLHdhKSxrYT1bW3dhXV07cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShFYSxbU2FdLFNhLmR0eXBlLGthKX0scGFkVjJDb25maWc9e2tlcm5lbE5hbWU6UGFkVjIsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnBhZFYyfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBQT1c9YAogIGlmKGEgPCAwLjAgJiYgZmxvb3IoYikgPCBiKXsKICAgIHJldHVybiBOQU47CiAgfQogIGlmIChiID09IDAuMCkgewogICAgcmV0dXJuIDEuMDsKICB9CiAgcmV0dXJuIChyb3VuZChtb2QoYiwgMi4wKSkgIT0gMSkgPwogICAgICBwb3coYWJzKGEpLCBiKSA6IHNpZ24oYSkgKiBwb3coYWJzKGEpLCBiKTsKYCxQT1dfUEFDS0VEPWAKICAvLyBpc01vZFJvdW5kMSBoYXMgMSBmb3IgY29tcG9uZW50cyB3aXRoIHJvdW5kKG1vZChiLCAyLjApKSA9PSAxLCAwIG90aGVyd2lzZS4KICB2ZWM0IGlzTW9kUm91bmQxID0gdmVjNChlcXVhbChyb3VuZChtb2QoYiwgMi4wKSksIGl2ZWM0KDEpKSk7CiAgdmVjNCBtdWx0aXBsaWVyID0gc2lnbihhKSAqIGlzTW9kUm91bmQxICsgKHZlYzQoMS4wKSAtIGlzTW9kUm91bmQxKTsKICB2ZWM0IHJlc3VsdCA9IG11bHRpcGxpZXIgKiBwb3coYWJzKGEpLCBiKTsKCiAgLy8gRW5zdXJlIHRoYXQgYV4wID0gMSwgaW5jbHVkaW5nIDBeMCA9IDEgYXMgdGhpcyBjb3JyZXNwb25kIHRvIFRGIGFuZCBKUwogIGJ2ZWM0IGlzRXhwWmVybyA9IGVxdWFsKGIsIHZlYzQoMC4wKSk7CiAgcmVzdWx0LnIgPSBpc0V4cFplcm8uciA/IDEuMCA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNFeHBaZXJvLmcgPyAxLjAgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzRXhwWmVyby5iID8gMS4wIDogcmVzdWx0LmI7CiAgcmVzdWx0LmEgPSBpc0V4cFplcm8uYSA/IDEuMCA6IHJlc3VsdC5hOwoKICBidmVjNCBpc05hTjEgPSBsZXNzVGhhbihhLCB2ZWM0KDAuMCkpOwogIGJ2ZWM0IGlzTmFOMiA9IGxlc3NUaGFuKGZsb29yKGIpLCBiKTsKICBidmVjNCBpc05hTiA9IGJ2ZWM0KGlzTmFOMS54ICYmIGlzTmFOMi54LCBpc05hTjEueSAmJiBpc05hTjIueSwgaXNOYU4xLnogJiYgaXNOYU4yLnosIGlzTmFOMS53ICYmIGlzTmFOMi53KTsKICBgK0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRCtgCiAgcmV0dXJuIHJlc3VsdDsKYCxwb3c9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlBPVyxwYWNrZWRPcFNuaXBwZXQ6UE9XX1BBQ0tFRH0pLHBvd0NvbmZpZz17a2VybmVsTmFtZTpQb3csYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnBvd307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcHJvZChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7YXhpczpUYSxrZWVwRGltczp3YX09YmEsRWE9U2Euc2hhcGUubGVuZ3RoLGthPVtdLEFhPXBhcnNlQXhpc1BhcmFtKFRhLFNhLnNoYXBlKTtsZXQgRmE9QWE7Y29uc3QgTGE9Z2V0QXhlc1Blcm11dGF0aW9uKEZhLEVhKTtsZXQgZWw9U2E7TGEhPW51bGwmJihlbD10cmFuc3Bvc2Uoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7cGVybTpMYX19KSxGYT1nZXRJbm5lck1vc3RBeGVzKEZhLmxlbmd0aCxFYSksa2EucHVzaChlbCkpLGFzc2VydEF4ZXNBcmVJbm5lck1vc3REaW1zKCJwcm9kIixGYSxFYSk7bGV0IHRsO2lmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbZWxdKSl7Y29uc3Qgbmw9eGEudGV4RGF0YS5nZXQoZWwuZGF0YUlkKS52YWx1ZXMse291dFZhbHM6c2wsb3V0U2hhcGU6cmwsb3V0RHR5cGU6b2x9PXByb2RJbXBsQ1BVKGVsLnNoYXBlLGVsLmR0eXBlLG5sLEZhKTt0bD14YS5tYWtlVGVuc29ySW5mbyhybCxvbCxzbCl9ZWxzZXtjb25zdFtubCxzbF09Y29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhlbC5zaGFwZSxGYSkscmw9c2l6ZUZyb21TaGFwZShzbCksb2w9cmVzaGFwZSh7aW5wdXRzOnt4OmVsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpbLTEscmxdfX0pLGFsPXN1bU91dFR5cGUoU2EuZHR5cGUpLGxsPXJlZHVjZShvbCxhbCwicHJvZCIseGEpO3RsPXJlc2hhcGUoe2lucHV0czp7eDpsbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSksa2EucHVzaChvbCksa2EucHVzaChsbCl9aWYod2Epe2thLnB1c2godGwpO2NvbnN0IG5sPWV4cGFuZFNoYXBlVG9LZWVwRGltKHRsLnNoYXBlLEFhKTt0bD1yZXNoYXBlKHtpbnB1dHM6e3g6dGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOm5sfX0pfXJldHVybiBrYS5mb3JFYWNoKG5sPT54YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhubCkpLHRsfWNvbnN0IHByb2RDb25maWc9e2tlcm5lbE5hbWU6UHJvZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cHJvZH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmFnZ2VkR2F0aGVyKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3BhcmFtc05lc3RlZFNwbGl0czpTYSxwYXJhbXNEZW5zZVZhbHVlczpUYSxpbmRpY2VzOndhfT1hYSx7b3V0cHV0UmFnZ2VkUmFuazpFYX09YmEsa2E9U2EubWFwKG9sPT54YS5yZWFkU3luYyhvbC5kYXRhSWQpKSxBYT1TYS5tYXAob2w9Pm9sLnNoYXBlKSxGYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLExhPXhhLnJlYWRTeW5jKHdhLmRhdGFJZCksW2VsLHRsLG5sXT1yYWdnZWRHYXRoZXJJbXBsQ1BVKGthLEFhLEZhLFRhLnNoYXBlLFRhLmR0eXBlLExhLHdhLnNoYXBlLEVhKSxzbD1lbC5tYXAob2w9PnhhLm1ha2VUZW5zb3JJbmZvKFtvbC5sZW5ndGhdLCJpbnQzMiIsb2wpKSxybD14YS5tYWtlVGVuc29ySW5mbyhubCxUYS5kdHlwZSx0bCk7cmV0dXJuIHNsLmNvbmNhdChbcmxdKX1jb25zdCByYWdnZWRHYXRoZXJDb25maWc9e2tlcm5lbE5hbWU6UmFnZ2VkR2F0aGVyLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyYWdnZWRHYXRoZXJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHJhZ2dlZFJhbmdlKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse3N0YXJ0czpiYSxsaW1pdHM6U2EsZGVsdGFzOlRhfT1hYSx3YT14YS5yZWFkU3luYyhiYS5kYXRhSWQpLEVhPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksa2E9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxbQWEsRmFdPXJhZ2dlZFJhbmdlSW1wbENQVSh3YSxiYS5zaGFwZSxiYS5kdHlwZSxFYSxTYS5zaGFwZSxrYSxUYS5zaGFwZSksTGE9eGEubWFrZVRlbnNvckluZm8oW0FhLmxlbmd0aF0sImludDMyIixBYSksZWw9eGEubWFrZVRlbnNvckluZm8oW0ZhLmxlbmd0aF0sYmEuZHR5cGUsRmEpO3JldHVybltMYSxlbF19Y29uc3QgcmFnZ2VkUmFuZ2VDb25maWc9e2tlcm5lbE5hbWU6UmFnZ2VkUmFuZ2UsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJhZ2dlZFJhbmdlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByYWdnZWRUZW5zb3JUb1RlbnNvcihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzaGFwZTpTYSx2YWx1ZXM6VGEsZGVmYXVsdFZhbHVlOndhLHJvd1BhcnRpdGlvblRlbnNvcnM6RWF9PWFhLHtyb3dQYXJ0aXRpb25UeXBlczprYX09YmEsQWE9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxGYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLExhPXhhLnJlYWRTeW5jKHdhLmRhdGFJZCksZWw9RWEubWFwKHJsPT54YS5yZWFkU3luYyhybC5kYXRhSWQpKSx0bD1FYS5tYXAocmw9PnJsLnNoYXBlKSxbbmwsc2xdPXJhZ2dlZFRlbnNvclRvVGVuc29ySW1wbENQVShBYSxTYS5zaGFwZSxGYSxUYS5zaGFwZSxUYS5kdHlwZSxMYSx3YS5zaGFwZSxlbCx0bCxrYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKG5sLFRhLmR0eXBlLHNsKX1jb25zdCByYWdnZWRUZW5zb3JUb1RlbnNvckNvbmZpZz17a2VybmVsTmFtZTpSYWdnZWRUZW5zb3JUb1RlbnNvcixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmFnZ2VkVGVuc29yVG9UZW5zb3J9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IHJhbmdlPWhhPT57Y29uc3R7YmFja2VuZDphYSxhdHRyczp4YX09aGEse3N0YXJ0OmJhLHN0b3A6U2Esc3RlcDpUYSxkdHlwZTp3YX09eGEsRWE9cmFuZ2VJbXBsQ1BVKGJhLFNhLFRhLHdhKTtyZXR1cm4gYWEubWFrZVRlbnNvckluZm8oW0VhLmxlbmd0aF0sd2EsRWEpfSxyYW5nZUNvbmZpZz17a2VybmVsTmFtZTpSYW5nZSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmFuZ2V9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFJFQ0lQUk9DQUw9InJldHVybiAxLjAgLyB4OyIscmVjaXByb2NhbD11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpSRUNJUFJPQ0FMfSkscmVjaXByb2NhbENvbmZpZz17a2VybmVsTmFtZTpSZWNpcHJvY2FsLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpyZWNpcHJvY2FsfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBSRUxVPUNIRUNLX05BTl9TTklQUEVUJDErYAogIHJldHVybiAoeCA8IDAuMCkgPyAwLjAgOiB4OwpgLFJFTFVfUEFDS0VEPWAKICB2ZWM0IHJlc3VsdCA9IHggKiB2ZWM0KGdyZWF0ZXJUaGFuRXF1YWwoeCwgdmVjNCgwLjApKSk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKCiAgcmVzdWx0LnIgPSBpc05hTi5yID8geC5yIDogcmVzdWx0LnI7CiAgcmVzdWx0LmcgPSBpc05hTi5nID8geC5nIDogcmVzdWx0Lmc7CiAgcmVzdWx0LmIgPSBpc05hTi5iID8geC5iIDogcmVzdWx0LmI7CiAgcmVzdWx0LmEgPSBpc05hTi5hID8geC5hIDogcmVzdWx0LmE7CgogIHJldHVybiByZXN1bHQ7CmAscmVsdT11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpSRUxVLHBhY2tlZE9wU25pcHBldDpSRUxVX1BBQ0tFRH0pLHJlbHVDb25maWc9e2tlcm5lbE5hbWU6UmVsdSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmVsdX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgUkVMVTY9Q0hFQ0tfTkFOX1NOSVBQRVQkMStgCiAgcmV0dXJuICh4IDwgMC4wKSA/IDAuMCA6IG1pbig2LjAsIHgpOwpgLFJFTFU2X1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSBtaW4oeCwgdmVjNCg2LikpICogdmVjNChncmVhdGVyVGhhbkVxdWFsKHgsIHZlYzQoMC4wKSkpOwogIGJ2ZWM0IGlzTmFOID0gaXNuYW4oeCk7CgogIHJlc3VsdC5yID0gaXNOYU4uciA/IHguciA6IHJlc3VsdC5yOwogIHJlc3VsdC5nID0gaXNOYU4uZyA/IHguZyA6IHJlc3VsdC5nOwogIHJlc3VsdC5iID0gaXNOYU4uYiA/IHguYiA6IHJlc3VsdC5iOwogIHJlc3VsdC5hID0gaXNOYU4uYSA/IHguYSA6IHJlc3VsdC5hOwoKICByZXR1cm4gcmVzdWx0OwpgLHJlbHU2PXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlJFTFU2LHBhY2tlZE9wU25pcHBldDpSRUxVNl9QQUNLRUR9KSxyZWx1NkNvbmZpZz17a2VybmVsTmFtZTpSZWx1NixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmVsdTZ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFJlc2l6ZUJpbGluZWFyUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMub3V0cHV0U2hhcGU9W107Y29uc3Rbd2EsRWEsa2EsQWFdPWFhO3RoaXMub3V0cHV0U2hhcGU9W3dhLHhhLGJhLEFhXTtjb25zdCBGYT1bU2EmJnhhPjE/RWEtMTpFYSxTYSYmYmE+MT9rYS0xOmthXSxMYT1bU2EmJnhhPjE/eGEtMTp4YSxTYSYmYmE+MT9iYS0xOmJhXTtsZXQgZWw7VGE/ZWw9Iih2ZWMyKHlSQykgKyB2ZWMyKDAuNSkpICogZWZmZWN0aXZlSW5wdXRPdmVyT3V0cHV0UmF0aW9SQyAtIHZlYzIoMC41KSI6ZWw9InZlYzIoeVJDKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMiLHRoaXMudXNlckNvZGU9YAogICAgICBjb25zdCB2ZWMyIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMgPSB2ZWMyKAogICAgICAgICAgJHtGYVswXS9MYVswXX0sCiAgICAgICAgICAke0ZhWzFdL0xhWzFdfSk7CiAgICAgIGNvbnN0IHZlYzIgaW5wdXRTaGFwZVJDID0gdmVjMigke0VhfS4wLCAke2thfS4wKTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYiA9IGNvb3Jkc1swXTsKICAgICAgICBpbnQgZCA9IGNvb3Jkc1szXTsKICAgICAgICBpdmVjMiB5UkMgPSBjb29yZHMueXo7CgogICAgICAgIC8vIEZyYWN0aW9uYWwgc291cmNlIGluZGV4LgogICAgICAgIHZlYzIgc291cmNlRnJhY0luZGV4UkMgPSAke2VsfTsKCiAgICAgICAgLy8gQ29tcHV0ZSB0aGUgZm91ciBpbnRlZ2VyIGluZGljZXMuCiAgICAgICAgaXZlYzIgc291cmNlRmxvb3JSQyA9IGl2ZWMyKG1heChzb3VyY2VGcmFjSW5kZXhSQywgdmVjMigwLjApKSk7CiAgICAgICAgaXZlYzIgc291cmNlQ2VpbFJDID0gaXZlYzIoCiAgICAgICAgICBtaW4oaW5wdXRTaGFwZVJDIC0gMS4wLCBjZWlsKHNvdXJjZUZyYWNJbmRleFJDKSkpOwoKICAgICAgICBmbG9hdCB0b3BMZWZ0ID0gZ2V0QShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUZsb29yUkMueSwgZCk7CiAgICAgICAgZmxvYXQgYm90dG9tTGVmdCA9IGdldEEoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUZsb29yUkMueSwgZCk7CiAgICAgICAgZmxvYXQgdG9wUmlnaHQgPSBnZXRBKGIsIHNvdXJjZUZsb29yUkMueCwgc291cmNlQ2VpbFJDLnksIGQpOwogICAgICAgIGZsb2F0IGJvdHRvbVJpZ2h0ID0gZ2V0QShiLCBzb3VyY2VDZWlsUkMueCwgc291cmNlQ2VpbFJDLnksIGQpOwoKICAgICAgICB2ZWMyIGZyYWNSQyA9IHNvdXJjZUZyYWNJbmRleFJDIC0gdmVjMihzb3VyY2VGbG9vclJDKTsKCiAgICAgICAgZmxvYXQgdG9wID0gdG9wTGVmdCArICh0b3BSaWdodCAtIHRvcExlZnQpICogZnJhY1JDLnk7CiAgICAgICAgZmxvYXQgYm90dG9tID0gYm90dG9tTGVmdCArIChib3R0b21SaWdodCAtIGJvdHRvbUxlZnQpICogZnJhY1JDLnk7CiAgICAgICAgZmxvYXQgbmV3VmFsdWUgPSB0b3AgKyAoYm90dG9tIC0gdG9wKSAqIGZyYWNSQy54OwoKICAgICAgICBzZXRPdXRwdXQobmV3VmFsdWUpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBSZXNpemVCaWxpbmVhclBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIkEiXSx0aGlzLnBhY2tlZElucHV0cz0hMCx0aGlzLnBhY2tlZE91dHB1dD0hMCx0aGlzLm91dHB1dFNoYXBlPVtdO2NvbnN0W3dhLEVhLGthLEFhXT1hYTt0aGlzLm91dHB1dFNoYXBlPVt3YSx4YSxiYSxBYV07Y29uc3QgRmE9W1NhJiZ4YT4xP0VhLTE6RWEsU2EmJmJhPjE/a2EtMTprYV0sTGE9W1NhJiZ4YT4xP3hhLTE6eGEsU2EmJmJhPjE/YmEtMTpiYV07bGV0IGVsO1RhP2VsPSIodmVjMyh5UkMpICsgdmVjMygwLjUpKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMgLSB2ZWMzKDAuNSkiOmVsPSJ2ZWMzKHlSQykgKiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDIix0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgdmVjMyBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDID0gdmVjMygKICAgICAgICAgICR7RmFbMF0vTGFbMF19LAogICAgICAgICAgJHtGYVsxXS9MYVsxXX0sCiAgICAgICAgICAke0ZhWzFdL0xhWzFdfSk7CiAgICAgIGNvbnN0IHZlYzMgaW5wdXRTaGFwZVJDID0gdmVjMygke0VhfS4wLCAke2thfS4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtrYX0uMCk7CgogICAgICBmbG9hdCBnZXRBVmFsdWUoaW50IGIsIGludCByLCBpbnQgYywgaW50IGQpIHsKICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChnZXRBKGIsIHIsIGMsIGQpLCB2ZWMyKGMsIGQpKTsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwogICAgICAgIC8vIENhbGN1bGF0ZSB2YWx1ZXMgZm9yIG5leHQgY29sdW1uIGluIHlSQy56LgogICAgICAgIGl2ZWMzIHlSQyA9IGNvb3Jkcy55enogKyBpdmVjMygwLCAwLCAxKTsKCiAgICAgICAgLy8gRnJhY3Rpb25hbCBzb3VyY2UgaW5kZXguCiAgICAgICAgdmVjMyBzb3VyY2VGcmFjSW5kZXhSQyA9ICR7ZWx9OwoKICAgICAgICAvLyBDb21wdXRlIHRoZSBmb3VyIGludGVnZXIgaW5kaWNlcy4KICAgICAgICBpdmVjMyBzb3VyY2VGbG9vclJDID0gaXZlYzMobWF4KHNvdXJjZUZyYWNJbmRleFJDLCB2ZWMzKDAuMCkpKTsKICAgICAgICBpdmVjMyBzb3VyY2VDZWlsUkMgPSBpdmVjMygKICAgICAgICAgIG1pbihpbnB1dFNoYXBlUkMgLSAxLjAsIGNlaWwoc291cmNlRnJhY0luZGV4UkMpKSk7CgogICAgICAgIC8vIFNob3VsZCB3ZSBjYWxjdWxhdGUgbmV4dCBjb2x1bW4gYW5kIHJvdyBlbGVtZW50cyBpbiAyeDIgcGFja2VkIGNlbGwuCiAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gZCA8ICR7QWEtMX07CiAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gY29vcmRzLnogPCAke2JhLTF9OwoKICAgICAgICAvLyBJbiBwYXJhbGxlbCwgY29uc3RydWN0IGZvdXIgY29ybmVycyBmb3IgYWxsIGZvdXIgY29tcG9uZW50cyBpbgogICAgICAgIC8vIHBhY2tlZCAyeDIgY2VsbC4KICAgICAgICB2ZWM0IHRvcExlZnQgPSB2ZWM0KAogICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZUZsb29yUkMueCwgc291cmNlRmxvb3JSQy55LCBkKSwKICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VGbG9vclJDLnksIGQgKyAxKQogICAgICAgICAgICAgICAgICAgICA6IDAuMCwKICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VGbG9vclJDLnosIGQpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPwogICAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VGbG9vclJDLnosIGQgKyAxKSA6IDAuMCk7CgogICAgICAgIHZlYzQgYm90dG9tTGVmdCA9IHZlYzQoCiAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUZsb29yUkMueSwgZCksCiAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGIsIHNvdXJjZUNlaWxSQy54LCBzb3VyY2VGbG9vclJDLnksIGQgKyAxKQogICAgICAgICAgICAgICAgICAgICA6IDAuMCwKICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUZsb29yUkMueiwgZCkKICAgICAgICAgICAgICAgICAgICAgOiAwLjAsCiAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/CiAgICAgICAgICAgIGdldEFWYWx1ZShiLCBzb3VyY2VDZWlsUkMueCwgc291cmNlRmxvb3JSQy56LCBkICsgMSkgOiAwLjApOwoKICAgICAgICB2ZWM0IHRvcFJpZ2h0ID0gdmVjNCgKICAgICAgICAgIGdldEFWYWx1ZShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUNlaWxSQy55LCBkKSwKICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYiwgc291cmNlRmxvb3JSQy54LCBzb3VyY2VDZWlsUkMueSwgZCArIDEpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiLCBzb3VyY2VGbG9vclJDLngsIHNvdXJjZUNlaWxSQy56LCBkKQogICAgICAgICAgICAgICAgICAgICA6IDAuMCwKICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8KICAgICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZUZsb29yUkMueCwgc291cmNlQ2VpbFJDLnosIGQgKyAxKSA6IDAuMCk7CgogICAgICAgIHZlYzQgYm90dG9tUmlnaHQgPSB2ZWM0KAogICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZUNlaWxSQy54LCBzb3VyY2VDZWlsUkMueSwgZCksCiAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGIsIHNvdXJjZUNlaWxSQy54LCBzb3VyY2VDZWlsUkMueSwgZCArIDEpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiLCBzb3VyY2VDZWlsUkMueCwgc291cmNlQ2VpbFJDLnosIGQpCiAgICAgICAgICAgICAgICAgICAgIDogMC4wLAogICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPwogICAgICAgICAgICBnZXRBVmFsdWUoYiwgc291cmNlQ2VpbFJDLngsIHNvdXJjZUNlaWxSQy56LCBkICsgMSkgOiAwLjApOwoKICAgICAgICB2ZWMzIGZyYWNSQyA9IHNvdXJjZUZyYWNJbmRleFJDIC0gdmVjMyhzb3VyY2VGbG9vclJDKTsKCiAgICAgICAgdmVjNCB0b3AgPSBtaXgodG9wTGVmdCwgdG9wUmlnaHQsIGZyYWNSQy55eXp6KTsKICAgICAgICB2ZWM0IGJvdHRvbSA9IG1peChib3R0b21MZWZ0LCBib3R0b21SaWdodCwgZnJhY1JDLnl5enopOwogICAgICAgIHZlYzQgbmV3VmFsdWUgPSBtaXgodG9wLCBib3R0b20sIGZyYWNSQy54KTsKCiAgICAgICAgc2V0T3V0cHV0KG5ld1ZhbHVlKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplQmlsaW5lYXIoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2VzOlNhfT1hYSx7YWxpZ25Db3JuZXJzOlRhLGhhbGZQaXhlbENlbnRlcnM6d2Esc2l6ZTpFYX09YmEsW2thLEFhXT1FYSxGYT1lbnYoKS5nZXRCb29sKCJXRUJHTF9QQUNLX0lNQUdFX09QRVJBVElPTlMiKT9uZXcgUmVzaXplQmlsaW5lYXJQYWNrZWRQcm9ncmFtKFNhLnNoYXBlLGthLEFhLFRhLHdhKTpuZXcgUmVzaXplQmlsaW5lYXJQcm9ncmFtKFNhLnNoYXBlLGthLEFhLFRhLHdhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEZhLFtTYV0sImZsb2F0MzIiKX1jb25zdCByZXNpemVCaWxpbmVhckNvbmZpZz17a2VybmVsTmFtZTpSZXNpemVCaWxpbmVhcixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmVzaXplQmlsaW5lYXJ9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFJlc2l6ZUJpbGluZWFyQmFja3Byb3BQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJkeSJdLHRoaXMub3V0cHV0U2hhcGU9W10sdGhpcy5vdXRwdXRTaGFwZT14YTtjb25zdFssU2EsVGFdPXhhLFssd2EsRWFdPWFhLGthPVtiYSYmd2E+MT9TYS0xOlNhLGJhJiZFYT4xP1RhLTE6VGFdLEFhPVtiYSYmd2E+MT93YS0xOndhLGJhJiZFYT4xP0VhLTE6RWFdLEZhPWthWzBdL0FhWzBdLExhPWthWzFdL0FhWzFdLGVsPTEvRmEsdGw9MS9MYSxubD1NYXRoLmNlaWwoZWwpKjIrMixzbD1NYXRoLmNlaWwodGwpKjIrMjt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwogICAgICAgIGludCByID0gY29vcmRzWzFdOwogICAgICAgIGludCBjID0gY29vcmRzWzJdOwoKICAgICAgICBmbG9hdCBhY2N1bXVsYXRvciA9IDAuMDsKCiAgICAgICAgY29uc3QgZmxvYXQgaGVpZ2h0U2NhbGUgPSBmbG9hdCgke0ZhfSk7CiAgICAgICAgY29uc3QgZmxvYXQgd2lkdGhTY2FsZSA9IGZsb2F0KCR7TGF9KTsKCiAgICAgICAgY29uc3QgZmxvYXQgaW52SGVpZ2h0U2NhbGUgPSBmbG9hdCgke2VsfSk7CiAgICAgICAgY29uc3QgZmxvYXQgaW52V2lkdGhTY2FsZSA9IGZsb2F0KCR7dGx9KTsKCiAgICAgICAgY29uc3QgaW50IHdpbkhlaWdodCA9IGludCgke25sfSk7CiAgICAgICAgY29uc3QgaW50IHdpbldpZHRoID0gaW50KCR7c2x9KTsKCiAgICAgICAgLy8gQ29tcHV0ZSBib3VuZHMgZm9yIHdoZXJlIGluIGR5IHdlIHdpbGwgbG9vawogICAgICAgIGZsb2F0IHN0YXJ0UkxlcnAgPSBmbG9vcihmbG9hdChyKSAqIGludkhlaWdodFNjYWxlKTsKICAgICAgICBpbnQgc3RhcnREeVIgPSBpbnQoc3RhcnRSTGVycCAtIGZsb2F0KHdpbkhlaWdodCAvIDIpKTsKCiAgICAgICAgZmxvYXQgc3RhcnRDTGVycCA9IGZsb29yKGZsb2F0KGMpICogaW52V2lkdGhTY2FsZSk7CiAgICAgICAgaW50IHN0YXJ0RHlDID0gaW50KHN0YXJ0Q0xlcnAgLSBmbG9hdCh3aW5XaWR0aCAvIDIpKTsKCiAgICAgICAgLy8gTG9vcCBvdmVyIGR5CiAgICAgICAgZm9yIChpbnQgZHlST2Zmc2V0ID0gMDsgZHlST2Zmc2V0IDwgd2luSGVpZ2h0OyBkeVJPZmZzZXQrKykgewogICAgICAgICAgaW50IGR5UiA9IGR5Uk9mZnNldCArIHN0YXJ0RHlSOwoKICAgICAgICAgIC8vIEd1YXJkIGFnYWluc3QgdGhlIHdpbmRvdyBleGNlZWRpbmcgdGhlIGJvdW5kcyBvZiBkeQogICAgICAgICAgaWYgKGR5UiA8IDAgfHwgZHlSID49ICR7d2F9KSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaW50IGR5Q09mZnNldCA9IDA7IGR5Q09mZnNldCA8IHdpbldpZHRoOyBkeUNPZmZzZXQrKykgewogICAgICAgICAgICBpbnQgZHlDID0gZHlDT2Zmc2V0ICsgc3RhcnREeUM7CgogICAgICAgICAgICAvLyBHdWFyZCBhZ2FpbnN0IHRoZSB3aW5kb3cgZXhjZWVkaW5nIHRoZSBib3VuZHMgb2YgZHkKICAgICAgICAgICAgaWYgKGR5QyA8IDAgfHwgZHlDID49ICR7RWF9KSB7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZsb2F0IGR4UiA9IGZsb2F0KGR5UikgKiBoZWlnaHRTY2FsZTsKICAgICAgICAgICAgaW50IHRvcER4UkluZGV4ID0gaW50KGZsb29yKGR4UikpOwogICAgICAgICAgICBpbnQgYm90dG9tRHhSSW5kZXggPSBpbnQobWluKGNlaWwoZHhSKSwgJHtTYS0xfS4wKSk7CiAgICAgICAgICAgIGZsb2F0IGR4UkxlcnAgPSBkeFIgLSBmbG9hdCh0b3BEeFJJbmRleCk7CiAgICAgICAgICAgIGZsb2F0IGludmVyc2VEeFJMZXJwID0gMS4wIC0gZHhSTGVycDsKCiAgICAgICAgICAgIGZsb2F0IGR4QyA9IGZsb2F0KGR5QykgKiB3aWR0aFNjYWxlOwogICAgICAgICAgICBpbnQgbGVmdER4Q0luZGV4ID0gaW50KGZsb29yKGR4QykpOwogICAgICAgICAgICBpbnQgcmlnaHREeENJbmRleCA9IGludChtaW4oY2VpbChkeEMpLCAke1RhLTF9LjApKTsKICAgICAgICAgICAgZmxvYXQgZHhDTGVycCA9IGR4QyAtIGZsb2F0KGxlZnREeENJbmRleCk7CiAgICAgICAgICAgIGZsb2F0IGludmVyc2VEeENMZXJwID0gMS4wIC0gZHhDTGVycDsKCiAgICAgICAgICAgIGlmIChyID09IHRvcER4UkluZGV4ICYmIGMgPT0gbGVmdER4Q0luZGV4KSB7CiAgICAgICAgICAgICAgLy8gdG9wTGVmdAogICAgICAgICAgICAgIGFjY3VtdWxhdG9yICs9CiAgICAgICAgICAgICAgICBnZXREeShiLCBkeVIsIGR5QywgZCkgKiBpbnZlcnNlRHhSTGVycCAqIGludmVyc2VEeENMZXJwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAociA9PSB0b3BEeFJJbmRleCAmJiBjID09IHJpZ2h0RHhDSW5kZXgpIHsKICAgICAgICAgICAgICAvLyB0b3BSaWdodAogICAgICAgICAgICAgIGFjY3VtdWxhdG9yICs9IGdldER5KGIsIGR5UiwgZHlDLCBkKSAqIGludmVyc2VEeFJMZXJwICogZHhDTGVycDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHIgPT0gYm90dG9tRHhSSW5kZXggJiYgYyA9PSBsZWZ0RHhDSW5kZXgpIHsKICAgICAgICAgICAgICAvLyBib3R0b21MZWZ0CiAgICAgICAgICAgICAgYWNjdW11bGF0b3IgKz0gZ2V0RHkoYiwgZHlSLCBkeUMsIGQpICogZHhSTGVycCAqIGludmVyc2VEeENMZXJwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAociA9PSBib3R0b21EeFJJbmRleCAmJiBjID09IHJpZ2h0RHhDSW5kZXgpIHsKICAgICAgICAgICAgICAvLyBib3R0b21SaWdodAogICAgICAgICAgICAgIGFjY3VtdWxhdG9yICs9IGdldER5KGIsIGR5UiwgZHlDLCBkKSAqIGR4UkxlcnAgKiBkeENMZXJwOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIEVuZCBsb29wIG92ZXIgZHkKCiAgICAgICAgc2V0T3V0cHV0KGFjY3VtdWxhdG9yKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplQmlsaW5lYXJHcmFkKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2ltYWdlczpTYSxkeTpUYX09YWEse2FsaWduQ29ybmVyczp3YX09YmEsRWE9bmV3IFJlc2l6ZUJpbGluZWFyQmFja3Byb3BQcm9ncmFtKFRhLnNoYXBlLFNhLnNoYXBlLHdhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEVhLFtUYV0sVGEuZHR5cGUpfWNvbnN0IHJlc2l6ZUJpbGluZWFyR3JhZENvbmZpZz17a2VybmVsTmFtZTpSZXNpemVCaWxpbmVhckdyYWQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlc2l6ZUJpbGluZWFyR3JhZH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmVzaXplTmVhcmVzdE5laWdoYm9yUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMub3V0cHV0U2hhcGU9W107Y29uc3Rbd2EsRWEsa2EsQWFdPWFhO3RoaXMub3V0cHV0U2hhcGU9W3dhLHhhLGJhLEFhXTtjb25zdCBGYT1bU2EmJnhhPjE/RWEtMTpFYSxTYSYmYmE+MT9rYS0xOmthXSxMYT1bU2EmJnhhPjE/eGEtMTp4YSxTYSYmYmE+MT9iYS0xOmJhXSxlbD1TYT8iMC41IjoiMC4wIjtsZXQgdGw7VGE/dGw9Im1heCgodmVjMih5UkMpICsgdmVjMigwLjUpKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMsIHZlYzIoMC4wKSkiOnRsPSJ2ZWMyKHlSQykgKiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDIix0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgdmVjMiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDID0gdmVjMigKICAgICAgICAgICR7RmFbMF0vTGFbMF19LAogICAgICAgICAgJHtGYVsxXS9MYVsxXX0pOwogICAgICBjb25zdCB2ZWMyIGlucHV0U2hhcGVSQyA9IHZlYzIoJHtFYX0uMCwgJHtrYX0uMCk7CgogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQgPSBjb29yZHNbM107CiAgICAgICAgaXZlYzIgeVJDID0gY29vcmRzLnl6OwoKICAgICAgICAvLyBGcmFjdGlvbmFsIHNvdXJjZSBpbmRleC4KICAgICAgICB2ZWMyIHNvdXJjZUZyYWNJbmRleFJDID0gJHt0bH07CgogICAgICAgIC8vIENvbXB1dGUgdGhlIGNvb3JkaW5hdG9ycyBvZiBuZWFyZXN0IG5laWdoYm9yIHBvaW50LgogICAgICAgIGl2ZWMyIHNvdXJjZU5lYXJlc3RSQyA9IGl2ZWMyKAogICAgICAgICAgbWluKGlucHV0U2hhcGVSQyAtIDEuMCwgZmxvb3Ioc291cmNlRnJhY0luZGV4UkMgKyAke2VsfSkpKTsKICAgICAgICBmbG9hdCBuZXdWYWx1ZSA9IGdldEEoYiwgc291cmNlTmVhcmVzdFJDLngsIHNvdXJjZU5lYXJlc3RSQy55LCBkKTsKCiAgICAgICAgc2V0T3V0cHV0KG5ld1ZhbHVlKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmVzaXplTmVhcmVzdE5laWdoYm9yUGFja2VkUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdLHRoaXMucGFja2VkSW5wdXRzPSEwLHRoaXMucGFja2VkT3V0cHV0PSEwLHRoaXMub3V0cHV0U2hhcGU9W107Y29uc3Rbd2EsRWEsa2EsQWFdPWFhO3RoaXMub3V0cHV0U2hhcGU9W3dhLHhhLGJhLEFhXTtjb25zdCBGYT1bU2EmJnhhPjE/RWEtMTpFYSxTYSYmYmE+MT9rYS0xOmthXSxMYT1bU2EmJnhhPjE/eGEtMTp4YSxTYSYmYmE+MT9iYS0xOmJhXSxlbD1TYT8iMC41IjoiMC4wIjtsZXQgdGw7VGE/dGw9Im1heCgodmVjMyh5UkMpICsgdmVjMygwLjUpKSAqIGVmZmVjdGl2ZUlucHV0T3Zlck91dHB1dFJhdGlvUkMsIHZlYzMoMC4wKSkiOnRsPSJ2ZWMzKHlSQykgKiBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDIix0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgdmVjMyBlZmZlY3RpdmVJbnB1dE92ZXJPdXRwdXRSYXRpb1JDID0gdmVjMygKICAgICAgICAgICR7RmFbMF0vTGFbMF19LAogICAgICAgICAgJHtGYVsxXS9MYVsxXX0sCiAgICAgICAgICAke0ZhWzFdL0xhWzFdfSk7CiAgICAgIGNvbnN0IHZlYzMgaW5wdXRTaGFwZVJDID0gdmVjMygke0VhfS4wLCAke2thfS4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtrYX0uMCk7CgogICAgICBmbG9hdCBnZXRBVmFsdWUoaW50IGIsIGludCByLCBpbnQgYywgaW50IGQpIHsKICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChnZXRBKGIsIHIsIGMsIGQpLCB2ZWMyKGMsIGQpKTsKICAgICAgfQoKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGludCBiID0gY29vcmRzWzBdOwogICAgICAgIGludCBkID0gY29vcmRzWzNdOwogICAgICAgIC8vIENhbGN1bGF0ZSB2YWx1ZXMgZm9yIG5leHQgY29sdW1uIGluIHlSQy56LgogICAgICAgIGl2ZWMzIHlSQyA9IGNvb3Jkcy55enogKyBpdmVjMygwLCAwLCAxKTsKCiAgICAgICAgLy8gRnJhY3Rpb25hbCBzb3VyY2UgaW5kZXguCiAgICAgICAgdmVjMyBzb3VyY2VGcmFjSW5kZXhSQyA9ICR7dGx9OwoKICAgICAgICAvLyBDb21wdXRlIHRoZSBjb29yZGluYXRvcnMgb2YgbmVhcmVzdCBuZWlnaGJvciBwb2ludC4KICAgICAgICBpdmVjMyBzb3VyY2VOZWFyZXN0UkMgPSBpdmVjMygKICAgICAgICAgIG1pbihpbnB1dFNoYXBlUkMgLSAxLjAsIGZsb29yKHNvdXJjZUZyYWNJbmRleFJDICsgJHtlbH0pKSk7CgogICAgICAgIC8vIFNob3VsZCB3ZSBjYWxjdWxhdGUgbmV4dCBjb2x1bW4gYW5kIHJvdyBlbGVtZW50cyBpbiAyeDIgcGFja2VkIGNlbGwuCiAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gZCA8ICR7QWEtMX07CiAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gY29vcmRzLnogPCAke2JhLTF9OwoKICAgICAgICB2ZWM0IG5ld1ZhbHVlID0gdmVjNCgKICAgICAgICAgIGdldEFWYWx1ZShiLCBzb3VyY2VOZWFyZXN0UkMueCwgc291cmNlTmVhcmVzdFJDLnksIGQpLAogICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiLCBzb3VyY2VOZWFyZXN0UkMueCwgc291cmNlTmVhcmVzdFJDLnksIGQgKyAxKQogICAgICAgICAgICAgICAgICAgICA6IDAuMCwKICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYiwgc291cmNlTmVhcmVzdFJDLngsIHNvdXJjZU5lYXJlc3RSQy56LCBkKQogICAgICAgICAgICAgICAgICAgICA6IDAuMCwKICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8KICAgICAgICAgICAgZ2V0QVZhbHVlKGIsIHNvdXJjZU5lYXJlc3RSQy54LCBzb3VyY2VOZWFyZXN0UkMueiwgZCArIDEpIDogMC4wKTsKCiAgICAgICAgc2V0T3V0cHV0KG5ld1ZhbHVlKTsKICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gcmVzaXplTmVhcmVzdE5laWdoYm9yKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2ltYWdlczpTYX09YWEse2FsaWduQ29ybmVyczpUYSxoYWxmUGl4ZWxDZW50ZXJzOndhLHNpemU6RWF9PWJhLFtrYSxBYV09RWEsRmE9ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDS19JTUFHRV9PUEVSQVRJT05TIik/bmV3IFJlc2l6ZU5lYXJlc3ROZWlnaGJvclBhY2tlZFByb2dyYW0oU2Euc2hhcGUsa2EsQWEsVGEsd2EpOm5ldyBSZXNpemVOZWFyZXN0TmVpZ2hib3JQcm9ncmFtKFNhLnNoYXBlLGthLEFhLFRhLHdhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEZhLFtTYV0sU2EuZHR5cGUpfWNvbnN0IHJlc2l6ZU5lYXJlc3ROZWlnaGJvckNvbmZpZz17a2VybmVsTmFtZTpSZXNpemVOZWFyZXN0TmVpZ2hib3IsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJlc2l6ZU5lYXJlc3ROZWlnaGJvcn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmVzaXplTmVhcmVzdE5laWdib3JCYWNrcHJvcFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bImR5Il0sdGhpcy5vdXRwdXRTaGFwZT1bXSx0aGlzLm91dHB1dFNoYXBlPXhhO2NvbnN0WyxTYSxUYV09eGEsWyx3YSxFYV09YWEsa2E9W2JhJiZ3YT4xP1NhLTE6U2EsYmEmJkVhPjE/VGEtMTpUYV0sQWE9W2JhJiZ3YT4xP3dhLTE6d2EsYmEmJkVhPjE/RWEtMTpFYV0sRmE9a2FbMF0vQWFbMF0sTGE9a2FbMV0vQWFbMV0sZWw9MS9GYSx0bD0xL0xhLG5sPU1hdGguY2VpbChlbCkqMisyLHNsPU1hdGguY2VpbCh0bCkqMisyO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgaW50IGIgPSBjb29yZHNbMF07CiAgICAgICAgaW50IGQgPSBjb29yZHNbM107CiAgICAgICAgaW50IHIgPSBjb29yZHNbMV07CiAgICAgICAgaW50IGMgPSBjb29yZHNbMl07CgogICAgICAgIGZsb2F0IGFjY3VtdWxhdG9yID0gMC4wOwoKICAgICAgICBjb25zdCBmbG9hdCBoZWlnaHRTY2FsZSA9IGZsb2F0KCR7RmF9KTsKICAgICAgICBjb25zdCBmbG9hdCB3aWR0aFNjYWxlID0gZmxvYXQoJHtMYX0pOwoKICAgICAgICBjb25zdCBmbG9hdCBpbnZIZWlnaHRTY2FsZSA9IGZsb2F0KCR7ZWx9KTsKICAgICAgICBjb25zdCBmbG9hdCBpbnZXaWR0aFNjYWxlID0gZmxvYXQoJHt0bH0pOwoKICAgICAgICBjb25zdCBpbnQgd2luSGVpZ2h0ID0gaW50KCR7bmx9KTsKICAgICAgICBjb25zdCBpbnQgd2luV2lkdGggPSBpbnQoJHtzbH0pOwoKICAgICAgICAvLyBDb21wdXRlIGJvdW5kcyBmb3Igd2hlcmUgaW4gZHkgd2Ugd2lsbCBsb29rCiAgICAgICAgZmxvYXQgc3RhcnRSTGVycCA9IGZsb29yKGZsb2F0KHIpICogaW52SGVpZ2h0U2NhbGUpOwogICAgICAgIGludCBzdGFydER5UiA9IGludChmbG9vcihzdGFydFJMZXJwIC0gZmxvYXQod2luSGVpZ2h0IC8gMikpKTsKCiAgICAgICAgZmxvYXQgc3RhcnRDTGVycCA9IGZsb29yKGZsb2F0KGMpICogaW52V2lkdGhTY2FsZSk7CiAgICAgICAgaW50IHN0YXJ0RHlDID0gaW50KGZsb29yKHN0YXJ0Q0xlcnAgLSBmbG9hdCh3aW5XaWR0aCAvIDIpKSk7CgogICAgICAgIC8vIExvb3Agb3ZlciBkeQogICAgICAgIGZvciAoaW50IGR5Uk9mZnNldCA9IDA7IGR5Uk9mZnNldCA8IHdpbkhlaWdodDsgZHlST2Zmc2V0KyspIHsKICAgICAgICAgIGludCBkeVIgPSBkeVJPZmZzZXQgKyBzdGFydER5UjsKCiAgICAgICAgICAvLyBHdWFyZCBhZ2FpbnN0IHRoZSB3aW5kb3cgZXhjZWVkaW5nIHRoZSBib3VuZHMgb2YgZHkKICAgICAgICAgIGlmIChkeVIgPCAwIHx8IGR5UiA+PSAke3dhfSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBmb3IgKGludCBkeUNPZmZzZXQgPSAwOyBkeUNPZmZzZXQgPCB3aW5XaWR0aDsgZHlDT2Zmc2V0KyspIHsKICAgICAgICAgICAgaW50IGR5QyA9IGR5Q09mZnNldCArIHN0YXJ0RHlDOwoKICAgICAgICAgICAgLy8gR3VhcmQgYWdhaW5zdCB0aGUgd2luZG93IGV4Y2VlZGluZyB0aGUgYm91bmRzIG9mIGR5CiAgICAgICAgICAgIGlmIChkeUMgPCAwIHx8IGR5QyA+PSAke0VhfSkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmbG9hdCBzb3VyY2VGcmFjUm93ID0KICAgICAgICAgICAgICBmbG9hdCgke2thWzBdfSkgKgogICAgICAgICAgICAgICAgKGZsb2F0KGR5UikgLyBmbG9hdCgke0FhWzBdfSkpOwoKICAgICAgICAgICAgZmxvYXQgc291cmNlRnJhY0NvbCA9CiAgICAgICAgICAgICAgICBmbG9hdCgke2thWzFdfSkgKgogICAgICAgICAgICAgICAgICAoZmxvYXQoZHlDKSAvIGZsb2F0KCR7QWFbMV19KSk7CgogICAgICAgICAgICBpbnQgc291cmNlTmVhcmVzdFJvdyA9IGludChtaW4oCiAgICAgICAgICAgICAgICBmbG9hdChpbnQoJHtTYX0pIC0gMSksCiAgICAgICAgICAgICAgICAke2JhfSA/IGZsb2F0KHJvdW5kKHNvdXJjZUZyYWNSb3cpKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdChmbG9vcihzb3VyY2VGcmFjUm93KSkpKTsKCiAgICAgICAgICAgIGludCBzb3VyY2VOZWFyZXN0Q29sID0gaW50KG1pbigKICAgICAgICAgICAgICAgIGZsb2F0KGludCgke1RhfSkgLSAxKSwKICAgICAgICAgICAgICAgICR7YmF9ID8gZmxvYXQocm91bmQoc291cmNlRnJhY0NvbCkpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0KGZsb29yKHNvdXJjZUZyYWNDb2wpKSkpOwoKICAgICAgICAgICAgaWYgKHIgPT0gc291cmNlTmVhcmVzdFJvdyAmJiBjID09IHNvdXJjZU5lYXJlc3RDb2wpIHsKICAgICAgICAgICAgICBhY2N1bXVsYXRvciArPSBnZXREeShiLCBkeVIsIGR5QywgZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gRW5kIGxvb3Agb3ZlciBkeQoKICAgICAgICBzZXRPdXRwdXQoYWNjdW11bGF0b3IpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse2ltYWdlczpTYSxkeTpUYX09YWEse2FsaWduQ29ybmVyczp3YX09YmEsRWE9bmV3IFJlc2l6ZU5lYXJlc3ROZWlnYm9yQmFja3Byb3BQcm9ncmFtKFRhLnNoYXBlLFNhLnNoYXBlLHdhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKEVhLFtUYV0sVGEuZHR5cGUpfWNvbnN0IHJlc2l6ZU5lYXJlc3ROZWlnaGJvckdyYWRDb25maWc9e2tlcm5lbE5hbWU6UmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmVzaXplTmVhcmVzdE5laWdoYm9yR3JhZH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUmV2ZXJzZVByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiXTtjb25zdCBiYT1hYS5sZW5ndGg7aWYoYmE+NCl0aHJvdyBuZXcgRXJyb3IoYFdlYkdMIGJhY2tlbmQ6IFJldmVyc2Ugb2YgcmFuay0ke2JhfSB0ZW5zb3IgaXMgbm90IHlldCBzdXBwb3J0ZWRgKTtpZih0aGlzLm91dHB1dFNoYXBlPWFhLGJhPT09MSl7dGhpcy51c2VyQ29kZT1gCiAgICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICAgaW50IGNvb3JkID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgICBzZXRPdXRwdXQoZ2V0WCgke2FhWzBdfSAtIGNvb3JkIC0gMSkpOwogICAgICAgIH0KICAgICAgYDtyZXR1cm59Y29uc3QgU2E9RWE9PnhhLmluZGV4T2YoRWEpIT09LTEmJmFhW0VhXSE9PTE/YCR7YWFbRWFdfSAtIGNvb3Jkc1ske0VhfV0gLSAxYDpgY29vcmRzWyR7RWF9XWAsVGE9YWEubWFwKChFYSxrYSk9PlNhKGthKSkuam9pbigiLCIpLHdhPWdldENvb3Jkc0RhdGFUeXBlKGJhKTt0aGlzLnVzZXJDb2RlPWAKICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICR7d2F9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIHNldE91dHB1dChnZXRYKCR7VGF9KSk7CiAgICAgIH0KICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFJldmVyc2VQYWNrZWRQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4Il0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITA7Y29uc3QgYmE9YWEubGVuZ3RoO2lmKGJhPjQpdGhyb3cgbmV3IEVycm9yKGBXZWJHTCBiYWNrZW5kOiBSZXZlcnNlIG9mIHJhbmstJHtiYX0gdGVuc29yIGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7dGhpcy5vdXRwdXRTaGFwZT1hYTtjb25zdCBTYT1nZXRDaGFubmVscygicmMiLGJhKSxUYT1gJHtTYVtiYS0xXX0gKyAxIDwgJHt0aGlzLm91dHB1dFNoYXBlW2JhLTFdfWAsd2E9YCR7U2FbYmEtMl19ICsgMSA8ICR7dGhpcy5vdXRwdXRTaGFwZVtiYS0yXX1gLEVhPWdldENvb3Jkc0RhdGFUeXBlKGJhKTtiYT09PTE/dGhpcy51c2VyQ29kZT1gCiAgICAgICAgdm9pZCBtYWluKCl7CiAgICAgICAgICBpbnQgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLik7CiAgICAgICAgICByZXN1bHQuciA9IGdldENoYW5uZWwoZ2V0WCgke2FhWzBdfSAtIHJjIC0gMSksCiAgICAgICAgICAgICR7YWFbMF19IC0gcmMgLSAxKTsKICAgICAgICAgIGlmKCR7VGF9KXsKICAgICAgICAgICAgICByZXN1bHQuZyA9IGdldENoYW5uZWwoZ2V0WCgke2FhWzBdfSAtIChyYyAgKyAxKSAtIDEpLAogICAgICAgICAgICAgICAgJHthYVswXX0gLSAocmMgICsgMSkgLSAxKTsKICAgICAgICAgIH0KICAgICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICAgIH0KICAgICAgYDp0aGlzLnVzZXJDb2RlPWAKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICAke0VhfSByYyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuKTsKICAgICAgICAgIHJlc3VsdC5yID0gJHtrYShTYS5zbGljZSgpKX07CiAgICAgICAgICBpZigke1RhfSl7CiAgICAgICAgICAgIHJlc3VsdC5nID0gJHtBYShTYS5zbGljZSgpKX07CiAgICAgICAgICB9CiAgICAgICAgICBpZigke3dhfSkgewogICAgICAgICAgICByZXN1bHQuYiA9ICR7RmEoU2Euc2xpY2UoKSl9OwogICAgICAgICAgICBpZigke1RhfSkgewogICAgICAgICAgICAgIHJlc3VsdC5hID0gJHtMYShTYS5zbGljZSgpKX07CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHNldE91dHB1dChyZXN1bHQpOwogICAgICAgIH0KICAgIGA7ZnVuY3Rpb24ga2Eobmwpe3JldHVybiBlbChubCl9ZnVuY3Rpb24gQWEobmwpe3JldHVybiBubFtiYS0xXT0iKCIrbmxbYmEtMV0rIiArIDEpIixlbChubCl9ZnVuY3Rpb24gRmEobmwpe3JldHVybiBubFtiYS0yXT0iKCIrbmxbYmEtMl0rIiArIDEpIixlbChubCl9ZnVuY3Rpb24gTGEobmwpe3JldHVybiBubFtiYS0xXT0iKCIrbmxbYmEtMV0rIiArIDEpIixubFtiYS0yXT0iKCIrbmxbYmEtMl0rIiArIDEpIixlbChubCl9ZnVuY3Rpb24gZWwobmwpe2NvbnN0IHNsPWFhLm1hcCgoYWwsbGwpPT50bChsbCxubCkpLHJsPXNsLmpvaW4oIiwiKSxvbD1zbC5zbGljZSgtMikuam9pbigiLCIpO3JldHVybmBnZXRDaGFubmVsKGdldFgoJHtybH0pLCB2ZWMyKCR7b2x9KSlgfWZ1bmN0aW9uIHRsKG5sLHNsKXtyZXR1cm4geGEuaW5kZXhPZihubCkhPT0tMSYmYWFbbmxdIT09MT9gJHthYVtubF19IC0gJHtzbFtubF19IC0gMWA6YCR7c2xbbmxdfWB9fX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiByZXZlcnNlKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtkaW1zOlRhfT1iYSx3YT1TYS5zaGFwZS5sZW5ndGgsRWE9cGFyc2VBeGlzUGFyYW0oVGEsU2Euc2hhcGUpO2lmKHdhPT09MClyZXR1cm4gaWRlbnRpdHkoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YX0pO2NvbnN0IGthPWVudigpLmdldEJvb2woIldFQkdMX1BBQ0tfQVJSQVlfT1BFUkFUSU9OUyIpP25ldyBSZXZlcnNlUGFja2VkUHJvZ3JhbShTYS5zaGFwZSxFYSk6bmV3IFJldmVyc2VQcm9ncmFtKFNhLnNoYXBlLEVhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKGthLFtTYV0sU2EuZHR5cGUpfWNvbnN0IHJldmVyc2VDb25maWc9e2tlcm5lbE5hbWU6UmV2ZXJzZSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cmV2ZXJzZX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgUm90YXRlUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiSW1hZ2UiXSx0aGlzLm91dHB1dFNoYXBlPVtdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJwYXJhbXMiLHR5cGU6InZlYzQifV07Y29uc3QgYmE9YWFbMV0sU2E9YWFbMl07dGhpcy5vdXRwdXRTaGFwZT1hYTtsZXQgVGE9IiI7dHlwZW9mIHhhPT0ibnVtYmVyIj9UYT1gZmxvYXQgb3V0cHV0VmFsdWUgPSAke3hhLnRvRml4ZWQoMil9O2A6VGE9YAogICAgICAgIHZlYzMgZmlsbCA9IHZlYzMoJHt4YS5qb2luKCIsIil9KTsKICAgICAgICBmbG9hdCBvdXRwdXRWYWx1ZSA9IGZpbGxbY29vcmRzWzNdXTtgLHRoaXMudXNlckNvZGU9YAogICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgaW50IHggPSBjb29yZHNbMl07CiAgICAgICAgICBpbnQgeSA9IGNvb3Jkc1sxXTsKICAgICAgICAgIGZsb2F0IGNvb3JkWEZsb2F0ID0gKGZsb2F0KHgpIC0gcGFyYW1zWzBdKSAqIHBhcmFtc1szXSAtCiAgICAgICAgICAgIChmbG9hdCh5KSAtIHBhcmFtc1sxXSkgKiBwYXJhbXNbMl07CiAgICAgICAgICBmbG9hdCBjb29yZFlGbG9hdCA9IChmbG9hdCh4KSAtIHBhcmFtc1swXSkgKiBwYXJhbXNbMl0gKwogICAgICAgICAgICAoZmxvYXQoeSkgLSBwYXJhbXNbMV0pICogcGFyYW1zWzNdOwogICAgICAgICAgaW50IGNvb3JkWCA9IGludChyb3VuZChjb29yZFhGbG9hdCArIHBhcmFtc1swXSkpOwogICAgICAgICAgaW50IGNvb3JkWSA9IGludChyb3VuZChjb29yZFlGbG9hdCArIHBhcmFtc1sxXSkpOwogICAgICAgICAgJHtUYX0KICAgICAgICAgIGlmKGNvb3JkWCA+PSAwICYmIGNvb3JkWCA8ICR7U2F9ICYmIGNvb3JkWSA+PSAwICYmIGNvb3JkWSA8ICR7YmF9KSB7CiAgICAgICAgICAgIG91dHB1dFZhbHVlID0gZ2V0SW1hZ2UoY29vcmRzWzBdLCBjb29yZFksIGNvb3JkWCwgY29vcmRzWzNdKTsKICAgICAgICAgIH0KICAgICAgICAgIHNldE91dHB1dChvdXRwdXRWYWx1ZSk7CiAgICAgICAgfQogICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgcm90YXRlV2l0aE9mZnNldENvbmZpZz17a2VybmVsTmFtZTpSb3RhdGVXaXRoT2Zmc2V0LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzooe2lucHV0czpoYSxhdHRyczphYSxiYWNrZW5kOnhhfSk9Pntjb25zdHtpbWFnZTpiYX09aGEse3JhZGlhbnM6U2EsZmlsbFZhbHVlOlRhLGNlbnRlcjp3YX09YWEsRWE9eGEsa2E9bmV3IFJvdGF0ZVByb2dyYW0oYmEuc2hhcGUsVGEpLFtBYSxGYV09Z2V0SW1hZ2VDZW50ZXIod2EsYmEuc2hhcGVbMV0sYmEuc2hhcGVbMl0pLExhPVtbQWEsRmEsTWF0aC5zaW4oU2EpLE1hdGguY29zKFNhKV1dO3JldHVybiBFYS5ydW5XZWJHTFByb2dyYW0oa2EsW2JhXSxiYS5kdHlwZSxMYSl9fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBST1VORD1gCiAgLy8gT3BlbkdMIEVTIGRvZXMgbm90IHN1cHBvcnQgcm91bmQgZnVuY3Rpb24uCiAgLy8gVGhlIGFsZ29yaXRobSBpcyBiYXNlZCBvbiBiYW5rZXIncyByb3VuZGluZy4KICBmbG9hdCBiYXNlID0gZmxvb3IoeCk7CiAgaWYgKCh4IC0gYmFzZSkgPCAwLjUpIHsKICAgIHJldHVybiBmbG9vcih4KTsKICB9IGVsc2UgaWYgKCh4IC0gYmFzZSkgPiAwLjUpIHsKICAgIHJldHVybiBjZWlsKHgpOwogIH0gZWxzZSB7CiAgICBpZiAobW9kKGJhc2UsIDIuMCkgPT0gMC4wKSB7CiAgICAgIHJldHVybiBiYXNlOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGJhc2UgKyAxLjA7CiAgICB9CiAgfQpgLHJvdW5kPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlJPVU5EfSkscm91bmRDb25maWc9e2tlcm5lbE5hbWU6Um91bmQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnJvdW5kfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBSU1FSVD0icmV0dXJuIGludmVyc2VzcXJ0KHgpOyIscnNxcnQ9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6UlNRUlQsY3B1S2VybmVsSW1wbDpyc3FydEltcGxDUFV9KSxyc3FydENvbmZpZz17a2VybmVsTmFtZTpSc3FydCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6cnNxcnR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFNjYXR0ZXJQcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhLEVhPSEwLGthPSExKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ1cGRhdGVzIiwiaW5kaWNlcyIsImRlZmF1bHRWYWx1ZSJdLHRoaXMub3V0cHV0U2hhcGU9d2E7Y29uc3QgQWE9Z2V0Q29vcmRzRGF0YVR5cGUoVGEubGVuZ3RoKSxGYT1nZXRDb29yZHNEYXRhVHlwZSh3YS5sZW5ndGgpO2xldCBMYT0iIjtiYT09PTE/TGE9ImkiOmJhPT09MiYmKExhPSJpLCBqIik7Y29uc3QgZWw9YGdldEluZGljZXMoJHtMYX0pYDtsZXQgdGw9IiI7U2E9PT0xP3RsPSJpIjpTYT09PTImJih0bD0iaSwgY29vcmRzWzFdIik7Y29uc3Qgbmw9YGdldFVwZGF0ZXMoJHt0bH0pYDtsZXQgc2w9IiI7a2EmJihzbD0iY29vcmRzWzBdLCBjb29yZHNbMV0iKTtjb25zdCBybD1gZ2V0RGVmYXVsdFZhbHVlKCR7c2x9KWAsb2w9eGE+MT8ic3RyaWRlc1tqXSI6InN0cmlkZXMiO3RoaXMudXNlckNvZGU9YAogICAgICAgICR7QWF9IHN0cmlkZXMgPSAke0FhfSgke1RhfSk7CgogICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgICR7RmF9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgICAgZmxvYXQgc3VtID0gMC4wOwogICAgICAgICAgYm9vbCBmb3VuZCA9IGZhbHNlOwogICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2FhfTsgaSsrKSB7CiAgICAgICAgICAgIGludCBmbGF0dGVuZWRJbmRleCA9IDA7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHt4YX07IGorKykgewogICAgICAgICAgICAgIGludCBpbmRleCA9IHJvdW5kKCR7ZWx9KTsKICAgICAgICAgICAgICBmbGF0dGVuZWRJbmRleCArPSBpbmRleCAqICR7b2x9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChmbGF0dGVuZWRJbmRleCA9PSBjb29yZHNbMF0pIHsKICAgICAgICAgICAgICBzdW0gKz0gJHtubH07CiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBzZXRPdXRwdXQobWl4KCR7cmx9LCBzdW0sIGZsb2F0KGZvdW5kKSkpOwogICAgICAgIH0KICAgICAgYH19LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgU2NhdHRlclBhY2tlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2EsVGEsd2EsRWE9ITAsa2E9ITEpe3RoaXMudmFyaWFibGVOYW1lcz1bInVwZGF0ZXMiLCJpbmRpY2VzIiwiZGVmYXVsdFZhbHVlIl0sdGhpcy5wYWNrZWRJbnB1dHM9ITAsdGhpcy5wYWNrZWRPdXRwdXQ9ITAsdGhpcy5vdXRwdXRTaGFwZT13YTtjb25zdCBBYT1nZXRDb29yZHNEYXRhVHlwZShUYS5sZW5ndGgpLEZhPWdldENvb3Jkc0RhdGFUeXBlKHdhLmxlbmd0aCk7bGV0IExhPSIiO2JhPT09MT9MYT0iaSI6YmE9PT0yJiYoTGE9ImksIGoiKTtjb25zdCBlbD1gZ2V0SW5kaWNlcygke0xhfSlgO2xldCB0bD0iIjtTYT09PTE/dGw9ImkiOlNhPT09MiYmKHRsPSJpLCBjb29yZHNbMV0iKTtjb25zdCBubD1gZ2V0VXBkYXRlcygke3RsfSlgO2xldCBzbD0iIjtrYSYmKHNsPSJjb29yZHNbMF0sIGNvb3Jkc1sxXSIpO2NvbnN0IHJsPWBnZXREZWZhdWx0VmFsdWUoJHtzbH0pYCxvbD14YT4xPyJzdHJpZGVzW2pdIjoic3RyaWRlcyIsYWw9eGE+MT8ic3RyaWRlc1tqICsgMV0iOiJzdHJpZGVzIjt0aGlzLnVzZXJDb2RlPWAKICAgICAgICAke0FhfSBzdHJpZGVzID0gJHtBYX0oJHtUYX0pOwoKICAgICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgICAke0ZhfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgIHZlYzQgc3VtID0gdmVjNCgwLik7CiAgICAgICAgICB2ZWM0IGZvdW5kID0gdmVjNCgwLik7CiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7YWF9OyBpKz0yKSB7CiAgICAgICAgICAgIGl2ZWMyIGZsYXR0ZW5lZEluZGV4ID0gaXZlYzIoMCk7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHt4YX07IGorPTIpIHsKICAgICAgICAgICAgICBpdmVjNCBpbmRleCA9IHJvdW5kKCR7ZWx9KTsKICAgICAgICAgICAgICBmbGF0dGVuZWRJbmRleCArPSBpbmRleC54eiAqICR7b2x9OwogICAgICAgICAgICAgIGlmIChqICsgMSA8ICR7eGF9KSB7CiAgICAgICAgICAgICAgICBmbGF0dGVuZWRJbmRleCArPSBpbmRleC55dyAqICR7YWx9OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZmxhdHRlbmVkSW5kZXhbMF0gPT0gY29vcmRzWzBdIHx8IGZsYXR0ZW5lZEluZGV4WzFdID09IGNvb3Jkc1swXSB8fAogICAgICAgICAgICAgICAgZmxhdHRlbmVkSW5kZXhbMF0gPT0gY29vcmRzWzBdICsgMSB8fCBmbGF0dGVuZWRJbmRleFsxXSA9PSBjb29yZHNbMF0gKyAxKSB7CiAgICAgICAgICAgICAgdmVjNCB1cGRWYWxzID0gJHtubH07CiAgICAgICAgICAgICAgaWYgKGZsYXR0ZW5lZEluZGV4WzBdID09IGNvb3Jkc1swXSkgewogICAgICAgICAgICAgICAgc3VtLnh5ICs9IHVwZFZhbHMueHk7CiAgICAgICAgICAgICAgICBmb3VuZC54eSA9IHZlYzIoMS4pOwogICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmxhdHRlbmVkSW5kZXhbMF0gPT0gY29vcmRzWzBdICsgMSkgewogICAgICAgICAgICAgICAgc3VtLnp3ICs9IHVwZFZhbHMueHk7CiAgICAgICAgICAgICAgICBmb3VuZC56dyA9IHZlYzIoMS4pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoZmxhdHRlbmVkSW5kZXhbMV0gPT0gY29vcmRzWzBdKSB7CiAgICAgICAgICAgICAgICBzdW0ueHkgKz0gdXBkVmFscy56dzsKICAgICAgICAgICAgICAgIGZvdW5kLnh5ID0gdmVjMigxLik7CiAgICAgICAgICAgICAgfSBlbHNlIGlmIChmbGF0dGVuZWRJbmRleFsxXSA9PSBjb29yZHNbMF0gKyAxKSB7CiAgICAgICAgICAgICAgICBzdW0uencgKz0gdXBkVmFscy56dzsKICAgICAgICAgICAgICAgIGZvdW5kLnp3ID0gdmVjMigxLik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBzZXRPdXRwdXQobWl4KCR7cmx9LCBzdW0sIGZvdW5kKSk7CiAgICAgICAgfQogICAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzY2F0dGVyTmQoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW5kaWNlczpTYSx1cGRhdGVzOlRhfT1hYSx7c2hhcGU6d2F9PWJhLHtzbGljZVJhbms6RWEsbnVtVXBkYXRlczprYSxzbGljZVNpemU6QWEsc3RyaWRlczpGYSxvdXRwdXRTaXplOkxhfT1jYWxjdWxhdGVTaGFwZXMoVGEsU2Esd2EpLGVsPVtMYS9BYSxBYV07aWYoTGE9PT0wKXJldHVybiB4YS5tYWtlVGVuc29ySW5mbyh3YSxTYS5kdHlwZSk7Y29uc3QgdGw9cmVzaGFwZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpba2EsRWFdfX0pLG5sPXJlc2hhcGUoe2lucHV0czp7eDpUYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6W2thLEFhXX19KSxzbD14YS5tYWtlVGVuc29ySW5mbyhbXSwiZmxvYXQzMiIsbmV3IEZsb2F0MzJBcnJheShbMF0pKTtsZXQgcmw7ZW52KCkuZ2V0Qm9vbCgiV0VCR0xfUEFDSyIpP3JsPW5ldyBTY2F0dGVyUGFja2VkUHJvZ3JhbShrYSxFYSx0bC5zaGFwZS5sZW5ndGgsbmwuc2hhcGUubGVuZ3RoLEZhLGVsKTpybD1uZXcgU2NhdHRlclByb2dyYW0oa2EsRWEsdGwuc2hhcGUubGVuZ3RoLG5sLnNoYXBlLmxlbmd0aCxGYSxlbCk7Y29uc3Qgb2w9eGEucnVuV2ViR0xQcm9ncmFtKHJsLFtubCx0bCxzbF0sbmwuZHR5cGUpLGFsPXJlc2hhcGUoe2lucHV0czp7eDpvbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6d2F9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHRsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhubCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSxhbH1jb25zdCBzY2F0dGVyTmRDb25maWc9e2tlcm5lbE5hbWU6U2NhdHRlck5kLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzY2F0dGVyTmR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFNlYXJjaFNvcnRlZFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEsU2Epe3RoaXMudmFyaWFibGVOYW1lcz1bInNvcnRlZFNlcXVlbmNlIiwidmFsdWVzIl0sdGhpcy5jdXN0b21Vbmlmb3Jtcz1be25hbWU6Im51bUlucHV0cyIsdHlwZToiaW50In1dLHRoaXMub3V0cHV0U2hhcGU9W2FhLGJhXTtjb25zdCBUYT0id2hpbGUgKGxlZnQgPCByaWdodCkgeyIsd2E9YGZvciAoaW50IGkgPSAwOyBpIDwgJHtNYXRoLmNlaWwoTWF0aC5sb2cyKHhhKzEpKX07ICsraSkgeyBpZiAobGVmdCA+PSByaWdodCkgYnJlYWs7YCxFYT1lbnYoKS5nZXROdW1iZXIoIldFQkdMX1ZFUlNJT04iKT09PTI/VGE6d2Esa2E9U2E9PT0ibGVmdCI/IjwiOiI8PSI7dGhpcy51c2VyQ29kZT1gCiAgICAgICBpbnQgZmluZEJvdW5kKGludCBiYXRjaCwgZmxvYXQgdmFsdWUpIHsKICAgICAgICAgaW50IGxlZnQgPSAwOwogICAgICAgICBpbnQgcmlnaHQgPSBudW1JbnB1dHM7CiAgICAgICAgIGludCBtaWQ7CiAgICAgICAgICR7RWF9CiAgICAgICAgICAgbWlkID0gKGxlZnQgKyByaWdodCkgLyAyOwogICAgICAgICAgIGlmIChnZXRTb3J0ZWRTZXF1ZW5jZShiYXRjaCwgbWlkKSAke2thfSB2YWx1ZSkgewogICAgICAgICAgICAgbGVmdCA9IG1pZCArIDE7CiAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgIHJpZ2h0ID0gbWlkOwogICAgICAgICAgIH0KICAgICAgICAgfQogICAgICAgICByZXR1cm4gcmlnaHQ7CiAgICAgICB9CgogICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgICBpbnQgdmFsdWVJbmRleCA9IGNvb3Jkc1sxXTsKCiAgICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0VmFsdWVzKGJhdGNoLCB2YWx1ZUluZGV4KTsKCiAgICAgICAgIHNldE91dHB1dChmbG9hdChmaW5kQm91bmQoYmF0Y2gsIHZhbHVlKSkpOwogICAgICAgfQogICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNlYXJjaFNvcnRlZChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzb3J0ZWRTZXF1ZW5jZTpTYSx2YWx1ZXM6VGF9PWFhLHtzaWRlOndhfT1iYSxFYT1uZXcgU2VhcmNoU29ydGVkUHJvZ3JhbShTYS5zaGFwZVswXSxTYS5zaGFwZVsxXSxUYS5zaGFwZVsxXSx3YSksa2E9W1tTYS5zaGFwZVsxXV1dO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0oRWEsW1NhLFRhXSwiaW50MzIiLGthKX1jb25zdCBzZWFyY2hTb3J0ZWRDb25maWc9e2tlcm5lbE5hbWU6U2VhcmNoU29ydGVkLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzZWFyY2hTb3J0ZWR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxNyBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFNlbGVjdFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEsYmEpe3RoaXMudmFyaWFibGVOYW1lcz1bImMiLCJhIiwiYiJdLHRoaXMub3V0cHV0U2hhcGU9eGE7bGV0IFNhLFRhO2lmKGJhPjQpdGhyb3cgRXJyb3IoYFdoZXJlIGZvciByYW5rICR7YmF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7aWYoYmE9PT0xKVRhPSJyZXNSQyIsU2E9InJlc1JDIjtlbHNle2NvbnN0IEVhPVsicmVzUkMueCIsInJlc1JDLnkiLCJyZXNSQy56IiwicmVzUkMudyJdLGthPVtdLEFhPVtdO2ZvcihsZXQgRmE9MDtGYTx4YS5sZW5ndGg7RmErKylBYS5wdXNoKGAke0VhW0ZhXX1gKSxGYTxhYSYma2EucHVzaChgJHtFYVtGYV19YCk7U2E9a2Euam9pbigpLFRhPUFhLmpvaW4oKX1jb25zdCB3YT1nZXRDb29yZHNEYXRhVHlwZShiYSk7dGhpcy51c2VyQ29kZT1gCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke3dhfSByZXNSQyA9IGdldE91dHB1dENvb3JkcygpOwogICAgICAgIGZsb2F0IGNWYWwgPSBnZXRDKCR7U2F9KTsKICAgICAgICBpZiAoY1ZhbCA+PSAxLjApIHsKICAgICAgICAgIHNldE91dHB1dChnZXRBKCR7VGF9KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHNldE91dHB1dChnZXRCKCR7VGF9KSk7CiAgICAgICAgfQogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzZWxlY3QoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7Y29uZGl0aW9uOmJhLHQ6U2EsZTpUYX09YWEsd2E9bmV3IFNlbGVjdFByb2dyYW0oYmEuc2hhcGUubGVuZ3RoLFNhLnNoYXBlLFNhLnNoYXBlLmxlbmd0aCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbSh3YSxbYmEsU2EsVGFdLHVwY2FzdFR5cGUoU2EuZHR5cGUsVGEuZHR5cGUpKX1jb25zdCBzZWxlY3RDb25maWc9e2tlcm5lbE5hbWU6U2VsZWN0LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzZWxlY3R9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNFTFU9YAogIC8vIFN0YWJsZSBhbmQgQXR0cmFjdGluZyBGaXhlZCBQb2ludCAoMCwgMSkgZm9yIE5vcm1hbGl6ZWQgV2VpZ2h0cy4KICAvLyBzZWU6IGh0dHBzOi8vYXJ4aXYub3JnL2Ficy8xNzA2LjAyNTE1CiAgZmxvYXQgc2NhbGVBbHBoYSA9ICR7U0VMVV9TQ0FMRUFMUEhBfTsKICBmbG9hdCBzY2FsZSA9ICR7U0VMVV9TQ0FMRX07CiAgcmV0dXJuICh4ID49IDAuMCkgPyBzY2FsZSAqIHggOiBzY2FsZUFscGhhICogKGV4cCh4KSAtIDEuMCk7CmAsc2VsdT11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTRUxVfSksc2VsdUNvbmZpZz17a2VybmVsTmFtZTpTZWx1LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzZWx1fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTSUdNT0lEPUNIRUNLX05BTl9TTklQUEVUX1VOQVJZK2AKICByZXR1cm4gMS4wIC8gKDEuMCArIGV4cCgtMS4wICogeCkpOwpgLFNJR01PSURfUEFDS0VEPWAKICB2ZWM0IHJlc3VsdCA9IDEuMCAvICgxLjAgKyBleHAoLTEuMCAqIHgpKTsKICBidmVjNCBpc05hTiA9IGlzbmFuKHgpOwoKICByZXN1bHQuciA9IGlzTmFOLnIgPyB4LnIgOiByZXN1bHQucjsKICByZXN1bHQuZyA9IGlzTmFOLmcgPyB4LmcgOiByZXN1bHQuZzsKICByZXN1bHQuYiA9IGlzTmFOLmIgPyB4LmIgOiByZXN1bHQuYjsKICByZXN1bHQuYSA9IGlzTmFOLmEgPyB4LmEgOiByZXN1bHQuYTsKCiAgcmV0dXJuIHJlc3VsdDsKYCxzaWdtb2lkPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlNJR01PSUQscGFja2VkT3BTbmlwcGV0OlNJR01PSURfUEFDS0VELGNwdUtlcm5lbEltcGw6c2lnbW9pZEltcGxDUFV9KSxzaWdtb2lkQ29uZmlnPXtrZXJuZWxOYW1lOlNpZ21vaWQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNpZ21vaWR9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNJR049YAogIGlmIChpc25hbih4KSkgeyByZXR1cm4gMC4wOyB9CiAgcmV0dXJuIHNpZ24oeCk7CmAsc2lnbj11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTSUdOfSksc2lnbkNvbmZpZz17a2VybmVsTmFtZTpTaWduLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzaWdufTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTSU49Q0hFQ0tfTkFOX1NOSVBQRVRfVU5BUlkrYAogIHJldHVybiBzaW4oeCk7CmAsU0lOX1BBQ0tFRD1gCiAgdmVjNCByZXN1bHQgPSBzaW4oeCk7CiAgYnZlYzQgaXNOYU4gPSBpc25hbih4KTsKICAke0NIRUNLX05BTl9TTklQUEVUX1BBQ0tFRH0KICByZXR1cm4gcmVzdWx0OwpgLHNpbj11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTSU4scGFja2VkT3BTbmlwcGV0OlNJTl9QQUNLRUR9KSxzaW5Db25maWc9e2tlcm5lbE5hbWU6U2luLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzaW59Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNJTkg9YAogIGZsb2F0IGUyeCA9IGV4cCh4KTsKICByZXR1cm4gKGUyeCAtIDEuMCAvIGUyeCkgLyAyLjA7CmAsc2luaD11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTSU5IfSksc2luaENvbmZpZz17a2VybmVsTmFtZTpTaW5oLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzaW5ofTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTT0ZUUExVUz1gCiAgZmxvYXQgZXBzaWxvbiA9IDEuMTkyMDkyODk1NTA3ODEyNWUtNzsKICBmbG9hdCB0aHJlc2hvbGQgPSBsb2coZXBzaWxvbikgKyAyLjA7CgogIGJvb2wgdG9vX2xhcmdlID0geCA+IC10aHJlc2hvbGQ7CiAgYm9vbCB0b29fc21hbGwgPSB4IDwgdGhyZXNob2xkOwoKICBmbG9hdCByZXN1bHQ7CiAgZmxvYXQgZXhwX3ggPSBleHAoeCk7CgogIGlmICh0b29fbGFyZ2UpewogICAgcmVzdWx0ID0geDsKICB9CiAgZWxzZSBpZiAodG9vX3NtYWxsKXsKICAgIHJlc3VsdCA9IGV4cF94OwogIH0KICBlbHNlewogICAgcmVzdWx0ID0gbG9nKGV4cF94ICsgMS4wKTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKYCxzb2Z0cGx1cz11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTT0ZUUExVU30pLHNvZnRwbHVzQ29uZmlnPXtrZXJuZWxOYW1lOlNvZnRwbHVzLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzb2Z0cGx1c307LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3Qgc3BhY2VUb0JhdGNoTkQ9aGE9Pntjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3g6U2F9PWFhLHtibG9ja1NoYXBlOlRhLHBhZGRpbmdzOndhfT1iYTthc3NlcnQoU2Euc2hhcGUubGVuZ3RoPD00LCgpPT4ic3BhY2VUb0JhdGNoTkQgZm9yIHJhbmsgPiA0IHdpdGggYSBXZWJHTCBiYWNrZW5kIG5vdCBpbXBsZW1lbnRlZCB5ZXQiKTtjb25zdCBFYT1UYS5yZWR1Y2UoKG9sLGFsKT0+b2wqYWwpLGthPVtbMCwwXV07a2EucHVzaCguLi53YSk7Zm9yKGxldCBvbD0xK1RhLmxlbmd0aDtvbDxTYS5zaGFwZS5sZW5ndGg7KytvbClrYS5wdXNoKFswLDBdKTtjb25zdCBBYT1bXSxGYT1wYWRWMih7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntwYWRkaW5nczprYSxjb25zdGFudFZhbHVlOjB9fSksTGE9Z2V0UmVzaGFwZWQoRmEuc2hhcGUsVGEsRWEsITEpLGVsPWdldFBlcm11dGVkKExhLmxlbmd0aCxUYS5sZW5ndGgsITEpLHRsPWdldFJlc2hhcGVkUGVybXV0ZWQoRmEuc2hhcGUsVGEsRWEsITEpLG5sPXJlc2hhcGUoe2lucHV0czp7eDpGYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6TGF9fSksc2w9dHJhbnNwb3NlKHtpbnB1dHM6e3g6bmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06ZWx9fSkscmw9cmVzaGFwZSh7aW5wdXRzOnt4OnNsfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTp0bH19KTtyZXR1cm4gQWEucHVzaChGYSksQWEucHVzaChubCksQWEucHVzaChzbCksQWEuZm9yRWFjaChvbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8ob2wpKSxybH0sc3BhY2VUb0JhdGNoTkRDb25maWc9e2tlcm5lbE5hbWU6U3BhY2VUb0JhdGNoTkQsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNwYWNlVG9CYXRjaE5EfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFyc2VGaWxsRW1wdHlSb3dzKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YX09aGEse2luZGljZXM6YmEsdmFsdWVzOlNhLGRlbnNlU2hhcGU6VGEsZGVmYXVsdFZhbHVlOndhfT1hYTtpZihUYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgRGVuc2Ugc2hhcGUgbXVzdCBiZSBhIHZlY3Rvciwgc2F3OgogICAgICAgICAke1RhLnNoYXBlfWApO2lmKGJhLnNoYXBlLmxlbmd0aCE9PTIpdGhyb3cgbmV3IEVycm9yKGBJbmRpY2VzIG11c3QgYmUgYSBtYXRyaXgsIHNhdzoKICAgICAgICAgJHtiYS5zaGFwZX1gKTtpZihTYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgVmFsdWVzIG11c3QgYmUgYSB2ZWN0b3IsIHNhdzoKICAgICAgICAgJHtTYS5zaGFwZX1gKTtpZih3YS5zaGFwZS5sZW5ndGghPT0wKXRocm93IG5ldyBFcnJvcihgRGVmYXVsdCB2YWx1ZSBtdXN0IGJlIGEgc2NhbGFyLCBzYXc6CiAgICAgICAgJHt3YS5zaGFwZX1gKTtjb25zdCBFYT14YS5yZWFkU3luYyhiYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksQWE9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxGYT14YS5yZWFkU3luYyh3YS5kYXRhSWQpWzBdLFtMYSxlbCx0bCxubCxzbF09c3BhcnNlRmlsbEVtcHR5Um93c0ltcGxDUFUoRWEsYmEuc2hhcGUsYmEuZHR5cGUsa2EsU2EuZHR5cGUsQWEsRmEpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhlbCxiYS5kdHlwZSxMYSkseGEubWFrZVRlbnNvckluZm8oW2VsWzBdXSxTYS5kdHlwZSx0bCkseGEubWFrZVRlbnNvckluZm8oW25sLmxlbmd0aF0sImJvb2wiLG5ldyBVaW50OEFycmF5KG5sLm1hcChybD0+TnVtYmVyKHJsKSkpKSx4YS5tYWtlVGVuc29ySW5mbyhbc2wubGVuZ3RoXSxiYS5kdHlwZSxuZXcgSW50MzJBcnJheShzbCkpXX1jb25zdCBzcGFyc2VGaWxsRW1wdHlSb3dzQ29uZmlnPXtrZXJuZWxOYW1lOlNwYXJzZUZpbGxFbXB0eVJvd3MsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNwYXJzZUZpbGxFbXB0eVJvd3N9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVJlc2hhcGUoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7aW5wdXRJbmRpY2VzOmJhLGlucHV0U2hhcGU6U2EsbmV3U2hhcGU6VGF9PWFhO2lmKGJhLnNoYXBlLmxlbmd0aCE9PTIpdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBpbmRpY2VzIHNob3VsZCBiZSBhIG1hdHJpeCBidXQgcmVjZWl2ZWQgc2hhcGUgJHtiYS5zaGFwZX1gKTtpZihTYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgSW5wdXQgc2hhcGUgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZSAke1NhLnNoYXBlfWApO2lmKFRhLnNoYXBlLmxlbmd0aCE9PTEpdGhyb3cgbmV3IEVycm9yKGBUYXJnZXQgc2hhcGUgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZSAke1RhLnNoYXBlfWApO2NvbnN0IHdhPUFycmF5LmZyb20oeGEucmVhZFN5bmMoU2EuZGF0YUlkKSksRWE9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSxrYT1BcnJheS5mcm9tKHhhLnJlYWRTeW5jKFRhLmRhdGFJZCkpLFtBYSxGYSxMYV09c3BhcnNlUmVzaGFwZUltcGxDUFUoRWEsYmEuc2hhcGUsYmEuZHR5cGUsd2Esa2EpO3JldHVyblt4YS5tYWtlVGVuc29ySW5mbyhGYSxiYS5kdHlwZSxBYSkseGEubWFrZVRlbnNvckluZm8oW0xhLmxlbmd0aF0sVGEuZHR5cGUsbmV3IEludDMyQXJyYXkoTGEpKV19Y29uc3Qgc3BhcnNlUmVzaGFwZUNvbmZpZz17a2VybmVsTmFtZTpTcGFyc2VSZXNoYXBlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzcGFyc2VSZXNoYXBlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGFyc2VTZWdtZW50TWVhbihoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGF9PWhhLHtkYXRhOmJhLGluZGljZXM6U2Esc2VnbWVudElkczpUYX09YWE7aWYoYmEuc2hhcGUubGVuZ3RoPDEpdGhyb3cgbmV3IEVycm9yKCJEYXRhIHNob3VsZCBiZSBhdCBsZWFzdCAxIGRpbWVuc2lvbmFsIGJ1dCByZWNlaXZlZCBzY2FsYXIiKTtpZihTYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgSW5kaWNlcyBzaG91bGQgYmUgYSB2ZWN0b3IgYnV0IHJlY2VpdmVkIHNoYXBlCiAgICAgICAgICAgICAgJHtTYS5zaGFwZX1gKTtpZihUYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgU2VnbWVudCBpZHMgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgICAgICR7VGEuc2hhcGV9YCk7Y29uc3Qgd2E9eGEucmVhZFN5bmMoYmEuZGF0YUlkKSxFYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKFRhLmRhdGFJZCksW0FhLEZhXT1zcGFyc2VTZWdtZW50UmVkdWN0aW9uSW1wbENQVSh3YSxiYS5zaGFwZSxiYS5kdHlwZSxFYSxrYSwhMCk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKEZhLGJhLmR0eXBlLEFhKX1jb25zdCBzcGFyc2VTZWdtZW50TWVhbkNvbmZpZz17a2VybmVsTmFtZTpTcGFyc2VTZWdtZW50TWVhbixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3BhcnNlU2VnbWVudE1lYW59Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHNwYXJzZVNlZ21lbnRTdW0oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhfT1oYSx7ZGF0YTpiYSxpbmRpY2VzOlNhLHNlZ21lbnRJZHM6VGF9PWFhO2lmKGJhLnNoYXBlLmxlbmd0aDwxKXRocm93IG5ldyBFcnJvcigiRGF0YSBzaG91bGQgYmUgYXQgbGVhc3QgMSBkaW1lbnNpb25hbCBidXQgcmVjZWl2ZWQgc2NhbGFyIik7aWYoU2Euc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgICAgJHtTYS5zaGFwZX1gKTtpZihUYS5zaGFwZS5sZW5ndGghPT0xKXRocm93IG5ldyBFcnJvcihgU2VnbWVudCBpZHMgc2hvdWxkIGJlIGEgdmVjdG9yIGJ1dCByZWNlaXZlZCBzaGFwZQogICAgICAgICAgICAgJHtUYS5zaGFwZX1gKTtjb25zdCB3YT14YS5yZWFkU3luYyhiYS5kYXRhSWQpLEVhPXhhLnJlYWRTeW5jKFNhLmRhdGFJZCksa2E9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxbQWEsRmFdPXNwYXJzZVNlZ21lbnRSZWR1Y3Rpb25JbXBsQ1BVKHdhLGJhLnNoYXBlLGJhLmR0eXBlLEVhLGthKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRmEsYmEuZHR5cGUsQWEpfWNvbnN0IHNwYXJzZVNlZ21lbnRTdW1Db25maWc9e2tlcm5lbE5hbWU6U3BhcnNlU2VnbWVudFN1bSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3BhcnNlU2VnbWVudFN1bX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3BhcnNlVG9EZW5zZShoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzcGFyc2VJbmRpY2VzOlNhLHNwYXJzZVZhbHVlczpUYSxkZWZhdWx0VmFsdWU6d2F9PWFhLHtvdXRwdXRTaGFwZTpFYX09YmEse3NsaWNlUmFuazprYSxudW1VcGRhdGVzOkFhLHNsaWNlU2l6ZTpGYSxzdHJpZGVzOkxhLG91dHB1dFNpemU6ZWx9PWNhbGN1bGF0ZVNoYXBlcyhUYSxTYSxFYSksdGw9ITE7aWYoVGEuZHR5cGU9PT0ic3RyaW5nIil7Y29uc3Qgb2w9eGEuYnVmZmVyU3luYyhTYSksYWw9eGEuYnVmZmVyU3luYyhUYSksbGw9ZGVjb2RlU3RyaW5nKHhhLnJlYWRTeW5jKHdhLmRhdGFJZClbMF0pLGlsPXNjYXR0ZXJJbXBsQ1BVKG9sLGFsLEVhLGVsLEZhLEFhLGthLExhLGxsLHRsKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oRWEsaWwuZHR5cGUsaWwudmFsdWVzKX1jb25zdCBubD1uZXcgU2NhdHRlclByb2dyYW0oQWEsa2EsU2Euc2hhcGUubGVuZ3RoLFRhLnNoYXBlLmxlbmd0aCxMYSxbZWwsMV0sdGwpLHNsPXhhLnJ1bldlYkdMUHJvZ3JhbShubCxbVGEsU2Esd2FdLFRhLmR0eXBlKSxybD1yZXNoYXBlKHtpbnB1dHM6e3g6c2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkVhfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhzbCkscmx9Y29uc3Qgc3BhcnNlVG9EZW5zZUNvbmZpZz17a2VybmVsTmFtZTpTcGFyc2VUb0RlbnNlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzcGFyc2VUb0RlbnNlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzcGxpdFYoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse251bU9yU2l6ZVNwbGl0czpUYSxheGlzOndhfT1iYSxFYT1wYXJzZUF4aXNQYXJhbSh3YSxTYS5zaGFwZSlbMF0sa2E9cHJlcGFyZVNwbGl0U2l6ZShTYSxUYSxFYSksQWE9U2Euc2hhcGUubGVuZ3RoLEZhPW5ldyBBcnJheShBYSkuZmlsbCgwKSxMYT1TYS5zaGFwZS5zbGljZSgpO3JldHVybiBrYS5tYXAoZWw9Pntjb25zdCB0bD1bLi4uTGFdO3RsW0VhXT1lbDtjb25zdCBubD1zbGljZSh7aW5wdXRzOnt4OlNhfSxiYWNrZW5kOnhhLGF0dHJzOntiZWdpbjpGYSxzaXplOnRsfX0pO3JldHVybiBGYVtFYV0rPWVsLG5sfSl9Y29uc3Qgc3BsaXRWQ29uZmlnPXtrZXJuZWxOYW1lOlNwbGl0VixiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3BsaXRWfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTUVJUPSJyZXR1cm4gc3FydCh4KTsiLHNxcnQ9dW5hcnlLZXJuZWxGdW5jKHtvcFNuaXBwZXQ6U1FSVCxwYWNrZWRPcFNuaXBwZXQ6U1FSVCxjcHVLZXJuZWxJbXBsOnNxcnRJbXBsQ1BVfSksc3FydENvbmZpZz17a2VybmVsTmFtZTpTcXJ0LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzcXJ0fTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jb25zdCBTUVVBUkU9InJldHVybiB4ICogeDsiLHNxdWFyZT11bmFyeUtlcm5lbEZ1bmMoe29wU25pcHBldDpTUVVBUkV9KSxzcXVhcmVDb25maWc9e2tlcm5lbE5hbWU6U3F1YXJlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzcXVhcmV9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IFNRVUFSRURfRElGRkVSRU5DRT0icmV0dXJuIChhIC0gYikgKiAoYSAtIGIpOyIsc3F1YXJlZERpZmZlcmVuY2U9YmluYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlNRVUFSRURfRElGRkVSRU5DRSxwYWNrZWRPcFNuaXBwZXQ6U1FVQVJFRF9ESUZGRVJFTkNFfSksc3F1YXJlZERpZmZlcmVuY2VDb25maWc9e2tlcm5lbE5hbWU6U3F1YXJlZERpZmZlcmVuY2UsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnNxdWFyZWREaWZmZXJlbmNlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQy4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdGF0aWNSZWdleFJlcGxhY2UoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWE7aWYoU2EuZHR5cGUhPT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIklucHV0IG11c3QgYmUgb2YgZGF0YXR5cGUgc3RyaW5nIik7Y29uc3QgVGE9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSx3YT1mcm9tVWludDhUb1N0cmluZ0FycmF5KFRhKSxFYT1zdGF0aWNSZWdleFJlcGxhY2VJbXBsQ1BVKHdhLCJzdHJpbmciLGJhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oU2Euc2hhcGUsInN0cmluZyIsRWEpfWNvbnN0IHN0YXRpY1JlZ2V4UmVwbGFjZUNvbmZpZz17a2VybmVsTmFtZTpTdGF0aWNSZWdleFJlcGxhY2UsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnN0YXRpY1JlZ2V4UmVwbGFjZX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RlcCh7aW5wdXRzOmhhLGF0dHJzOmFhLGJhY2tlbmQ6eGF9KXtjb25zdHt4OmJhfT1oYSxTYT1DSEVDS19OQU5fU05JUFBFVCQxK2AKICAgIHJldHVybiB4ID4gMC4wID8gMS4wIDogZmxvYXQoJHthYS5hbHBoYX0pOwogIGAsVGE9bmV3IFVuYXJ5T3BQcm9ncmFtKGJhLnNoYXBlLFNhKTtyZXR1cm4geGEucnVuV2ViR0xQcm9ncmFtKFRhLFtiYV0sYmEuZHR5cGUpfWNvbnN0IHN0ZXBDb25maWc9e2tlcm5lbE5hbWU6U3RlcCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3RlcH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY2xhc3MgU3RyaWRlZFNsaWNlUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSxiYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCJdLHRoaXMub3V0cHV0U2hhcGU9YmE7Y29uc3QgU2E9YmEubGVuZ3RoLFRhPWdldENvb3Jkc0RhdGFUeXBlKGJhLmxlbmd0aCksd2E9Z2V0Q29vcmRzRGF0YVR5cGUoYmEubGVuZ3RoKTtsZXQgRWE9IiI7aWYoU2E9PT0xKUVhPSJjb29yZHMgKiBzdHJpZGVzICsgYmVnaW4iO2Vsc2V7bGV0IGthPTA7RWE9YmEubWFwKChBYSxGYSk9PihrYSsrLGJhLmxlbmd0aD09PTE/YGNvb3JkcyAqIHN0cmlkZXNbJHtGYX1dICsgYmVnaW5bJHtGYX1dYDpgY29vcmRzWyR7a2EtMX1dICogc3RyaWRlc1ske0ZhfV0gKyBiZWdpblske0ZhfV1gKSkuam9pbigiLCIpfXRoaXMudXNlckNvZGU9YAogICAgICAke1RhfSBiZWdpbiA9ICR7VGF9KCR7YWF9KTsKICAgICAgJHtUYX0gc3RyaWRlcyA9ICR7VGF9KCR7eGF9KTsKCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAke3dhfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBzZXRPdXRwdXQoZ2V0WCgke0VhfSkpOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiBzdHJpZGVkU2xpY2UoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse2JlZ2luOlRhLGVuZDp3YSxzdHJpZGVzOkVhLGJlZ2luTWFzazprYSxlbmRNYXNrOkFhLGVsbGlwc2lzTWFzazpGYSxuZXdBeGlzTWFzazpMYSxzaHJpbmtBeGlzTWFzazplbH09YmEse2ZpbmFsU2hhcGVTcGFyc2U6dGwsZmluYWxTaGFwZTpubCxpc0lkZW50aXR5OnNsLHNsaWNlRGltMDpybCxpc1NpbXBsZVNsaWNlOm9sLGJlZ2luOmFsLGVuZDpsbCxzdHJpZGVzOmlsfT1zbGljZUluZm8oU2Euc2hhcGUsVGEsd2EsRWEsa2EsQWEsRmEsTGEsZWwpO2xldCBjbDtpZihzbCljbD1yZXNoYXBlKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOm5sfX0pO2Vsc2UgaWYocmx8fG9sKXthc3NlcnQoU2Euc2hhcGUubGVuZ3RoPj0xLCgpPT5gSW5wdXQgbXVzdCBoYXZlIHJhbmsgYXQgbGVhc3QgMSwgZ290OiAke1NhLnNoYXBlLmxlbmd0aH1gKTtjb25zdCBkbD1jb21wdXRlT3V0U2hhcGUkMihhbCxsbCxpbCksaGw9c2xpY2Uoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46YWwsc2l6ZTpkbH19KTtjbD1yZXNoYXBlKHtpbnB1dHM6e3g6aGx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOm5sfX0pLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGhsKX1lbHNlIGlmKHhhLnNob3VsZEV4ZWN1dGVPbkNQVShbU2FdKSl7Y29uc3QgaGw9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxwbD1idWZmZXIoU2Euc2hhcGUsU2EuZHR5cGUsaGwpLGZsPXN0cmlkZWRTbGljZUltcGxDUFUodGwscGwsaWwsYWwpO2NsPXhhLm1ha2VUZW5zb3JJbmZvKG5sLFNhLmR0eXBlLGZsLnZhbHVlcyl9ZWxzZXtjb25zdCBobD1uZXcgU3RyaWRlZFNsaWNlUHJvZ3JhbShhbCxpbCx0bCk7Y2w9eGEucnVuV2ViR0xQcm9ncmFtKGhsLFtTYV0sU2EuZHR5cGUpfWNvbnN0IHVsPXJlc2hhcGUoe2lucHV0czp7eDpjbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6bmx9fSk7cmV0dXJuIHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGNsKSx1bH1jb25zdCBzdHJpZGVkU2xpY2VDb25maWc9e2tlcm5lbE5hbWU6U3RyaWRlZFNsaWNlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzdHJpZGVkU2xpY2V9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0cmluZ05HcmFtcyhoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtzZXBhcmF0b3I6U2EsbkdyYW1XaWR0aHM6VGEsbGVmdFBhZDp3YSxyaWdodFBhZDpFYSxwYWRXaWR0aDprYSxwcmVzZXJ2ZVNob3J0U2VxdWVuY2VzOkFhfT1iYSx7ZGF0YTpGYSxkYXRhU3BsaXRzOkxhfT1hYSxlbD14YS5yZWFkU3luYyhGYS5kYXRhSWQpLHRsPXhhLnJlYWRTeW5jKExhLmRhdGFJZCksW25sLHNsXT1zdHJpbmdOR3JhbXNJbXBsQ1BVKGVsLHRsLFNhLFRhLHdhLEVhLGthLEFhKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oW25sLmxlbmd0aF0sInN0cmluZyIsbmwpLHhhLm1ha2VUZW5zb3JJbmZvKExhLnNoYXBlLCJpbnQzMiIsc2wpXX1jb25zdCBzdHJpbmdOR3JhbXNDb25maWc9e2tlcm5lbE5hbWU6U3RyaW5nTkdyYW1zLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzdHJpbmdOR3JhbXN9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHN0cmluZ1NwbGl0KGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3NraXBFbXB0eTpTYX09YmEse2lucHV0OlRhLGRlbGltaXRlcjp3YX09YWE7aWYoVGEuZHR5cGUhPT0ic3RyaW5nIil0aHJvdyBuZXcgRXJyb3IoIklucHV0IG11c3QgYmUgb2YgZGF0YXR5cGUgc3RyaW5nIik7aWYoVGEuc2hhcGUubGVuZ3RoIT09MSl0aHJvdyBuZXcgRXJyb3IoYElucHV0IG11c3QgYmUgYSB2ZWN0b3IsIGdvdCBzaGFwZTogJHtUYS5zaGFwZX1gKTtpZih3YS5zaGFwZS5sZW5ndGghPT0wKXRocm93IG5ldyBFcnJvcihgRGVsaW1pdGVyIG11c3QgYmUgYSBzY2FsYXIsIGdvdCBzaGFwZTogJHt3YS5zaGFwZX1gKTtjb25zdCBFYT14YS5yZWFkU3luYyhUYS5kYXRhSWQpLGthPXhhLnJlYWRTeW5jKHdhLmRhdGFJZClbMF0sW0FhLEZhLExhXT1zdHJpbmdTcGxpdEltcGxDUFUoRWEsa2EsU2EpLGVsPUZhLmxlbmd0aDtyZXR1cm5beGEubWFrZVRlbnNvckluZm8oW2VsLDJdLCJpbnQzMiIsQWEpLHhhLm1ha2VUZW5zb3JJbmZvKFtlbF0sInN0cmluZyIsRmEpLHhhLm1ha2VUZW5zb3JJbmZvKFsyXSwiaW50MzIiLG5ldyBJbnQzMkFycmF5KExhKSldfWNvbnN0IHN0cmluZ1NwbGl0Q29uZmlnPXtrZXJuZWxOYW1lOlN0cmluZ1NwbGl0LGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzpzdHJpbmdTcGxpdH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gc3RyaW5nVG9IYXNoQnVja2V0RmFzdChoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHtudW1CdWNrZXRzOlNhfT1iYSx7aW5wdXQ6VGF9PWFhO2lmKFRhLmR0eXBlIT09InN0cmluZyIpdGhyb3cgbmV3IEVycm9yKCJJbnB1dCBtdXN0IGJlIG9mIGRhdGF0eXBlIHN0cmluZyIpO2lmKFNhPD0wKXRocm93IG5ldyBFcnJvcigiTnVtYmVyIG9mIGJ1Y2tldHMgbXVzdCBiZSBhdCBsZWFzdCAxIik7Y29uc3Qgd2E9eGEucmVhZFN5bmMoVGEuZGF0YUlkKSxFYT1zdHJpbmdUb0hhc2hCdWNrZXRGYXN0SW1wbENQVSh3YSxTYSk7cmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFRhLnNoYXBlLCJpbnQzMiIsRWEpfWNvbnN0IHN0cmluZ1RvSGFzaEJ1Y2tldEZhc3RDb25maWc9e2tlcm5lbE5hbWU6U3RyaW5nVG9IYXNoQnVja2V0RmFzdCxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6c3RyaW5nVG9IYXNoQnVja2V0RmFzdH07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgVEFOPSJyZXR1cm4gdGFuKHgpOyIsdGFuPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlRBTn0pLHRhbkNvbmZpZz17a2VybmVsTmFtZTpUYW4sYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRhbn07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovY29uc3QgVEFOSD1gCiAgZmxvYXQgZTJ4ID0gZXhwKC0yLjAgKiBhYnMoeCkpOwogIHJldHVybiBzaWduKHgpICogKDEuMCAtIGUyeCkgLyAoMS4wICsgZTJ4KTsKYCx0YW5oPXVuYXJ5S2VybmVsRnVuYyh7b3BTbmlwcGV0OlRBTkh9KSx0YW5oQ29uZmlnPXtrZXJuZWxOYW1lOlRhbmgsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnRhbmh9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRlbnNvclNjYXR0ZXJVcGRhdGUoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7dGVuc29yOlNhLGluZGljZXM6VGEsdXBkYXRlczp3YX09YWEse3NsaWNlUmFuazpFYSxudW1VcGRhdGVzOmthLHNsaWNlU2l6ZTpBYSxzdHJpZGVzOkZhLG91dHB1dFNpemU6TGF9PWNhbGN1bGF0ZVNoYXBlcyh3YSxUYSxTYS5zaGFwZSksZWw9W0xhL0FhLEFhXTtpZihMYT09PTApcmV0dXJuIHhhLm1ha2VUZW5zb3JJbmZvKFNhLnNoYXBlLFRhLmR0eXBlKTtjb25zdCB0bD1yZXNoYXBlKHtpbnB1dHM6e3g6VGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOltrYSxFYV19fSksbmw9cmVzaGFwZSh7aW5wdXRzOnt4OndhfSxiYWNrZW5kOnhhLGF0dHJzOntzaGFwZTpba2EsQWFdfX0pLHNsPXJlc2hhcGUoe2lucHV0czp7eDpTYX0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6ZWx9fSkscmw9bmV3IFNjYXR0ZXJQcm9ncmFtKGthLEVhLHRsLnNoYXBlLmxlbmd0aCxubC5zaGFwZS5sZW5ndGgsRmEsZWwsITEsITApLG9sPXhhLnJ1bldlYkdMUHJvZ3JhbShybCxbbmwsdGwsc2xdLHNsLmR0eXBlKSxhbD1yZXNoYXBlKHtpbnB1dHM6e3g6b2x9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlNhLnNoYXBlfX0pO3JldHVybiB4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyh0bCkseGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8obmwpLHhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKHNsKSx4YS5kaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mbyhvbCksYWx9Y29uc3QgdGVuc29yU2NhdHRlclVwZGF0ZUNvbmZpZz17a2VybmVsTmFtZTpUZW5zb3JTY2F0dGVyVXBkYXRlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp0ZW5zb3JTY2F0dGVyVXBkYXRlfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBUaWxlUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSx4YSl7dGhpcy52YXJpYWJsZU5hbWVzPVsiQSJdO2NvbnN0IGJhPW5ldyBBcnJheShhYS5sZW5ndGgpO2ZvcihsZXQgd2E9MDt3YTxiYS5sZW5ndGg7d2ErKyliYVt3YV09YWFbd2FdKnhhW3dhXTt0aGlzLm91dHB1dFNoYXBlPWJhLHRoaXMucmFuaz1iYS5sZW5ndGg7Y29uc3QgU2E9Z2V0Q29vcmRzRGF0YVR5cGUodGhpcy5yYW5rKSxUYT1nZXRTb3VyY2VDb29yZHMoYWEpO3RoaXMudXNlckNvZGU9YAogICAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgJHtTYX0gcmVzUkMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBzZXRPdXRwdXQoZ2V0QSgke1RhfSkpOwogICAgICB9CiAgICBgfX1mdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMoaGEpe2NvbnN0IGFhPWhhLmxlbmd0aDtpZihhYT41KXRocm93IEVycm9yKGBUaWxlIGZvciByYW5rICR7YWF9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7aWYoYWE9PT0xKXJldHVybmBpbW9kKHJlc1JDLCAke2hhWzBdfSlgO2NvbnN0IHhhPVsicmVzUkMueCIsInJlc1JDLnkiLCJyZXNSQy56IiwicmVzUkMudyIsInJlc1JDLnUiXSxiYT1bXTtmb3IobGV0IFNhPTA7U2E8aGEubGVuZ3RoO1NhKyspYmEucHVzaChgaW1vZCgke3hhW1NhXX0sICR7aGFbU2FdfSlgKTtyZXR1cm4gYmEuam9pbigpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHRpbGUoaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYX09YWEse3JlcHM6VGF9PWJhO2lmKFNhLmR0eXBlPT09InN0cmluZyJ8fFNhLnNoYXBlLmxlbmd0aD41KXtjb25zdCBrYT14YS5yZWFkU3luYyhTYS5kYXRhSWQpLEFhPVNhLmR0eXBlPT09InN0cmluZyI/a2EubWFwKGVsPT5kZWNvZGVTdHJpbmcoZWwpKTprYSxGYT1idWZmZXIoU2Euc2hhcGUsU2EuZHR5cGUsQWEpLExhPXRpbGVJbXBsQ1BVKEZhLFRhKTtyZXR1cm4geGEubWFrZVRlbnNvckluZm8oTGEuc2hhcGUsTGEuZHR5cGUsTGEudmFsdWVzKX1jb25zdCB3YT1uZXcgVGlsZVByb2dyYW0oU2Euc2hhcGUsVGEpO3JldHVybiB4YS5ydW5XZWJHTFByb2dyYW0od2EsW1NhXSxTYS5kdHlwZSl9Y29uc3QgdGlsZUNvbmZpZz17a2VybmVsTmFtZTpUaWxlLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp0aWxlfTtjbGFzcyBTd2FwUHJvZ3JhbXtjb25zdHJ1Y3RvcihhYSl7dGhpcy52YXJpYWJsZU5hbWVzPVsieCIsImluZGljZXMiXSx0aGlzLmN1c3RvbVVuaWZvcm1zPVt7bmFtZToibiIsdHlwZToiaW50In0se25hbWU6ImZpcnN0UGFzcyIsdHlwZToiaW50In0se25hbWU6Im5lZ2F0aXZlSW5mIix0eXBlOiJmbG9hdCJ9LHtuYW1lOiJkaXIiLHR5cGU6ImludCJ9LHtuYW1lOiJpbmMiLHR5cGU6ImludCJ9XSx0aGlzLm91dHB1dFNoYXBlPWFhLHRoaXMudXNlckNvZGU9YAogICAgICAgdm9pZCBtYWluKCkgewogICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgaW50IGJhdGNoID0gY29vcmRzWzBdOwogICAgICAgICBpbnQgZWxlbUlkeCA9IGNvb3Jkc1sxXTsKCiAgICAgICAgIC8vIFdlIGNvbXBhcmUgZWxlbWVudHMgcGFpci13aXNlIHdpdGhpbiBhIGdyb3VwIG9mIHNpemUgMiAqIGluYy4KICAgICAgICAgLy8gVGhlIGNvbXBhcmluZyBydWxlIGZvciBlYWNoIGdyb3VwIGFsdGVybmF0ZXMgYmV0d2VlbiBhc2NlbmRpbmcKICAgICAgICAgLy8gYW5kIGRlc2NlbmRpbmcuIFdpdGhpbiBlYWNoIGdyb3VwLCB3ZSBjb21wYXJlIGVhY2ggcGFpciBhdAogICAgICAgICAvLyBwb3NpdGlvbnMgaSBhbmQgaStpbmMuIFRvIGRlY2lkZSB3aGV0aGVyIGFuIGVsZW1lbnQgYXQgcG9zaXRpb24gaQogICAgICAgICAvLyBpcyB4MCBvciB4MSwgd2UgbW9kIGl0IGJ5IDIgKiBpbmMsIGlmIHRoZSByZXN1bHQgaXMgc21hbGxlciB0aGFuCiAgICAgICAgIC8vIGluYywgaXQgaXMgaW4gdGhlIGZpcnN0IGhhbGYgb2YgdGhlIGdyb3VwLCB3ZSBkZW5vdGUgaXQgYXMgeDAsCiAgICAgICAgIC8vIG90aGVyd2lzZSB3ZSBkZW5vdGUgaXQgYXMgeDEuCiAgICAgICAgIC8vIEZvciBleGFtcGxlLCBhcyBzaG93biBpbiB0aGUgQml0b25pYyB0b3AgSyBwYXBlciByZWZlcmVuY2VkIGFib3ZlLAogICAgICAgICAvLyBGaWd1cmU1KGEpIHNob3dzIHRoYXQgZWxlbWVudFsxXSBpcyBpbiB0aGUKICAgICAgICAgLy8gc2Vjb25kIGhhbGYgb2YgdGhlIGdyb3VwIHdoZW4gZ3JvdXAgc2l6ZSBpcyAyLCBidXQgaXQgaXMgaW4gdGhlCiAgICAgICAgIC8vIGZpcnN0IGhhbGYgb2YgdGhlIGdyb3VwIHdoZW4gZ3JvdXAgc2l6ZSBpcyA0LgoKICAgICAgICAgYm9vbCBpc0ZpcnN0SW5QYWlyID0gaW1vZChlbGVtSWR4LCAyICogaW5jKSA8IGluYzsKICAgICAgICAgaW50IGkgPSBpc0ZpcnN0SW5QYWlyID8gZWxlbUlkeCA6IGVsZW1JZHggLSBpbmM7CgogICAgICAgICBpbnQgaTAgPSBmaXJzdFBhc3MgPT0gMSA/IGkgOiBpbnQoZ2V0SW5kaWNlcyhiYXRjaCwgaSkpOwogICAgICAgICBpbnQgaTEgPSBmaXJzdFBhc3MgPT0gMSA/IGkgKyBpbmMgOiBpbnQoZ2V0SW5kaWNlcyhiYXRjaCwgaSArIGluYykpOwogICAgICAgICBmbG9hdCB4MCA9IGkwIDwgbiA/IGdldFgoYmF0Y2gsIGkwKSA6IG5lZ2F0aXZlSW5mOwogICAgICAgICBmbG9hdCB4MSA9IGkxIDwgbiA/IGdldFgoYmF0Y2gsIGkxKSA6IG5lZ2F0aXZlSW5mOwoKICAgICAgICAgLy8gRGVub3RlcyB3aGljaCBkaXJlY3Rpb24gaW5kaWNlcyBhcmUgaW4gKGFzY2VuZGluZyBvciBkZXNjZW5kaW5nKS4KICAgICAgICAgYm9vbCByZXZlcnNlID0gaW1vZChlbGVtSWR4LCAyICogZGlyKSA+PSBkaXI7CiAgICAgICAgIGJvb2wgaXNHcmVhdGVyID0geDAgPiB4MSB8fCAoeDAgPT0geDEgJiYgaTEgPiBpMCk7CiAgICAgICAgIGlmIChyZXZlcnNlID09IGlzR3JlYXRlcikgeyAvLyBFbGVtZW50cyBpbiBvcHBvc2l0ZSBvcmRlciBvZiBkaXJlY3Rpb24KICAgICAgICAgICBpbnQgaVRlbXAgPSBpMDsKICAgICAgICAgICBpMCA9IGkxOwogICAgICAgICAgIGkxID0gaVRlbXA7CiAgICAgICAgIH0KICAgICAgICAgaWYgKGlzRmlyc3RJblBhaXIpIHsKICAgICAgICAgICAgc2V0T3V0cHV0KGZsb2F0KGkwKSk7CiAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNldE91dHB1dChmbG9hdChpMSkpOwogICAgICAgICB9CiAgICAgICB9CiAgICAgYH19Y2xhc3MgTWVyZ2VQcm9ncmFte2NvbnN0cnVjdG9yKGFhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJ4IiwiaW5kaWNlcyJdLHRoaXMuY3VzdG9tVW5pZm9ybXM9W3tuYW1lOiJuIix0eXBlOiJpbnQifSx7bmFtZToiZmlyc3RQYXNzIix0eXBlOiJpbnQifSx7bmFtZToiayIsdHlwZToiaW50In1dLHRoaXMub3V0cHV0U2hhcGU9YWEsdGhpcy51c2VyQ29kZT1gCiAgICB2b2lkIG1haW4oKSB7CiAgICAgICAgIC8vIFRha2VzIG1heCBvZiBpbmRpY2VzICgwLCBrKSwgKDEsIGsgKyAxKSwgKDIsIGsgKyAyKSAuLi4KICAgICAgICAgaXZlYzIgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7CiAgICAgICAgIGludCBiYXRjaCA9IGNvb3Jkc1swXTsKICAgICAgICAgaW50IGVsZW1JZHggPSBjb29yZHNbMV07CgogICAgICAgICAvLyBUaGUgb3V0cHV0IHNpemUgaXMgaGFsZiBvZiB0aGUgcHJldmlvdXMgc2l6ZS4KICAgICAgICAgLy8gSWYgdGhlIHByZXZpb3VzIHNlcXVlbmNlIGlzIHwgfCB8IHwgXyBfIF8gXyAgfCB8IHwgfCAgXyBfIF8gXyAoaz00KSwKICAgICAgICAgLy8gd2Ugb25seSBuZWVkIHRvIG91dHB1dCB0aGUgaW5kaWNlcyBhdCBwb3NpdGlvbnMgfCwgdGhlIGluZGljZXMgYXQKICAgICAgICAgLy8gcG9zaXRpb25zIF8gY2FuIGJlIHRocm93biBhd2F5LCBzZWUgRmlndXJlNShiKSBBZnRlciBQaGFzZSAyCiAgICAgICAgIC8vIChNZXJnZSBwaGFzZSkgaW4gdGhlIEJpdG9uaWMgVG9wIEsgcGFwZXIgcmVmZXJlbmNlZCBhYm92ZS4KICAgICAgICAgLy8gRm9yIGV4YW1wbGUsIHRoZSBwYXBlciBzaG93cyB3ZSBvbmx5IG5lZWQgdG8gb3V0cHV0IHRoZSBvcmFuZ2UgYmFycy4KICAgICAgICAgLy8gVGhlIG91dHB1dCBzZXF1ZW5jZSBzaG91bGQgbG9vayBsaWtlIHRoaXMgfCB8IHwgfCB8IHwgfCB8LgogICAgICAgICAvLyBCZWNhdXNlIHRoZSBzZXF1ZW5jZSBpcyBoYWx2ZWQsIHRvIG1hcCB0aGUgb3V0cHV0IGluZGV4IGJhY2sKICAgICAgICAgLy8gdG8gdGhlIHByZXZpb3VzIHNlcXVlbmNlIHRvIGZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUsCiAgICAgICAgIC8vIHdlIG5lZWQgdG8gZG91YmxlIHRoZSBpbmRleC4gV2hlbiB3ZSBkb3VibGUgdGhlIGluZGV4LAogICAgICAgICAvLyB3ZSBiYXNpY2FsbHkgaW50ZXJwb2xhdGUgYSBwb3NpdGlvbiwgc28gMmkgbG9va3MgbGlrZQogICAgICAgICAvLyB8IF8gfCBfIHwgXyB8IF8gfCBfIHwgXyB8IF8uIFdlIG1vdmUgdGhlIHwgdG8gdGhlIGZpcnN0IGsgcG9zaXRpb24KICAgICAgICAgLy8gb2YgZWFjaCAyayBwb3NpdGlvbnMgYnkgLSBlbGVtSWR4ICUgay4gRS5nLiBmb3Igb3V0cHV0IGF0CiAgICAgICAgIC8vIGluZGV4IDQsNSw2LDcsIHdlIHdhbnQgdG8gZ2V0IHRoZSBjb3JyZXNwb25kaW5nIGVsZW1lbnQgYXQKICAgICAgICAgLy8gb3JpZ2luYWwgaW5kZXggOCw5LDEwLDExLCBmb3Igb3V0cHV0IGF0IGluZGV4IDgsOSwxMCwxMSwKICAgICAgICAgLy8gd2Ugd2FudCB0byBnZXQgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBhdCBvcmlnaW5hbCBpbmRleAogICAgICAgICAvLyAxNiwxNywxOCwxOSwgc28gb24gYW5kIHNvIGZvcnRoLgoKICAgICAgICAgaW50IGkgPSBlbGVtSWR4IDwgayA/IGVsZW1JZHggOiAoZWxlbUlkeCAqIDIgLSBpbW9kKGVsZW1JZHgsIGspKTsKICAgICAgICAgaW50IGkwID0gZmlyc3RQYXNzID09IDEgPyBpIDogaW50KGdldEluZGljZXMoYmF0Y2gsIGkpKTsKICAgICAgICAgaW50IGkxID0gZmlyc3RQYXNzID09IDEgPyBpICsgayA6IGludChnZXRJbmRpY2VzKGJhdGNoLCBpICsgaykpOwoKICAgICAgICAgZmxvYXQgeDAgPSBnZXRYKGJhdGNoLCBpMCk7CiAgICAgICAgIGZsb2F0IHgxID0gaTEgPCBuID8gZ2V0WChiYXRjaCwgaTEpIDogeDA7CgogICAgICAgICBzZXRPdXRwdXQoeDAgPj0geDEgPyBmbG9hdChpMCkgOiBmbG9hdChpMSkpOwogICAgICAgfQogICAgIGB9fS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIGRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvT3JOdWxsKGhhLGFhKXthYSE9PW51bGwmJmhhLmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvKGFhKX1mdW5jdGlvbiByb3VuZFVwVG9Qb3cyKGhhKXtsZXQgYWE9MTtmb3IoO2FhPGhhOylhYSo9MjtyZXR1cm4gYWF9ZnVuY3Rpb24gdG9wSyhoYSl7Y29uc3R7aW5wdXRzOmFhLGJhY2tlbmQ6eGEsYXR0cnM6YmF9PWhhLHt4OlNhfT1hYSx7azpUYSxzb3J0ZWQ6d2F9PWJhLEVhPWVudigpLmdldE51bWJlcigiVE9QS19MQVNUX0RJTV9DUFVfSEFORE9GRl9TSVpFX1RIUkVTSE9MRCIpLGthPWVudigpLmdldE51bWJlcigiVE9QS19LX0NQVV9IQU5ET0ZGX1RIUkVTSE9MRCIpLEFhPVNhLnNoYXBlLEZhPUFhW0FhLmxlbmd0aC0xXTtpZih4YS5zaG91bGRFeGVjdXRlT25DUFUoW1NhXSl8fEZhPEVhfHxUYT5rYSl7Y29uc3QgZmw9eGEucmVhZFN5bmMoU2EuZGF0YUlkKSxbbWwsZ2xdPXRvcEtJbXBsQ1BVKGZsLEFhLFNhLmR0eXBlLFRhLHdhKTtyZXR1cm5beGEubWFrZVRlbnNvckluZm8obWwuc2hhcGUsbWwuZHR5cGUsbWwudmFsdWVzKSx4YS5tYWtlVGVuc29ySW5mbyhnbC5zaGFwZSxnbC5kdHlwZSxnbC52YWx1ZXMpXX1pZihUYT09PTApcmV0dXJuIEFhW0FhLmxlbmd0aC0xXT0wLFt4YS5tYWtlVGVuc29ySW5mbyhBYSxTYS5kdHlwZSxbXSkseGEubWFrZVRlbnNvckluZm8oQWEsImludDMyIixbXSldO2lmKEZhPT09MSlyZXR1cm5bU2EsZmlsbCh7YXR0cnM6e3NoYXBlOkFhLGR0eXBlOiJpbnQzMiIsdmFsdWU6MH0sYmFja2VuZDp4YX0pXTtjb25zdCBMYT14YS50ZXhEYXRhLmdldChTYS5kYXRhSWQpLGVsPUxhIT09bnVsbCYmTGEuaXNQYWNrZWQsdGw9ZWw/eGEudW5wYWNrVGVuc29yKFNhKTpTYSxzbD1zaXplRnJvbVNoYXBlKEFhKS9GYSxybD1yZXNoYXBlKHtpbnB1dHM6e3g6dGx9LGF0dHJzOntzaGFwZTpbc2wsRmFdfSxiYWNrZW5kOnhhfSk7ZWwmJmRpc3Bvc2VJbnRlcm1lZGlhdGVUZW5zb3JJbmZvT3JOdWxsKHhhLHRsKTtjb25zdCBvbD1yb3VuZFVwVG9Qb3cyKFRhKSxhbD1yb3VuZFVwVG9Qb3cyKEZhKTtsZXQgbGw9bnVsbDtjb25zdCBpbD0oKT0+bGw9PT1udWxsP1tybCxybF06W3JsLGxsXSxjbD0oZmwsbWwsZ2wpPT57Y29uc3QgJGw9aWwoKSx4bD1uZXcgU3dhcFByb2dyYW0oZ2wpLGJsPVtbRmFdLFtsbD09PW51bGw/MTowXSxbTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZXSxbZmxdLFttbF1dLFNsPWxsO2xsPXhhLnJ1bldlYkdMUHJvZ3JhbSh4bCwkbCwiaW50MzIiLGJsKSxkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCh4YSxTbCl9O2ZvcihsZXQgZmw9MTtmbDxvbDtmbCo9Mil7Y29uc3QgbWw9ZmwqMjtmb3IobGV0IGdsPWZsO2dsPj0xO2dsLz0yKWNsKG1sLGdsLFtzbCxhbF0pfWZvcihsZXQgZmw9YWw7Zmw+b2w7ZmwvPTIpe2NvbnN0IG1sPWlsKCksZ2w9bmV3IE1lcmdlUHJvZ3JhbShbc2wsZmwvMl0pLHhsPVtbRmFdLFtsbD09PW51bGw/MTowXSxbb2xdXSx5bD1sbDtsbD14YS5ydW5XZWJHTFByb2dyYW0oZ2wsbWwsImludDMyIix4bCksZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm9Pck51bGwoeGEseWwpO2NvbnN0IGJsPW9sLzIsU2w9YmwqMjtmb3IobGV0IENsPWJsO0NsPj0xO0NsLz0yKWNsKFNsLENsLGxsLnNoYXBlKX1sZXQgdWw9bGw7bGw9c2xpY2Uoe2lucHV0czp7eDpsbH0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46MCxzaXplOltzbCxUYV19fSksZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm9Pck51bGwoeGEsdWwpO2xldCBkbD1nYXRoZXJWMih7aW5wdXRzOnt4OnJsLGluZGljZXM6bGx9LGJhY2tlbmQ6eGEsYXR0cnM6e2F4aXM6MSxiYXRjaERpbXM6MX19KTtkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCh4YSxybCk7Y29uc3QgaGw9QWEuc2xpY2UoMCwtMSk7aGwucHVzaChUYSksdWw9bGwsbGw9cmVzaGFwZSh7aW5wdXRzOnt4OmxsfSxhdHRyczp7c2hhcGU6aGx9LGJhY2tlbmQ6eGF9KSxkaXNwb3NlSW50ZXJtZWRpYXRlVGVuc29ySW5mb09yTnVsbCh4YSx1bCk7Y29uc3QgcGw9ZGw7cmV0dXJuIGRsPXJlc2hhcGUoe2lucHV0czp7eDpkbH0sYXR0cnM6e3NoYXBlOmhsfSxiYWNrZW5kOnhhfSksZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm9Pck51bGwoeGEscGwpLFtkbCxsbF19Y29uc3QgdG9wS0NvbmZpZz17a2VybmVsTmFtZTpUb3BLLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp0b3BLfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9jbGFzcyBUcmFuc2Zvcm1Qcm9ncmFte2NvbnN0cnVjdG9yKGFhLHhhLGJhLFNhLFRhLHdhKXt0aGlzLnZhcmlhYmxlTmFtZXM9WyJJbWFnZSIsIlRyYW5zZm9ybXMiXSx0aGlzLm91dHB1dFNoYXBlPXdhO2NvbnN0IEVhPWJhPT09Im5lYXJlc3QiPzE6MjtsZXQga2E7c3dpdGNoKFNhKXtjYXNlImNvbnN0YW50IjprYT0xO2JyZWFrO2Nhc2UicmVmbGVjdCI6a2E9MjticmVhaztjYXNlIndyYXAiOmthPTM7YnJlYWs7Y2FzZSJuZWFyZXN0IjprYT00O2JyZWFrO2RlZmF1bHQ6a2E9MTticmVha310aGlzLnVzZXJDb2RlPWAKICAgICAgICAgICAgZmxvYXQgbWFwQ29vcmQoZmxvYXQgb3V0Q29vcmQsIGZsb2F0IGxlbikgewogICAgICAgICAgICAgIGZsb2F0IGluQ29vcmQgPSBvdXRDb29yZDsKICAgICAgICAgICAgICBpZigke2thfSA9PSAyKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5Db29yZCA8IDAuMCkgewogICAgICAgICAgICAgICAgICBpZiAobGVuIDw9IDEuMCkgewogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgPSAwLjA7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgc3oyID0gMi4wICogbGVuOwogICAgICAgICAgICAgICAgICAgIGlmIChpbkNvb3JkIDwgc3oyKSB7CiAgICAgICAgICAgICAgICAgICAgICBpbkNvb3JkID0gc3oyICogZmxvYXQoaW50KGZsb2F0KC1pbkNvb3JkIC8gc3oyKSkpICsKICAgICAgICAgICAgICAgICAgICAgIGluQ29vcmQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgPSBpbkNvb3JkIDwgLWxlbiA/IGluQ29vcmQgKyBzejIgOiAtaW5Db29yZCAtIDEuMDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbkNvb3JkID4gbGVuIC0gMS4wKSB7CiAgICAgICAgICAgICAgICAgIGlmIChsZW4gPD0gMS4wKSB7CiAgICAgICAgICAgICAgICAgICAgaW5Db29yZCA9IDAuMDsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmbG9hdCBzejIgPSAyLjAgKiBsZW47CiAgICAgICAgICAgICAgICAgICAgaW5Db29yZCAtPSBzejIgKiBmbG9hdChpbnQoZmxvYXQoaW5Db29yZCAvIHN6MikpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5Db29yZCA+PSBsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgIGluQ29vcmQgPSBzejIgLSBpbkNvb3JkIC0gMS4wOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNsYW1wKGluQ29vcmQsIDAuMCwgbGVuIC0gMS4wKTsKICAgICAgICAgICAgICB9IGVsc2UgaWYgKCR7a2F9ID09IDMpIHsKICAgICAgICAgICAgICAgIGlmIChpbkNvb3JkIDwgMC4wKSB7CiAgICAgICAgICAgICAgICAgIGlmIChsZW4gPD0gMS4wKSB7CiAgICAgICAgICAgICAgICAgICAgaW5Db29yZCA9IDAuMDsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmbG9hdCBzeiA9IGxlbiAtIDEuMDsKICAgICAgICAgICAgICAgICAgICBpbkNvb3JkICs9IGxlbiAqIChmbG9hdChpbnQoZmxvYXQoLWluQ29vcmQgLyBzeikpKSArIDEuMCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5Db29yZCA+IGxlbiAtIDEuMCkgewogICAgICAgICAgICAgICAgICBpZiAobGVuIDw9IDEuMCkgewogICAgICAgICAgICAgICAgICAgIGluQ29vcmQgPSAwLjA7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgc3ogPSBsZW4gLSAxLjA7CiAgICAgICAgICAgICAgICAgICAgaW5Db29yZCAtPSBsZW4gKiBmbG9hdChpbnQoZmxvYXQoaW5Db29yZCAvIHN6KSkpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gY2xhbXAoaW5Db29yZCwgMC4wLCBsZW4gLSAxLjApOwogICAgICAgICAgICAgIH0gZWxzZSBpZiAoJHtrYX0gPT0gNCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsYW1wKG91dENvb3JkLCAwLjAsIGxlbiAtIDEuMCk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBvdXRDb29yZDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZsb2F0IHJlYWRXaXRoRmlsbFZhbHVlKGludCBiYXRjaCwgaW50IGNvb3JkWSwgaW50IGNvb3JkWCwKICAgICAgICAgICAgICBpbnQgY2hhbm5lbCkgewogICAgICAgICAgICAgIGZsb2F0IG91dHB1dFZhbHVlOwogICAgICAgICAgICAgIGlmICgwIDw9IGNvb3JkWSAmJiBjb29yZFkgPCAke2FhfSAmJiAwIDw9IGNvb3JkWCAmJiBjb29yZFggPCAke3hhfSkgewogICAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IGdldEltYWdlKGJhdGNoLCBjb29yZFksIGNvb3JkWCwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG91dHB1dFZhbHVlID0gZmxvYXQoJHtUYX0pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0VmFsdWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICAgICAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICAgICAgICBmbG9hdCBvdXRwdXRWYWx1ZTsKICAgICAgICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgICAgICAgaW50IHggPSBjb29yZHNbMl07CiAgICAgICAgICAgICAgaW50IHkgPSBjb29yZHNbMV07CiAgICAgICAgICAgICAgaW50IGNoYW5uZWwgPSBjb29yZHNbM107CiAgICAgICAgICAgICAgZmxvYXQgeGYgPSBmbG9hdCh4KTsKICAgICAgICAgICAgICBmbG9hdCB5ZiA9IGZsb2F0KHkpOwogICAgICAgICAgICAgIGZsb2F0IGExID0gZ2V0VHJhbnNmb3JtcyhiYXRjaCwgMCk7CiAgICAgICAgICAgICAgZmxvYXQgYTIgPSBnZXRUcmFuc2Zvcm1zKGJhdGNoLCAxKTsKICAgICAgICAgICAgICBmbG9hdCBhMyA9IGdldFRyYW5zZm9ybXMoYmF0Y2gsIDIpOwogICAgICAgICAgICAgIGZsb2F0IGIxID0gZ2V0VHJhbnNmb3JtcyhiYXRjaCwgMyk7CiAgICAgICAgICAgICAgZmxvYXQgYjIgPSBnZXRUcmFuc2Zvcm1zKGJhdGNoLCA0KTsKICAgICAgICAgICAgICBmbG9hdCBiMyA9IGdldFRyYW5zZm9ybXMoYmF0Y2gsIDUpOwogICAgICAgICAgICAgIGZsb2F0IGMxID0gZ2V0VHJhbnNmb3JtcyhiYXRjaCwgNik7CiAgICAgICAgICAgICAgZmxvYXQgYzIgPSBnZXRUcmFuc2Zvcm1zKGJhdGNoLCA3KTsKICAgICAgICAgICAgICBmbG9hdCBwcm9qZWN0aW9uID0gYzEgKiB4ZiArIGMyICogeWYgKyAxLjA7CiAgICAgICAgICAgICAgaWYgKHByb2plY3Rpb24gPT0gMC4wKSB7CiAgICAgICAgICAgICAgICBvdXRwdXRWYWx1ZSA9IGZsb2F0KCR7VGF9KTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZmxvYXQgaW5YID0gKGExICogeGYgKyBhMiAqIHlmICsgYTMpIC8gcHJvamVjdGlvbjsKICAgICAgICAgICAgICAgIGZsb2F0IGluWSA9IChiMSAqIHhmICsgYjIgKiB5ZiArIGIzKSAvIHByb2plY3Rpb247CiAgICAgICAgICAgICAgICBmbG9hdCBtYXBYID0gbWFwQ29vcmQoaW5YLCBmbG9hdCgke3hhfSkpOwogICAgICAgICAgICAgICAgZmxvYXQgbWFwWSA9IG1hcENvb3JkKGluWSwgZmxvYXQoJHthYX0pKTsKCiAgICAgICAgICAgICAgICBpZiAoJHtFYX0gPT0gMSkgewogICAgICAgICAgICAgICAgICBpbnQgY29vcmRZID0gaW50KHJvdW5kKG1hcFkpKTsKICAgICAgICAgICAgICAgICAgaW50IGNvb3JkWCA9IGludChyb3VuZChtYXBYKSk7CiAgICAgICAgICAgICAgICAgIG91dHB1dFZhbHVlID0gcmVhZFdpdGhGaWxsVmFsdWUoYmF0Y2gsIGNvb3JkWSwgY29vcmRYLAogICAgICAgICAgICAgICAgICAgIGNoYW5uZWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZmxvYXQgeUZsb29yID0gZmxvb3IobWFwWSk7CiAgICAgICAgICAgICAgICAgIGZsb2F0IHhGbG9vciA9IGZsb29yKG1hcFgpOwogICAgICAgICAgICAgICAgICBmbG9hdCB5Q2VpbCA9IHlGbG9vciArIDEuMDsKICAgICAgICAgICAgICAgICAgZmxvYXQgeENlaWwgPSB4Rmxvb3IgKyAxLjA7CiAgICAgICAgICAgICAgICAgIGZsb2F0IHZhbHVlWUZsb29yID0gKHhDZWlsIC0gbWFwWCkgKgogICAgICAgICAgICAgICAgICByZWFkV2l0aEZpbGxWYWx1ZShiYXRjaCwgaW50KHlGbG9vciksIGludCh4Rmxvb3IpLCBjaGFubmVsKSArCiAgICAgICAgICAgICAgICAgIChtYXBYIC0geEZsb29yKSAqCiAgICAgICAgICAgICAgICAgIHJlYWRXaXRoRmlsbFZhbHVlKGJhdGNoLCBpbnQoeUZsb29yKSwgaW50KHhDZWlsKSwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgIGZsb2F0IHZhbHVlWUNlaWwgPSAoeENlaWwgLSBtYXBYKSAqCiAgICAgICAgICAgICAgICAgIHJlYWRXaXRoRmlsbFZhbHVlKGJhdGNoLCBpbnQoeUNlaWwpLCBpbnQoeEZsb29yKSwgY2hhbm5lbCkgKwogICAgICAgICAgICAgICAgICAobWFwWCAtIHhGbG9vcikgKgogICAgICAgICAgICAgICAgICByZWFkV2l0aEZpbGxWYWx1ZShiYXRjaCwgaW50KHlDZWlsKSwgaW50KHhDZWlsKSwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgIG91dHB1dFZhbHVlID0gKHlDZWlsIC0gbWFwWSkgKiB2YWx1ZVlGbG9vciArCiAgICAgICAgICAgICAgICAgIChtYXBZIC0geUZsb29yKSAqIHZhbHVlWUNlaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHNldE91dHB1dChvdXRwdXRWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB0cmFuc2Zvcm0oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7aW1hZ2U6U2EsdHJhbnNmb3JtczpUYX09YWEse2ludGVycG9sYXRpb246d2EsZmlsbE1vZGU6RWEsZmlsbFZhbHVlOmthLG91dHB1dFNoYXBlOkFhfT1iYSxbRmEsTGEsZWwsdGxdPVNhLnNoYXBlLFtubCxzbF09QWE/P1tMYSxlbF0scmw9W0ZhLG5sLHNsLHRsXSxvbD1uZXcgVHJhbnNmb3JtUHJvZ3JhbShMYSxlbCx3YSxFYSxrYSxybCk7cmV0dXJuIHhhLnJ1bldlYkdMUHJvZ3JhbShvbCxbU2EsVGFdLCJmbG9hdDMyIil9Y29uc3QgdHJhbnNmb3JtQ29uZmlnPXtrZXJuZWxOYW1lOlRyYW5zZm9ybSxiYWNrZW5kTmFtZToid2ViZ2wiLGtlcm5lbEZ1bmM6dHJhbnNmb3JtfTsvKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIExpY2Vuc2UpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBBUyBJUyBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2Z1bmN0aW9uIHVuaXF1ZShoYSl7Y29uc3R7aW5wdXRzOmFhLGF0dHJzOnhhLGJhY2tlbmQ6YmF9PWhhLHtheGlzOlNhfT14YSx7eDpUYX09YWE7YXNzZXJ0Tm90Q29tcGxleChUYSwidW5pcXVlIiksY29uc29sZS53YXJuKCJXQVJOSU5HOiAiLCJVSSBtaWdodCBiZSBsb2NrZWQgdGVtcG9yYXJpbHkgYXMgZGF0YSBpcyBiZWluZyBkb3dubG9hZGVkIik7Y29uc3Qgd2E9YmEucmVhZFN5bmMoVGEuZGF0YUlkKSx7b3V0cHV0VmFsdWVzOkVhLG91dHB1dFNoYXBlOmthLGluZGljZXM6QWF9PXVuaXF1ZUltcGxDUFUod2EsU2EsVGEuc2hhcGUsVGEuZHR5cGUpO3JldHVybltiYS5tYWtlVGVuc29ySW5mbyhrYSxUYS5kdHlwZSxFYSksYmEubWFrZVRlbnNvckluZm8oW0FhLmxlbmd0aF0sImludDMyIixBYSldfWNvbnN0IHVuaXF1ZUNvbmZpZz17a2VybmVsTmFtZTpVbmlxdWUsYmFja2VuZE5hbWU6IndlYmdsIixrZXJuZWxGdW5jOnVuaXF1ZX07LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICovZnVuY3Rpb24gdW5wYWNrKGhhKXtjb25zdHtpbnB1dHM6YWEsYmFja2VuZDp4YSxhdHRyczpiYX09aGEse3ZhbHVlOlNhfT1hYTtsZXR7YXhpczpUYX09YmE7VGE8MCYmKFRhKz1TYS5zaGFwZS5sZW5ndGgpO2NvbnN0IHdhPVNhLEVhPXdhLnNoYXBlLmxlbmd0aCxrYT1TYS5zaGFwZVtUYV0sQWE9bmV3IEFycmF5KEVhLTEpO2xldCBGYT0wO2ZvcihsZXQgc2w9MDtzbDxFYTtzbCsrKXNsIT09VGEmJihBYVtGYSsrXT13YS5zaGFwZVtzbF0pO2NvbnN0IExhPVtdLGVsPW5ldyBBcnJheShFYSkuZmlsbCgwKSx0bD13YS5zaGFwZS5zbGljZSgpO3RsW1RhXT0xO2NvbnN0IG5sPW5ldyBBcnJheShrYSk7Zm9yKGxldCBzbD0wO3NsPG5sLmxlbmd0aDtzbCsrKXtlbFtUYV09c2w7Y29uc3Qgcmw9c2xpY2Uoe2lucHV0czp7eDp3YX0sYmFja2VuZDp4YSxhdHRyczp7YmVnaW46ZWwsc2l6ZTp0bH19KSxvbD1yZXNoYXBlKHtpbnB1dHM6e3g6cmx9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOkFhfX0pO25sW3NsXT1vbCxMYS5wdXNoKHJsKX1yZXR1cm4gTGEuZm9yRWFjaChzbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oc2wpKSxubH1jb25zdCB1bnBhY2tDb25maWc9e2tlcm5lbE5hbWU6VW5wYWNrLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp1bnBhY2t9Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NsYXNzIFNlZ21lbnRPcFByb2dyYW17Y29uc3RydWN0b3IoYWEseGEpe3RoaXMudmFyaWFibGVOYW1lcz1bIngiLCJzZWdtZW50SWRzIl07Y29uc3QgYmE9YWEud2luZG93U2l6ZSxTYT1hYS5iYXRjaFNpemUsVGE9YWEuaW5TaXplLHdhPWFhLm51bVNlZ21lbnRzLEVhPXdhKk1hdGguY2VpbChUYS9iYSk7dGhpcy5vdXRwdXRTaGFwZT1bU2EsRWFdO2NvbnN0IGthPSIwLjAiLEFhPSJzdW1WYWx1ZSIsRmE9TWF0aC5mbG9vcihiYS80KSo0LExhPWJhJTQsZWw9YAogICAgICAgIHN1bVZhbHVlICs9IGRvdCh2YWx1ZXMsIHNlZ0ZpbHRlcik7CiAgICBgO2xldCB0bD0iIjtUYSViYT4wJiYodGw9YAogICAgICAgIGlmIChpbklkeCA8IDAgfHwgaW5JZHggPj0gJHtUYX0pIHsKICAgICAgICAgIHJldHVybiBpbml0aWFsaXphdGlvblZhbHVlOwogICAgICAgIH0KICAgICAgYCk7bGV0IG5sPSIiO1RhJWJhPjAmJihubD1gCiAgICAgICAgaWYgKGluSWR4IDwgMCB8fCBpbklkeCA+PSAke1RhfSkgewogICAgICAgICAgcmV0dXJuIC0xLjA7CiAgICAgICAgfQogICAgICBgKSx0aGlzLnVzZXJDb2RlPWAKICAgICAgY29uc3QgZmxvYXQgaW5pdGlhbGl6YXRpb25WYWx1ZSA9ICR7a2F9OwoKICAgICAgZmxvYXQgZ2V0VmFsdWUoaW50IGJhdGNoLCBpbnQgaW5JZHgpIHsKICAgICAgICAke3RsfQogICAgICAgIHJldHVybiBnZXRYKGJhdGNoLCBpbklkeCk7CiAgICAgIH0KCiAgICAgIGZsb2F0IGdldFNlZ21lbnRJZEF0SW5kZXgoaW50IGluSWR4KSB7CiAgICAgICAgJHtubH0KICAgICAgICByZXR1cm4gZ2V0U2VnbWVudElkcyhpbklkeCk7CiAgICAgIH0KCiAgICAgIHZvaWQgbWFpbigpIHsKICAgICAgICBpdmVjMiBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTsKICAgICAgICBpbnQgYmF0Y2ggPSBjb29yZHNbMF07CiAgICAgICAgaW50IG91dElkeCA9IGNvb3Jkc1sxXTsKICAgICAgICBpbnQgaW5PZmZzZXQgPSBpbnQoZmxvb3IoZmxvYXQob3V0SWR4KSAvIGZsb2F0KAogICAgICAgICAgJHt3YX0pKSAqIGZsb2F0KCR7YmF9KSk7CiAgICAgICAgaW50IGN1cnJlbnRTZWcgPSBpbnQobW9kKGZsb2F0KG91dElkeCksIGZsb2F0KCR7d2F9KSkpOwoKICAgICAgICBmbG9hdCBzdW1WYWx1ZSA9IDAuMDsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke0ZhfTsgaSArPSA0KSB7CiAgICAgICAgICBpbnQgaW5JZHggPSBpbk9mZnNldCArIGk7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAyKSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMykKICAgICAgICAgICk7CgogICAgICAgICAgdmVjNCBzZWdGaWx0ZXIgPSB2ZWM0KAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCkpID09IGN1cnJlbnRTZWcgPyAxIDogMCwKICAgICAgICAgICAgaW50KGdldFNlZ21lbnRJZEF0SW5kZXgoaW5JZHggKyAxKSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCArIDIpKSA9PSBjdXJyZW50U2VnID8gMSA6IDAsCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4ICsgMykpID09IGN1cnJlbnRTZWcgPyAxIDogMAogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0KCiAgICAgICAgaW50IGluSWR4ID0gaW5PZmZzZXQgKyAke0ZhfTsKICAgICAgICBpZiAoJHtMYT09PTF9KSB7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICk7CgogICAgICAgICAgaW50IGluSWR4U2VnID0gaW50KGdldFNlZ21lbnRJZEF0SW5kZXgoaW5JZHgpKTsKCiAgICAgICAgICB2ZWM0IHNlZ0ZpbHRlciA9IHZlYzQoCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4KSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICAwLAogICAgICAgICAgICAwLAogICAgICAgICAgICAwCiAgICAgICAgICApOwoKICAgICAgICAgICR7ZWx9CiAgICAgICAgfSBlbHNlIGlmICgke0xhPT09Mn0pIHsKICAgICAgICAgIHZlYzQgdmFsdWVzID0gdmVjNCgKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4KSwKICAgICAgICAgICAgZ2V0VmFsdWUoYmF0Y2gsIGluSWR4ICsgMSksCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUsCiAgICAgICAgICAgIGluaXRpYWxpemF0aW9uVmFsdWUKICAgICAgICAgICk7CgogICAgICAgICAgdmVjNCBzZWdGaWx0ZXIgPSB2ZWM0KAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCkpID09IGN1cnJlbnRTZWcgPyAxIDogMCwKICAgICAgICAgICAgaW50KGdldFNlZ21lbnRJZEF0SW5kZXgoaW5JZHggKyAxKSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgMAogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0gZWxzZSBpZiAoJHtMYT09PTN9KSB7CiAgICAgICAgICB2ZWM0IHZhbHVlcyA9IHZlYzQoCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCksCiAgICAgICAgICAgIGdldFZhbHVlKGJhdGNoLCBpbklkeCArIDEpLAogICAgICAgICAgICBnZXRWYWx1ZShiYXRjaCwgaW5JZHggKyAyKSwKICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25WYWx1ZQogICAgICAgICAgKTsKCiAgICAgICAgICB2ZWM0IHNlZ0ZpbHRlciA9IHZlYzQoCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4KSkgPT0gY3VycmVudFNlZyA/IDEgOiAwLAogICAgICAgICAgICBpbnQoZ2V0U2VnbWVudElkQXRJbmRleChpbklkeCArIDEpKSA9PSBjdXJyZW50U2VnID8gMSA6IDAsCiAgICAgICAgICAgIGludChnZXRTZWdtZW50SWRBdEluZGV4KGluSWR4ICsgMikpID09IGN1cnJlbnRTZWcgPyAxIDogMCwKICAgICAgICAgICAgMAogICAgICAgICAgKTsKCiAgICAgICAgICAke2VsfQogICAgICAgIH0KICAgICAgICBzZXRPdXRwdXQoJHtBYX0pOwogICAgICB9CiAgICBgfX0vKioKICogQGxpY2Vuc2UKICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKi9mdW5jdGlvbiB1bnNvcnRlZFNlZ21lbnRTdW0oaGEpe2NvbnN0e2lucHV0czphYSxiYWNrZW5kOnhhLGF0dHJzOmJhfT1oYSx7eDpTYSxzZWdtZW50SWRzOlRhfT1hYSx7bnVtU2VnbWVudHM6d2F9PWJhLEVhPVNhLnNoYXBlLmxlbmd0aCxrYT1bXTtsZXQgQWE9MDtjb25zdCBGYT1nZXRBeGVzUGVybXV0YXRpb24oW0FhXSxFYSk7bGV0IExhPVNhO0ZhIT1udWxsJiYoTGE9dHJhbnNwb3NlKHtpbnB1dHM6e3g6U2F9LGJhY2tlbmQ6eGEsYXR0cnM6e3Blcm06RmF9fSksa2EucHVzaChMYSksQWE9Z2V0SW5uZXJNb3N0QXhlcygxLEVhKVswXSk7Y29uc3QgZWw9Y29tcHV0ZU91dFNoYXBlKExhLnNoYXBlLEFhLHdhKSx0bD1zaXplRnJvbVNoYXBlKFtMYS5zaGFwZVtBYV1dKSxubD1yZXNoYXBlKHtpbnB1dHM6e3g6TGF9LGJhY2tlbmQ6eGEsYXR0cnM6e3NoYXBlOlstMSx0bF19fSk7a2EucHVzaChubCk7Y29uc3Qgc2w9c3VtT3V0VHlwZShTYS5kdHlwZSkscmw9KGlsLGNsLHVsLGRsLGhsKT0+e2NvbnN0IHBsPWlsLnNoYXBlWzBdLGZsPWlsLnNoYXBlWzFdLG1sPXNlZ09wQ29tcHV0ZU9wdGltYWxXaW5kb3dTaXplKGZsLGhsKSxnbD17d2luZG93U2l6ZTptbCxpblNpemU6ZmwsYmF0Y2hTaXplOnBsLG51bVNlZ21lbnRzOmhsfSwkbD1uZXcgU2VnbWVudE9wUHJvZ3JhbShnbCxjbCkseGw9eGEuY29tcGlsZUFuZFJ1bigkbCxbaWwsdWxdLGRsKTtpZihrYS5wdXNoKHhsKSx4bC5zaGFwZVsxXT09PWhsKXJldHVybiB4bDtjb25zdCB5bD1yYW5nZSh7YmFja2VuZDp4YSxhdHRyczp7c3RhcnQ6MCxzdG9wOmhsLHN0ZXA6MSxkdHlwZToiZmxvYXQzMiJ9fSksYmw9dGlsZSh7aW5wdXRzOnt4OnlsfSxiYWNrZW5kOnhhLGF0dHJzOntyZXBzOltmbC9tbF19fSk7cmV0dXJuIGthLnB1c2goeWwpLGthLnB1c2goYmwpLHJsKHhsLGNsLGJsLGRsLGhsKX0sb2w9cmwobmwsInVuc29ydGVkU2VnbWVudFN1bSIsVGEsc2wsd2EpLGFsPXJlc2hhcGUoe2lucHV0czp7eDpvbH0sYmFja2VuZDp4YSxhdHRyczp7c2hhcGU6ZWx9fSk7bGV0IGxsPWFsO2lmKEZhIT1udWxsKXtrYS5wdXNoKGFsKTtjb25zdCBpbD1nZXRVbmRvQXhlc1Blcm11dGF0aW9uKEZhKTtsbD10cmFuc3Bvc2Uoe2lucHV0czp7eDpsbH0sYmFja2VuZDp4YSxhdHRyczp7cGVybTppbH19KX1yZXR1cm4ga2EuZm9yRWFjaChpbD0+eGEuZGlzcG9zZUludGVybWVkaWF0ZVRlbnNvckluZm8oaWwpKSxsbH1jb25zdCB1bnNvcnRlZFNlZ21lbnRTdW1Db25maWc9e2tlcm5lbE5hbWU6VW5zb3J0ZWRTZWdtZW50U3VtLGJhY2tlbmROYW1lOiJ3ZWJnbCIsa2VybmVsRnVuYzp1bnNvcnRlZFNlZ21lbnRTdW19Oy8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqL2NvbnN0IGtlcm5lbENvbmZpZ3M9W19mdXNlZE1hdE11bENvbmZpZyxhYnNDb25maWcsYWNvc0NvbmZpZyxhY29zaENvbmZpZyxhZGRDb25maWcsYWRkTkNvbmZpZyxhbGxDb25maWcsYW55Q29uZmlnLGFyZ01heENvbmZpZyxhcmdNaW5Db25maWcsYXNpbkNvbmZpZyxhc2luaENvbmZpZyxhdGFuQ29uZmlnLGF0YW4yQ29uZmlnLGF0YW5oQ29uZmlnLGF2Z1Bvb2xDb25maWcsYXZnUG9vbDNEQ29uZmlnLGF2Z1Bvb2wzREdyYWRDb25maWcsYXZnUG9vbEdyYWRDb25maWcsYmF0Y2hNYXRNdWxDb25maWcsYmF0Y2hOb3JtQ29uZmlnLGJhdGNoVG9TcGFjZU5EQ29uZmlnLGJpbmNvdW50Q29uZmlnLGJpdHdpc2VBbmRDb25maWcsYnJvYWRjYXN0QXJnc0NvbmZpZyxjYXN0Q29uZmlnLGNlaWxDb25maWcsY2xpcEJ5VmFsdWVDb25maWcsY29tcGxleENvbmZpZyxjb21wbGV4QWJzQ29uZmlnLGNvbmNhdENvbmZpZyxjb252MkRDb25maWcsY29udjJEQmFja3Byb3BGaWx0ZXJDb25maWcsY29udjJEQmFja3Byb3BJbnB1dENvbmZpZyxjb252M0RDb25maWcsY29udjNEQmFja3Byb3BGaWx0ZXJWMkNvbmZpZyxjb252M0RCYWNrcHJvcElucHV0Q29uZmlnLGNvc0NvbmZpZyxjb3NoQ29uZmlnLGNyb3BBbmRSZXNpemVDb25maWcsY3VtcHJvZENvbmZpZyxjdW1zdW1Db25maWcsZGVuc2VCaW5jb3VudENvbmZpZyxkZXB0aFRvU3BhY2VDb25maWcsZGVwdGh3aXNlQ29udjJkTmF0aXZlQ29uZmlnLGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wRmlsdGVyQ29uZmlnLGRlcHRod2lzZUNvbnYyZE5hdGl2ZUJhY2twcm9wSW5wdXRDb25maWcsZGlhZ0NvbmZpZyxkaWxhdGlvbjJEQ29uZmlnLGVpbnN1bUNvbmZpZyxlbHVDb25maWcsZWx1R3JhZENvbmZpZyxlcXVhbENvbmZpZyxlcmZDb25maWcsZXhwQ29uZmlnLGV4cGFuZERpbXNDb25maWcsZXhwbTFDb25maWcsZmZ0Q29uZmlnLGZpbGxDb25maWcsZmxpcExlZnRSaWdodENvbmZpZyxmbG9vckNvbmZpZyxmbG9vckRpdkNvbmZpZyxmcm9tUGl4ZWxzQ29uZmlnLGZ1c2VkQ29udjJEQ29uZmlnLGZ1c2VkRGVwdGh3aXNlQ29udjJEQ29uZmlnLGdhdGhlck5kQ29uZmlnLGdhdGhlclYyQ29uZmlnLGdyZWF0ZXJDb25maWcsZ3JlYXRlckVxdWFsQ29uZmlnLGlkZW50aXR5Q29uZmlnLGlmZnRDb25maWcsaW1hZ0NvbmZpZyxpc0Zpbml0ZUNvbmZpZyxpc0luZkNvbmZpZyxpc05hTkNvbmZpZyxsZWFreVJlbHVDb25maWcsbGVzc0NvbmZpZyxsZXNzRXF1YWxDb25maWcsbGluU3BhY2VDb25maWcsbG9nQ29uZmlnLGxvZzFwQ29uZmlnLGxvZ2ljYWxBbmRDb25maWcsbG9naWNhbE5vdENvbmZpZyxsb2dpY2FsT3JDb25maWcsTFJOQ29uZmlnLExSTkdyYWRDb25maWcsbWF4Q29uZmlnLG1heGltdW1Db25maWcsbWF4UG9vbENvbmZpZyxtYXhQb29sM0RDb25maWcsbWF4UG9vbDNER3JhZENvbmZpZyxtYXhQb29sR3JhZENvbmZpZyxtYXhQb29sV2l0aEFyZ21heENvbmZpZyxtZWFuQ29uZmlnLG1pbkNvbmZpZyxtaW5pbXVtQ29uZmlnLG1pcnJvclBhZENvbmZpZyxtb2RDb25maWcsbXVsdGlub21pYWxDb25maWcsbXVsdGlwbHlDb25maWcsbmVnQ29uZmlnLG5vbk1heFN1cHByZXNzaW9uVjNDb25maWcsbm9uTWF4U3VwcHJlc3Npb25WNENvbmZpZyxub25NYXhTdXBwcmVzc2lvblY1Q29uZmlnLG5vdEVxdWFsQ29uZmlnLG9uZUhvdENvbmZpZyxvbmVzTGlrZUNvbmZpZyxwYWNrQ29uZmlnLHBhZFYyQ29uZmlnLHBvd0NvbmZpZyxwcmVsdUNvbmZpZyxwcm9kQ29uZmlnLHJhZ2dlZEdhdGhlckNvbmZpZyxyYWdnZWRSYW5nZUNvbmZpZyxyYWdnZWRUZW5zb3JUb1RlbnNvckNvbmZpZyxyYW5nZUNvbmZpZyxyZWFsQ29uZmlnLHJlYWxEaXZDb25maWcscmVjaXByb2NhbENvbmZpZyxyZWx1Q29uZmlnLHJlbHU2Q29uZmlnLHJlc2hhcGVDb25maWcscmVzaXplQmlsaW5lYXJDb25maWcscmVzaXplQmlsaW5lYXJHcmFkQ29uZmlnLHJlc2l6ZU5lYXJlc3ROZWlnaGJvckNvbmZpZyxyZXNpemVOZWFyZXN0TmVpZ2hib3JHcmFkQ29uZmlnLHJldmVyc2VDb25maWcscm90YXRlV2l0aE9mZnNldENvbmZpZyxyb3VuZENvbmZpZyxyc3FydENvbmZpZyxzY2F0dGVyTmRDb25maWcsc2VhcmNoU29ydGVkQ29uZmlnLHNlbGVjdENvbmZpZyxzZWx1Q29uZmlnLHNpZ21vaWRDb25maWcsc2lnbkNvbmZpZyxzaW5Db25maWcsc2luaENvbmZpZyxzbGljZUNvbmZpZyxzb2Z0bWF4Q29uZmlnLHNvZnRwbHVzQ29uZmlnLHNwYWNlVG9CYXRjaE5EQ29uZmlnLHNwYXJzZUZpbGxFbXB0eVJvd3NDb25maWcsc3BhcnNlUmVzaGFwZUNvbmZpZyxzcGFyc2VTZWdtZW50TWVhbkNvbmZpZyxzcGFyc2VTZWdtZW50U3VtQ29uZmlnLHNwYXJzZVRvRGVuc2VDb25maWcsc3BsaXRWQ29uZmlnLHNxcnRDb25maWcsc3F1YXJlQ29uZmlnLHNxdWFyZWREaWZmZXJlbmNlQ29uZmlnLHN0YXRpY1JlZ2V4UmVwbGFjZUNvbmZpZyxzdGVwQ29uZmlnLHN0cmlkZWRTbGljZUNvbmZpZyxzdHJpbmdOR3JhbXNDb25maWcsc3RyaW5nU3BsaXRDb25maWcsc3RyaW5nVG9IYXNoQnVja2V0RmFzdENvbmZpZyxzdWJDb25maWcsc3VtQ29uZmlnLHRhbkNvbmZpZyx0YW5oQ29uZmlnLHRlbnNvclNjYXR0ZXJVcGRhdGVDb25maWcsdGlsZUNvbmZpZyx0b3BLQ29uZmlnLHRyYW5zZm9ybUNvbmZpZyx0cmFuc3Bvc2VDb25maWcsdW5pcXVlQ29uZmlnLHVucGFja0NvbmZpZyx1bnNvcnRlZFNlZ21lbnRTdW1Db25maWcsemVyb3NMaWtlQ29uZmlnXTtmb3IoY29uc3QgaGEgb2Yga2VybmVsQ29uZmlncylyZWdpc3Rlcktlcm5lbChoYSk7Y2xhc3MgSW5mZXJlbmNlRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihhYSx4YSl7c3VwZXIoYWEgaW5zdGFuY2VvZiBFcnJvcj9hYS5tZXNzYWdlOnR5cGVvZiBhYT09InN0cmluZyI/YWE6SlNPTi5zdHJpbmdpZnkoYWEpKSx0aGlzLmNvZGU9eGF9fWNsYXNzIE1vZGVsRG93bmxvYWRRdW90YUV4aGF1c3RlZCBleHRlbmRzIEluZmVyZW5jZUVycm9ye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSw0MjkpfX1jbGFzcyBNb2RlbERvd25sb2FkRXJyb3IgZXh0ZW5kcyBJbmZlcmVuY2VFcnJvcntjb25zdHJ1Y3RvcihhYSl7c3VwZXIoYWEsNDA0KX19Y2xhc3MgTW9kZWxOb3RJbml0aWFsaXplZCBleHRlbmRzIEluZmVyZW5jZUVycm9ye2NvbnN0cnVjdG9yKGFhKXtzdXBlcihhYSw0MDQpfX1jbGFzcyBSZXF1ZXN0VG9vT2xkIGV4dGVuZHMgSW5mZXJlbmNlRXJyb3J7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhLDQwNCl9fWNsYXNzIENWTW9kZWx7Y29uc3RydWN0b3IoKXtlbnYkMSgpLnNldCgiUFJPRCIsITApfWFzeW5jIGluaXRpYWxpemUoLi4uYWEpe31hc3luYyBpbmZlcihhYSl7dGhyb3cgbmV3IEVycm9yKCJOb3QgaW1wbGVtZW50ZWQiKX1jb25maWd1cmUoLi4uYWEpe31hc3luYyBfbG9hZFJvYm9mbG93TW9kZWwoYWEpe2xldCB4YTtjb25zdCBiYT1hd2FpdCBsb2FkR3JhcGhNb2RlbChhYSx7ZmV0Y2hGdW5jOmFzeW5jKFNhLFRhKT0+e2lmKHR5cGVvZiBTYSE9InN0cmluZyIpcmV0dXJuIGZldGNoKFNhLFRhKTtjb25zdCB3YT1TYS5tYXRjaCgvKGh0dHBzOlwvXC9zdG9yYWdlXC5nb29nbGVhcGlzXC5jb21cLy4rXC9ncm91cC4rc2hhcmQuK1wuYmluKVw/cHVibGlzaGFibGVfa2V5PS4qLyk7aWYod2Epe2NvbnN0IEZhPXdhWzFdO3JldHVybiBmZXRjaChGYSxUYSl9Y29uc3QgRWE9YXdhaXQgZmV0Y2goU2EsVGEpLGthPUVhLnN0YXR1cyxBYT1hd2FpdCBFYS5qc29uKCkuY2F0Y2goKCk9Pm51bGwpO2lmKGthPT00MjkpdGhyb3cgbmV3IE1vZGVsRG93bmxvYWRRdW90YUV4aGF1c3RlZCgiTW9kZWwgZG93bmxvYWQgcXVvdGEgZXhoYXVzdGVkLiAiK0pTT04uc3RyaW5naWZ5KEFhKSk7aWYoa2EhPTIwMCl0aHJvdyBuZXcgTW9kZWxEb3dubG9hZEVycm9yKCJFcnJvciBoYXBwZW5lZCBkdXJpbmcgbW9kZWwgZG93bmxvYWRpbmcuICIrSlNPTi5zdHJpbmdpZnkoQWEpKTtyZXR1cm4geGE9QWEsUmVzcG9uc2UuanNvbihBYS50ZmpzLm1vZGVsKX19KTtyZXR1cm5beGEsYmFdfX1hc3luYyBmdW5jdGlvbiBpbml0TW9kdWxlRmFjdG9yeShoYSl7Y29uc3QgYWE9c2VsZjthYS5leHBvcnRzPXt9LGFhLmRiZz0oKT0+e30sYWEubW9kdWxlPXtleHBvcnRzOnNlbGYuZXhwb3J0c30sYXdhaXQgaW1wb3J0KGhhKSxhYS5Nb2R1bGVGYWN0b3J5PXNlbGYubW9kdWxlLmV4cG9ydHMsZGVsZXRlIGFhLm1vZHVsZSxkZWxldGUgYWEuZXhwb3J0c31zZWxmLmltcG9ydFNjcmlwdHM9KC4uLmhhKT0+e307Y2xhc3MgR2F6ZSBleHRlbmRzIENWTW9kZWx7Y29uc3RydWN0b3IoKXtzdXBlcigpLHRoaXMuaXNEZWJ1Z01vZGU9ITF9YXN5bmMgaW5pdGlhbGl6ZShhYSx4YSxiYSxTYSxUYT0hMSl7dGhpcy53b3JrZXJJZD1hYSx0aGlzLmlzRGVidWdNb2RlPVRhLHRoaXMuaXNEZWJ1Z01vZGUmJmNvbnNvbGUubG9nKGAke3RoaXMud29ya2VySWR9IExvYWRpbmcgZmFjZSBkZXRlY3Rvci4uLmApLGF3YWl0IGluaXRNb2R1bGVGYWN0b3J5KCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BtZWRpYXBpcGUvdGFza3MtdmlzaW9uQDAuMTAuMTIvd2FzbS92aXNpb25fd2FzbV9pbnRlcm5hbC5qcyIpO2NvbnN0IHdhPWF3YWl0IENvLmZvclZpc2lvblRhc2tzKCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BtZWRpYXBpcGUvdGFza3MtdmlzaW9uQDAuMTAuMTIvd2FzbSIpO3RoaXMuZmFjZURldGVjdG9yPWF3YWl0IHFhLmNyZWF0ZUZyb21PcHRpb25zKHdhLHtiYXNlT3B0aW9uczp7bW9kZWxBc3NldFBhdGg6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9tZWRpYXBpcGUtbW9kZWxzL2ZhY2VfZGV0ZWN0b3IvYmxhemVfZmFjZV9zaG9ydF9yYW5nZS9mbG9hdDE2LzEvYmxhemVfZmFjZV9zaG9ydF9yYW5nZS50ZmxpdGUiLGRlbGVnYXRlOiJHUFUifSxydW5uaW5nTW9kZToiSU1BR0UifSksYXdhaXQgdGhpcy5mYWNlRGV0ZWN0b3IuZGV0ZWN0KG5ldyBJbWFnZURhdGEoVWludDhDbGFtcGVkQXJyYXkuZnJvbSh7bGVuZ3RoOjEwMCoyMDAqNH0sKCk9Pk1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSoyNTUpKSwxMDApKSx0aGlzLmlzRGVidWdNb2RlJiYoY29uc29sZS5sb2coYCR7dGhpcy53b3JrZXJJZH0gTG9hZGluZyBmYWNlIGRldGVjdG9yIERPTkVgKSxjb25zb2xlLmxvZyhgJHt0aGlzLndvcmtlcklkfSBMb2FkaW5nIGdhemUgZGV0ZWN0b3IuLi5gKSk7Y29uc3QgRWE9YGh0dHBzOi8vYXBpLnJvYm9mbG93LmNvbS90ZmpzX2NvcmUvJHt4YX0vJHtiYX0/cHVibGlzaGFibGVfa2V5PSR7U2F9YCxba2EsQWFdPWF3YWl0IHRoaXMuX2xvYWRSb2JvZmxvd01vZGVsKEVhKTtpZih0aGlzLnJmTW9kZWw9a2EsdGhpcy5nYXplRGV0ZWN0b3I9QWEsIXRoaXMuZ2F6ZURldGVjdG9yKXtjb25zb2xlLmVycm9yKGAke3RoaXMud29ya2VySWR9IExvYWRpbmcgZ2F6ZSBkZXRlY3RvciBGQUlMRUQgKG1vZGVsIG5vdCBmb3VuZClgKTtyZXR1cm59YXdhaXQgdGhpcy5nYXplRGV0ZWN0b3IucHJlZGljdChyYW5kb21Vbmlmb3JtKFsxLDQ0OCw0NDgsM10pKSx0aGlzLmlzRGVidWdNb2RlJiZjb25zb2xlLmxvZyhgJHt0aGlzLndvcmtlcklkfSBMb2FkaW5nIGdhemUgZGV0ZWN0b3IgRE9ORWApfWRldGVjdEdhemVzKGFhLHhhKXtsZXQgYmE9W107Y29uc3QgU2E9dGhpcy5nYXplRGV0ZWN0b3IsVGE9dGhpcztyZXR1cm4gU2E/KHRpZHkkMSgoKT0+e2NvbnN0IHdhPWFhLnRlbnNvcigpLnRvRmxvYXQoKS5kaXYoMjU1KS5leHBhbmREaW1zKDApLEVhPXdhLnNoYXBlWzFdLGthPXdhLnNoYXBlWzJdO2lmKCFFYXx8IWthKXtjb25zb2xlLmVycm9yKGAke3RoaXMud29ya2VySWR9IGltYWdlIGhhcyBpbnZhbGlkIGRpbWVuc2lvbnNgKTtyZXR1cm59Zm9yKGxldCBBYT0wO0FhPHhhLmxlbmd0aDsrK0FhKXtjb25zdCBGYT14YVtBYV0sTGE9RmEuYm91bmRpbmdCb3g7aWYoIUxhKXtjb25zb2xlLmVycm9yKGAke3RoaXMud29ya2VySWR9IE5vIGJvdW5kaW5nIGJveCBmb3VuZCBmb3IgZmFjZSAke0FhfWApO2NvbnRpbnVlfWNvbnN0IGVsPXBlcmZvcm1hbmNlLm5vdygpLHRsPUxhLm9yaWdpblkvRWEsbmw9TGEub3JpZ2luWC9rYSxzbD0oTGEub3JpZ2luWStMYS5oZWlnaHQpL0VhLHJsPShMYS5vcmlnaW5YK0xhLndpZHRoKS9rYSxvbD1bW3RsLG5sLHNsLHJsXV0sYWw9aW1hZ2UkMS5jcm9wQW5kUmVzaXplKHdhLG9sLFswXSxbNDQ4LDQ0OF0pLnNxdWVlemUoKSxsbD1hbC5zbGljZShbMCwwLDBdLFstMSwtMSwxXSkuc3ViKHNjYWxhciQxKC40ODUpKS5kaXYoc2NhbGFyJDEoLjIyOSkpLGlsPWFsLnNsaWNlKFswLDAsMV0sWy0xLC0xLDFdKS5zdWIoc2NhbGFyJDEoLjQ1NikpLmRpdihzY2FsYXIkMSguMjI0KSksY2w9YWwuc2xpY2UoWzAsMCwyXSxbLTEsLTEsMV0pLnN1YihzY2FsYXIkMSguNDA2KSkuZGl2KHNjYWxhciQxKC4yMjUpKSx1bD1jb25jYXQkMyhbbGwsaWwsY2xdLDIpLmV4cGFuZERpbXMoMCksZGw9cGVyZm9ybWFuY2Uubm93KCksaGw9U2EucHJlZGljdCh1bCkscGw9cGVyZm9ybWFuY2Uubm93KCk7aWYoIUFycmF5LmlzQXJyYXkoaGwpfHxobC5sZW5ndGg8Mil7Y29uc29sZS5lcnJvcihgJHtUYS53b3JrZXJJZH0gR2F6ZSBkZXRlY3RvciByZXR1cm5lZCBpbnZhbGlkIG91dHB1dGApO3JldHVybn1jb25zdCBmbD10ZW5zb3IoWy4uLkFycmF5KDkwKS5rZXlzKCldLFs5MF0sImZsb2F0MzIiKSxtbD1zb2Z0bWF4JDMoaGxbMF0sMSkuc3F1ZWV6ZSgpLm11bChmbCkuc3VtKCksZ2w9c29mdG1heCQzKGhsWzFdLDEpLnNxdWVlemUoKS5tdWwoZmwpLnN1bSgpLCRsPW1sLmRhdGFTeW5jKCkseGw9Z2wuZGF0YVN5bmMoKSx5bD0oJGwqNC0xODApKk1hdGguUEkvMTgwLGJsPSh4bCo0LTE4MCkqTWF0aC5QSS8xODA7YmEucHVzaCh7bGVmdEV5ZTpGYS5rZXlwb2ludHNbMF0scmlnaHRFeWU6RmEua2V5cG9pbnRzWzFdLHlhdzp5bCxwaXRjaDpibH0pO2NvbnN0IFNsPXBlcmZvcm1hbmNlLm5vdygpO1RhLmlzRGVidWdNb2RlJiZjb25zb2xlLmxvZyhUYS53b3JrZXJJZCsiZ2F6ZSAtLT4gIHlhdzogIisoeWwqMTgwL01hdGguUEkpLnRvRml4ZWQoMikrIiAgcGl0Y2g6ICIrKGJsKjE4MC9NYXRoLlBJKS50b0ZpeGVkKDIpKyIgIHByZTogIisoZGwtZWwpLnRvRml4ZWQoMikrIiAgaW5mZXI6ICIrKHBsLWRsKS50b0ZpeGVkKDIpKyIgIHBvc3Q6ICIrKFNsLXBsKS50b0ZpeGVkKDIpKX19KSxiYSk6KGNvbnNvbGUuZXJyb3IoYCR7dGhpcy53b3JrZXJJZH0gR2F6ZSBkZXRlY3RvciBub3QgZm91bmRgKSxbXSl9YXN5bmMgaW5mZXIoYWEpe2NvbnN0IHhhPXBlcmZvcm1hbmNlLm5vdygpLGJhPXRoaXMuZmFjZURldGVjdG9yO2lmKCFiYSlyZXR1cm4gY29uc29sZS5lcnJvcihgJHt0aGlzLndvcmtlcklkfSBGYWNlIGRldGVjdG9yIG5vdCBmb3VuZGApLFtdO2NvbnN0IFNhPWF3YWl0IGFhLmJpdG1hcCgpO2lmKCFTYSlyZXR1cm4gY29uc29sZS5lcnJvcihgJHt0aGlzLndvcmtlcklkfSBJbWFnZSBub3QgZm91bmRgKSxbXTtjb25zdCBUYT1iYS5kZXRlY3QoU2EpLmRldGVjdGlvbnM7aWYoVGEubGVuZ3RoPT09MClyZXR1cm4gdGhpcy5pc0RlYnVnTW9kZSYmY29uc29sZS5sb2coYCR7dGhpcy53b3JrZXJJZH0gLS0tLS0tLS0+IE5vIGZhY2UgZGV0ZWN0ZWQhYCksW107Y29uc3Qgd2E9cGVyZm9ybWFuY2Uubm93KCksRWE9dGhpcy5kZXRlY3RHYXplcyhhYSxUYSksa2E9cGVyZm9ybWFuY2Uubm93KCk7aWYodGhpcy5pc0RlYnVnTW9kZSl7bGV0IEFhPWAke3RoaXMud29ya2VySWR9ICBgO2ZvcihsZXQgRmE9MDtGYTxUYS5sZW5ndGg7KytGYSl7bGV0IExhPUVhW0ZhXTtBYSs9InlhdzogIisoTGEueWF3KjE4MC9NYXRoLlBJKS50b0ZpeGVkKDIpKyIgIHBpdGNoOiAiKyhMYS5waXRjaCoxODAvTWF0aC5QSSkudG9GaXhlZCgyKStgCmB9QWErPSJ0aW1lKG1zKTogZmFjZSAiKyh3YS14YSkudG9GaXhlZCgyKSsiIGdhemUgIisoa2Etd2EpLnRvRml4ZWQoMikrIiBhbGwgIisoa2EteGEpLnRvRml4ZWQoMikrYCAKRlBTOiAgICAgIGZhY2UgYCsoMWUzLyh3YS14YSkpLnRvRml4ZWQoMikrIiBnYXplICIrKDFlMy8oa2Etd2EpKS50b0ZpeGVkKDIpKyIgYWxsICIrKDFlMy8oa2EteGEpKS50b0ZpeGVkKDIpK2AKYCxjb25zb2xlLmxvZyhBYSl9cmV0dXJuIEVhfX1jbGFzcyBDVkltYWdle2NvbnN0cnVjdG9yKGFhKXthYSBpbnN0YW5jZW9mIFRlbnNvciQxPyhhYS5zaGFwZS5sZW5ndGg9PTQmJihhYT1yZXNoYXBlJDQoYWEsYWEuc2hhcGUuc2xpY2UoMSkpKSx0aGlzLnRlbnNvckltYWdlPWFhKTphYSBpbnN0YW5jZW9mIEltYWdlQml0bWFwP3RoaXMuYml0bWFwSW1hZ2U9YWE6KGFhIGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudHx8YWEgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSYmKHRoaXMuaHRtbEltYWdlPWFhKX1hc3luYyBiaXRtYXAoKXtpZih0aGlzLmJpdG1hcEltYWdlKXJldHVybiB0aGlzLmJpdG1hcEltYWdlO2lmKHRoaXMuaHRtbEltYWdlKXRoaXMuYml0bWFwSW1hZ2U9YXdhaXQgY3JlYXRlSW1hZ2VCaXRtYXAodGhpcy5odG1sSW1hZ2UpO2Vsc2UgaWYodGhpcy50ZW5zb3JJbWFnZSl0aHJvdyBuZXcgRXJyb3IoIk5vdCBpbXBsZW1lbnRlZCIpO3JldHVybiB0aGlzLmJpdG1hcEltYWdlfXRlbnNvcigpe2NvbnN0IGFhPXRoaXMuYml0bWFwSW1hZ2V8fHRoaXMuaHRtbEltYWdlO2lmKCFhYSl0aHJvdyBuZXcgRXJyb3IoIk5vIGltYWdlIik7cmV0dXJuIHRoaXMudGVuc29ySW1hZ2V8fCh0aGlzLnRlbnNvckltYWdlPWZyb21QaXhlbHMkMihhYSkpLHRoaXMudGVuc29ySW1hZ2V9YXN5bmMgdGVuc29yNEQoKXtpZighdGhpcy50ZW5zb3I0REltYWdlKXtsZXQgYWE9YXdhaXQgdGhpcy50ZW5zb3IoKTt0aGlzLnRlbnNvcjRESW1hZ2U9ZXhwYW5kRGltcyQ0KGFhKX1yZXR1cm4gdGhpcy50ZW5zb3I0REltYWdlfWFzeW5jIGFycmF5KCl7cmV0dXJuIHRoaXMudGVuc29ySW1hZ2U/dGhpcy50ZW5zb3JJbWFnZS5hcnJheSgpOihhd2FpdCB0aGlzLnRlbnNvcigpKS5hcnJheSgpfWRpbXMoKXtyZXR1cm4gdGhpcy5iaXRtYXBJbWFnZT9bdGhpcy5iaXRtYXBJbWFnZS53aWR0aCx0aGlzLmJpdG1hcEltYWdlLmhlaWdodF06dGhpcy50ZW5zb3JJbWFnZT9bdGhpcy50ZW5zb3JJbWFnZS5zaGFwZVswXSx0aGlzLnRlbnNvckltYWdlLnNoYXBlWzFdXTp0aGlzLmh0bWxJbWFnZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQ/W3RoaXMuaHRtbEltYWdlLndpZHRoLHRoaXMuaHRtbEltYWdlLmhlaWdodF06WzAsMF19ZGlzcG9zZSgpe3RoaXMudGVuc29ySW1hZ2UmJmRpc3Bvc2UkMSh0aGlzLnRlbnNvckltYWdlKSx0aGlzLnRlbnNvcjRESW1hZ2UmJmRpc3Bvc2UkMSh0aGlzLnRlbnNvcjRESW1hZ2UpfXN0YXRpYyBmcm9tQXJyYXkoYWEpe2xldCB4YT10ZW5zb3IoYWEpO3JldHVybiBuZXcgQ1ZJbWFnZSh4YSl9fWNvbnN0IE1BWF9SRVFVRVNUX0FHRT0xZTMqMTA7Y2xhc3MgSlNPTkhhbmRsZXJ7Y29uc3RydWN0b3IoYWEpe3RoaXMucGF0aD0iIix0aGlzLndlaWdodFBhdGhQcmVmaXg9IiIsdGhpcy5yZXF1ZXN0SW5pdD17fSx0aGlzLmZldGNoPWZldGNoLHRoaXMub25Qcm9ncmVzcz0oKT0+e30sdGhpcy53ZWlnaHRVcmxDb252ZXJ0ZXI9bnVsbCx0aGlzLmpzb249YWF9YXN5bmMgbG9hZCgpe2NvbnN0IGFhPXRoaXMuanNvbix4YT1hYS5tb2RlbFRvcG9sb2d5LGJhPWFhLndlaWdodHNNYW5pZmVzdCxTYT1hYS5nZW5lcmF0ZWRCeSxUYT1hYS5jb252ZXJ0ZWRCeSx3YT1hYS5mb3JtYXQsRWE9YWEudXNlckRlZmluZWRNZXRhZGF0YTtpZih4YT09bnVsbCYmYmE9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBUaGUgSlNPTiBmcm9tIEhUVFAgcGF0aCAke3RoaXMucGF0aH0gY29udGFpbnMgbmVpdGhlciBtb2RlbCB0b3BvbG9neSBvciBtYW5pZmVzdCBmb3Igd2VpZ2h0cy5gKTtsZXQga2E9W10sQWE9bmV3IEFycmF5QnVmZmVyKDApO2JhIT1udWxsJiYoW2thLEFhXT1hd2FpdCB0aGlzLmxvYWRXZWlnaHRzKGJhKSk7Y29uc3QgRmE9YWEuc2lnbmF0dXJlLExhPXttb2RlbFRvcG9sb2d5OnhhLHdlaWdodFNwZWNzOmthLHdlaWdodERhdGE6QWEsdXNlckRlZmluZWRNZXRhZGF0YTpFYSxnZW5lcmF0ZWRCeTpTYSxjb252ZXJ0ZWRCeTpUYSxmb3JtYXQ6d2Esc2lnbmF0dXJlOkZhfSxlbD1hYS5tb2RlbEluaXRpYWxpemVyO3JldHVybiBlbCYmKExhLm1vZGVsSW5pdGlhbGl6ZXI9ZWwpLExhfWFzeW5jIGxvYWRXZWlnaHRzKGFhKXtBcnJheS5pc0FycmF5KHRoaXMucGF0aCk/dGhpcy5wYXRoWzFdOnRoaXMucGF0aDtjb25zdFt4YSxiYV09WyIiLCIiXSxTYT10aGlzLndlaWdodFBhdGhQcmVmaXh8fHhhLFRhPVtdO2Zvcihjb25zdCBBYSBvZiBhYSlUYS5wdXNoKC4uLkFhLndlaWdodHMpO2NvbnN0IHdhPVtdLEVhPVtdO2Zvcihjb25zdCBBYSBvZiBhYSlmb3IoY29uc3QgRmEgb2YgQWEucGF0aHMpdGhpcy53ZWlnaHRVcmxDb252ZXJ0ZXI/RWEucHVzaCh0aGlzLndlaWdodFVybENvbnZlcnRlcihGYSkpOndhLnB1c2goU2ErRmErYmEpO3RoaXMud2VpZ2h0VXJsQ29udmVydGVyJiZ3YS5wdXNoKC4uLmF3YWl0IFByb21pc2UuYWxsKEVhKSk7Y29uc3Qga2E9YXdhaXQgbG9hZFdlaWdodHNBc0FycmF5QnVmZmVyKHdhLHtyZXF1ZXN0SW5pdDp0aGlzLnJlcXVlc3RJbml0LGZldGNoRnVuYzp0aGlzLmZldGNoLG9uUHJvZ3Jlc3M6dGhpcy5vblByb2dyZXNzfSk7cmV0dXJuW1RhLGNvbmNhdGVuYXRlQXJyYXlCdWZmZXJzKGthKV19fWZ1bmN0aW9uIGNvbmNhdGVuYXRlQXJyYXlCdWZmZXJzKGhhKXtpZihoYS5sZW5ndGg9PT0xKXJldHVybiBoYVswXTtsZXQgYWE9MDtoYS5mb3JFYWNoKFNhPT57YWErPVNhLmJ5dGVMZW5ndGh9KTtjb25zdCB4YT1uZXcgVWludDhBcnJheShhYSk7bGV0IGJhPTA7cmV0dXJuIGhhLmZvckVhY2goU2E9Pnt4YS5zZXQobmV3IFVpbnQ4QXJyYXkoU2EpLGJhKSxiYSs9U2EuYnl0ZUxlbmd0aH0pLHhhLmJ1ZmZlcn1hc3luYyBmdW5jdGlvbiBsb2FkV2VpZ2h0c0FzQXJyYXlCdWZmZXIoaGEsYWEpe2FhPT1udWxsJiYoYWE9e30pO2NvbnN0IHhhPWFhLmZldGNoRnVuYz09bnVsbD9mZXRjaDphYS5mZXRjaEZ1bmMsYmE9aGEubWFwKEVhPT54YShFYSxhYT9hYS5yZXF1ZXN0SW5pdDp7fSkpLFRhPShhd2FpdCBQcm9taXNlLmFsbChiYSkpLm1hcChFYT0+RWEuYXJyYXlCdWZmZXIoKSk7cmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKFRhKX12YXIganNvbkhhbmRsZXI9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsSlNPTkhhbmRsZXIsY29uY2F0ZW5hdGVBcnJheUJ1ZmZlcnMsbG9hZFdlaWdodHNBc0FycmF5QnVmZmVyfSk7Y2xhc3MgRGVmYXVsdFlPTE9PcHRpb25ze2NvbnN0cnVjdG9yKGFhKXt0aGlzLm1vZGVsPW51bGwsdGhpcy5zaXplPTY0MCx0aGlzLm1heE51bUJveGVzPTIwLHRoaXMuc2NvcmVUaHJlc2hvbGQ9LjUsdGhpcy5pb3VUaHJlc2hvbGQ9LjUsdGhpcy5jbGFzc2VzPVtdLHRoaXMuY29sb3JzPXt9LHRoaXMudXBkYXRlKGFhKX11cGRhdGUoYWEpe3RoaXMubW9kZWw9YWEubW9kZWw/P3RoaXMubW9kZWwsdGhpcy5zaXplPWFhLnNpemU/P3RoaXMuc2l6ZSx0aGlzLm1heE51bUJveGVzPWFhLm1heE51bUJveGVzPz90aGlzLm1heE51bUJveGVzLHRoaXMuc2NvcmVUaHJlc2hvbGQ9YWEuc2NvcmVUaHJlc2hvbGQ/P3RoaXMuc2NvcmVUaHJlc2hvbGQsdGhpcy5pb3VUaHJlc2hvbGQ9YWEuaW91VGhyZXNob2xkPz90aGlzLmlvdVRocmVzaG9sZCx0aGlzLmNsYXNzZXM9YWEuY2xhc3Nlcz8/dGhpcy5jbGFzc2VzLHRoaXMuY29sb3JzPWFhLmNvbG9ycz8/dGhpcy5jb2xvcnN9fWNsYXNzIFlPTE92OCBleHRlbmRzIENWTW9kZWx7Y29uc3RydWN0b3IoYWEpe3N1cGVyKCksdGhpcy5hc3luY19tb2RlbD0hMSx0aGlzLm9wdGlvbnM9bmV3IERlZmF1bHRZT0xPT3B0aW9ucyhhYSl9YXN5bmMgaW5pdGlhbGl6ZSgpe2NvbnN0IGFhPW5ldyBKU09OSGFuZGxlcih0aGlzLm9wdGlvbnMubW9kZWwpO3RoaXMubW9kZWw9YXdhaXQgbG9hZEdyYXBoTW9kZWwoYWEpO2NvbnN0IHhhPXRoaXMuemVyb3MoKTt2YXIgYmE7dHJ5e2JhPXRoaXMubW9kZWwuZXhlY3V0ZSh4YSl9Y2F0Y2h7YmE9YXdhaXQgdGhpcy5tb2RlbC5leGVjdXRlQXN5bmMoeGEpLHRoaXMuYXN5bmNfbW9kZWw9ITB9ZGlzcG9zZSQxKGJhKSxkaXNwb3NlJDEoeGEpfWNvbmZpZ3VyZShhYSl7dGhpcy5vcHRpb25zLnVwZGF0ZShhYSl9emVyb3MoKXtyZXR1cm4gemVyb3MkMihbMSwzLHRoaXMub3B0aW9ucy5zaXplLHRoaXMub3B0aW9ucy5zaXplXSwiZmxvYXQzMiIpfWFzeW5jIHByZXByb2Nlc3MoYWEpe2xldCB4YT1hd2FpdCBhYS50ZW5zb3I0RCgpLGJhPXRpZHkkMSgoKT0+dHJhbnNwb3NlJDMoZGl2JDIoeGEucmVzaXplTmVhcmVzdE5laWdoYm9yKFt0aGlzLm9wdGlvbnMuc2l6ZSx0aGlzLm9wdGlvbnMuc2l6ZV0pLmFzVHlwZSgiZmxvYXQzMiIpLDI1NSksWzAsMywxLDJdKSk7cmV0dXJuIHhhLmRpc3Bvc2UoKSxiYX1hc3luYyBpbmZlcihhYSl7bGV0IHhhPWF3YWl0IHRoaXMucHJlcHJvY2VzcyhhYSk7aWYocGVyZm9ybWFuY2Uubm93KCksIXRoaXMubW9kZWwpdGhyb3cgbmV3IEVycm9yKCJNb2RlbCBub3QgbG9hZGVkIik7Y29uc3QgYmE9dGhpcy5hc3luY19tb2RlbD9hd2FpdCB0aGlzLm1vZGVsLmV4ZWN1dGVBc3luYyh4YSk6dGhpcy5tb2RlbC5leGVjdXRlKHhhKTtsZXQgU2E9dHJhbnNwb3NlJDMoYmEsWzAsMiwxXSk7Y29uc3QgVGE9U2EuZGF0YVN5bmMoKSx3YT1TYS5zaGFwZVsxXSxFYT1TYS5zaGFwZVsyXS00LGthPXRoaXMuY2FsY3VsYXRlTWF4U2NvcmVzWW9sb3Y1KFRhLHdhLEVhKSxBYT1rYS5zY29yZXMsRmE9a2EuY2xhc3NlcyxMYT10aGlzLmdldEJveGVzWW9sb1Y1KFRhLHdhLEVhLHRoaXMub3B0aW9ucy5zaXplKTtkaXNwb3NlJDEoeGEpLGRpc3Bvc2UkMShiYSksZGlzcG9zZSQxKFNhKTtjb25zdCBlbD1nZXRCYWNrZW5kKCk7c2V0QmFja2VuZCgiY3B1Iik7Y29uc3QgdGw9dGlkeSQxKCgpPT57Y29uc3Qgc2w9dGVuc29yMmQoTGEsW3dhLDRdKTtyZXR1cm4gaW1hZ2UkMS5ub25NYXhTdXBwcmVzc2lvbihzbCxBYSx0aGlzLm9wdGlvbnMubWF4TnVtQm94ZXMsdGhpcy5vcHRpb25zLmlvdVRocmVzaG9sZCx0aGlzLm9wdGlvbnMuc2NvcmVUaHJlc2hvbGQpfSksbmw9dGwuZGF0YVN5bmMoKTtyZXR1cm4gdGwuZGlzcG9zZSgpLHNldEJhY2tlbmQoZWwpLHBlcmZvcm1hbmNlLm5vdygpLHRoaXMuYnVpbGREZXRlY3RlZE9iamVjdHMoYWEuZGltcygpWzBdLGFhLmRpbXMoKVsxXSxMYSxBYSxubCxGYSl9YnVpbGREZXRlY3RlZE9iamVjdHMoYWEseGEsYmEsU2EsVGEsd2Epe2NvbnN0IEVhPVRhLmxlbmd0aCxrYT1bXTtmb3IobGV0IEFhPTA7QWE8RWE7QWErKyl7Y29uc3QgRmE9W107Zm9yKGxldCBzbD0wO3NsPDQ7c2wrKylGYVtzbF09YmFbVGFbQWFdKjQrc2xdO2NvbnN0IExhPUZhWzBdKnhhLGVsPUZhWzFdKmFhLHRsPUZhWzJdKnhhLG5sPUZhWzNdKmFhO2thLnB1c2goe2NsYXNzOnRoaXMub3B0aW9ucy5jbGFzc2VzW3dhW1RhW0FhXV1dLGNvbmZpZGVuY2U6U2FbVGFbQWFdXSxiYm94Ont4OihlbCtubCkvMix5OihMYSt0bCkvMix3aWR0aDpubC1lbCxoZWlnaHQ6dGwtTGF9LGNvbG9yOnRoaXMub3B0aW9ucy5jb2xvcnM/dGhpcy5vcHRpb25zLmNvbG9yc1t0aGlzLm9wdGlvbnMuY2xhc3Nlc1t3YVtUYVtBYV1dXV06IiMwMDAifSl9cmV0dXJuIGthfWNhbGN1bGF0ZU1heFNjb3Jlc1lvbG92NShhYSx4YSxiYSl7Y29uc3QgU2E9W10sVGE9W107Zm9yKGxldCB3YT0wO3dhPHhhO3dhKyspe2xldCBFYT1OdW1iZXIuTUlOX1ZBTFVFLGthPS0xO2ZvcihsZXQgQWE9MDtBYTxiYTtBYSsrKWFhW3dhKmJhKyh3YSsxKSo0K0FhXT5FYSYmKEVhPWFhW3dhKmJhKyh3YSsxKSo0K0FhXSxrYT1BYSk7U2Fbd2FdPUVhLFRhW3dhXT1rYX1yZXR1cm57Y2xhc3NlczpUYSxzY29yZXM6U2F9fWdldEJveGVzWW9sb1Y1KGFhLHhhLGJhLFNhKXtjb25zdCBUYT1bXTtmb3IobGV0IHdhPTA7d2E8eGE7d2ErKyl7Y29uc3QgRWE9YWFbd2EqKGJhKzQpKzBdLGthPWFhW3dhKihiYSs0KSsxXSxBYT1hYVt3YSooYmErNCkrMl0sRmE9YWFbd2EqKGJhKzQpKzNdLExhPUVhLUFhLzIsZWw9a2EtRmEvMix0bD1FYStBYS8yLG5sPWthK0ZhLzI7VGFbd2EqNF09ZWwvU2EsVGFbd2EqNCsxXT1MYS9TYSxUYVt3YSo0KzJdPW5sL1NhLFRhW3dhKjQrM109dGwvU2F9cmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoVGEpfX1jbGFzcyBZT0xPdjUgZXh0ZW5kcyBZT0xPdjh7Y29uc3RydWN0b3IoYWEpe3N1cGVyKGFhKSx0aGlzLmFzeW5jX21vZGVsPSExfWFzeW5jIGluaXRpYWxpemUoKXtjb25zdCBhYT1uZXcgSlNPTkhhbmRsZXIodGhpcy5vcHRpb25zLm1vZGVsKTt0aGlzLm1vZGVsPWF3YWl0IGxvYWRHcmFwaE1vZGVsKGFhKTtjb25zdCB4YT16ZXJvcyQyKFsxLHRoaXMub3B0aW9ucy5zaXplLHRoaXMub3B0aW9ucy5zaXplLDNdLCJmbG9hdDMyIik7dmFyIGJhO3RyeXtiYT10aGlzLm1vZGVsLmV4ZWN1dGUoeGEpfWNhdGNoe2JhPWF3YWl0IHRoaXMubW9kZWwuZXhlY3V0ZUFzeW5jKHhhKSx0aGlzLmFzeW5jX21vZGVsPSEwfWRpc3Bvc2UkMShiYSkseGEuZGlzcG9zZSgpfWFzeW5jIGluZmVyKGFhKXtsZXQgeGE9YXdhaXQgYWEudGVuc29yNEQoKSxiYT10aWR5JDEoKCk9PmRpdiQyKHhhLnJlc2l6ZU5lYXJlc3ROZWlnaGJvcihbdGhpcy5vcHRpb25zLnNpemUsdGhpcy5vcHRpb25zLnNpemVdKS5hc1R5cGUoImZsb2F0MzIiKSwyNTUpKSxTYT10cmFuc3Bvc2UkMyhiYSxbMCwxLDIsM10pO2lmKGJhLmRpc3Bvc2UoKSxwZXJmb3JtYW5jZS5ub3coKSwhdGhpcy5tb2RlbCl0aHJvdyBuZXcgRXJyb3IoIk1vZGVsIG5vdCBsb2FkZWQiKTtjb25zdCBUYT10aGlzLmFzeW5jX21vZGVsP2F3YWl0IHRoaXMubW9kZWwuZXhlY3V0ZUFzeW5jKFNhKTp0aGlzLm1vZGVsLmV4ZWN1dGUoU2EpO2xldCB3YT1UYTtjb25zdCBFYT13YS5kYXRhU3luYygpLGthPXdhLnNoYXBlWzFdLEFhPXdhLnNoYXBlWzJdLTUsRmE9dGhpcy5jYWxjdWxhdGVNYXhTY29yZXNZb2xvdjUoRWEsa2EsQWEpLExhPXRoaXMuZ2V0Q29uZmlkZW5jZVlvbG9WNShFYSxrYSxBYSksZWw9dGhpcy5nZXRCb3hlc1lvbG9WNShFYSxrYSxBYSx0aGlzLm9wdGlvbnMuc2l6ZSk7ZGlzcG9zZSQxKFNhKSxkaXNwb3NlJDEoVGEpLGRpc3Bvc2UkMSh3YSk7Y29uc3QgdGw9Z2V0QmFja2VuZCgpO3NldEJhY2tlbmQoImNwdSIpO2NvbnN0IG5sPXRpZHkkMSgoKT0+e2NvbnN0IHJsPXRlbnNvcjJkKGVsLFtrYSw0XSk7cmV0dXJuIGltYWdlJDEubm9uTWF4U3VwcHJlc3Npb24ocmwsTGEsdGhpcy5vcHRpb25zLm1heE51bUJveGVzLHRoaXMub3B0aW9ucy5pb3VUaHJlc2hvbGQsdGhpcy5vcHRpb25zLnNjb3JlVGhyZXNob2xkKX0pLHNsPW5sLmRhdGFTeW5jKCk7cmV0dXJuIG5sLmRpc3Bvc2UoKSxzZXRCYWNrZW5kKHRsKSx0aGlzLmJ1aWxkRGV0ZWN0ZWRPYmplY3RzKGFhLmRpbXMoKVswXSxhYS5kaW1zKClbMV0sZWwsTGEsc2wsRmEpfWNhbGN1bGF0ZU1heFNjb3Jlc1lvbG92NShhYSx4YSxiYSl7Y29uc3QgU2E9W107Zm9yKGxldCBUYT0wO1RhPHhhO1RhKyspe2xldCB3YT1OdW1iZXIuTUlOX1ZBTFVFLEVhPS0xO2ZvcihsZXQga2E9MDtrYTxiYTtrYSsrKWFhW1RhKmJhKyhUYSsxKSo1K2thXT53YSYmKHdhPWFhW1RhKmJhKyhUYSsxKSo1K2thXSxFYT1rYSk7U2FbVGFdPUVhfXJldHVybiBTYX1nZXRDb25maWRlbmNlWW9sb1Y1KGFhLHhhLGJhKXtjb25zdCBTYT1bXTtmb3IobGV0IFRhPTA7VGE8eGE7VGErKylTYVtUYV09YWFbVGEqKGJhKzUpKzRdO3JldHVybiBTYX1nZXRCb3hlc1lvbG9WNShhYSx4YSxiYSxTYSl7Y29uc3QgVGE9W107Zm9yKGxldCB3YT0wO3dhPHhhO3dhKyspe2NvbnN0IEVhPWFhW3dhKihiYSs1KSswXSxrYT1hYVt3YSooYmErNSkrMV0sQWE9YWFbd2EqKGJhKzUpKzJdLEZhPWFhW3dhKihiYSs1KSszXSxMYT1FYS1BYS8yLGVsPWthLUZhLzIsdGw9RWErQWEvMixubD1rYStGYS8yO1RhW3dhKjRdPWVsLFRhW3dhKjQrMV09TGEsVGFbd2EqNCsyXT1ubCxUYVt3YSo0KzNdPXRsfXJldHVybiBuZXcgRmxvYXQzMkFycmF5KFRhKX19ZnVuY3Rpb24gZ2V0RGV2aWNlUGl4ZWxSYXRpbygpe3JldHVybiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpb31mdW5jdGlvbiBnZXRVc2VyQWdlbnQoKXtyZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudH1mdW5jdGlvbiBnZXRQbGF0Zm9ybSgpe3JldHVybiBuYXZpZ2F0b3IucGxhdGZvcm19ZnVuY3Rpb24gZ2V0UGx1Z2lucygpe3JldHVybiBBcnJheS5mcm9tKG5hdmlnYXRvci5wbHVnaW5zKS5tYXAoaGE9PmAke2hhLm5hbWV9IC0gJHtoYS5maWxlbmFtZX1gKS5qb2luKCIsICIpfWFzeW5jIGZ1bmN0aW9uIGdldEhlYWRlcnMoKXtsZXQgaGE9YXdhaXQgZmV0Y2goImh0dHBzOi8vaHR0cGJpbi5vcmcvaGVhZGVycyIpLHtoZWFkZXJzOmFhfT1hd2FpdCBoYS5qc29uKCk7cmV0dXJuWyJBY2NlcHQiLCJBY2NlcHQtRW5jb2RpbmciLCJBY2NlcHQtTGFuZ3VhZ2UiLCJVc2VyLUFnZW50Il0ubWFwKHhhPT5gJHt4YX06ICR7YWFbeGFdfWApLmpvaW4oYApgKX1mdW5jdGlvbiBnZXREYXRlRm9ybWF0KCl7cmV0dXJuIG5ldyBEYXRlKDApLnRvU3RyaW5nKCl9ZnVuY3Rpb24gZ2V0Rm9udHMoKXtyZXR1cm5bIi1hcHBsZS1zeXN0ZW0iLCJCbGlua01hY1N5c3RlbUZvbnQiLCJDYW50YXJlbGwiLCJDb25zb2xhcyIsIkNvdXJpZXIgTmV3IiwiRHJvaWQgU2FucyIsIkZpcmEgU2FucyIsIkhlbHZldGljYSBOZXVlIiwiTWVubG8iLCJNb25hY28iLCJPeHlnZW4iLCJSb2JvdG8iLCJzb3VyY2UtY29kZS1wcm8iLCJTZWdvZSBVSSIsIlVidW50dSJdLmZpbHRlcihhYT0+ZG9jdW1lbnQuZm9udHMuY2hlY2soYDEycHggIiR7YWF9ImApKS5qb2luKCIsICIpfWZ1bmN0aW9uIGdldENhbnZhczJkUmVuZGVyKCl7bGV0IGhhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNhbnZhcyIpO2hhLndpZHRoPTIwMCxoYS5oZWlnaHQ9NTA7bGV0IGFhPWhhLmdldENvbnRleHQoIjJkIik7YWEuZm9udD0iMjEuNXB4IEFyaWFsIixhYS5maWxsVGV4dCgi8J+YiSIsMCwyMCksYWEuZm9udD0iMTUuN3B4IHNlcmlmIixhYS5maWxsVGV4dCgiYWJjZGVmZ2hpamtsbW5vcHFydHN1dnd4eXoiLDAsNDApLGFhLmZvbnQ9IjIwLjVweCBBcmlhbCI7bGV0IHhhPWFhLmNyZWF0ZUxpbmVhckdyYWRpZW50KDAsMCxoYS53aWR0aCxoYS5oZWlnaHQpO3JldHVybiB4YS5hZGRDb2xvclN0b3AoMCwicmVkIikseGEuYWRkQ29sb3JTdG9wKC41LCJncmVlbiIpLHhhLmFkZENvbG9yU3RvcCgxLCJibHVlIiksYWEuZmlsbFN0eWxlPXhhLGFhLmZpbGxUZXh0KCJMb3JlbSBpcHN1bSEiLDMwLDIwKSxhYS5iZWdpblBhdGgoKSxhYS5tb3ZlVG8oMTcwLDUpLGFhLmxpbmVUbygxNjAsMjUpLGFhLmxpbmVUbygxODUsMjApLGFhLmZpbGwoKSxoYS50b0RhdGFVUkwoKX1mdW5jdGlvbiBnZXRXZWJnbFJlbmRlcmVyKCl7bGV0IGFhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNhbnZhcyIpLmdldENvbnRleHQoIndlYmdsIik7aWYoIWFhKXJldHVybiBudWxsO2xldCB4YT1hYS5nZXRFeHRlbnNpb24oIldFQkdMX2RlYnVnX3JlbmRlcmVyX2luZm8iKTtyZXR1cm5bYWEuZ2V0UGFyYW1ldGVyKHhhLlVOTUFTS0VEX1ZFTkRPUl9XRUJHTCksYWEuZ2V0UGFyYW1ldGVyKHhhLlVOTUFTS0VEX1JFTkRFUkVSX1dFQkdMKV0uam9pbigiLCAiKX1mdW5jdGlvbiBnZXRXZWJnbFJlbmRlcigpe2xldCBoYT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKTtoYS53aWR0aD01MCxoYS5oZWlnaHQ9NTA7bGV0IGFhPWhhLmdldENvbnRleHQoIndlYmdsIik7aWYoIWFhKXJldHVybiBudWxsO2xldCB4YT1bWy0uMSwuOCwwXSxbLS44LC0uOCwwXSxbLjgsLS43LDBdXS5mbGF0KCksYmE9YWEuY3JlYXRlQnVmZmVyKCk7YWEuYmluZEJ1ZmZlcihhYS5BUlJBWV9CVUZGRVIsYmEpLGFhLmJ1ZmZlckRhdGEoYWEuQVJSQVlfQlVGRkVSLG5ldyBGbG9hdDMyQXJyYXkoeGEpLGFhLlNUQVRJQ19EUkFXKTtsZXQgU2E9WzAsMSwyXSxUYT1hYS5jcmVhdGVCdWZmZXIoKTthYS5iaW5kQnVmZmVyKGFhLkVMRU1FTlRfQVJSQVlfQlVGRkVSLFRhKSxhYS5idWZmZXJEYXRhKGFhLkVMRU1FTlRfQVJSQVlfQlVGRkVSLG5ldyBVaW50MTZBcnJheShTYSksYWEuU1RBVElDX0RSQVcpO2xldCB3YT1gCiAgICBhdHRyaWJ1dGUgdmVjMyBjb29yZGluYXRlczsKICAgIHZvaWQgbWFpbih2b2lkKSB7CiAgICAgIGdsX1Bvc2l0aW9uID0gdmVjNChjb29yZGluYXRlcywgMS4wKTsKICAgIH0KICAgYCxFYT1hYS5jcmVhdGVTaGFkZXIoYWEuVkVSVEVYX1NIQURFUik7YWEuc2hhZGVyU291cmNlKEVhLHdhKSxhYS5jb21waWxlU2hhZGVyKEVhKTtsZXQga2E9YAogICAgdm9pZCBtYWluKHZvaWQpIHsKICAgICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjUpOwogICAgfQogIGAsQWE9YWEuY3JlYXRlU2hhZGVyKGFhLkZSQUdNRU5UX1NIQURFUik7YWEuc2hhZGVyU291cmNlKEFhLGthKSxhYS5jb21waWxlU2hhZGVyKEFhKTtsZXQgRmE9YWEuY3JlYXRlUHJvZ3JhbSgpO2FhLmF0dGFjaFNoYWRlcihGYSxFYSksYWEuYXR0YWNoU2hhZGVyKEZhLEFhKSxhYS5saW5rUHJvZ3JhbShGYSksYWEudXNlUHJvZ3JhbShGYSk7bGV0IExhPWFhLmdldEF0dHJpYkxvY2F0aW9uKEZhLCJjb29yZGluYXRlcyIpO3JldHVybiBhYS52ZXJ0ZXhBdHRyaWJQb2ludGVyKExhLDMsYWEuRkxPQVQsITEsMCwwKSxhYS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShMYSksYWEuY2xlYXJDb2xvcigxLDEsMSwxKSxhYS5lbmFibGUoYWEuREVQVEhfVEVTVCksYWEuY2xlYXIoYWEuQ09MT1JfQlVGRkVSX0JJVCksYWEudmlld3BvcnQoMCwwLGhhLndpZHRoLGhhLmhlaWdodCksYWEuZHJhd0VsZW1lbnRzKGFhLlRSSUFOR0xFUyxTYS5sZW5ndGgsYWEuVU5TSUdORURfU0hPUlQsMCksaGEudG9EYXRhVVJMKCl9dmFyIHNoYTEkMT17ZXhwb3J0czp7fX07LyoKICogW2pzLXNoYTFde0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9lbW4xNzgvanMtc2hhMX0KICoKICogQHZlcnNpb24gMC42LjAKICogQGF1dGhvciBDaGVuLCBZaS1DeXVhbiBbZW1uMTc4QGdtYWlsLmNvbV0KICogQGNvcHlyaWdodCBDaGVuLCBZaS1DeXVhbiAyMDE0LTIwMTcKICogQGxpY2Vuc2UgTUlUCiAqLyhmdW5jdGlvbihtb2R1bGUpeyhmdW5jdGlvbigpe3ZhciByb290PXR5cGVvZiB3aW5kb3c9PSJvYmplY3QiP3dpbmRvdzp7fSxOT0RFX0pTPSFyb290LkpTX1NIQTFfTk9fTk9ERV9KUyYmdHlwZW9mIHByb2Nlc3M9PSJvYmplY3QiJiZwcm9jZXNzLnZlcnNpb25zJiZwcm9jZXNzLnZlcnNpb25zLm5vZGU7Tk9ERV9KUyYmKHJvb3Q9Y29tbW9uanNHbG9iYWwpO3ZhciBDT01NT05fSlM9IXJvb3QuSlNfU0hBMV9OT19DT01NT05fSlMmJiEwJiZtb2R1bGUuZXhwb3J0cyxIRVhfQ0hBUlM9IjAxMjM0NTY3ODlhYmNkZWYiLnNwbGl0KCIiKSxFWFRSQT1bLTIxNDc0ODM2NDgsODM4ODYwOCwzMjc2OCwxMjhdLFNISUZUPVsyNCwxNiw4LDBdLE9VVFBVVF9UWVBFUz1bImhleCIsImFycmF5IiwiZGlnZXN0IiwiYXJyYXlCdWZmZXIiXSxibG9ja3M9W10sY3JlYXRlT3V0cHV0TWV0aG9kPWZ1bmN0aW9uKGhhKXtyZXR1cm4gZnVuY3Rpb24oYWEpe3JldHVybiBuZXcgU2hhMSghMCkudXBkYXRlKGFhKVtoYV0oKX19LGNyZWF0ZU1ldGhvZD1mdW5jdGlvbigpe3ZhciBoYT1jcmVhdGVPdXRwdXRNZXRob2QoImhleCIpO05PREVfSlMmJihoYT1ub2RlV3JhcChoYSkpLGhhLmNyZWF0ZT1mdW5jdGlvbigpe3JldHVybiBuZXcgU2hhMX0saGEudXBkYXRlPWZ1bmN0aW9uKGJhKXtyZXR1cm4gaGEuY3JlYXRlKCkudXBkYXRlKGJhKX07Zm9yKHZhciBhYT0wO2FhPE9VVFBVVF9UWVBFUy5sZW5ndGg7KythYSl7dmFyIHhhPU9VVFBVVF9UWVBFU1thYV07aGFbeGFdPWNyZWF0ZU91dHB1dE1ldGhvZCh4YSl9cmV0dXJuIGhhfSxub2RlV3JhcD1mdW5jdGlvbihtZXRob2Qpe3ZhciBjcnlwdG89ZXZhbCgicmVxdWlyZSgnY3J5cHRvJykiKSxCdWZmZXI9ZXZhbCgicmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyIiksbm9kZU1ldGhvZD1mdW5jdGlvbihoYSl7aWYodHlwZW9mIGhhPT0ic3RyaW5nIilyZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goInNoYTEiKS51cGRhdGUoaGEsInV0ZjgiKS5kaWdlc3QoImhleCIpO2lmKGhhLmNvbnN0cnVjdG9yPT09QXJyYXlCdWZmZXIpaGE9bmV3IFVpbnQ4QXJyYXkoaGEpO2Vsc2UgaWYoaGEubGVuZ3RoPT09dm9pZCAwKXJldHVybiBtZXRob2QoaGEpO3JldHVybiBjcnlwdG8uY3JlYXRlSGFzaCgic2hhMSIpLnVwZGF0ZShuZXcgQnVmZmVyKGhhKSkuZGlnZXN0KCJoZXgiKX07cmV0dXJuIG5vZGVNZXRob2R9O2Z1bmN0aW9uIFNoYTEoaGEpe2hhPyhibG9ja3NbMF09YmxvY2tzWzE2XT1ibG9ja3NbMV09YmxvY2tzWzJdPWJsb2Nrc1szXT1ibG9ja3NbNF09YmxvY2tzWzVdPWJsb2Nrc1s2XT1ibG9ja3NbN109YmxvY2tzWzhdPWJsb2Nrc1s5XT1ibG9ja3NbMTBdPWJsb2Nrc1sxMV09YmxvY2tzWzEyXT1ibG9ja3NbMTNdPWJsb2Nrc1sxNF09YmxvY2tzWzE1XT0wLHRoaXMuYmxvY2tzPWJsb2Nrcyk6dGhpcy5ibG9ja3M9WzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF0sdGhpcy5oMD0xNzMyNTg0MTkzLHRoaXMuaDE9NDAyMzIzMzQxNyx0aGlzLmgyPTI1NjIzODMxMDIsdGhpcy5oMz0yNzE3MzM4NzgsdGhpcy5oND0zMjg1Mzc3NTIwLHRoaXMuYmxvY2s9dGhpcy5zdGFydD10aGlzLmJ5dGVzPXRoaXMuaEJ5dGVzPTAsdGhpcy5maW5hbGl6ZWQ9dGhpcy5oYXNoZWQ9ITEsdGhpcy5maXJzdD0hMH1TaGExLnByb3RvdHlwZS51cGRhdGU9ZnVuY3Rpb24oaGEpe2lmKCF0aGlzLmZpbmFsaXplZCl7dmFyIGFhPXR5cGVvZiBoYSE9InN0cmluZyI7YWEmJmhhLmNvbnN0cnVjdG9yPT09cm9vdC5BcnJheUJ1ZmZlciYmKGhhPW5ldyBVaW50OEFycmF5KGhhKSk7Zm9yKHZhciB4YSxiYT0wLFNhLFRhPWhhLmxlbmd0aHx8MCx3YT10aGlzLmJsb2NrcztiYTxUYTspe2lmKHRoaXMuaGFzaGVkJiYodGhpcy5oYXNoZWQ9ITEsd2FbMF09dGhpcy5ibG9jayx3YVsxNl09d2FbMV09d2FbMl09d2FbM109d2FbNF09d2FbNV09d2FbNl09d2FbN109d2FbOF09d2FbOV09d2FbMTBdPXdhWzExXT13YVsxMl09d2FbMTNdPXdhWzE0XT13YVsxNV09MCksYWEpZm9yKFNhPXRoaXMuc3RhcnQ7YmE8VGEmJlNhPDY0OysrYmEpd2FbU2E+PjJdfD1oYVtiYV08PFNISUZUW1NhKysmM107ZWxzZSBmb3IoU2E9dGhpcy5zdGFydDtiYTxUYSYmU2E8NjQ7KytiYSl4YT1oYS5jaGFyQ29kZUF0KGJhKSx4YTwxMjg/d2FbU2E+PjJdfD14YTw8U0hJRlRbU2ErKyYzXTp4YTwyMDQ4Pyh3YVtTYT4+Ml18PSgxOTJ8eGE+PjYpPDxTSElGVFtTYSsrJjNdLHdhW1NhPj4yXXw9KDEyOHx4YSY2Myk8PFNISUZUW1NhKysmM10pOnhhPDU1Mjk2fHx4YT49NTczNDQ/KHdhW1NhPj4yXXw9KDIyNHx4YT4+MTIpPDxTSElGVFtTYSsrJjNdLHdhW1NhPj4yXXw9KDEyOHx4YT4+NiY2Myk8PFNISUZUW1NhKysmM10sd2FbU2E+PjJdfD0oMTI4fHhhJjYzKTw8U0hJRlRbU2ErKyYzXSk6KHhhPTY1NTM2KygoeGEmMTAyMyk8PDEwfGhhLmNoYXJDb2RlQXQoKytiYSkmMTAyMyksd2FbU2E+PjJdfD0oMjQwfHhhPj4xOCk8PFNISUZUW1NhKysmM10sd2FbU2E+PjJdfD0oMTI4fHhhPj4xMiY2Myk8PFNISUZUW1NhKysmM10sd2FbU2E+PjJdfD0oMTI4fHhhPj42JjYzKTw8U0hJRlRbU2ErKyYzXSx3YVtTYT4+Ml18PSgxMjh8eGEmNjMpPDxTSElGVFtTYSsrJjNdKTt0aGlzLmxhc3RCeXRlSW5kZXg9U2EsdGhpcy5ieXRlcys9U2EtdGhpcy5zdGFydCxTYT49NjQ/KHRoaXMuYmxvY2s9d2FbMTZdLHRoaXMuc3RhcnQ9U2EtNjQsdGhpcy5oYXNoKCksdGhpcy5oYXNoZWQ9ITApOnRoaXMuc3RhcnQ9U2F9cmV0dXJuIHRoaXMuYnl0ZXM+NDI5NDk2NzI5NSYmKHRoaXMuaEJ5dGVzKz10aGlzLmJ5dGVzLzQyOTQ5NjcyOTY8PDAsdGhpcy5ieXRlcz10aGlzLmJ5dGVzJTQyOTQ5NjcyOTYpLHRoaXN9fSxTaGExLnByb3RvdHlwZS5maW5hbGl6ZT1mdW5jdGlvbigpe2lmKCF0aGlzLmZpbmFsaXplZCl7dGhpcy5maW5hbGl6ZWQ9ITA7dmFyIGhhPXRoaXMuYmxvY2tzLGFhPXRoaXMubGFzdEJ5dGVJbmRleDtoYVsxNl09dGhpcy5ibG9jayxoYVthYT4+Ml18PUVYVFJBW2FhJjNdLHRoaXMuYmxvY2s9aGFbMTZdLGFhPj01NiYmKHRoaXMuaGFzaGVkfHx0aGlzLmhhc2goKSxoYVswXT10aGlzLmJsb2NrLGhhWzE2XT1oYVsxXT1oYVsyXT1oYVszXT1oYVs0XT1oYVs1XT1oYVs2XT1oYVs3XT1oYVs4XT1oYVs5XT1oYVsxMF09aGFbMTFdPWhhWzEyXT1oYVsxM109aGFbMTRdPWhhWzE1XT0wKSxoYVsxNF09dGhpcy5oQnl0ZXM8PDN8dGhpcy5ieXRlcz4+PjI5LGhhWzE1XT10aGlzLmJ5dGVzPDwzLHRoaXMuaGFzaCgpfX0sU2hhMS5wcm90b3R5cGUuaGFzaD1mdW5jdGlvbigpe3ZhciBoYT10aGlzLmgwLGFhPXRoaXMuaDEseGE9dGhpcy5oMixiYT10aGlzLmgzLFNhPXRoaXMuaDQsVGEsd2EsRWEsa2E9dGhpcy5ibG9ja3M7Zm9yKHdhPTE2O3dhPDgwOysrd2EpRWE9a2Fbd2EtM11ea2Fbd2EtOF1ea2Fbd2EtMTRdXmthW3dhLTE2XSxrYVt3YV09RWE8PDF8RWE+Pj4zMTtmb3Iod2E9MDt3YTwyMDt3YSs9NSlUYT1hYSZ4YXx+YWEmYmEsRWE9aGE8PDV8aGE+Pj4yNyxTYT1FYStUYStTYSsxNTE4NTAwMjQ5K2thW3dhXTw8MCxhYT1hYTw8MzB8YWE+Pj4yLFRhPWhhJmFhfH5oYSZ4YSxFYT1TYTw8NXxTYT4+PjI3LGJhPUVhK1RhK2JhKzE1MTg1MDAyNDkra2Fbd2ErMV08PDAsaGE9aGE8PDMwfGhhPj4+MixUYT1TYSZoYXx+U2EmYWEsRWE9YmE8PDV8YmE+Pj4yNyx4YT1FYStUYSt4YSsxNTE4NTAwMjQ5K2thW3dhKzJdPDwwLFNhPVNhPDwzMHxTYT4+PjIsVGE9YmEmU2F8fmJhJmhhLEVhPXhhPDw1fHhhPj4+MjcsYWE9RWErVGErYWErMTUxODUwMDI0OStrYVt3YSszXTw8MCxiYT1iYTw8MzB8YmE+Pj4yLFRhPXhhJmJhfH54YSZTYSxFYT1hYTw8NXxhYT4+PjI3LGhhPUVhK1RhK2hhKzE1MTg1MDAyNDkra2Fbd2ErNF08PDAseGE9eGE8PDMwfHhhPj4+Mjtmb3IoO3dhPDQwO3dhKz01KVRhPWFhXnhhXmJhLEVhPWhhPDw1fGhhPj4+MjcsU2E9RWErVGErU2ErMTg1OTc3NTM5MytrYVt3YV08PDAsYWE9YWE8PDMwfGFhPj4+MixUYT1oYV5hYV54YSxFYT1TYTw8NXxTYT4+PjI3LGJhPUVhK1RhK2JhKzE4NTk3NzUzOTMra2Fbd2ErMV08PDAsaGE9aGE8PDMwfGhhPj4+MixUYT1TYV5oYV5hYSxFYT1iYTw8NXxiYT4+PjI3LHhhPUVhK1RhK3hhKzE4NTk3NzUzOTMra2Fbd2ErMl08PDAsU2E9U2E8PDMwfFNhPj4+MixUYT1iYV5TYV5oYSxFYT14YTw8NXx4YT4+PjI3LGFhPUVhK1RhK2FhKzE4NTk3NzUzOTMra2Fbd2ErM108PDAsYmE9YmE8PDMwfGJhPj4+MixUYT14YV5iYV5TYSxFYT1hYTw8NXxhYT4+PjI3LGhhPUVhK1RhK2hhKzE4NTk3NzUzOTMra2Fbd2ErNF08PDAseGE9eGE8PDMwfHhhPj4+Mjtmb3IoO3dhPDYwO3dhKz01KVRhPWFhJnhhfGFhJmJhfHhhJmJhLEVhPWhhPDw1fGhhPj4+MjcsU2E9RWErVGErU2EtMTg5NDAwNzU4OCtrYVt3YV08PDAsYWE9YWE8PDMwfGFhPj4+MixUYT1oYSZhYXxoYSZ4YXxhYSZ4YSxFYT1TYTw8NXxTYT4+PjI3LGJhPUVhK1RhK2JhLTE4OTQwMDc1ODgra2Fbd2ErMV08PDAsaGE9aGE8PDMwfGhhPj4+MixUYT1TYSZoYXxTYSZhYXxoYSZhYSxFYT1iYTw8NXxiYT4+PjI3LHhhPUVhK1RhK3hhLTE4OTQwMDc1ODgra2Fbd2ErMl08PDAsU2E9U2E8PDMwfFNhPj4+MixUYT1iYSZTYXxiYSZoYXxTYSZoYSxFYT14YTw8NXx4YT4+PjI3LGFhPUVhK1RhK2FhLTE4OTQwMDc1ODgra2Fbd2ErM108PDAsYmE9YmE8PDMwfGJhPj4+MixUYT14YSZiYXx4YSZTYXxiYSZTYSxFYT1hYTw8NXxhYT4+PjI3LGhhPUVhK1RhK2hhLTE4OTQwMDc1ODgra2Fbd2ErNF08PDAseGE9eGE8PDMwfHhhPj4+Mjtmb3IoO3dhPDgwO3dhKz01KVRhPWFhXnhhXmJhLEVhPWhhPDw1fGhhPj4+MjcsU2E9RWErVGErU2EtODk5NDk3NTE0K2thW3dhXTw8MCxhYT1hYTw8MzB8YWE+Pj4yLFRhPWhhXmFhXnhhLEVhPVNhPDw1fFNhPj4+MjcsYmE9RWErVGErYmEtODk5NDk3NTE0K2thW3dhKzFdPDwwLGhhPWhhPDwzMHxoYT4+PjIsVGE9U2FeaGFeYWEsRWE9YmE8PDV8YmE+Pj4yNyx4YT1FYStUYSt4YS04OTk0OTc1MTQra2Fbd2ErMl08PDAsU2E9U2E8PDMwfFNhPj4+MixUYT1iYV5TYV5oYSxFYT14YTw8NXx4YT4+PjI3LGFhPUVhK1RhK2FhLTg5OTQ5NzUxNCtrYVt3YSszXTw8MCxiYT1iYTw8MzB8YmE+Pj4yLFRhPXhhXmJhXlNhLEVhPWFhPDw1fGFhPj4+MjcsaGE9RWErVGEraGEtODk5NDk3NTE0K2thW3dhKzRdPDwwLHhhPXhhPDwzMHx4YT4+PjI7dGhpcy5oMD10aGlzLmgwK2hhPDwwLHRoaXMuaDE9dGhpcy5oMSthYTw8MCx0aGlzLmgyPXRoaXMuaDIreGE8PDAsdGhpcy5oMz10aGlzLmgzK2JhPDwwLHRoaXMuaDQ9dGhpcy5oNCtTYTw8MH0sU2hhMS5wcm90b3R5cGUuaGV4PWZ1bmN0aW9uKCl7dGhpcy5maW5hbGl6ZSgpO3ZhciBoYT10aGlzLmgwLGFhPXRoaXMuaDEseGE9dGhpcy5oMixiYT10aGlzLmgzLFNhPXRoaXMuaDQ7cmV0dXJuIEhFWF9DSEFSU1toYT4+MjgmMTVdK0hFWF9DSEFSU1toYT4+MjQmMTVdK0hFWF9DSEFSU1toYT4+MjAmMTVdK0hFWF9DSEFSU1toYT4+MTYmMTVdK0hFWF9DSEFSU1toYT4+MTImMTVdK0hFWF9DSEFSU1toYT4+OCYxNV0rSEVYX0NIQVJTW2hhPj40JjE1XStIRVhfQ0hBUlNbaGEmMTVdK0hFWF9DSEFSU1thYT4+MjgmMTVdK0hFWF9DSEFSU1thYT4+MjQmMTVdK0hFWF9DSEFSU1thYT4+MjAmMTVdK0hFWF9DSEFSU1thYT4+MTYmMTVdK0hFWF9DSEFSU1thYT4+MTImMTVdK0hFWF9DSEFSU1thYT4+OCYxNV0rSEVYX0NIQVJTW2FhPj40JjE1XStIRVhfQ0hBUlNbYWEmMTVdK0hFWF9DSEFSU1t4YT4+MjgmMTVdK0hFWF9DSEFSU1t4YT4+MjQmMTVdK0hFWF9DSEFSU1t4YT4+MjAmMTVdK0hFWF9DSEFSU1t4YT4+MTYmMTVdK0hFWF9DSEFSU1t4YT4+MTImMTVdK0hFWF9DSEFSU1t4YT4+OCYxNV0rSEVYX0NIQVJTW3hhPj40JjE1XStIRVhfQ0hBUlNbeGEmMTVdK0hFWF9DSEFSU1tiYT4+MjgmMTVdK0hFWF9DSEFSU1tiYT4+MjQmMTVdK0hFWF9DSEFSU1tiYT4+MjAmMTVdK0hFWF9DSEFSU1tiYT4+MTYmMTVdK0hFWF9DSEFSU1tiYT4+MTImMTVdK0hFWF9DSEFSU1tiYT4+OCYxNV0rSEVYX0NIQVJTW2JhPj40JjE1XStIRVhfQ0hBUlNbYmEmMTVdK0hFWF9DSEFSU1tTYT4+MjgmMTVdK0hFWF9DSEFSU1tTYT4+MjQmMTVdK0hFWF9DSEFSU1tTYT4+MjAmMTVdK0hFWF9DSEFSU1tTYT4+MTYmMTVdK0hFWF9DSEFSU1tTYT4+MTImMTVdK0hFWF9DSEFSU1tTYT4+OCYxNV0rSEVYX0NIQVJTW1NhPj40JjE1XStIRVhfQ0hBUlNbU2EmMTVdfSxTaGExLnByb3RvdHlwZS50b1N0cmluZz1TaGExLnByb3RvdHlwZS5oZXgsU2hhMS5wcm90b3R5cGUuZGlnZXN0PWZ1bmN0aW9uKCl7dGhpcy5maW5hbGl6ZSgpO3ZhciBoYT10aGlzLmgwLGFhPXRoaXMuaDEseGE9dGhpcy5oMixiYT10aGlzLmgzLFNhPXRoaXMuaDQ7cmV0dXJuW2hhPj4yNCYyNTUsaGE+PjE2JjI1NSxoYT4+OCYyNTUsaGEmMjU1LGFhPj4yNCYyNTUsYWE+PjE2JjI1NSxhYT4+OCYyNTUsYWEmMjU1LHhhPj4yNCYyNTUseGE+PjE2JjI1NSx4YT4+OCYyNTUseGEmMjU1LGJhPj4yNCYyNTUsYmE+PjE2JjI1NSxiYT4+OCYyNTUsYmEmMjU1LFNhPj4yNCYyNTUsU2E+PjE2JjI1NSxTYT4+OCYyNTUsU2EmMjU1XX0sU2hhMS5wcm90b3R5cGUuYXJyYXk9U2hhMS5wcm90b3R5cGUuZGlnZXN0LFNoYTEucHJvdG90eXBlLmFycmF5QnVmZmVyPWZ1bmN0aW9uKCl7dGhpcy5maW5hbGl6ZSgpO3ZhciBoYT1uZXcgQXJyYXlCdWZmZXIoMjApLGFhPW5ldyBEYXRhVmlldyhoYSk7cmV0dXJuIGFhLnNldFVpbnQzMigwLHRoaXMuaDApLGFhLnNldFVpbnQzMig0LHRoaXMuaDEpLGFhLnNldFVpbnQzMig4LHRoaXMuaDIpLGFhLnNldFVpbnQzMigxMix0aGlzLmgzKSxhYS5zZXRVaW50MzIoMTYsdGhpcy5oNCksaGF9O3ZhciBleHBvcnRzPWNyZWF0ZU1ldGhvZCgpO0NPTU1PTl9KUz9tb2R1bGUuZXhwb3J0cz1leHBvcnRzOnJvb3Quc2hhMT1leHBvcnRzfSkoKX0pKHNoYTEkMSk7dmFyIHNoYTFFeHBvcnRzPXNoYTEkMS5leHBvcnRzLHNoYTE9Z2V0RGVmYXVsdEV4cG9ydEZyb21DanMoc2hhMUV4cG9ydHMpO2FzeW5jIGZ1bmN0aW9uIHJ1bkNhdGNoaW5nKGhhKXt0cnl7cmV0dXJuIGF3YWl0IGhhKCl9Y2F0Y2h7cmV0dXJuIG51bGx9fWFzeW5jIGZ1bmN0aW9uIGNvbXB1dGVTdGFibGVDb21wb25lbnRzKCl7cmV0dXJue2RldmljZVBpeGVsUmF0aW86YXdhaXQgcnVuQ2F0Y2hpbmcoZ2V0RGV2aWNlUGl4ZWxSYXRpbyksdXNlckFnZW50OmF3YWl0IHJ1bkNhdGNoaW5nKGdldFVzZXJBZ2VudCkscGxhdGZvcm06YXdhaXQgcnVuQ2F0Y2hpbmcoZ2V0UGxhdGZvcm0pLHBsdWdpbnM6YXdhaXQgcnVuQ2F0Y2hpbmcoZ2V0UGx1Z2lucyksaGVhZGVyczphd2FpdCBydW5DYXRjaGluZyhnZXRIZWFkZXJzKSxkYXRlRm9ybWF0OmF3YWl0IHJ1bkNhdGNoaW5nKGdldERhdGVGb3JtYXQpLGZvbnRzOmF3YWl0IHJ1bkNhdGNoaW5nKGdldEZvbnRzKSxjYW52YXMyZFJlbmRlcjphd2FpdCBydW5DYXRjaGluZyhnZXRDYW52YXMyZFJlbmRlciksd2ViZ2xSZW5kZXJlcjphd2FpdCBydW5DYXRjaGluZyhnZXRXZWJnbFJlbmRlcmVyKSx3ZWJnbFJlbmRlcjphd2FpdCBydW5DYXRjaGluZyhnZXRXZWJnbFJlbmRlcil9fWFzeW5jIGZ1bmN0aW9uIGNvbXB1dGVGaW5nZXJwcmludCgpe2xldCBoYT1hd2FpdCBjb21wdXRlU3RhYmxlQ29tcG9uZW50cygpLGFhPU9iamVjdC52YWx1ZXMoaGEpLm1hcChTdHJpbmcpLmpvaW4oYApgKTtyZXR1cm4gc2hhMShhYSl9Y2xhc3MgRGVmYXVsdFJGREVUUk9wdGlvbnN7Y29uc3RydWN0b3IoYWEpe3RoaXMubW9kZWw9bnVsbCx0aGlzLnNpemU9Mzg0LHRoaXMubWF4TnVtQm94ZXM9MjAsdGhpcy5zY29yZVRocmVzaG9sZD0uNSx0aGlzLmNsYXNzZXM9W10sdGhpcy5jb2xvcnM9e30sdGhpcy51cGRhdGUoYWEpfXVwZGF0ZShhYSl7dGhpcy5tb2RlbD1hYS5tb2RlbD8/dGhpcy5tb2RlbCx0aGlzLnNpemU9YWEuc2l6ZT8/dGhpcy5zaXplLHRoaXMubWF4TnVtQm94ZXM9YWEubWF4TnVtQm94ZXM/P3RoaXMubWF4TnVtQm94ZXMsdGhpcy5zY29yZVRocmVzaG9sZD1hYS5zY29yZVRocmVzaG9sZD8/dGhpcy5zY29yZVRocmVzaG9sZCx0aGlzLmNsYXNzZXM9YWEuY2xhc3Nlcz8/dGhpcy5jbGFzc2VzLHRoaXMuY29sb3JzPWFhLmNvbG9ycz8/dGhpcy5jb2xvcnN9fWNsYXNzIFJGRGV0ciBleHRlbmRzIENWTW9kZWx7Y29uc3RydWN0b3IoYWEpe3N1cGVyKCksdGhpcy5hc3luY19tb2RlbD0hMSx0aGlzLmltYWdlbmV0TWVhbnM9dGVuc29yKFsuNDg1LC40NTYsLjQwNl0sWzEsMSwzXSksdGhpcy5pbWFnZW5ldFN0ZHM9dGVuc29yKFsuMjI5LC4yMjQsLjIyNV0sWzEsMSwzXSksdGhpcy5vcHRpb25zPW5ldyBEZWZhdWx0UkZERVRST3B0aW9ucyhhYSl9YXN5bmMgaW5pdGlhbGl6ZSgpe2NvbnN0IGFhPW5ldyBKU09OSGFuZGxlcih0aGlzLm9wdGlvbnMubW9kZWwpO3RoaXMubW9kZWw9YXdhaXQgbG9hZEdyYXBoTW9kZWwoYWEpO2NvbnN0IHhhPXRoaXMuemVyb3MoKTt2YXIgYmE7dHJ5e2JhPXRoaXMubW9kZWwuZXhlY3V0ZSh4YSl9Y2F0Y2h7YmE9YXdhaXQgdGhpcy5tb2RlbC5leGVjdXRlQXN5bmMoeGEpLHRoaXMuYXN5bmNfbW9kZWw9ITB9ZGlzcG9zZSQxKGJhKSxkaXNwb3NlJDEoeGEpfWNvbmZpZ3VyZShhYSl7dGhpcy5vcHRpb25zLnVwZGF0ZShhYSl9emVyb3MoKXtyZXR1cm4gemVyb3MkMihbMSx0aGlzLm9wdGlvbnMuc2l6ZSx0aGlzLm9wdGlvbnMuc2l6ZSwzXSwiZmxvYXQzMiIpfWFzeW5jIHByZXByb2Nlc3MoYWEpe2xldCB4YT1hd2FpdCBhYS50ZW5zb3I0RCgpLGJhPXRpZHkkMSgoKT0+e2NvbnN0IFNhPXhhLnJlc2l6ZU5lYXJlc3ROZWlnaGJvcihbdGhpcy5vcHRpb25zLnNpemUsdGhpcy5vcHRpb25zLnNpemVdKS5hc1R5cGUoImZsb2F0MzIiKSxUYT1kaXYkMihTYSwyNTUpLHdhPXN1YiQ0KFRhLHRoaXMuaW1hZ2VuZXRNZWFucyk7cmV0dXJuIGRpdiQyKHdhLHRoaXMuaW1hZ2VuZXRTdGRzKX0pO3JldHVybiB4YS5kaXNwb3NlKCksYmF9YXN5bmMgaW5mZXIoYWEpe2xldCB4YT1hd2FpdCB0aGlzLnByZXByb2Nlc3MoYWEpO2lmKHBlcmZvcm1hbmNlLm5vdygpLCF0aGlzLm1vZGVsKXRocm93IG5ldyBFcnJvcigiTW9kZWwgbm90IGxvYWRlZCIpO2NvbnN0IGJhPXRoaXMuYXN5bmNfbW9kZWw/YXdhaXQgdGhpcy5tb2RlbC5leGVjdXRlQXN5bmMoeGEpOnRoaXMubW9kZWwuZXhlY3V0ZSh4YSksU2E9dGhpcy5tb2RlbC5vdXRwdXRzLm1hcChMYT0+TGEubmFtZSksVGE9U2EuaW5kZXhPZigiSWRlbnRpdHkiKSx3YT1TYS5pbmRleE9mKCJJZGVudGl0eV8xIik7bGV0IEVhLGthO2lmKFRhIT09LTEmJndhIT09LTEpRWE9YmFbVGFdLGthPWJhW3dhXTtlbHNle2NvbnN0IExhPWJhWzBdLnNoYXBlW2JhWzBdLnNoYXBlLmxlbmd0aC0xXSxlbD1iYVsxXS5zaGFwZVtiYVsxXS5zaGFwZS5sZW5ndGgtMV07aWYoTGE9PT00JiZlbCE9PTQpRWE9YmFbMF0sa2E9YmFbMV07ZWxzZSBpZihlbD09PTQmJkxhIT09NClFYT1iYVsxXSxrYT1iYVswXTtlbHNle2NvbnN0IHRsPWJhWzBdLmRhdGFTeW5jKCk7YmFbMV0uZGF0YVN5bmMoKTtjb25zdCBubD1NYXRoLm1pbigxMDAsdGwubGVuZ3RoKSxzbD1BcnJheS5mcm9tKHRsLnNsaWNlKDAsbmwpKS5zb21lKHJsPT5ybDwtMSk7RWE9c2w/YmFbMV06YmFbMF0sa2E9c2w/YmFbMF06YmFbMV19fWNvbnN0IEFhPXNpZ21vaWQkNChrYSksRmE9dGhpcy5wcm9jZXNzRGV0ZWN0aW9ucyhFYS5kYXRhU3luYygpLEFhLmRhdGFTeW5jKCksRWEuc2hhcGUsQWEuc2hhcGUsdGhpcy5vcHRpb25zLnNjb3JlVGhyZXNob2xkLGFhLmRpbXMoKVswXSxhYS5kaW1zKClbMV0pO3JldHVybiB4YS5kaXNwb3NlKCksYmEuZm9yRWFjaChMYT0+TGEuZGlzcG9zZSgpKSxBYS5kaXNwb3NlKCksRWEuZGlzcG9zZSgpLGthLmRpc3Bvc2UoKSxGYX1wcm9jZXNzRGV0ZWN0aW9ucyhhYSx4YSxiYSxTYSxUYSx3YSxFYSl7Y29uc3Rba2EsQWEsRmFdPWJhLFssLExhXT1TYSxlbD1bXSx0bD10aGlzLm9wdGlvbnMuY2xhc3Nlcy5sZW5ndGg+MD90aGlzLm9wdGlvbnMuY2xhc3NlczpBcnJheS5mcm9tKHtsZW5ndGg6TGF9LChubCxzbCk9PmBjbGFzc18ke3NsfWApO2ZvcihsZXQgbmw9MDtubDxBYTtubCsrKXtjb25zdCBzbD1ubCo0LHJsPWFhW3NsKzBdKndhLG9sPWFhW3NsKzFdKkVhLGFsPWFhW3NsKzJdKndhLGxsPWFhW3NsKzNdKkVhLGlsPW5sKkxhO2xldCBjbD0wO2NvbnN0IGRsPXRsLmxlbmd0aD4wJiZ0bFswXS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCJiYWNrZ3JvdW5kIik/MTowO2xldCBobD1kbDtjb25zdCBwbD1NYXRoLm1pbih0bC5sZW5ndGgsTGEpO2ZvcihsZXQgZmw9ZGw7Zmw8cGw7ZmwrKyl7Y29uc3QgbWw9eGFbaWwrZmxdO21sPmNsJiYoY2w9bWwsaGw9ZmwpfWNsPlRhJiZobDx0bC5sZW5ndGgmJmVsLnB1c2goe2Jib3g6e3g6cmwseTpvbCx3aWR0aDphbCxoZWlnaHQ6bGx9LGNsYXNzOnRsW2hsXSxjb25maWRlbmNlOmNsLGNvbG9yOnRoaXMub3B0aW9ucy5jb2xvcnNbdGxbaGxdXX0pfXJldHVybiBlbC5zb3J0KChubCxzbCk9PnNsLmNvbmZpZGVuY2UtbmwuY29uZmlkZW5jZSksZWx9fWNsYXNzIFlPTE92MTEgZXh0ZW5kcyBZT0xPdjh7emVyb3MoKXtyZXR1cm4gemVyb3MkMihbMSx0aGlzLm9wdGlvbnMuc2l6ZSx0aGlzLm9wdGlvbnMuc2l6ZSwzXSwiZmxvYXQzMiIpfWFzeW5jIHByZXByb2Nlc3MoYWEpe2xldCB4YT1hd2FpdCBhYS50ZW5zb3I0RCgpLGJhPXRpZHkkMSgoKT0+ZGl2JDIoeGEucmVzaXplTmVhcmVzdE5laWdoYm9yKFt0aGlzLm9wdGlvbnMuc2l6ZSx0aGlzLm9wdGlvbnMuc2l6ZV0pLmFzVHlwZSgiZmxvYXQzMiIpLDI1NSkpO3JldHVybiB4YS5kaXNwb3NlKCksYmF9fWNsYXNzIFlPTE8yNiBleHRlbmRzIFlPTE92OHt6ZXJvcygpe3JldHVybiB6ZXJvcyQyKFsxLHRoaXMub3B0aW9ucy5zaXplLHRoaXMub3B0aW9ucy5zaXplLDNdLCJmbG9hdDMyIil9YXN5bmMgcHJlcHJvY2VzcyhhYSl7bGV0IHhhPWF3YWl0IGFhLnRlbnNvcjREKCksYmE9dGlkeSQxKCgpPT5kaXYkMih4YS5yZXNpemVOZWFyZXN0TmVpZ2hib3IoW3RoaXMub3B0aW9ucy5zaXplLHRoaXMub3B0aW9ucy5zaXplXSkuYXNUeXBlKCJmbG9hdDMyIiksMjU1KSk7cmV0dXJuIHhhLmRpc3Bvc2UoKSxiYX1hc3luYyBpbmZlcihhYSl7bGV0IHhhPWF3YWl0IHRoaXMucHJlcHJvY2VzcyhhYSk7aWYoIXRoaXMubW9kZWwpdGhyb3cgbmV3IEVycm9yKCJNb2RlbCBub3QgbG9hZGVkIik7Y29uc3QgYmE9dGhpcy5hc3luY19tb2RlbD9hd2FpdCB0aGlzLm1vZGVsLmV4ZWN1dGVBc3luYyh4YSk6dGhpcy5tb2RlbC5leGVjdXRlKHhhKSxTYT1BcnJheS5pc0FycmF5KGJhKT9iYVswXTpiYSxUYT1TYS5kYXRhU3luYygpLHdhPVNhLnNoYXBlWzFdO3JldHVybiBkaXNwb3NlJDEoeGEpLGRpc3Bvc2UkMShiYSksdGhpcy5idWlsZERldGVjdGVkT2JqZWN0c0Zyb21Qb3N0cHJvY2Vzc2VkKGFhLmRpbXMoKVswXSxhYS5kaW1zKClbMV0sVGEsd2EpfWJ1aWxkRGV0ZWN0ZWRPYmplY3RzRnJvbVBvc3Rwcm9jZXNzZWQoYWEseGEsYmEsU2Epe2NvbnN0IFRhPVtdLHdhPXRoaXMub3B0aW9ucy5zaXplO2ZvcihsZXQgRWE9MDtFYTxTYTtFYSsrKXtjb25zdCBrYT1iYVtFYSo2KzBdL3dhLEFhPWJhW0VhKjYrMV0vd2EsRmE9YmFbRWEqNisyXS93YSxMYT1iYVtFYSo2KzNdL3dhLGVsPWJhW0VhKjYrNF0sdGw9TWF0aC5yb3VuZChiYVtFYSo2KzVdKTtpZihlbDx0aGlzLm9wdGlvbnMuc2NvcmVUaHJlc2hvbGQpY29udGludWU7Y29uc3Qgbmw9KGthK0ZhKS8yKmFhLHNsPShBYStMYSkvMip4YSxybD0oRmEta2EpKmFhLG9sPShMYS1BYSkqeGE7aWYoVGEucHVzaCh7Y2xhc3M6dGhpcy5vcHRpb25zLmNsYXNzZXNbdGxdLGNvbmZpZGVuY2U6ZWwsYmJveDp7eDpubCx5OnNsLHdpZHRoOnJsLGhlaWdodDpvbH0sY29sb3I6dGhpcy5vcHRpb25zLmNvbG9ycz90aGlzLm9wdGlvbnMuY29sb3JzW3RoaXMub3B0aW9ucy5jbGFzc2VzW3RsXV06IiMwMDAifSksVGEubGVuZ3RoPj10aGlzLm9wdGlvbnMubWF4TnVtQm94ZXMpYnJlYWt9cmV0dXJuIFRhfX1jb25zdCBJTUFHRU5FVF9NRUFOUz1bLjQ4NSwuNDU2LC40MDZdLElNQUdFTkVUX1NURFM9Wy4yMjksLjIyNCwuMjI1XSxPVVRQVVRfS0VZUz1bImJveGVzIiwic2NvcmVzIiwiY2xhc3NlcyJdO2NsYXNzIFlPTE9MaXRlIGV4dGVuZHMgWU9MT3Y4e2NvbnN0cnVjdG9yKCl7c3VwZXIoLi4uYXJndW1lbnRzKSx0aGlzLl9vdXRwdXROYW1lcz1bXSx0aGlzLl9jYWNoZWRUaHJlc2hvbGRzPW51bGx9emVyb3MoKXtyZXR1cm4gemVyb3MkMihbMSx0aGlzLm9wdGlvbnMuc2l6ZSx0aGlzLm9wdGlvbnMuc2l6ZSwzXSl9YXN5bmMgaW5pdGlhbGl6ZSgpe2NvbnN0e0pTT05IYW5kbGVyOmFhfT1hd2FpdCBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGpzb25IYW5kbGVyfSkseGE9bmV3IGFhKHRoaXMub3B0aW9ucy5tb2RlbCk7dGhpcy5tb2RlbD1hd2FpdCBsb2FkR3JhcGhNb2RlbCh4YSk7Y29uc3QgYmE9dGhpcy5tb2RlbC5zaWduYXR1cmU7aWYoYmEhPW51bGwmJmJhLm91dHB1dHMmJih0aGlzLl9vdXRwdXROYW1lcz1PVVRQVVRfS0VZUy5tYXAoRWE9Pnt2YXIga2E7cmV0dXJuKGthPWJhLm91dHB1dHNbRWFdKT09bnVsbD92b2lkIDA6a2EubmFtZX0pLmZpbHRlcihCb29sZWFuKSksdGhpcy5fb3V0cHV0TmFtZXMubGVuZ3RoIT09T1VUUFVUX0tFWVMubGVuZ3RoKXRocm93IG5ldyBFcnJvcihgWU9MT0xpdGU6IG1vZGVsIHNpZ25hdHVyZSBtaXNzaW5nIG91dHB1dHMgKGV4cGVjdGVkICR7T1VUUFVUX0tFWVMuam9pbigiLCAiKX0sIGdvdCAke3RoaXMuX291dHB1dE5hbWVzLmxlbmd0aH0pYCk7Y29uc3QgU2E9dGhpcy56ZXJvcygpLFRhPXRoaXMuX2J1aWxkSW5wdXRzKFNhKSx3YT1hd2FpdCB0aGlzLm1vZGVsLmV4ZWN1dGVBc3luYyhUYSx0aGlzLl9vdXRwdXROYW1lcyk7ZGlzcG9zZSQxKHdhKSxTYS5kaXNwb3NlKCl9YXN5bmMgcHJlcHJvY2VzcyhhYSl7bGV0IHhhPWF3YWl0IGFhLnRlbnNvcjREKCksYmE9dGlkeSQxKCgpPT57Y29uc3QgU2E9eGEucmVzaXplTmVhcmVzdE5laWdoYm9yKFt0aGlzLm9wdGlvbnMuc2l6ZSx0aGlzLm9wdGlvbnMuc2l6ZV0pLmFzVHlwZSgiZmxvYXQzMiIpLFRhPWRpdiQyKFNhLDI1NSksd2E9dGVuc29yKElNQUdFTkVUX01FQU5TLFsxLDEsM10pLEVhPXRlbnNvcihJTUFHRU5FVF9TVERTLFsxLDEsM10pO3JldHVybiBkaXYkMihzdWIkNChUYSx3YSksRWEpfSk7cmV0dXJuIHhhLmRpc3Bvc2UoKSxiYX1hc3luYyBpbmZlcihhYSl7Y29uc3RbeGEsYmFdPWFhLmRpbXMoKSxTYT1hd2FpdCB0aGlzLnByZXByb2Nlc3MoYWEpO2lmKCF0aGlzLm1vZGVsKXRocm93IG5ldyBFcnJvcigiTW9kZWwgbm90IGxvYWRlZCIpO2NvbnN0IFRhPXRoaXMuX2J1aWxkSW5wdXRzKFNhKTtsZXQgd2E7dHJ5e2NvbnN0IEVhPWF3YWl0IHRoaXMubW9kZWwuZXhlY3V0ZUFzeW5jKFRhLHRoaXMuX291dHB1dE5hbWVzKTt3YT1BcnJheS5pc0FycmF5KEVhKT9FYTpbRWFdfWZpbmFsbHl7U2EuZGlzcG9zZSgpfXRyeXtjb25zdFtFYSxrYSxBYV09d2EsRmE9RWEuZGF0YVN5bmMoKSxMYT1rYS5kYXRhU3luYygpLGVsPUFhLmRhdGFTeW5jKCksdGw9dGhpcy5vcHRpb25zLnNpemUsbmw9W107Zm9yKGxldCBzbD0wO3NsPExhLmxlbmd0aDtzbCsrKXtjb25zdCBybD1GYVtzbCo0XS90bCxvbD1GYVtzbCo0KzFdL3RsLGFsPUZhW3NsKjQrMl0vdGwsbGw9RmFbc2wqNCszXS90bCxpbD1lbFtzbF07bmwucHVzaCh7Y2xhc3M6dGhpcy5vcHRpb25zLmNsYXNzZXNbaWxdLGNvbmZpZGVuY2U6TGFbc2xdLGJib3g6e3g6KHJsK2FsKS8yKnhhLHk6KG9sK2xsKS8yKmJhLHdpZHRoOihhbC1ybCkqeGEsaGVpZ2h0OihsbC1vbCkqYmF9LGNvbG9yOnRoaXMub3B0aW9ucy5jb2xvcnM/dGhpcy5vcHRpb25zLmNvbG9yc1t0aGlzLm9wdGlvbnMuY2xhc3Nlc1tpbF1dOiIjMDAwIn0pfXJldHVybiBubH1maW5hbGx5e3dhLmZvckVhY2goRWE9PkVhLmRpc3Bvc2UoKSl9fV9idWlsZElucHV0cyhhYSl7Y29uc3QgeGE9dGhpcy5fZ2V0VGhyZXNob2xkcygpO3JldHVybntpbWFnZXM6YWEsaW91X3RocmVzaG9sZDp4YS5pb3Usc2NvcmVfdGhyZXNob2xkOnhhLnNjb3JlfX1fZ2V0VGhyZXNob2xkcygpe2NvbnN0IGFhPXRoaXMub3B0aW9ucy5pb3VUaHJlc2hvbGQseGE9dGhpcy5vcHRpb25zLnNjb3JlVGhyZXNob2xkO3JldHVybiB0aGlzLl9jYWNoZWRUaHJlc2hvbGRzJiZ0aGlzLl9jYWNoZWRUaHJlc2hvbGRzLmlvdVZhbD09PWFhJiZ0aGlzLl9jYWNoZWRUaHJlc2hvbGRzLnNjb3JlVmFsPT09eGE/dGhpcy5fY2FjaGVkVGhyZXNob2xkczoodGhpcy5fY2FjaGVkVGhyZXNob2xkcyYmKHRoaXMuX2NhY2hlZFRocmVzaG9sZHMuaW91LmRpc3Bvc2UoKSx0aGlzLl9jYWNoZWRUaHJlc2hvbGRzLnNjb3JlLmRpc3Bvc2UoKSksdGhpcy5fY2FjaGVkVGhyZXNob2xkcz17aW91OnNjYWxhciQxKGFhLCJmbG9hdDMyIiksc2NvcmU6c2NhbGFyJDEoeGEsImZsb2F0MzIiKSxpb3VWYWw6YWEsc2NvcmVWYWw6eGF9LHRoaXMuX2NhY2hlZFRocmVzaG9sZHMpfX1jbGFzcyBSb2JvZmxvd3tjb25zdHJ1Y3RvcihhYSx4YSxiYSxTYSxUYSx3YSl7dGhpcy5maW5nZXJwcmludD0iIix0aGlzLnVybD1hYSx0aGlzLmRhdGFzZXQ9eGEsdGhpcy52ZXJzaW9uPWJhLHRoaXMubW9kZWxJZD13YSx0aGlzLnB1Ymxpc2hhYmxlX2tleT1TYSx0aGlzLm9wdGlvbnM9VGE/T2JqZWN0LmFzc2lnbih7fSwuLi5UYSk6e319YXN5bmMgZ2VuZXJhdGVGaW5nZXJwcmludCgpe3RoaXMuZmluZ2VycHJpbnQ9YXdhaXQgY29tcHV0ZUZpbmdlcnByaW50KCl9aGFzaENvZGUoYWEpe2Zvcih2YXIgeGE9MCxiYT0wO2JhPGFhLmxlbmd0aDtiYSsrKXt2YXIgU2E9YWEuY2hhckNvZGVBdChiYSk7eGE9KHhhPDw1KS14YStTYSx4YT14YSZ4YX1yZXR1cm4geGF9YXN5bmMgZmV0Y2hBbmRMb2FkTW9kZWwoKXthd2FpdCB0aGlzLmdlbmVyYXRlRmluZ2VycHJpbnQoKTtsZXQgYWE9YXdhaXQgdGhpcy5mZXRjaFdlaWdodHMoKTtjb25zdCB4YT1bIm9iamVjdC1kZXRlY3Rpb24iXSxiYT17Imluc3RhbmNlLXNlZ21lbnRhdGlvbiI6Ikluc3RhbmNlIHNlZ21lbnRhdGlvbiBtb2RlbHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gaW5mZXJlbmNlanMuIFBsZWFzZSB1c2UgQHJvYm9mbG93L2luZmVyZW5jZS1zZGsgaW5zdGVhZDogaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvQHJvYm9mbG93L2luZmVyZW5jZS1zZGsiLCJzZW1hbnRpYy1zZWdtZW50YXRpb24iOiJTZW1hbnRpYyBzZWdtZW50YXRpb24gbW9kZWxzIGFyZSBub3Qgc3VwcG9ydGVkIGluIGluZmVyZW5jZWpzLiBQbGVhc2UgdXNlIEByb2JvZmxvdy9pbmZlcmVuY2Utc2RrIGluc3RlYWQ6IGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL0Byb2JvZmxvdy9pbmZlcmVuY2Utc2RrIiwia2V5cG9pbnQtZGV0ZWN0aW9uIjoiS2V5cG9pbnQgZGV0ZWN0aW9uIG1vZGVscyBhcmUgbm90IHN1cHBvcnRlZCBpbiBpbmZlcmVuY2Vqcy4gUGxlYXNlIHVzZSBAcm9ib2Zsb3cvaW5mZXJlbmNlLXNkayBpbnN0ZWFkOiBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9Acm9ib2Zsb3cvaW5mZXJlbmNlLXNkayIsY2xhc3NpZmljYXRpb246IkNsYXNzaWZpY2F0aW9uIG1vZGVscyBhcmUgbm90IHN1cHBvcnRlZCBpbiBpbmZlcmVuY2Vqcy4gUGxlYXNlIHVzZSBAcm9ib2Zsb3cvaW5mZXJlbmNlLXNkayBpbnN0ZWFkOiBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9Acm9ib2Zsb3cvaW5mZXJlbmNlLXNkayJ9O2lmKGFhLnR5cGUmJmJhW2FhLnR5cGVdKXRocm93IG5ldyBFcnJvcihiYVthYS50eXBlXSk7aWYoYWEudHlwZSYmIXhhLmluY2x1ZGVzKGFhLnR5cGUpKXRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdGFzayB0eXBlOiAiJHthYS50eXBlfSIuIE9ubHkgb2JqZWN0IGRldGVjdGlvbiBtb2RlbHMgYXJlIGN1cnJlbnRseSBzdXBwb3J0ZWQgaW4gaW5mZXJlbmNlanMuIFBsZWFzZSB1c2UgQHJvYm9mbG93L2luZmVyZW5jZS1zZGsgaW5zdGVhZDogaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvQHJvYm9mbG93L2luZmVyZW5jZS1zZGtgKTtpZihhYS5tb2RlbFR5cGUuc3RhcnRzV2l0aCgieW9sb3Y4IikpcmV0dXJuIG5ldyBZT0xPdjgoey4uLmFhLC4uLnRoaXMub3B0aW9uc30pO2lmKGFhLm1vZGVsVHlwZS5zdGFydHNXaXRoKCJ5b2xvdjUiKSlyZXR1cm4gbmV3IFlPTE92NSh7Li4uYWEsLi4udGhpcy5vcHRpb25zfSk7aWYoYWEubW9kZWxUeXBlLnN0YXJ0c1dpdGgoInJmZGV0ciIpKXJldHVybiBuZXcgUkZEZXRyKHsuLi5hYSwuLi50aGlzLm9wdGlvbnN9KTtpZihhYS5tb2RlbFR5cGUuc3RhcnRzV2l0aCgieW9sb3YxMSIpKXJldHVybiBuZXcgWU9MT3YxMSh7Li4uYWEsLi4udGhpcy5vcHRpb25zfSk7aWYoYWEubW9kZWxUeXBlLnN0YXJ0c1dpdGgoInlvbG92MjYiKXx8YWEubW9kZWxUeXBlLnN0YXJ0c1dpdGgoInlvbG8yNiIpKXJldHVybiBuZXcgWU9MTzI2KHsuLi5hYSwuLi50aGlzLm9wdGlvbnN9KTtpZihhYS5tb2RlbFR5cGUuc3RhcnRzV2l0aCgieW9sb2xpdGUiKSlyZXR1cm4gbmV3IFlPTE9MaXRlKHsuLi5hYSwuLi50aGlzLm9wdGlvbnN9KTt0aHJvdyBuZXcgRXJyb3IoIlVuc3VwcG9ydGVkIG1vZGVsIHR5cGU6ICIrYWEubW9kZWxUeXBlKyIuIE9ubHkgeW9sb3Y1LCB5b2xvdjgsIHlvbG92MTEsIHlvbG8yNiwgeW9sb2xpdGUsIGFuZCByZmRldHIgbW9kZWxzIGFyZSBjdXJyZW50bHkgc3VwcG9ydGVkLiIpfWFzeW5jIGZldGNoV2VpZ2h0cygpe3ZhciBhYT10aGlzLnVybCsiL3RmanMiLHhhPXRoaXMubW9kZWxJZD9bYWEsIm1vZGVsIix0aGlzLm1vZGVsSWRdLmpvaW4oIi8iKTpbYWEsdGhpcy5kYXRhc2V0LHRoaXMudmVyc2lvbl0uam9pbigiLyIpLGJhPXhhKyI/IituZXcgVVJMU2VhcmNoUGFyYW1zKHtwdWJsaXNoYWJsZV9rZXk6dGhpcy5wdWJsaXNoYWJsZV9rZXksaG9zdDp0eXBlb2Ygd2luZG93PCJ1Ij93aW5kb3cubG9jYXRpb24uaG9zdDp0eXBlb2Ygc2VsZiE9bnVsbCYmc2VsZi5sb2NhdGlvbiE9bnVsbD9zZWxmLmxvY2F0aW9uLmhvc3Q6Im5vZGUiLHU6dGhpcy5maW5nZXJwcmludH0pO2xldCBTYT1hd2FpdCBmZXRjaChiYSkuY2F0Y2goZnVuY3Rpb24oRWEpe3Rocm93IG5ldyBFcnJvcigiRXJyb3IgaGFwcGVuZWQgd2hpbGUgcmVxdWVzdGluZyBtb2RlbCBtZXRhZGF0YS4gIitKU09OLnN0cmluZ2lmeShFYSkpfSk7aWYoIVNhLm9rKXtjb25zdCBFYT1hd2FpdCBTYS50ZXh0KCk7dGhyb3cgbmV3IEVycm9yKGBFcnJvciBoYXBwZW5lZCB3aGlsZSByZXF1ZXN0aW5nIG1vZGVsIG1ldGFkYXRhLiBTdGF0dXM6ICR7U2Euc3RhdHVzfSwgUmVzcG9uc2U6ICR7RWF9YCl9bGV0IFRhPWF3YWl0IFNhLmpzb24oKTtpZihjb25zb2xlLmxvZygiQVBJIFJlc3BvbnNlOiIsVGEpLGNvbnNvbGUubG9nKCJBUEkgVVJMOiIsYmEpLFRhLmVycm9yfHwhKFRhIT1udWxsJiZUYS50ZmpzKSl0aHJvdyBuZXcgRXJyb3IoIkVycm9yIGhhcHBlbmVkIHdoaWxlIHBhcnNpbmcgbW9kZWwgbWV0YWRhdGEuIFJlc3BvbnNlOiAiK0pTT04uc3RyaW5naWZ5KFRhKSsiLCBVUkw6ICIrYmEpO3ZhciB3YT1UYS50ZmpzO3JldHVybiB3YX19bGV0IG1vZGVsPW51bGwsbW9kZWxJbml0aWFsaXplZD0hMTthc3luYyBmdW5jdGlvbiBpbml0TW9kZWwoaGEsYWEseGEsYmEsU2EsVGE9W10sd2Epe2NvbnN0IEVhPSEhd2Esa2E9RWE/d2E6YCR7eGF9LyR7YmF9YDt0cnl7IUVhJiZrYT09ImdhemUvMSI/bW9kZWw9bmV3IEdhemU6bW9kZWw9YXdhaXQoRWE/bmV3IFJvYm9mbG93KGhhLHhhLGAke2JhfWAsU2EsVGEsd2EpOm5ldyBSb2JvZmxvdyhoYSx4YSxiYS50b1N0cmluZygpLFNhLFRhKSkuZmV0Y2hBbmRMb2FkTW9kZWwoKX1jYXRjaChBYSl7dGhyb3cgbmV3IEVycm9yKGBFcnJvciBsb2FkaW5nIG1vZGVsICR7a2F9OiAke0FhfWApfXJldHVybiBhd2FpdCBtb2RlbC5pbml0aWFsaXplKGFhLEVhP3dhOnhhLGJhLFNhLCExLC4uLlRhKSxtb2RlbH1zZWxmLm9ubWVzc2FnZT1hc3luYyBmdW5jdGlvbiBoYShhYSl7Y29uc3QgeGE9YWEuZGF0YSxiYT14YS5yZXFJZDt0cnl7c3dpdGNoKHhhLmNtZCl7Y2FzZSJpbml0Ijphd2FpdCBpbml0TW9kZWwoeGEudXJsLHhhLndvcmtlcklkLHhhLm1vZGVsTmFtZSx4YS5tb2RlbFZlcnNpb24seGEucHVibGlzaGFibGVLZXkseGEub3B0aW9ucyx4YS5tb2RlbElkKSxtb2RlbEluaXRpYWxpemVkPSEwLHNlbGYucG9zdE1lc3NhZ2Uoe3JlcUlkOmJhLGNtZDp4YS5jbWQscmVzOiJtb2RlbCBpbml0aWFsaXplZCIsc3RhdHVzOjIwMH0pO2JyZWFrO2Nhc2UiaW5mZXIiOmlmKCFtb2RlbEluaXRpYWxpemVkfHwhbW9kZWwpdGhyb3cgbmV3IE1vZGVsTm90SW5pdGlhbGl6ZWQoIk1vZGVsIG5vdCBpbml0aWFsaXplZCIpO2lmKERhdGUubm93KCkteGEudGltZXN0YW1wPk1BWF9SRVFVRVNUX0FHRSl0aHJvdyBuZXcgUmVxdWVzdFRvb09sZChgUmVxdWVzdCBpcyBvbGRlciB0aGFuICR7TUFYX1JFUVVFU1RfQUdFfSBtcy5gKTtjb25zdCBTYT1uZXcgQ1ZJbWFnZSh4YS5pbWcpO3hhLm9wdGlvbnMmJm1vZGVsLmNvbmZpZ3VyZSguLi54YS5vcHRpb25zKTtjb25zdCBUYT1hd2FpdCBtb2RlbC5pbmZlcihTYSk7U2EuZGlzcG9zZSgpLHNlbGYucG9zdE1lc3NhZ2Uoe3JlcUlkOmJhLGNtZDp4YS5jbWQscmVzOlRhLHN0YXR1czoyMDB9KTticmVha319Y2F0Y2goU2Epe2lmKFNhIGluc3RhbmNlb2YgSW5mZXJlbmNlRXJyb3IpcmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uoe3JlcUlkOmJhLGNtZDp4YS5jbWQscmVzOlNhLm1lc3NhZ2Usc3RhdHVzOlNhLmNvZGV9KTtpZih4YS5jbWQ9PSJpbml0IilyZXR1cm4gY29uc29sZS5lcnJvcihTYSksc2VsZi5wb3N0TWVzc2FnZSh7cmVxSWQ6YmEsY21kOnhhLmNtZCxyZXM6Ik1vZGVsIGluaXRpYWxpemF0aW9uIGZhaWxlZCIsc3RhdHVzOjUwMH0pO3Rocm93IFNhfX19KSgpOwo=\", tv = (I) => Uint8Array.from(atob(I), (l) => l.charCodeAt(0)), Xi = typeof window < \"u\" && window.Blob && new Blob([tv(dn)], { type: \"text/javascript;charset=utf-8\" });\nfunction uv(I) {\n  let l;\n  try {\n    if (l = Xi && (window.URL || window.webkitURL).createObjectURL(Xi), !l) throw \"\";\n    const G = new Worker(l, {\n      name: I == null ? void 0 : I.name\n    });\n    return G.addEventListener(\"error\", () => {\n      (window.URL || window.webkitURL).revokeObjectURL(l);\n    }), G;\n  } catch {\n    return new Worker(\n      \"data:text/javascript;base64,\" + dn,\n      {\n        name: I == null ? void 0 : I.name\n      }\n    );\n  } finally {\n    l && (window.URL || window.webkitURL).revokeObjectURL(l);\n  }\n}\nvar Q0, lZ, _Z, gc, UI, NZ, LW, MW;\nclass Nv {\n  constructor(l = \"https://api.roboflow.com\") {\n    MZ(this, NZ);\n    MZ(this, Q0, 0);\n    MZ(this, lZ, {});\n    MZ(this, _Z);\n    MZ(this, gc, 0);\n    MZ(this, UI, {});\n    this.url = l;\n    try {\n      const G = Math.min(navigator.hardwareConcurrency, Bi);\n      ib(this, _Z, G);\n    } catch {\n      ib(this, _Z, Bi);\n    }\n  }\n  async startWorker(l, G, Z, h = []) {\n    const g = `worker_${mb(this, Q0)._++}_${l}_${G}`;\n    return B0(this, NZ, MW).call(this, g, {\n      modelName: l,\n      modelVersion: G,\n      publishableKey: Z,\n      options: h\n    });\n  }\n  /**\n   * Load a model by its full model id (`{workspace}/{model-slug}`) — the id shown on\n   * the model page, which covers versionless / MMPV models. For legacy models\n   * addressed by project + integer version, use {@link startWorker}.\n   */\n  async startWorkerByModelId(l, G, Z = []) {\n    const h = `worker_${mb(this, Q0)._++}_${l}`;\n    return B0(this, NZ, MW).call(this, h, {\n      modelName: \"\",\n      modelVersion: 0,\n      modelId: l,\n      publishableKey: G,\n      options: Z\n    });\n  }\n  async stopWorker(l) {\n    const G = uG(this, lZ)[l];\n    if (!G)\n      throw new Ci(`Worker ${l} not found.`);\n    return G.terminate(), delete uG(this, lZ)[l], delete uG(this, UI)[l], !0;\n  }\n  async infer(l, G, Z = null) {\n    try {\n      return G instanceof x9 && (G = await G.bitmap()), await B0(this, NZ, LW).call(this, l, { cmd: \"infer\", img: G, options: Z }, [G]);\n    } catch (h) {\n      throw new Xv(h);\n    }\n  }\n}\nQ0 = new WeakMap(), lZ = new WeakMap(), _Z = new WeakMap(), gc = new WeakMap(), UI = new WeakMap(), NZ = new WeakSet(), LW = async function(l, G, Z = []) {\n  const h = uG(this, lZ)[l];\n  if (!h)\n    throw new Ci(`Worker ${l} not found.`);\n  if (Object.keys(uG(this, UI)[l]).length >= ni)\n    throw new nv(\n      `Cannot run more than ${ni} concurrent requests per worker.`\n    );\n  const g = mb(this, gc)._++, b = { ...G, reqId: g, timestamp: Date.now() };\n  return new Promise(async (c, d) => {\n    uG(this, UI)[l][g] = { accept: c, reject: d }, h.postMessage(b, Z);\n  }).then((c) => c).catch((c) => {\n    if (c === \"Model initialization failed\")\n      throw new Error(\"Model initialization failed\");\n    return c;\n  }).finally(() => {\n    delete uG(this, UI)[l][g];\n  });\n}, MW = async function(l, G) {\n  if (Object.keys(uG(this, lZ)).length >= uG(this, _Z))\n    throw new Bv(`Cannot create more than ${uG(this, _Z)} workers.`);\n  const Z = this;\n  uG(this, UI)[l] = {};\n  function h(b) {\n    const c = b.data, d = c.reqId, W = uG(Z, UI)[l][d];\n    c.status != 200 ? (console.log(`Request ${d} failed in worker ${l}: ${c.res}`), W.reject(c.res)) : W.accept(c.res);\n  }\n  const g = new uv();\n  return g.addEventListener(\"message\", h), uG(this, lZ)[l] = g, B0(this, NZ, LW).call(this, l, {\n    cmd: \"init\",\n    url: this.url,\n    workerId: l,\n    ...G\n  }).then((b) => l).catch((b) => {\n    throw g.terminate(), delete uG(this, lZ)[l], delete uG(this, UI)[l], new Cv(b);\n  });\n};\nclass Pv {\n}\nexport {\n  x9 as CVImage,\n  Nv as InferenceEngine,\n  Pv as YOLOOptions\n};\n"]}