qrcode.js 238 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.QRCode = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  2. // can-promise has a crash in some versions of react native that dont have
  3. // standard global objects
  4. // https://github.com/soldair/node-qrcode/issues/157
  5. module.exports = function () {
  6. return typeof Promise === 'function' && Promise.prototype && Promise.prototype.then
  7. }
  8. },{}],2:[function(require,module,exports){
  9. /**
  10. * Alignment pattern are fixed reference pattern in defined positions
  11. * in a matrix symbology, which enables the decode software to re-synchronise
  12. * the coordinate mapping of the image modules in the event of moderate amounts
  13. * of distortion of the image.
  14. *
  15. * Alignment patterns are present only in QR Code symbols of version 2 or larger
  16. * and their number depends on the symbol version.
  17. */
  18. var getSymbolSize = require('./utils').getSymbolSize
  19. /**
  20. * Calculate the row/column coordinates of the center module of each alignment pattern
  21. * for the specified QR Code version.
  22. *
  23. * The alignment patterns are positioned symmetrically on either side of the diagonal
  24. * running from the top left corner of the symbol to the bottom right corner.
  25. *
  26. * Since positions are simmetrical only half of the coordinates are returned.
  27. * Each item of the array will represent in turn the x and y coordinate.
  28. * @see {@link getPositions}
  29. *
  30. * @param {Number} version QR Code version
  31. * @return {Array} Array of coordinate
  32. */
  33. exports.getRowColCoords = function getRowColCoords (version) {
  34. if (version === 1) return []
  35. var posCount = Math.floor(version / 7) + 2
  36. var size = getSymbolSize(version)
  37. var intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2
  38. var positions = [size - 7] // Last coord is always (size - 7)
  39. for (var i = 1; i < posCount - 1; i++) {
  40. positions[i] = positions[i - 1] - intervals
  41. }
  42. positions.push(6) // First coord is always 6
  43. return positions.reverse()
  44. }
  45. /**
  46. * Returns an array containing the positions of each alignment pattern.
  47. * Each array's element represent the center point of the pattern as (x, y) coordinates
  48. *
  49. * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
  50. * and filtering out the items that overlaps with finder pattern
  51. *
  52. * @example
  53. * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
  54. * The alignment patterns, therefore, are to be centered on (row, column)
  55. * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
  56. * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
  57. * and are not therefore used for alignment patterns.
  58. *
  59. * var pos = getPositions(7)
  60. * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
  61. *
  62. * @param {Number} version QR Code version
  63. * @return {Array} Array of coordinates
  64. */
  65. exports.getPositions = function getPositions (version) {
  66. var coords = []
  67. var pos = exports.getRowColCoords(version)
  68. var posLength = pos.length
  69. for (var i = 0; i < posLength; i++) {
  70. for (var j = 0; j < posLength; j++) {
  71. // Skip if position is occupied by finder patterns
  72. if ((i === 0 && j === 0) || // top-left
  73. (i === 0 && j === posLength - 1) || // bottom-left
  74. (i === posLength - 1 && j === 0)) { // top-right
  75. continue
  76. }
  77. coords.push([pos[i], pos[j]])
  78. }
  79. }
  80. return coords
  81. }
  82. },{"./utils":21}],3:[function(require,module,exports){
  83. var Mode = require('./mode')
  84. /**
  85. * Array of characters available in alphanumeric mode
  86. *
  87. * As per QR Code specification, to each character
  88. * is assigned a value from 0 to 44 which in this case coincides
  89. * with the array index
  90. *
  91. * @type {Array}
  92. */
  93. var ALPHA_NUM_CHARS = [
  94. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  95. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  96. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  97. ' ', '$', '%', '*', '+', '-', '.', '/', ':'
  98. ]
  99. function AlphanumericData (data) {
  100. this.mode = Mode.ALPHANUMERIC
  101. this.data = data
  102. }
  103. AlphanumericData.getBitsLength = function getBitsLength (length) {
  104. return 11 * Math.floor(length / 2) + 6 * (length % 2)
  105. }
  106. AlphanumericData.prototype.getLength = function getLength () {
  107. return this.data.length
  108. }
  109. AlphanumericData.prototype.getBitsLength = function getBitsLength () {
  110. return AlphanumericData.getBitsLength(this.data.length)
  111. }
  112. AlphanumericData.prototype.write = function write (bitBuffer) {
  113. var i
  114. // Input data characters are divided into groups of two characters
  115. // and encoded as 11-bit binary codes.
  116. for (i = 0; i + 2 <= this.data.length; i += 2) {
  117. // The character value of the first character is multiplied by 45
  118. var value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45
  119. // The character value of the second digit is added to the product
  120. value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1])
  121. // The sum is then stored as 11-bit binary number
  122. bitBuffer.put(value, 11)
  123. }
  124. // If the number of input data characters is not a multiple of two,
  125. // the character value of the final character is encoded as a 6-bit binary number.
  126. if (this.data.length % 2) {
  127. bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6)
  128. }
  129. }
  130. module.exports = AlphanumericData
  131. },{"./mode":14}],4:[function(require,module,exports){
  132. function BitBuffer () {
  133. this.buffer = []
  134. this.length = 0
  135. }
  136. BitBuffer.prototype = {
  137. get: function (index) {
  138. var bufIndex = Math.floor(index / 8)
  139. return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) === 1
  140. },
  141. put: function (num, length) {
  142. for (var i = 0; i < length; i++) {
  143. this.putBit(((num >>> (length - i - 1)) & 1) === 1)
  144. }
  145. },
  146. getLengthInBits: function () {
  147. return this.length
  148. },
  149. putBit: function (bit) {
  150. var bufIndex = Math.floor(this.length / 8)
  151. if (this.buffer.length <= bufIndex) {
  152. this.buffer.push(0)
  153. }
  154. if (bit) {
  155. this.buffer[bufIndex] |= (0x80 >>> (this.length % 8))
  156. }
  157. this.length++
  158. }
  159. }
  160. module.exports = BitBuffer
  161. },{}],5:[function(require,module,exports){
  162. var Buffer = require('../utils/buffer')
  163. /**
  164. * Helper class to handle QR Code symbol modules
  165. *
  166. * @param {Number} size Symbol size
  167. */
  168. function BitMatrix (size) {
  169. if (!size || size < 1) {
  170. throw new Error('BitMatrix size must be defined and greater than 0')
  171. }
  172. this.size = size
  173. this.data = new Buffer(size * size)
  174. this.data.fill(0)
  175. this.reservedBit = new Buffer(size * size)
  176. this.reservedBit.fill(0)
  177. }
  178. /**
  179. * Set bit value at specified location
  180. * If reserved flag is set, this bit will be ignored during masking process
  181. *
  182. * @param {Number} row
  183. * @param {Number} col
  184. * @param {Boolean} value
  185. * @param {Boolean} reserved
  186. */
  187. BitMatrix.prototype.set = function (row, col, value, reserved) {
  188. var index = row * this.size + col
  189. this.data[index] = value
  190. if (reserved) this.reservedBit[index] = true
  191. }
  192. /**
  193. * Returns bit value at specified location
  194. *
  195. * @param {Number} row
  196. * @param {Number} col
  197. * @return {Boolean}
  198. */
  199. BitMatrix.prototype.get = function (row, col) {
  200. return this.data[row * this.size + col]
  201. }
  202. /**
  203. * Applies xor operator at specified location
  204. * (used during masking process)
  205. *
  206. * @param {Number} row
  207. * @param {Number} col
  208. * @param {Boolean} value
  209. */
  210. BitMatrix.prototype.xor = function (row, col, value) {
  211. this.data[row * this.size + col] ^= value
  212. }
  213. /**
  214. * Check if bit at specified location is reserved
  215. *
  216. * @param {Number} row
  217. * @param {Number} col
  218. * @return {Boolean}
  219. */
  220. BitMatrix.prototype.isReserved = function (row, col) {
  221. return this.reservedBit[row * this.size + col]
  222. }
  223. module.exports = BitMatrix
  224. },{"../utils/buffer":28}],6:[function(require,module,exports){
  225. var Buffer = require('../utils/buffer')
  226. var Mode = require('./mode')
  227. function ByteData (data) {
  228. this.mode = Mode.BYTE
  229. this.data = new Buffer(data)
  230. }
  231. ByteData.getBitsLength = function getBitsLength (length) {
  232. return length * 8
  233. }
  234. ByteData.prototype.getLength = function getLength () {
  235. return this.data.length
  236. }
  237. ByteData.prototype.getBitsLength = function getBitsLength () {
  238. return ByteData.getBitsLength(this.data.length)
  239. }
  240. ByteData.prototype.write = function (bitBuffer) {
  241. for (var i = 0, l = this.data.length; i < l; i++) {
  242. bitBuffer.put(this.data[i], 8)
  243. }
  244. }
  245. module.exports = ByteData
  246. },{"../utils/buffer":28,"./mode":14}],7:[function(require,module,exports){
  247. var ECLevel = require('./error-correction-level')
  248. var EC_BLOCKS_TABLE = [
  249. // L M Q H
  250. 1, 1, 1, 1,
  251. 1, 1, 1, 1,
  252. 1, 1, 2, 2,
  253. 1, 2, 2, 4,
  254. 1, 2, 4, 4,
  255. 2, 4, 4, 4,
  256. 2, 4, 6, 5,
  257. 2, 4, 6, 6,
  258. 2, 5, 8, 8,
  259. 4, 5, 8, 8,
  260. 4, 5, 8, 11,
  261. 4, 8, 10, 11,
  262. 4, 9, 12, 16,
  263. 4, 9, 16, 16,
  264. 6, 10, 12, 18,
  265. 6, 10, 17, 16,
  266. 6, 11, 16, 19,
  267. 6, 13, 18, 21,
  268. 7, 14, 21, 25,
  269. 8, 16, 20, 25,
  270. 8, 17, 23, 25,
  271. 9, 17, 23, 34,
  272. 9, 18, 25, 30,
  273. 10, 20, 27, 32,
  274. 12, 21, 29, 35,
  275. 12, 23, 34, 37,
  276. 12, 25, 34, 40,
  277. 13, 26, 35, 42,
  278. 14, 28, 38, 45,
  279. 15, 29, 40, 48,
  280. 16, 31, 43, 51,
  281. 17, 33, 45, 54,
  282. 18, 35, 48, 57,
  283. 19, 37, 51, 60,
  284. 19, 38, 53, 63,
  285. 20, 40, 56, 66,
  286. 21, 43, 59, 70,
  287. 22, 45, 62, 74,
  288. 24, 47, 65, 77,
  289. 25, 49, 68, 81
  290. ]
  291. var EC_CODEWORDS_TABLE = [
  292. // L M Q H
  293. 7, 10, 13, 17,
  294. 10, 16, 22, 28,
  295. 15, 26, 36, 44,
  296. 20, 36, 52, 64,
  297. 26, 48, 72, 88,
  298. 36, 64, 96, 112,
  299. 40, 72, 108, 130,
  300. 48, 88, 132, 156,
  301. 60, 110, 160, 192,
  302. 72, 130, 192, 224,
  303. 80, 150, 224, 264,
  304. 96, 176, 260, 308,
  305. 104, 198, 288, 352,
  306. 120, 216, 320, 384,
  307. 132, 240, 360, 432,
  308. 144, 280, 408, 480,
  309. 168, 308, 448, 532,
  310. 180, 338, 504, 588,
  311. 196, 364, 546, 650,
  312. 224, 416, 600, 700,
  313. 224, 442, 644, 750,
  314. 252, 476, 690, 816,
  315. 270, 504, 750, 900,
  316. 300, 560, 810, 960,
  317. 312, 588, 870, 1050,
  318. 336, 644, 952, 1110,
  319. 360, 700, 1020, 1200,
  320. 390, 728, 1050, 1260,
  321. 420, 784, 1140, 1350,
  322. 450, 812, 1200, 1440,
  323. 480, 868, 1290, 1530,
  324. 510, 924, 1350, 1620,
  325. 540, 980, 1440, 1710,
  326. 570, 1036, 1530, 1800,
  327. 570, 1064, 1590, 1890,
  328. 600, 1120, 1680, 1980,
  329. 630, 1204, 1770, 2100,
  330. 660, 1260, 1860, 2220,
  331. 720, 1316, 1950, 2310,
  332. 750, 1372, 2040, 2430
  333. ]
  334. /**
  335. * Returns the number of error correction block that the QR Code should contain
  336. * for the specified version and error correction level.
  337. *
  338. * @param {Number} version QR Code version
  339. * @param {Number} errorCorrectionLevel Error correction level
  340. * @return {Number} Number of error correction blocks
  341. */
  342. exports.getBlocksCount = function getBlocksCount (version, errorCorrectionLevel) {
  343. switch (errorCorrectionLevel) {
  344. case ECLevel.L:
  345. return EC_BLOCKS_TABLE[(version - 1) * 4 + 0]
  346. case ECLevel.M:
  347. return EC_BLOCKS_TABLE[(version - 1) * 4 + 1]
  348. case ECLevel.Q:
  349. return EC_BLOCKS_TABLE[(version - 1) * 4 + 2]
  350. case ECLevel.H:
  351. return EC_BLOCKS_TABLE[(version - 1) * 4 + 3]
  352. default:
  353. return undefined
  354. }
  355. }
  356. /**
  357. * Returns the number of error correction codewords to use for the specified
  358. * version and error correction level.
  359. *
  360. * @param {Number} version QR Code version
  361. * @param {Number} errorCorrectionLevel Error correction level
  362. * @return {Number} Number of error correction codewords
  363. */
  364. exports.getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel) {
  365. switch (errorCorrectionLevel) {
  366. case ECLevel.L:
  367. return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0]
  368. case ECLevel.M:
  369. return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1]
  370. case ECLevel.Q:
  371. return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2]
  372. case ECLevel.H:
  373. return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3]
  374. default:
  375. return undefined
  376. }
  377. }
  378. },{"./error-correction-level":8}],8:[function(require,module,exports){
  379. exports.L = { bit: 1 }
  380. exports.M = { bit: 0 }
  381. exports.Q = { bit: 3 }
  382. exports.H = { bit: 2 }
  383. function fromString (string) {
  384. if (typeof string !== 'string') {
  385. throw new Error('Param is not a string')
  386. }
  387. var lcStr = string.toLowerCase()
  388. switch (lcStr) {
  389. case 'l':
  390. case 'low':
  391. return exports.L
  392. case 'm':
  393. case 'medium':
  394. return exports.M
  395. case 'q':
  396. case 'quartile':
  397. return exports.Q
  398. case 'h':
  399. case 'high':
  400. return exports.H
  401. default:
  402. throw new Error('Unknown EC Level: ' + string)
  403. }
  404. }
  405. exports.isValid = function isValid (level) {
  406. return level && typeof level.bit !== 'undefined' &&
  407. level.bit >= 0 && level.bit < 4
  408. }
  409. exports.from = function from (value, defaultValue) {
  410. if (exports.isValid(value)) {
  411. return value
  412. }
  413. try {
  414. return fromString(value)
  415. } catch (e) {
  416. return defaultValue
  417. }
  418. }
  419. },{}],9:[function(require,module,exports){
  420. var getSymbolSize = require('./utils').getSymbolSize
  421. var FINDER_PATTERN_SIZE = 7
  422. /**
  423. * Returns an array containing the positions of each finder pattern.
  424. * Each array's element represent the top-left point of the pattern as (x, y) coordinates
  425. *
  426. * @param {Number} version QR Code version
  427. * @return {Array} Array of coordinates
  428. */
  429. exports.getPositions = function getPositions (version) {
  430. var size = getSymbolSize(version)
  431. return [
  432. // top-left
  433. [0, 0],
  434. // top-right
  435. [size - FINDER_PATTERN_SIZE, 0],
  436. // bottom-left
  437. [0, size - FINDER_PATTERN_SIZE]
  438. ]
  439. }
  440. },{"./utils":21}],10:[function(require,module,exports){
  441. var Utils = require('./utils')
  442. var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)
  443. var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
  444. var G15_BCH = Utils.getBCHDigit(G15)
  445. /**
  446. * Returns format information with relative error correction bits
  447. *
  448. * The format information is a 15-bit sequence containing 5 data bits,
  449. * with 10 error correction bits calculated using the (15, 5) BCH code.
  450. *
  451. * @param {Number} errorCorrectionLevel Error correction level
  452. * @param {Number} mask Mask pattern
  453. * @return {Number} Encoded format information bits
  454. */
  455. exports.getEncodedBits = function getEncodedBits (errorCorrectionLevel, mask) {
  456. var data = ((errorCorrectionLevel.bit << 3) | mask)
  457. var d = data << 10
  458. while (Utils.getBCHDigit(d) - G15_BCH >= 0) {
  459. d ^= (G15 << (Utils.getBCHDigit(d) - G15_BCH))
  460. }
  461. // xor final data with mask pattern in order to ensure that
  462. // no combination of Error Correction Level and data mask pattern
  463. // will result in an all-zero data string
  464. return ((data << 10) | d) ^ G15_MASK
  465. }
  466. },{"./utils":21}],11:[function(require,module,exports){
  467. var Buffer = require('../utils/buffer')
  468. var EXP_TABLE
  469. var LOG_TABLE
  470. if (Buffer.alloc) {
  471. EXP_TABLE = Buffer.alloc(512)
  472. LOG_TABLE = Buffer.alloc(256)
  473. } else {
  474. EXP_TABLE = new Buffer(512)
  475. LOG_TABLE = new Buffer(256)
  476. }
  477. /**
  478. * Precompute the log and anti-log tables for faster computation later
  479. *
  480. * For each possible value in the galois field 2^8, we will pre-compute
  481. * the logarithm and anti-logarithm (exponential) of this value
  482. *
  483. * ref {@link https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#Introduction_to_mathematical_fields}
  484. */
  485. ;(function initTables () {
  486. var x = 1
  487. for (var i = 0; i < 255; i++) {
  488. EXP_TABLE[i] = x
  489. LOG_TABLE[x] = i
  490. x <<= 1 // multiply by 2
  491. // The QR code specification says to use byte-wise modulo 100011101 arithmetic.
  492. // This means that when a number is 256 or larger, it should be XORed with 0x11D.
  493. if (x & 0x100) { // similar to x >= 256, but a lot faster (because 0x100 == 256)
  494. x ^= 0x11D
  495. }
  496. }
  497. // Optimization: double the size of the anti-log table so that we don't need to mod 255 to
  498. // stay inside the bounds (because we will mainly use this table for the multiplication of
  499. // two GF numbers, no more).
  500. // @see {@link mul}
  501. for (i = 255; i < 512; i++) {
  502. EXP_TABLE[i] = EXP_TABLE[i - 255]
  503. }
  504. }())
  505. /**
  506. * Returns log value of n inside Galois Field
  507. *
  508. * @param {Number} n
  509. * @return {Number}
  510. */
  511. exports.log = function log (n) {
  512. if (n < 1) throw new Error('log(' + n + ')')
  513. return LOG_TABLE[n]
  514. }
  515. /**
  516. * Returns anti-log value of n inside Galois Field
  517. *
  518. * @param {Number} n
  519. * @return {Number}
  520. */
  521. exports.exp = function exp (n) {
  522. return EXP_TABLE[n]
  523. }
  524. /**
  525. * Multiplies two number inside Galois Field
  526. *
  527. * @param {Number} x
  528. * @param {Number} y
  529. * @return {Number}
  530. */
  531. exports.mul = function mul (x, y) {
  532. if (x === 0 || y === 0) return 0
  533. // should be EXP_TABLE[(LOG_TABLE[x] + LOG_TABLE[y]) % 255] if EXP_TABLE wasn't oversized
  534. // @see {@link initTables}
  535. return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]]
  536. }
  537. },{"../utils/buffer":28}],12:[function(require,module,exports){
  538. var Mode = require('./mode')
  539. var Utils = require('./utils')
  540. function KanjiData (data) {
  541. this.mode = Mode.KANJI
  542. this.data = data
  543. }
  544. KanjiData.getBitsLength = function getBitsLength (length) {
  545. return length * 13
  546. }
  547. KanjiData.prototype.getLength = function getLength () {
  548. return this.data.length
  549. }
  550. KanjiData.prototype.getBitsLength = function getBitsLength () {
  551. return KanjiData.getBitsLength(this.data.length)
  552. }
  553. KanjiData.prototype.write = function (bitBuffer) {
  554. var i
  555. // In the Shift JIS system, Kanji characters are represented by a two byte combination.
  556. // These byte values are shifted from the JIS X 0208 values.
  557. // JIS X 0208 gives details of the shift coded representation.
  558. for (i = 0; i < this.data.length; i++) {
  559. var value = Utils.toSJIS(this.data[i])
  560. // For characters with Shift JIS values from 0x8140 to 0x9FFC:
  561. if (value >= 0x8140 && value <= 0x9FFC) {
  562. // Subtract 0x8140 from Shift JIS value
  563. value -= 0x8140
  564. // For characters with Shift JIS values from 0xE040 to 0xEBBF
  565. } else if (value >= 0xE040 && value <= 0xEBBF) {
  566. // Subtract 0xC140 from Shift JIS value
  567. value -= 0xC140
  568. } else {
  569. throw new Error(
  570. 'Invalid SJIS character: ' + this.data[i] + '\n' +
  571. 'Make sure your charset is UTF-8')
  572. }
  573. // Multiply most significant byte of result by 0xC0
  574. // and add least significant byte to product
  575. value = (((value >>> 8) & 0xff) * 0xC0) + (value & 0xff)
  576. // Convert result to a 13-bit binary string
  577. bitBuffer.put(value, 13)
  578. }
  579. }
  580. module.exports = KanjiData
  581. },{"./mode":14,"./utils":21}],13:[function(require,module,exports){
  582. /**
  583. * Data mask pattern reference
  584. * @type {Object}
  585. */
  586. exports.Patterns = {
  587. PATTERN000: 0,
  588. PATTERN001: 1,
  589. PATTERN010: 2,
  590. PATTERN011: 3,
  591. PATTERN100: 4,
  592. PATTERN101: 5,
  593. PATTERN110: 6,
  594. PATTERN111: 7
  595. }
  596. /**
  597. * Weighted penalty scores for the undesirable features
  598. * @type {Object}
  599. */
  600. var PenaltyScores = {
  601. N1: 3,
  602. N2: 3,
  603. N3: 40,
  604. N4: 10
  605. }
  606. /**
  607. * Check if mask pattern value is valid
  608. *
  609. * @param {Number} mask Mask pattern
  610. * @return {Boolean} true if valid, false otherwise
  611. */
  612. exports.isValid = function isValid (mask) {
  613. return mask != null && mask !== '' && !isNaN(mask) && mask >= 0 && mask <= 7
  614. }
  615. /**
  616. * Returns mask pattern from a value.
  617. * If value is not valid, returns undefined
  618. *
  619. * @param {Number|String} value Mask pattern value
  620. * @return {Number} Valid mask pattern or undefined
  621. */
  622. exports.from = function from (value) {
  623. return exports.isValid(value) ? parseInt(value, 10) : undefined
  624. }
  625. /**
  626. * Find adjacent modules in row/column with the same color
  627. * and assign a penalty value.
  628. *
  629. * Points: N1 + i
  630. * i is the amount by which the number of adjacent modules of the same color exceeds 5
  631. */
  632. exports.getPenaltyN1 = function getPenaltyN1 (data) {
  633. var size = data.size
  634. var points = 0
  635. var sameCountCol = 0
  636. var sameCountRow = 0
  637. var lastCol = null
  638. var lastRow = null
  639. for (var row = 0; row < size; row++) {
  640. sameCountCol = sameCountRow = 0
  641. lastCol = lastRow = null
  642. for (var col = 0; col < size; col++) {
  643. var module = data.get(row, col)
  644. if (module === lastCol) {
  645. sameCountCol++
  646. } else {
  647. if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)
  648. lastCol = module
  649. sameCountCol = 1
  650. }
  651. module = data.get(col, row)
  652. if (module === lastRow) {
  653. sameCountRow++
  654. } else {
  655. if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)
  656. lastRow = module
  657. sameCountRow = 1
  658. }
  659. }
  660. if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5)
  661. if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5)
  662. }
  663. return points
  664. }
  665. /**
  666. * Find 2x2 blocks with the same color and assign a penalty value
  667. *
  668. * Points: N2 * (m - 1) * (n - 1)
  669. */
  670. exports.getPenaltyN2 = function getPenaltyN2 (data) {
  671. var size = data.size
  672. var points = 0
  673. for (var row = 0; row < size - 1; row++) {
  674. for (var col = 0; col < size - 1; col++) {
  675. var last = data.get(row, col) +
  676. data.get(row, col + 1) +
  677. data.get(row + 1, col) +
  678. data.get(row + 1, col + 1)
  679. if (last === 4 || last === 0) points++
  680. }
  681. }
  682. return points * PenaltyScores.N2
  683. }
  684. /**
  685. * Find 1:1:3:1:1 ratio (dark:light:dark:light:dark) pattern in row/column,
  686. * preceded or followed by light area 4 modules wide
  687. *
  688. * Points: N3 * number of pattern found
  689. */
  690. exports.getPenaltyN3 = function getPenaltyN3 (data) {
  691. var size = data.size
  692. var points = 0
  693. var bitsCol = 0
  694. var bitsRow = 0
  695. for (var row = 0; row < size; row++) {
  696. bitsCol = bitsRow = 0
  697. for (var col = 0; col < size; col++) {
  698. bitsCol = ((bitsCol << 1) & 0x7FF) | data.get(row, col)
  699. if (col >= 10 && (bitsCol === 0x5D0 || bitsCol === 0x05D)) points++
  700. bitsRow = ((bitsRow << 1) & 0x7FF) | data.get(col, row)
  701. if (col >= 10 && (bitsRow === 0x5D0 || bitsRow === 0x05D)) points++
  702. }
  703. }
  704. return points * PenaltyScores.N3
  705. }
  706. /**
  707. * Calculate proportion of dark modules in entire symbol
  708. *
  709. * Points: N4 * k
  710. *
  711. * k is the rating of the deviation of the proportion of dark modules
  712. * in the symbol from 50% in steps of 5%
  713. */
  714. exports.getPenaltyN4 = function getPenaltyN4 (data) {
  715. var darkCount = 0
  716. var modulesCount = data.data.length
  717. for (var i = 0; i < modulesCount; i++) darkCount += data.data[i]
  718. var k = Math.abs(Math.ceil((darkCount * 100 / modulesCount) / 5) - 10)
  719. return k * PenaltyScores.N4
  720. }
  721. /**
  722. * Return mask value at given position
  723. *
  724. * @param {Number} maskPattern Pattern reference value
  725. * @param {Number} i Row
  726. * @param {Number} j Column
  727. * @return {Boolean} Mask value
  728. */
  729. function getMaskAt (maskPattern, i, j) {
  730. switch (maskPattern) {
  731. case exports.Patterns.PATTERN000: return (i + j) % 2 === 0
  732. case exports.Patterns.PATTERN001: return i % 2 === 0
  733. case exports.Patterns.PATTERN010: return j % 3 === 0
  734. case exports.Patterns.PATTERN011: return (i + j) % 3 === 0
  735. case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0
  736. case exports.Patterns.PATTERN101: return (i * j) % 2 + (i * j) % 3 === 0
  737. case exports.Patterns.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 === 0
  738. case exports.Patterns.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 === 0
  739. default: throw new Error('bad maskPattern:' + maskPattern)
  740. }
  741. }
  742. /**
  743. * Apply a mask pattern to a BitMatrix
  744. *
  745. * @param {Number} pattern Pattern reference number
  746. * @param {BitMatrix} data BitMatrix data
  747. */
  748. exports.applyMask = function applyMask (pattern, data) {
  749. var size = data.size
  750. for (var col = 0; col < size; col++) {
  751. for (var row = 0; row < size; row++) {
  752. if (data.isReserved(row, col)) continue
  753. data.xor(row, col, getMaskAt(pattern, row, col))
  754. }
  755. }
  756. }
  757. /**
  758. * Returns the best mask pattern for data
  759. *
  760. * @param {BitMatrix} data
  761. * @return {Number} Mask pattern reference number
  762. */
  763. exports.getBestMask = function getBestMask (data, setupFormatFunc) {
  764. var numPatterns = Object.keys(exports.Patterns).length
  765. var bestPattern = 0
  766. var lowerPenalty = Infinity
  767. for (var p = 0; p < numPatterns; p++) {
  768. setupFormatFunc(p)
  769. exports.applyMask(p, data)
  770. // Calculate penalty
  771. var penalty =
  772. exports.getPenaltyN1(data) +
  773. exports.getPenaltyN2(data) +
  774. exports.getPenaltyN3(data) +
  775. exports.getPenaltyN4(data)
  776. // Undo previously applied mask
  777. exports.applyMask(p, data)
  778. if (penalty < lowerPenalty) {
  779. lowerPenalty = penalty
  780. bestPattern = p
  781. }
  782. }
  783. return bestPattern
  784. }
  785. },{}],14:[function(require,module,exports){
  786. var VersionCheck = require('./version-check')
  787. var Regex = require('./regex')
  788. /**
  789. * Numeric mode encodes data from the decimal digit set (0 - 9)
  790. * (byte values 30HEX to 39HEX).
  791. * Normally, 3 data characters are represented by 10 bits.
  792. *
  793. * @type {Object}
  794. */
  795. exports.NUMERIC = {
  796. id: 'Numeric',
  797. bit: 1 << 0,
  798. ccBits: [10, 12, 14]
  799. }
  800. /**
  801. * Alphanumeric mode encodes data from a set of 45 characters,
  802. * i.e. 10 numeric digits (0 - 9),
  803. * 26 alphabetic characters (A - Z),
  804. * and 9 symbols (SP, $, %, *, +, -, ., /, :).
  805. * Normally, two input characters are represented by 11 bits.
  806. *
  807. * @type {Object}
  808. */
  809. exports.ALPHANUMERIC = {
  810. id: 'Alphanumeric',
  811. bit: 1 << 1,
  812. ccBits: [9, 11, 13]
  813. }
  814. /**
  815. * In byte mode, data is encoded at 8 bits per character.
  816. *
  817. * @type {Object}
  818. */
  819. exports.BYTE = {
  820. id: 'Byte',
  821. bit: 1 << 2,
  822. ccBits: [8, 16, 16]
  823. }
  824. /**
  825. * The Kanji mode efficiently encodes Kanji characters in accordance with
  826. * the Shift JIS system based on JIS X 0208.
  827. * The Shift JIS values are shifted from the JIS X 0208 values.
  828. * JIS X 0208 gives details of the shift coded representation.
  829. * Each two-byte character value is compacted to a 13-bit binary codeword.
  830. *
  831. * @type {Object}
  832. */
  833. exports.KANJI = {
  834. id: 'Kanji',
  835. bit: 1 << 3,
  836. ccBits: [8, 10, 12]
  837. }
  838. /**
  839. * Mixed mode will contain a sequences of data in a combination of any of
  840. * the modes described above
  841. *
  842. * @type {Object}
  843. */
  844. exports.MIXED = {
  845. bit: -1
  846. }
  847. /**
  848. * Returns the number of bits needed to store the data length
  849. * according to QR Code specifications.
  850. *
  851. * @param {Mode} mode Data mode
  852. * @param {Number} version QR Code version
  853. * @return {Number} Number of bits
  854. */
  855. exports.getCharCountIndicator = function getCharCountIndicator (mode, version) {
  856. if (!mode.ccBits) throw new Error('Invalid mode: ' + mode)
  857. if (!VersionCheck.isValid(version)) {
  858. throw new Error('Invalid version: ' + version)
  859. }
  860. if (version >= 1 && version < 10) return mode.ccBits[0]
  861. else if (version < 27) return mode.ccBits[1]
  862. return mode.ccBits[2]
  863. }
  864. /**
  865. * Returns the most efficient mode to store the specified data
  866. *
  867. * @param {String} dataStr Input data string
  868. * @return {Mode} Best mode
  869. */
  870. exports.getBestModeForData = function getBestModeForData (dataStr) {
  871. if (Regex.testNumeric(dataStr)) return exports.NUMERIC
  872. else if (Regex.testAlphanumeric(dataStr)) return exports.ALPHANUMERIC
  873. else if (Regex.testKanji(dataStr)) return exports.KANJI
  874. else return exports.BYTE
  875. }
  876. /**
  877. * Return mode name as string
  878. *
  879. * @param {Mode} mode Mode object
  880. * @returns {String} Mode name
  881. */
  882. exports.toString = function toString (mode) {
  883. if (mode && mode.id) return mode.id
  884. throw new Error('Invalid mode')
  885. }
  886. /**
  887. * Check if input param is a valid mode object
  888. *
  889. * @param {Mode} mode Mode object
  890. * @returns {Boolean} True if valid mode, false otherwise
  891. */
  892. exports.isValid = function isValid (mode) {
  893. return mode && mode.bit && mode.ccBits
  894. }
  895. /**
  896. * Get mode object from its name
  897. *
  898. * @param {String} string Mode name
  899. * @returns {Mode} Mode object
  900. */
  901. function fromString (string) {
  902. if (typeof string !== 'string') {
  903. throw new Error('Param is not a string')
  904. }
  905. var lcStr = string.toLowerCase()
  906. switch (lcStr) {
  907. case 'numeric':
  908. return exports.NUMERIC
  909. case 'alphanumeric':
  910. return exports.ALPHANUMERIC
  911. case 'kanji':
  912. return exports.KANJI
  913. case 'byte':
  914. return exports.BYTE
  915. default:
  916. throw new Error('Unknown mode: ' + string)
  917. }
  918. }
  919. /**
  920. * Returns mode from a value.
  921. * If value is not a valid mode, returns defaultValue
  922. *
  923. * @param {Mode|String} value Encoding mode
  924. * @param {Mode} defaultValue Fallback value
  925. * @return {Mode} Encoding mode
  926. */
  927. exports.from = function from (value, defaultValue) {
  928. if (exports.isValid(value)) {
  929. return value
  930. }
  931. try {
  932. return fromString(value)
  933. } catch (e) {
  934. return defaultValue
  935. }
  936. }
  937. },{"./regex":19,"./version-check":22}],15:[function(require,module,exports){
  938. var Mode = require('./mode')
  939. function NumericData (data) {
  940. this.mode = Mode.NUMERIC
  941. this.data = data.toString()
  942. }
  943. NumericData.getBitsLength = function getBitsLength (length) {
  944. return 10 * Math.floor(length / 3) + ((length % 3) ? ((length % 3) * 3 + 1) : 0)
  945. }
  946. NumericData.prototype.getLength = function getLength () {
  947. return this.data.length
  948. }
  949. NumericData.prototype.getBitsLength = function getBitsLength () {
  950. return NumericData.getBitsLength(this.data.length)
  951. }
  952. NumericData.prototype.write = function write (bitBuffer) {
  953. var i, group, value
  954. // The input data string is divided into groups of three digits,
  955. // and each group is converted to its 10-bit binary equivalent.
  956. for (i = 0; i + 3 <= this.data.length; i += 3) {
  957. group = this.data.substr(i, 3)
  958. value = parseInt(group, 10)
  959. bitBuffer.put(value, 10)
  960. }
  961. // If the number of input digits is not an exact multiple of three,
  962. // the final one or two digits are converted to 4 or 7 bits respectively.
  963. var remainingNum = this.data.length - i
  964. if (remainingNum > 0) {
  965. group = this.data.substr(i)
  966. value = parseInt(group, 10)
  967. bitBuffer.put(value, remainingNum * 3 + 1)
  968. }
  969. }
  970. module.exports = NumericData
  971. },{"./mode":14}],16:[function(require,module,exports){
  972. var Buffer = require('../utils/buffer')
  973. var GF = require('./galois-field')
  974. /**
  975. * Multiplies two polynomials inside Galois Field
  976. *
  977. * @param {Buffer} p1 Polynomial
  978. * @param {Buffer} p2 Polynomial
  979. * @return {Buffer} Product of p1 and p2
  980. */
  981. exports.mul = function mul (p1, p2) {
  982. var coeff = new Buffer(p1.length + p2.length - 1)
  983. coeff.fill(0)
  984. for (var i = 0; i < p1.length; i++) {
  985. for (var j = 0; j < p2.length; j++) {
  986. coeff[i + j] ^= GF.mul(p1[i], p2[j])
  987. }
  988. }
  989. return coeff
  990. }
  991. /**
  992. * Calculate the remainder of polynomials division
  993. *
  994. * @param {Buffer} divident Polynomial
  995. * @param {Buffer} divisor Polynomial
  996. * @return {Buffer} Remainder
  997. */
  998. exports.mod = function mod (divident, divisor) {
  999. var result = new Buffer(divident)
  1000. while ((result.length - divisor.length) >= 0) {
  1001. var coeff = result[0]
  1002. for (var i = 0; i < divisor.length; i++) {
  1003. result[i] ^= GF.mul(divisor[i], coeff)
  1004. }
  1005. // remove all zeros from buffer head
  1006. var offset = 0
  1007. while (offset < result.length && result[offset] === 0) offset++
  1008. result = result.slice(offset)
  1009. }
  1010. return result
  1011. }
  1012. /**
  1013. * Generate an irreducible generator polynomial of specified degree
  1014. * (used by Reed-Solomon encoder)
  1015. *
  1016. * @param {Number} degree Degree of the generator polynomial
  1017. * @return {Buffer} Buffer containing polynomial coefficients
  1018. */
  1019. exports.generateECPolynomial = function generateECPolynomial (degree) {
  1020. var poly = new Buffer([1])
  1021. for (var i = 0; i < degree; i++) {
  1022. poly = exports.mul(poly, [1, GF.exp(i)])
  1023. }
  1024. return poly
  1025. }
  1026. },{"../utils/buffer":28,"./galois-field":11}],17:[function(require,module,exports){
  1027. var Buffer = require('../utils/buffer')
  1028. var Utils = require('./utils')
  1029. var ECLevel = require('./error-correction-level')
  1030. var BitBuffer = require('./bit-buffer')
  1031. var BitMatrix = require('./bit-matrix')
  1032. var AlignmentPattern = require('./alignment-pattern')
  1033. var FinderPattern = require('./finder-pattern')
  1034. var MaskPattern = require('./mask-pattern')
  1035. var ECCode = require('./error-correction-code')
  1036. var ReedSolomonEncoder = require('./reed-solomon-encoder')
  1037. var Version = require('./version')
  1038. var FormatInfo = require('./format-info')
  1039. var Mode = require('./mode')
  1040. var Segments = require('./segments')
  1041. var isArray = require('isarray')
  1042. /**
  1043. * QRCode for JavaScript
  1044. *
  1045. * modified by Ryan Day for nodejs support
  1046. * Copyright (c) 2011 Ryan Day
  1047. *
  1048. * Licensed under the MIT license:
  1049. * http://www.opensource.org/licenses/mit-license.php
  1050. *
  1051. //---------------------------------------------------------------------
  1052. // QRCode for JavaScript
  1053. //
  1054. // Copyright (c) 2009 Kazuhiko Arase
  1055. //
  1056. // URL: http://www.d-project.com/
  1057. //
  1058. // Licensed under the MIT license:
  1059. // http://www.opensource.org/licenses/mit-license.php
  1060. //
  1061. // The word "QR Code" is registered trademark of
  1062. // DENSO WAVE INCORPORATED
  1063. // http://www.denso-wave.com/qrcode/faqpatent-e.html
  1064. //
  1065. //---------------------------------------------------------------------
  1066. */
  1067. /**
  1068. * Add finder patterns bits to matrix
  1069. *
  1070. * @param {BitMatrix} matrix Modules matrix
  1071. * @param {Number} version QR Code version
  1072. */
  1073. function setupFinderPattern (matrix, version) {
  1074. var size = matrix.size
  1075. var pos = FinderPattern.getPositions(version)
  1076. for (var i = 0; i < pos.length; i++) {
  1077. var row = pos[i][0]
  1078. var col = pos[i][1]
  1079. for (var r = -1; r <= 7; r++) {
  1080. if (row + r <= -1 || size <= row + r) continue
  1081. for (var c = -1; c <= 7; c++) {
  1082. if (col + c <= -1 || size <= col + c) continue
  1083. if ((r >= 0 && r <= 6 && (c === 0 || c === 6)) ||
  1084. (c >= 0 && c <= 6 && (r === 0 || r === 6)) ||
  1085. (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {
  1086. matrix.set(row + r, col + c, true, true)
  1087. } else {
  1088. matrix.set(row + r, col + c, false, true)
  1089. }
  1090. }
  1091. }
  1092. }
  1093. }
  1094. /**
  1095. * Add timing pattern bits to matrix
  1096. *
  1097. * Note: this function must be called before {@link setupAlignmentPattern}
  1098. *
  1099. * @param {BitMatrix} matrix Modules matrix
  1100. */
  1101. function setupTimingPattern (matrix) {
  1102. var size = matrix.size
  1103. for (var r = 8; r < size - 8; r++) {
  1104. var value = r % 2 === 0
  1105. matrix.set(r, 6, value, true)
  1106. matrix.set(6, r, value, true)
  1107. }
  1108. }
  1109. /**
  1110. * Add alignment patterns bits to matrix
  1111. *
  1112. * Note: this function must be called after {@link setupTimingPattern}
  1113. *
  1114. * @param {BitMatrix} matrix Modules matrix
  1115. * @param {Number} version QR Code version
  1116. */
  1117. function setupAlignmentPattern (matrix, version) {
  1118. var pos = AlignmentPattern.getPositions(version)
  1119. for (var i = 0; i < pos.length; i++) {
  1120. var row = pos[i][0]
  1121. var col = pos[i][1]
  1122. for (var r = -2; r <= 2; r++) {
  1123. for (var c = -2; c <= 2; c++) {
  1124. if (r === -2 || r === 2 || c === -2 || c === 2 ||
  1125. (r === 0 && c === 0)) {
  1126. matrix.set(row + r, col + c, true, true)
  1127. } else {
  1128. matrix.set(row + r, col + c, false, true)
  1129. }
  1130. }
  1131. }
  1132. }
  1133. }
  1134. /**
  1135. * Add version info bits to matrix
  1136. *
  1137. * @param {BitMatrix} matrix Modules matrix
  1138. * @param {Number} version QR Code version
  1139. */
  1140. function setupVersionInfo (matrix, version) {
  1141. var size = matrix.size
  1142. var bits = Version.getEncodedBits(version)
  1143. var row, col, mod
  1144. for (var i = 0; i < 18; i++) {
  1145. row = Math.floor(i / 3)
  1146. col = i % 3 + size - 8 - 3
  1147. mod = ((bits >> i) & 1) === 1
  1148. matrix.set(row, col, mod, true)
  1149. matrix.set(col, row, mod, true)
  1150. }
  1151. }
  1152. /**
  1153. * Add format info bits to matrix
  1154. *
  1155. * @param {BitMatrix} matrix Modules matrix
  1156. * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
  1157. * @param {Number} maskPattern Mask pattern reference value
  1158. */
  1159. function setupFormatInfo (matrix, errorCorrectionLevel, maskPattern) {
  1160. var size = matrix.size
  1161. var bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern)
  1162. var i, mod
  1163. for (i = 0; i < 15; i++) {
  1164. mod = ((bits >> i) & 1) === 1
  1165. // vertical
  1166. if (i < 6) {
  1167. matrix.set(i, 8, mod, true)
  1168. } else if (i < 8) {
  1169. matrix.set(i + 1, 8, mod, true)
  1170. } else {
  1171. matrix.set(size - 15 + i, 8, mod, true)
  1172. }
  1173. // horizontal
  1174. if (i < 8) {
  1175. matrix.set(8, size - i - 1, mod, true)
  1176. } else if (i < 9) {
  1177. matrix.set(8, 15 - i - 1 + 1, mod, true)
  1178. } else {
  1179. matrix.set(8, 15 - i - 1, mod, true)
  1180. }
  1181. }
  1182. // fixed module
  1183. matrix.set(size - 8, 8, 1, true)
  1184. }
  1185. /**
  1186. * Add encoded data bits to matrix
  1187. *
  1188. * @param {BitMatrix} matrix Modules matrix
  1189. * @param {Buffer} data Data codewords
  1190. */
  1191. function setupData (matrix, data) {
  1192. var size = matrix.size
  1193. var inc = -1
  1194. var row = size - 1
  1195. var bitIndex = 7
  1196. var byteIndex = 0
  1197. for (var col = size - 1; col > 0; col -= 2) {
  1198. if (col === 6) col--
  1199. while (true) {
  1200. for (var c = 0; c < 2; c++) {
  1201. if (!matrix.isReserved(row, col - c)) {
  1202. var dark = false
  1203. if (byteIndex < data.length) {
  1204. dark = (((data[byteIndex] >>> bitIndex) & 1) === 1)
  1205. }
  1206. matrix.set(row, col - c, dark)
  1207. bitIndex--
  1208. if (bitIndex === -1) {
  1209. byteIndex++
  1210. bitIndex = 7
  1211. }
  1212. }
  1213. }
  1214. row += inc
  1215. if (row < 0 || size <= row) {
  1216. row -= inc
  1217. inc = -inc
  1218. break
  1219. }
  1220. }
  1221. }
  1222. }
  1223. /**
  1224. * Create encoded codewords from data input
  1225. *
  1226. * @param {Number} version QR Code version
  1227. * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
  1228. * @param {ByteData} data Data input
  1229. * @return {Buffer} Buffer containing encoded codewords
  1230. */
  1231. function createData (version, errorCorrectionLevel, segments) {
  1232. // Prepare data buffer
  1233. var buffer = new BitBuffer()
  1234. segments.forEach(function (data) {
  1235. // prefix data with mode indicator (4 bits)
  1236. buffer.put(data.mode.bit, 4)
  1237. // Prefix data with character count indicator.
  1238. // The character count indicator is a string of bits that represents the
  1239. // number of characters that are being encoded.
  1240. // The character count indicator must be placed after the mode indicator
  1241. // and must be a certain number of bits long, depending on the QR version
  1242. // and data mode
  1243. // @see {@link Mode.getCharCountIndicator}.
  1244. buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version))
  1245. // add binary data sequence to buffer
  1246. data.write(buffer)
  1247. })
  1248. // Calculate required number of bits
  1249. var totalCodewords = Utils.getSymbolTotalCodewords(version)
  1250. var ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)
  1251. var dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8
  1252. // Add a terminator.
  1253. // If the bit string is shorter than the total number of required bits,
  1254. // a terminator of up to four 0s must be added to the right side of the string.
  1255. // If the bit string is more than four bits shorter than the required number of bits,
  1256. // add four 0s to the end.
  1257. if (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits) {
  1258. buffer.put(0, 4)
  1259. }
  1260. // If the bit string is fewer than four bits shorter, add only the number of 0s that
  1261. // are needed to reach the required number of bits.
  1262. // After adding the terminator, if the number of bits in the string is not a multiple of 8,
  1263. // pad the string on the right with 0s to make the string's length a multiple of 8.
  1264. while (buffer.getLengthInBits() % 8 !== 0) {
  1265. buffer.putBit(0)
  1266. }
  1267. // Add pad bytes if the string is still shorter than the total number of required bits.
  1268. // Extend the buffer to fill the data capacity of the symbol corresponding to
  1269. // the Version and Error Correction Level by adding the Pad Codewords 11101100 (0xEC)
  1270. // and 00010001 (0x11) alternately.
  1271. var remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8
  1272. for (var i = 0; i < remainingByte; i++) {
  1273. buffer.put(i % 2 ? 0x11 : 0xEC, 8)
  1274. }
  1275. return createCodewords(buffer, version, errorCorrectionLevel)
  1276. }
  1277. /**
  1278. * Encode input data with Reed-Solomon and return codewords with
  1279. * relative error correction bits
  1280. *
  1281. * @param {BitBuffer} bitBuffer Data to encode
  1282. * @param {Number} version QR Code version
  1283. * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
  1284. * @return {Buffer} Buffer containing encoded codewords
  1285. */
  1286. function createCodewords (bitBuffer, version, errorCorrectionLevel) {
  1287. // Total codewords for this QR code version (Data + Error correction)
  1288. var totalCodewords = Utils.getSymbolTotalCodewords(version)
  1289. // Total number of error correction codewords
  1290. var ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)
  1291. // Total number of data codewords
  1292. var dataTotalCodewords = totalCodewords - ecTotalCodewords
  1293. // Total number of blocks
  1294. var ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel)
  1295. // Calculate how many blocks each group should contain
  1296. var blocksInGroup2 = totalCodewords % ecTotalBlocks
  1297. var blocksInGroup1 = ecTotalBlocks - blocksInGroup2
  1298. var totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks)
  1299. var dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks)
  1300. var dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1
  1301. // Number of EC codewords is the same for both groups
  1302. var ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1
  1303. // Initialize a Reed-Solomon encoder with a generator polynomial of degree ecCount
  1304. var rs = new ReedSolomonEncoder(ecCount)
  1305. var offset = 0
  1306. var dcData = new Array(ecTotalBlocks)
  1307. var ecData = new Array(ecTotalBlocks)
  1308. var maxDataSize = 0
  1309. var buffer = new Buffer(bitBuffer.buffer)
  1310. // Divide the buffer into the required number of blocks
  1311. for (var b = 0; b < ecTotalBlocks; b++) {
  1312. var dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2
  1313. // extract a block of data from buffer
  1314. dcData[b] = buffer.slice(offset, offset + dataSize)
  1315. // Calculate EC codewords for this data block
  1316. ecData[b] = rs.encode(dcData[b])
  1317. offset += dataSize
  1318. maxDataSize = Math.max(maxDataSize, dataSize)
  1319. }
  1320. // Create final data
  1321. // Interleave the data and error correction codewords from each block
  1322. var data = new Buffer(totalCodewords)
  1323. var index = 0
  1324. var i, r
  1325. // Add data codewords
  1326. for (i = 0; i < maxDataSize; i++) {
  1327. for (r = 0; r < ecTotalBlocks; r++) {
  1328. if (i < dcData[r].length) {
  1329. data[index++] = dcData[r][i]
  1330. }
  1331. }
  1332. }
  1333. // Apped EC codewords
  1334. for (i = 0; i < ecCount; i++) {
  1335. for (r = 0; r < ecTotalBlocks; r++) {
  1336. data[index++] = ecData[r][i]
  1337. }
  1338. }
  1339. return data
  1340. }
  1341. /**
  1342. * Build QR Code symbol
  1343. *
  1344. * @param {String} data Input string
  1345. * @param {Number} version QR Code version
  1346. * @param {ErrorCorretionLevel} errorCorrectionLevel Error level
  1347. * @param {MaskPattern} maskPattern Mask pattern
  1348. * @return {Object} Object containing symbol data
  1349. */
  1350. function createSymbol (data, version, errorCorrectionLevel, maskPattern) {
  1351. var segments
  1352. if (isArray(data)) {
  1353. segments = Segments.fromArray(data)
  1354. } else if (typeof data === 'string') {
  1355. var estimatedVersion = version
  1356. if (!estimatedVersion) {
  1357. var rawSegments = Segments.rawSplit(data)
  1358. // Estimate best version that can contain raw splitted segments
  1359. estimatedVersion = Version.getBestVersionForData(rawSegments,
  1360. errorCorrectionLevel)
  1361. }
  1362. // Build optimized segments
  1363. // If estimated version is undefined, try with the highest version
  1364. segments = Segments.fromString(data, estimatedVersion || 40)
  1365. } else {
  1366. throw new Error('Invalid data')
  1367. }
  1368. // Get the min version that can contain data
  1369. var bestVersion = Version.getBestVersionForData(segments,
  1370. errorCorrectionLevel)
  1371. // If no version is found, data cannot be stored
  1372. if (!bestVersion) {
  1373. throw new Error('The amount of data is too big to be stored in a QR Code')
  1374. }
  1375. // If not specified, use min version as default
  1376. if (!version) {
  1377. version = bestVersion
  1378. // Check if the specified version can contain the data
  1379. } else if (version < bestVersion) {
  1380. throw new Error('\n' +
  1381. 'The chosen QR Code version cannot contain this amount of data.\n' +
  1382. 'Minimum version required to store current data is: ' + bestVersion + '.\n'
  1383. )
  1384. }
  1385. var dataBits = createData(version, errorCorrectionLevel, segments)
  1386. // Allocate matrix buffer
  1387. var moduleCount = Utils.getSymbolSize(version)
  1388. var modules = new BitMatrix(moduleCount)
  1389. // Add function modules
  1390. setupFinderPattern(modules, version)
  1391. setupTimingPattern(modules)
  1392. setupAlignmentPattern(modules, version)
  1393. // Add temporary dummy bits for format info just to set them as reserved.
  1394. // This is needed to prevent these bits from being masked by {@link MaskPattern.applyMask}
  1395. // since the masking operation must be performed only on the encoding region.
  1396. // These blocks will be replaced with correct values later in code.
  1397. setupFormatInfo(modules, errorCorrectionLevel, 0)
  1398. if (version >= 7) {
  1399. setupVersionInfo(modules, version)
  1400. }
  1401. // Add data codewords
  1402. setupData(modules, dataBits)
  1403. if (isNaN(maskPattern)) {
  1404. // Find best mask pattern
  1405. maskPattern = MaskPattern.getBestMask(modules,
  1406. setupFormatInfo.bind(null, modules, errorCorrectionLevel))
  1407. }
  1408. // Apply mask pattern
  1409. MaskPattern.applyMask(maskPattern, modules)
  1410. // Replace format info bits with correct values
  1411. setupFormatInfo(modules, errorCorrectionLevel, maskPattern)
  1412. return {
  1413. modules: modules,
  1414. version: version,
  1415. errorCorrectionLevel: errorCorrectionLevel,
  1416. maskPattern: maskPattern,
  1417. segments: segments
  1418. }
  1419. }
  1420. /**
  1421. * QR Code
  1422. *
  1423. * @param {String | Array} data Input data
  1424. * @param {Object} options Optional configurations
  1425. * @param {Number} options.version QR Code version
  1426. * @param {String} options.errorCorrectionLevel Error correction level
  1427. * @param {Function} options.toSJISFunc Helper func to convert utf8 to sjis
  1428. */
  1429. exports.create = function create (data, options) {
  1430. if (typeof data === 'undefined' || data === '') {
  1431. throw new Error('No input text')
  1432. }
  1433. var errorCorrectionLevel = ECLevel.M
  1434. var version
  1435. var mask
  1436. if (typeof options !== 'undefined') {
  1437. // Use higher error correction level as default
  1438. errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M)
  1439. version = Version.from(options.version)
  1440. mask = MaskPattern.from(options.maskPattern)
  1441. if (options.toSJISFunc) {
  1442. Utils.setToSJISFunction(options.toSJISFunc)
  1443. }
  1444. }
  1445. return createSymbol(data, version, errorCorrectionLevel, mask)
  1446. }
  1447. },{"../utils/buffer":28,"./alignment-pattern":2,"./bit-buffer":4,"./bit-matrix":5,"./error-correction-code":7,"./error-correction-level":8,"./finder-pattern":9,"./format-info":10,"./mask-pattern":13,"./mode":14,"./reed-solomon-encoder":18,"./segments":20,"./utils":21,"./version":23,"isarray":30}],18:[function(require,module,exports){
  1448. var Buffer = require('../utils/buffer')
  1449. var Polynomial = require('./polynomial')
  1450. function ReedSolomonEncoder (degree) {
  1451. this.genPoly = undefined
  1452. this.degree = degree
  1453. if (this.degree) this.initialize(this.degree)
  1454. }
  1455. /**
  1456. * Initialize the encoder.
  1457. * The input param should correspond to the number of error correction codewords.
  1458. *
  1459. * @param {Number} degree
  1460. */
  1461. ReedSolomonEncoder.prototype.initialize = function initialize (degree) {
  1462. // create an irreducible generator polynomial
  1463. this.degree = degree
  1464. this.genPoly = Polynomial.generateECPolynomial(this.degree)
  1465. }
  1466. /**
  1467. * Encodes a chunk of data
  1468. *
  1469. * @param {Buffer} data Buffer containing input data
  1470. * @return {Buffer} Buffer containing encoded data
  1471. */
  1472. ReedSolomonEncoder.prototype.encode = function encode (data) {
  1473. if (!this.genPoly) {
  1474. throw new Error('Encoder not initialized')
  1475. }
  1476. // Calculate EC for this data block
  1477. // extends data size to data+genPoly size
  1478. var pad = new Buffer(this.degree)
  1479. pad.fill(0)
  1480. var paddedData = Buffer.concat([data, pad], data.length + this.degree)
  1481. // The error correction codewords are the remainder after dividing the data codewords
  1482. // by a generator polynomial
  1483. var remainder = Polynomial.mod(paddedData, this.genPoly)
  1484. // return EC data blocks (last n byte, where n is the degree of genPoly)
  1485. // If coefficients number in remainder are less than genPoly degree,
  1486. // pad with 0s to the left to reach the needed number of coefficients
  1487. var start = this.degree - remainder.length
  1488. if (start > 0) {
  1489. var buff = new Buffer(this.degree)
  1490. buff.fill(0)
  1491. remainder.copy(buff, start)
  1492. return buff
  1493. }
  1494. return remainder
  1495. }
  1496. module.exports = ReedSolomonEncoder
  1497. },{"../utils/buffer":28,"./polynomial":16}],19:[function(require,module,exports){
  1498. var numeric = '[0-9]+'
  1499. var alphanumeric = '[A-Z $%*+\\-./:]+'
  1500. var kanji = '(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|' +
  1501. '[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|' +
  1502. '[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|' +
  1503. '[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+'
  1504. kanji = kanji.replace(/u/g, '\\u')
  1505. var byte = '(?:(?![A-Z0-9 $%*+\\-./:]|' + kanji + ')(?:.|[\r\n]))+'
  1506. exports.KANJI = new RegExp(kanji, 'g')
  1507. exports.BYTE_KANJI = new RegExp('[^A-Z0-9 $%*+\\-./:]+', 'g')
  1508. exports.BYTE = new RegExp(byte, 'g')
  1509. exports.NUMERIC = new RegExp(numeric, 'g')
  1510. exports.ALPHANUMERIC = new RegExp(alphanumeric, 'g')
  1511. var TEST_KANJI = new RegExp('^' + kanji + '$')
  1512. var TEST_NUMERIC = new RegExp('^' + numeric + '$')
  1513. var TEST_ALPHANUMERIC = new RegExp('^[A-Z0-9 $%*+\\-./:]+$')
  1514. exports.testKanji = function testKanji (str) {
  1515. return TEST_KANJI.test(str)
  1516. }
  1517. exports.testNumeric = function testNumeric (str) {
  1518. return TEST_NUMERIC.test(str)
  1519. }
  1520. exports.testAlphanumeric = function testAlphanumeric (str) {
  1521. return TEST_ALPHANUMERIC.test(str)
  1522. }
  1523. },{}],20:[function(require,module,exports){
  1524. var Mode = require('./mode')
  1525. var NumericData = require('./numeric-data')
  1526. var AlphanumericData = require('./alphanumeric-data')
  1527. var ByteData = require('./byte-data')
  1528. var KanjiData = require('./kanji-data')
  1529. var Regex = require('./regex')
  1530. var Utils = require('./utils')
  1531. var dijkstra = require('dijkstrajs')
  1532. /**
  1533. * Returns UTF8 byte length
  1534. *
  1535. * @param {String} str Input string
  1536. * @return {Number} Number of byte
  1537. */
  1538. function getStringByteLength (str) {
  1539. return unescape(encodeURIComponent(str)).length
  1540. }
  1541. /**
  1542. * Get a list of segments of the specified mode
  1543. * from a string
  1544. *
  1545. * @param {Mode} mode Segment mode
  1546. * @param {String} str String to process
  1547. * @return {Array} Array of object with segments data
  1548. */
  1549. function getSegments (regex, mode, str) {
  1550. var segments = []
  1551. var result
  1552. while ((result = regex.exec(str)) !== null) {
  1553. segments.push({
  1554. data: result[0],
  1555. index: result.index,
  1556. mode: mode,
  1557. length: result[0].length
  1558. })
  1559. }
  1560. return segments
  1561. }
  1562. /**
  1563. * Extracts a series of segments with the appropriate
  1564. * modes from a string
  1565. *
  1566. * @param {String} dataStr Input string
  1567. * @return {Array} Array of object with segments data
  1568. */
  1569. function getSegmentsFromString (dataStr) {
  1570. var numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr)
  1571. var alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr)
  1572. var byteSegs
  1573. var kanjiSegs
  1574. if (Utils.isKanjiModeEnabled()) {
  1575. byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr)
  1576. kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr)
  1577. } else {
  1578. byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr)
  1579. kanjiSegs = []
  1580. }
  1581. var segs = numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs)
  1582. return segs
  1583. .sort(function (s1, s2) {
  1584. return s1.index - s2.index
  1585. })
  1586. .map(function (obj) {
  1587. return {
  1588. data: obj.data,
  1589. mode: obj.mode,
  1590. length: obj.length
  1591. }
  1592. })
  1593. }
  1594. /**
  1595. * Returns how many bits are needed to encode a string of
  1596. * specified length with the specified mode
  1597. *
  1598. * @param {Number} length String length
  1599. * @param {Mode} mode Segment mode
  1600. * @return {Number} Bit length
  1601. */
  1602. function getSegmentBitsLength (length, mode) {
  1603. switch (mode) {
  1604. case Mode.NUMERIC:
  1605. return NumericData.getBitsLength(length)
  1606. case Mode.ALPHANUMERIC:
  1607. return AlphanumericData.getBitsLength(length)
  1608. case Mode.KANJI:
  1609. return KanjiData.getBitsLength(length)
  1610. case Mode.BYTE:
  1611. return ByteData.getBitsLength(length)
  1612. }
  1613. }
  1614. /**
  1615. * Merges adjacent segments which have the same mode
  1616. *
  1617. * @param {Array} segs Array of object with segments data
  1618. * @return {Array} Array of object with segments data
  1619. */
  1620. function mergeSegments (segs) {
  1621. return segs.reduce(function (acc, curr) {
  1622. var prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null
  1623. if (prevSeg && prevSeg.mode === curr.mode) {
  1624. acc[acc.length - 1].data += curr.data
  1625. return acc
  1626. }
  1627. acc.push(curr)
  1628. return acc
  1629. }, [])
  1630. }
  1631. /**
  1632. * Generates a list of all possible nodes combination which
  1633. * will be used to build a segments graph.
  1634. *
  1635. * Nodes are divided by groups. Each group will contain a list of all the modes
  1636. * in which is possible to encode the given text.
  1637. *
  1638. * For example the text '12345' can be encoded as Numeric, Alphanumeric or Byte.
  1639. * The group for '12345' will contain then 3 objects, one for each
  1640. * possible encoding mode.
  1641. *
  1642. * Each node represents a possible segment.
  1643. *
  1644. * @param {Array} segs Array of object with segments data
  1645. * @return {Array} Array of object with segments data
  1646. */
  1647. function buildNodes (segs) {
  1648. var nodes = []
  1649. for (var i = 0; i < segs.length; i++) {
  1650. var seg = segs[i]
  1651. switch (seg.mode) {
  1652. case Mode.NUMERIC:
  1653. nodes.push([seg,
  1654. { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },
  1655. { data: seg.data, mode: Mode.BYTE, length: seg.length }
  1656. ])
  1657. break
  1658. case Mode.ALPHANUMERIC:
  1659. nodes.push([seg,
  1660. { data: seg.data, mode: Mode.BYTE, length: seg.length }
  1661. ])
  1662. break
  1663. case Mode.KANJI:
  1664. nodes.push([seg,
  1665. { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
  1666. ])
  1667. break
  1668. case Mode.BYTE:
  1669. nodes.push([
  1670. { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
  1671. ])
  1672. }
  1673. }
  1674. return nodes
  1675. }
  1676. /**
  1677. * Builds a graph from a list of nodes.
  1678. * All segments in each node group will be connected with all the segments of
  1679. * the next group and so on.
  1680. *
  1681. * At each connection will be assigned a weight depending on the
  1682. * segment's byte length.
  1683. *
  1684. * @param {Array} nodes Array of object with segments data
  1685. * @param {Number} version QR Code version
  1686. * @return {Object} Graph of all possible segments
  1687. */
  1688. function buildGraph (nodes, version) {
  1689. var table = {}
  1690. var graph = {'start': {}}
  1691. var prevNodeIds = ['start']
  1692. for (var i = 0; i < nodes.length; i++) {
  1693. var nodeGroup = nodes[i]
  1694. var currentNodeIds = []
  1695. for (var j = 0; j < nodeGroup.length; j++) {
  1696. var node = nodeGroup[j]
  1697. var key = '' + i + j
  1698. currentNodeIds.push(key)
  1699. table[key] = { node: node, lastCount: 0 }
  1700. graph[key] = {}
  1701. for (var n = 0; n < prevNodeIds.length; n++) {
  1702. var prevNodeId = prevNodeIds[n]
  1703. if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {
  1704. graph[prevNodeId][key] =
  1705. getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) -
  1706. getSegmentBitsLength(table[prevNodeId].lastCount, node.mode)
  1707. table[prevNodeId].lastCount += node.length
  1708. } else {
  1709. if (table[prevNodeId]) table[prevNodeId].lastCount = node.length
  1710. graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) +
  1711. 4 + Mode.getCharCountIndicator(node.mode, version) // switch cost
  1712. }
  1713. }
  1714. }
  1715. prevNodeIds = currentNodeIds
  1716. }
  1717. for (n = 0; n < prevNodeIds.length; n++) {
  1718. graph[prevNodeIds[n]]['end'] = 0
  1719. }
  1720. return { map: graph, table: table }
  1721. }
  1722. /**
  1723. * Builds a segment from a specified data and mode.
  1724. * If a mode is not specified, the more suitable will be used.
  1725. *
  1726. * @param {String} data Input data
  1727. * @param {Mode | String} modesHint Data mode
  1728. * @return {Segment} Segment
  1729. */
  1730. function buildSingleSegment (data, modesHint) {
  1731. var mode
  1732. var bestMode = Mode.getBestModeForData(data)
  1733. mode = Mode.from(modesHint, bestMode)
  1734. // Make sure data can be encoded
  1735. if (mode !== Mode.BYTE && mode.bit < bestMode.bit) {
  1736. throw new Error('"' + data + '"' +
  1737. ' cannot be encoded with mode ' + Mode.toString(mode) +
  1738. '.\n Suggested mode is: ' + Mode.toString(bestMode))
  1739. }
  1740. // Use Mode.BYTE if Kanji support is disabled
  1741. if (mode === Mode.KANJI && !Utils.isKanjiModeEnabled()) {
  1742. mode = Mode.BYTE
  1743. }
  1744. switch (mode) {
  1745. case Mode.NUMERIC:
  1746. return new NumericData(data)
  1747. case Mode.ALPHANUMERIC:
  1748. return new AlphanumericData(data)
  1749. case Mode.KANJI:
  1750. return new KanjiData(data)
  1751. case Mode.BYTE:
  1752. return new ByteData(data)
  1753. }
  1754. }
  1755. /**
  1756. * Builds a list of segments from an array.
  1757. * Array can contain Strings or Objects with segment's info.
  1758. *
  1759. * For each item which is a string, will be generated a segment with the given
  1760. * string and the more appropriate encoding mode.
  1761. *
  1762. * For each item which is an object, will be generated a segment with the given
  1763. * data and mode.
  1764. * Objects must contain at least the property "data".
  1765. * If property "mode" is not present, the more suitable mode will be used.
  1766. *
  1767. * @param {Array} array Array of objects with segments data
  1768. * @return {Array} Array of Segments
  1769. */
  1770. exports.fromArray = function fromArray (array) {
  1771. return array.reduce(function (acc, seg) {
  1772. if (typeof seg === 'string') {
  1773. acc.push(buildSingleSegment(seg, null))
  1774. } else if (seg.data) {
  1775. acc.push(buildSingleSegment(seg.data, seg.mode))
  1776. }
  1777. return acc
  1778. }, [])
  1779. }
  1780. /**
  1781. * Builds an optimized sequence of segments from a string,
  1782. * which will produce the shortest possible bitstream.
  1783. *
  1784. * @param {String} data Input string
  1785. * @param {Number} version QR Code version
  1786. * @return {Array} Array of segments
  1787. */
  1788. exports.fromString = function fromString (data, version) {
  1789. var segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled())
  1790. var nodes = buildNodes(segs)
  1791. var graph = buildGraph(nodes, version)
  1792. var path = dijkstra.find_path(graph.map, 'start', 'end')
  1793. var optimizedSegs = []
  1794. for (var i = 1; i < path.length - 1; i++) {
  1795. optimizedSegs.push(graph.table[path[i]].node)
  1796. }
  1797. return exports.fromArray(mergeSegments(optimizedSegs))
  1798. }
  1799. /**
  1800. * Splits a string in various segments with the modes which
  1801. * best represent their content.
  1802. * The produced segments are far from being optimized.
  1803. * The output of this function is only used to estimate a QR Code version
  1804. * which may contain the data.
  1805. *
  1806. * @param {string} data Input string
  1807. * @return {Array} Array of segments
  1808. */
  1809. exports.rawSplit = function rawSplit (data) {
  1810. return exports.fromArray(
  1811. getSegmentsFromString(data, Utils.isKanjiModeEnabled())
  1812. )
  1813. }
  1814. },{"./alphanumeric-data":3,"./byte-data":6,"./kanji-data":12,"./mode":14,"./numeric-data":15,"./regex":19,"./utils":21,"dijkstrajs":29}],21:[function(require,module,exports){
  1815. var toSJISFunction
  1816. var CODEWORDS_COUNT = [
  1817. 0, // Not used
  1818. 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,
  1819. 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,
  1820. 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,
  1821. 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706
  1822. ]
  1823. /**
  1824. * Returns the QR Code size for the specified version
  1825. *
  1826. * @param {Number} version QR Code version
  1827. * @return {Number} size of QR code
  1828. */
  1829. exports.getSymbolSize = function getSymbolSize (version) {
  1830. if (!version) throw new Error('"version" cannot be null or undefined')
  1831. if (version < 1 || version > 40) throw new Error('"version" should be in range from 1 to 40')
  1832. return version * 4 + 17
  1833. }
  1834. /**
  1835. * Returns the total number of codewords used to store data and EC information.
  1836. *
  1837. * @param {Number} version QR Code version
  1838. * @return {Number} Data length in bits
  1839. */
  1840. exports.getSymbolTotalCodewords = function getSymbolTotalCodewords (version) {
  1841. return CODEWORDS_COUNT[version]
  1842. }
  1843. /**
  1844. * Encode data with Bose-Chaudhuri-Hocquenghem
  1845. *
  1846. * @param {Number} data Value to encode
  1847. * @return {Number} Encoded value
  1848. */
  1849. exports.getBCHDigit = function (data) {
  1850. var digit = 0
  1851. while (data !== 0) {
  1852. digit++
  1853. data >>>= 1
  1854. }
  1855. return digit
  1856. }
  1857. exports.setToSJISFunction = function setToSJISFunction (f) {
  1858. if (typeof f !== 'function') {
  1859. throw new Error('"toSJISFunc" is not a valid function.')
  1860. }
  1861. toSJISFunction = f
  1862. }
  1863. exports.isKanjiModeEnabled = function () {
  1864. return typeof toSJISFunction !== 'undefined'
  1865. }
  1866. exports.toSJIS = function toSJIS (kanji) {
  1867. return toSJISFunction(kanji)
  1868. }
  1869. },{}],22:[function(require,module,exports){
  1870. /**
  1871. * Check if QR Code version is valid
  1872. *
  1873. * @param {Number} version QR Code version
  1874. * @return {Boolean} true if valid version, false otherwise
  1875. */
  1876. exports.isValid = function isValid (version) {
  1877. return !isNaN(version) && version >= 1 && version <= 40
  1878. }
  1879. },{}],23:[function(require,module,exports){
  1880. var Utils = require('./utils')
  1881. var ECCode = require('./error-correction-code')
  1882. var ECLevel = require('./error-correction-level')
  1883. var Mode = require('./mode')
  1884. var VersionCheck = require('./version-check')
  1885. var isArray = require('isarray')
  1886. // Generator polynomial used to encode version information
  1887. var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)
  1888. var G18_BCH = Utils.getBCHDigit(G18)
  1889. function getBestVersionForDataLength (mode, length, errorCorrectionLevel) {
  1890. for (var currentVersion = 1; currentVersion <= 40; currentVersion++) {
  1891. if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode)) {
  1892. return currentVersion
  1893. }
  1894. }
  1895. return undefined
  1896. }
  1897. function getReservedBitsCount (mode, version) {
  1898. // Character count indicator + mode indicator bits
  1899. return Mode.getCharCountIndicator(mode, version) + 4
  1900. }
  1901. function getTotalBitsFromDataArray (segments, version) {
  1902. var totalBits = 0
  1903. segments.forEach(function (data) {
  1904. var reservedBits = getReservedBitsCount(data.mode, version)
  1905. totalBits += reservedBits + data.getBitsLength()
  1906. })
  1907. return totalBits
  1908. }
  1909. function getBestVersionForMixedData (segments, errorCorrectionLevel) {
  1910. for (var currentVersion = 1; currentVersion <= 40; currentVersion++) {
  1911. var length = getTotalBitsFromDataArray(segments, currentVersion)
  1912. if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED)) {
  1913. return currentVersion
  1914. }
  1915. }
  1916. return undefined
  1917. }
  1918. /**
  1919. * Returns version number from a value.
  1920. * If value is not a valid version, returns defaultValue
  1921. *
  1922. * @param {Number|String} value QR Code version
  1923. * @param {Number} defaultValue Fallback value
  1924. * @return {Number} QR Code version number
  1925. */
  1926. exports.from = function from (value, defaultValue) {
  1927. if (VersionCheck.isValid(value)) {
  1928. return parseInt(value, 10)
  1929. }
  1930. return defaultValue
  1931. }
  1932. /**
  1933. * Returns how much data can be stored with the specified QR code version
  1934. * and error correction level
  1935. *
  1936. * @param {Number} version QR Code version (1-40)
  1937. * @param {Number} errorCorrectionLevel Error correction level
  1938. * @param {Mode} mode Data mode
  1939. * @return {Number} Quantity of storable data
  1940. */
  1941. exports.getCapacity = function getCapacity (version, errorCorrectionLevel, mode) {
  1942. if (!VersionCheck.isValid(version)) {
  1943. throw new Error('Invalid QR Code version')
  1944. }
  1945. // Use Byte mode as default
  1946. if (typeof mode === 'undefined') mode = Mode.BYTE
  1947. // Total codewords for this QR code version (Data + Error correction)
  1948. var totalCodewords = Utils.getSymbolTotalCodewords(version)
  1949. // Total number of error correction codewords
  1950. var ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)
  1951. // Total number of data codewords
  1952. var dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8
  1953. if (mode === Mode.MIXED) return dataTotalCodewordsBits
  1954. var usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version)
  1955. // Return max number of storable codewords
  1956. switch (mode) {
  1957. case Mode.NUMERIC:
  1958. return Math.floor((usableBits / 10) * 3)
  1959. case Mode.ALPHANUMERIC:
  1960. return Math.floor((usableBits / 11) * 2)
  1961. case Mode.KANJI:
  1962. return Math.floor(usableBits / 13)
  1963. case Mode.BYTE:
  1964. default:
  1965. return Math.floor(usableBits / 8)
  1966. }
  1967. }
  1968. /**
  1969. * Returns the minimum version needed to contain the amount of data
  1970. *
  1971. * @param {Segment} data Segment of data
  1972. * @param {Number} [errorCorrectionLevel=H] Error correction level
  1973. * @param {Mode} mode Data mode
  1974. * @return {Number} QR Code version
  1975. */
  1976. exports.getBestVersionForData = function getBestVersionForData (data, errorCorrectionLevel) {
  1977. var seg
  1978. var ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M)
  1979. if (isArray(data)) {
  1980. if (data.length > 1) {
  1981. return getBestVersionForMixedData(data, ecl)
  1982. }
  1983. if (data.length === 0) {
  1984. return 1
  1985. }
  1986. seg = data[0]
  1987. } else {
  1988. seg = data
  1989. }
  1990. return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl)
  1991. }
  1992. /**
  1993. * Returns version information with relative error correction bits
  1994. *
  1995. * The version information is included in QR Code symbols of version 7 or larger.
  1996. * It consists of an 18-bit sequence containing 6 data bits,
  1997. * with 12 error correction bits calculated using the (18, 6) Golay code.
  1998. *
  1999. * @param {Number} version QR Code version
  2000. * @return {Number} Encoded version info bits
  2001. */
  2002. exports.getEncodedBits = function getEncodedBits (version) {
  2003. if (!VersionCheck.isValid(version) || version < 7) {
  2004. throw new Error('Invalid QR Code version')
  2005. }
  2006. var d = version << 12
  2007. while (Utils.getBCHDigit(d) - G18_BCH >= 0) {
  2008. d ^= (G18 << (Utils.getBCHDigit(d) - G18_BCH))
  2009. }
  2010. return (version << 12) | d
  2011. }
  2012. },{"./error-correction-code":7,"./error-correction-level":8,"./mode":14,"./utils":21,"./version-check":22,"isarray":30}],24:[function(require,module,exports){
  2013. var canPromise = require('./can-promise')
  2014. var QRCode = require('./core/qrcode')
  2015. var CanvasRenderer = require('./renderer/canvas')
  2016. var SvgRenderer = require('./renderer/svg-tag.js')
  2017. function renderCanvas (renderFunc, canvas, text, opts, cb) {
  2018. var args = [].slice.call(arguments, 1)
  2019. var argsNum = args.length
  2020. var isLastArgCb = typeof args[argsNum - 1] === 'function'
  2021. if (!isLastArgCb && !canPromise()) {
  2022. throw new Error('Callback required as last argument')
  2023. }
  2024. if (isLastArgCb) {
  2025. if (argsNum < 2) {
  2026. throw new Error('Too few arguments provided')
  2027. }
  2028. if (argsNum === 2) {
  2029. cb = text
  2030. text = canvas
  2031. canvas = opts = undefined
  2032. } else if (argsNum === 3) {
  2033. if (canvas.getContext && typeof cb === 'undefined') {
  2034. cb = opts
  2035. opts = undefined
  2036. } else {
  2037. cb = opts
  2038. opts = text
  2039. text = canvas
  2040. canvas = undefined
  2041. }
  2042. }
  2043. } else {
  2044. if (argsNum < 1) {
  2045. throw new Error('Too few arguments provided')
  2046. }
  2047. if (argsNum === 1) {
  2048. text = canvas
  2049. canvas = opts = undefined
  2050. } else if (argsNum === 2 && !canvas.getContext) {
  2051. opts = text
  2052. text = canvas
  2053. canvas = undefined
  2054. }
  2055. return new Promise(function (resolve, reject) {
  2056. try {
  2057. var data = QRCode.create(text, opts)
  2058. resolve(renderFunc(data, canvas, opts))
  2059. } catch (e) {
  2060. reject(e)
  2061. }
  2062. })
  2063. }
  2064. try {
  2065. var data = QRCode.create(text, opts)
  2066. cb(null, renderFunc(data, canvas, opts))
  2067. } catch (e) {
  2068. cb(e)
  2069. }
  2070. }
  2071. exports.create = QRCode.create
  2072. exports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render)
  2073. exports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL)
  2074. // only svg for now.
  2075. exports.toString = renderCanvas.bind(null, function (data, _, opts) {
  2076. return SvgRenderer.render(data, opts)
  2077. })
  2078. },{"./can-promise":1,"./core/qrcode":17,"./renderer/canvas":25,"./renderer/svg-tag.js":26}],25:[function(require,module,exports){
  2079. var Utils = require('./utils')
  2080. function clearCanvas (ctx, canvas, size) {
  2081. ctx.clearRect(0, 0, canvas.width, canvas.height)
  2082. if (!canvas.style) canvas.style = {}
  2083. canvas.height = size
  2084. canvas.width = size
  2085. canvas.style.height = size + 'px'
  2086. canvas.style.width = size + 'px'
  2087. }
  2088. function getCanvasElement () {
  2089. try {
  2090. return document.createElement('canvas')
  2091. } catch (e) {
  2092. throw new Error('You need to specify a canvas element')
  2093. }
  2094. }
  2095. exports.render = function render (qrData, canvas, options) {
  2096. var opts = options
  2097. var canvasEl = canvas
  2098. if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {
  2099. opts = canvas
  2100. canvas = undefined
  2101. }
  2102. if (!canvas) {
  2103. canvasEl = getCanvasElement()
  2104. }
  2105. opts = Utils.getOptions(opts)
  2106. var size = Utils.getImageWidth(qrData.modules.size, opts)
  2107. var ctx = canvasEl.getContext('2d')
  2108. var image = ctx.createImageData(size, size)
  2109. Utils.qrToImageData(image.data, qrData, opts)
  2110. clearCanvas(ctx, canvasEl, size)
  2111. ctx.putImageData(image, 0, 0)
  2112. return canvasEl
  2113. }
  2114. exports.renderToDataURL = function renderToDataURL (qrData, canvas, options) {
  2115. var opts = options
  2116. if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {
  2117. opts = canvas
  2118. canvas = undefined
  2119. }
  2120. if (!opts) opts = {}
  2121. var canvasEl = exports.render(qrData, canvas, opts)
  2122. var type = opts.type || 'image/png'
  2123. var rendererOpts = opts.rendererOpts || {}
  2124. return canvasEl.toDataURL(type, rendererOpts.quality)
  2125. }
  2126. },{"./utils":27}],26:[function(require,module,exports){
  2127. var Utils = require('./utils')
  2128. function getColorAttrib (color, attrib) {
  2129. var alpha = color.a / 255
  2130. var str = attrib + '="' + color.hex + '"'
  2131. return alpha < 1
  2132. ? str + ' ' + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"'
  2133. : str
  2134. }
  2135. function svgCmd (cmd, x, y) {
  2136. var str = cmd + x
  2137. if (typeof y !== 'undefined') str += ' ' + y
  2138. return str
  2139. }
  2140. function qrToPath (data, size, margin) {
  2141. var path = ''
  2142. var moveBy = 0
  2143. var newRow = false
  2144. var lineLength = 0
  2145. for (var i = 0; i < data.length; i++) {
  2146. var col = Math.floor(i % size)
  2147. var row = Math.floor(i / size)
  2148. if (!col && !newRow) newRow = true
  2149. if (data[i]) {
  2150. lineLength++
  2151. if (!(i > 0 && col > 0 && data[i - 1])) {
  2152. path += newRow
  2153. ? svgCmd('M', col + margin, 0.5 + row + margin)
  2154. : svgCmd('m', moveBy, 0)
  2155. moveBy = 0
  2156. newRow = false
  2157. }
  2158. if (!(col + 1 < size && data[i + 1])) {
  2159. path += svgCmd('h', lineLength)
  2160. lineLength = 0
  2161. }
  2162. } else {
  2163. moveBy++
  2164. }
  2165. }
  2166. return path
  2167. }
  2168. exports.render = function render (qrData, options, cb) {
  2169. var opts = Utils.getOptions(options)
  2170. var size = qrData.modules.size
  2171. var data = qrData.modules.data
  2172. var qrcodesize = size + opts.margin * 2
  2173. var bg = !opts.color.light.a
  2174. ? ''
  2175. : '<path ' + getColorAttrib(opts.color.light, 'fill') +
  2176. ' d="M0 0h' + qrcodesize + 'v' + qrcodesize + 'H0z"/>'
  2177. var path =
  2178. '<path ' + getColorAttrib(opts.color.dark, 'stroke') +
  2179. ' d="' + qrToPath(data, size, opts.margin) + '"/>'
  2180. var viewBox = 'viewBox="' + '0 0 ' + qrcodesize + ' ' + qrcodesize + '"'
  2181. var width = !opts.width ? '' : 'width="' + opts.width + '" height="' + opts.width + '" '
  2182. var svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path + '</svg>\n'
  2183. if (typeof cb === 'function') {
  2184. cb(null, svgTag)
  2185. }
  2186. return svgTag
  2187. }
  2188. },{"./utils":27}],27:[function(require,module,exports){
  2189. function hex2rgba (hex) {
  2190. if (typeof hex === 'number') {
  2191. hex = hex.toString()
  2192. }
  2193. if (typeof hex !== 'string') {
  2194. throw new Error('Color should be defined as hex string')
  2195. }
  2196. var hexCode = hex.slice().replace('#', '').split('')
  2197. if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8) {
  2198. throw new Error('Invalid hex color: ' + hex)
  2199. }
  2200. // Convert from short to long form (fff -> ffffff)
  2201. if (hexCode.length === 3 || hexCode.length === 4) {
  2202. hexCode = Array.prototype.concat.apply([], hexCode.map(function (c) {
  2203. return [c, c]
  2204. }))
  2205. }
  2206. // Add default alpha value
  2207. if (hexCode.length === 6) hexCode.push('F', 'F')
  2208. var hexValue = parseInt(hexCode.join(''), 16)
  2209. return {
  2210. r: (hexValue >> 24) & 255,
  2211. g: (hexValue >> 16) & 255,
  2212. b: (hexValue >> 8) & 255,
  2213. a: hexValue & 255,
  2214. hex: '#' + hexCode.slice(0, 6).join('')
  2215. }
  2216. }
  2217. exports.getOptions = function getOptions (options) {
  2218. if (!options) options = {}
  2219. if (!options.color) options.color = {}
  2220. var margin = typeof options.margin === 'undefined' ||
  2221. options.margin === null ||
  2222. options.margin < 0 ? 4 : options.margin
  2223. var width = options.width && options.width >= 21 ? options.width : undefined
  2224. var scale = options.scale || 4
  2225. return {
  2226. width: width,
  2227. scale: width ? 4 : scale,
  2228. margin: margin,
  2229. color: {
  2230. dark: hex2rgba(options.color.dark || '#000000ff'),
  2231. light: hex2rgba(options.color.light || '#ffffffff')
  2232. },
  2233. type: options.type,
  2234. rendererOpts: options.rendererOpts || {}
  2235. }
  2236. }
  2237. exports.getScale = function getScale (qrSize, opts) {
  2238. return opts.width && opts.width >= qrSize + opts.margin * 2
  2239. ? opts.width / (qrSize + opts.margin * 2)
  2240. : opts.scale
  2241. }
  2242. exports.getImageWidth = function getImageWidth (qrSize, opts) {
  2243. var scale = exports.getScale(qrSize, opts)
  2244. return Math.floor((qrSize + opts.margin * 2) * scale)
  2245. }
  2246. exports.qrToImageData = function qrToImageData (imgData, qr, opts) {
  2247. var size = qr.modules.size
  2248. var data = qr.modules.data
  2249. var scale = exports.getScale(size, opts)
  2250. var symbolSize = Math.floor((size + opts.margin * 2) * scale)
  2251. var scaledMargin = opts.margin * scale
  2252. var palette = [opts.color.light, opts.color.dark]
  2253. for (var i = 0; i < symbolSize; i++) {
  2254. for (var j = 0; j < symbolSize; j++) {
  2255. var posDst = (i * symbolSize + j) * 4
  2256. var pxColor = opts.color.light
  2257. if (i >= scaledMargin && j >= scaledMargin &&
  2258. i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {
  2259. var iSrc = Math.floor((i - scaledMargin) / scale)
  2260. var jSrc = Math.floor((j - scaledMargin) / scale)
  2261. pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0]
  2262. }
  2263. imgData[posDst++] = pxColor.r
  2264. imgData[posDst++] = pxColor.g
  2265. imgData[posDst++] = pxColor.b
  2266. imgData[posDst] = pxColor.a
  2267. }
  2268. }
  2269. }
  2270. },{}],28:[function(require,module,exports){
  2271. /**
  2272. * Implementation of a subset of node.js Buffer methods for the browser.
  2273. * Based on https://github.com/feross/buffer
  2274. */
  2275. /* eslint-disable no-proto */
  2276. 'use strict'
  2277. var isArray = require('isarray')
  2278. function typedArraySupport () {
  2279. // Can typed array instances be augmented?
  2280. try {
  2281. var arr = new Uint8Array(1)
  2282. arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
  2283. return arr.foo() === 42
  2284. } catch (e) {
  2285. return false
  2286. }
  2287. }
  2288. Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
  2289. var K_MAX_LENGTH = Buffer.TYPED_ARRAY_SUPPORT
  2290. ? 0x7fffffff
  2291. : 0x3fffffff
  2292. function Buffer (arg, offset, length) {
  2293. if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
  2294. return new Buffer(arg, offset, length)
  2295. }
  2296. if (typeof arg === 'number') {
  2297. return allocUnsafe(this, arg)
  2298. }
  2299. return from(this, arg, offset, length)
  2300. }
  2301. if (Buffer.TYPED_ARRAY_SUPPORT) {
  2302. Buffer.prototype.__proto__ = Uint8Array.prototype
  2303. Buffer.__proto__ = Uint8Array
  2304. // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
  2305. if (typeof Symbol !== 'undefined' && Symbol.species &&
  2306. Buffer[Symbol.species] === Buffer) {
  2307. Object.defineProperty(Buffer, Symbol.species, {
  2308. value: null,
  2309. configurable: true,
  2310. enumerable: false,
  2311. writable: false
  2312. })
  2313. }
  2314. }
  2315. function checked (length) {
  2316. // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
  2317. // length is NaN (which is otherwise coerced to zero.)
  2318. if (length >= K_MAX_LENGTH) {
  2319. throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
  2320. 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
  2321. }
  2322. return length | 0
  2323. }
  2324. function isnan (val) {
  2325. return val !== val // eslint-disable-line no-self-compare
  2326. }
  2327. function createBuffer (that, length) {
  2328. var buf
  2329. if (Buffer.TYPED_ARRAY_SUPPORT) {
  2330. buf = new Uint8Array(length)
  2331. buf.__proto__ = Buffer.prototype
  2332. } else {
  2333. // Fallback: Return an object instance of the Buffer class
  2334. buf = that
  2335. if (buf === null) {
  2336. buf = new Buffer(length)
  2337. }
  2338. buf.length = length
  2339. }
  2340. return buf
  2341. }
  2342. function allocUnsafe (that, size) {
  2343. var buf = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
  2344. if (!Buffer.TYPED_ARRAY_SUPPORT) {
  2345. for (var i = 0; i < size; ++i) {
  2346. buf[i] = 0
  2347. }
  2348. }
  2349. return buf
  2350. }
  2351. function fromString (that, string) {
  2352. var length = byteLength(string) | 0
  2353. var buf = createBuffer(that, length)
  2354. var actual = buf.write(string)
  2355. if (actual !== length) {
  2356. // Writing a hex string, for example, that contains invalid characters will
  2357. // cause everything after the first invalid character to be ignored. (e.g.
  2358. // 'abxxcd' will be treated as 'ab')
  2359. buf = buf.slice(0, actual)
  2360. }
  2361. return buf
  2362. }
  2363. function fromArrayLike (that, array) {
  2364. var length = array.length < 0 ? 0 : checked(array.length) | 0
  2365. var buf = createBuffer(that, length)
  2366. for (var i = 0; i < length; i += 1) {
  2367. buf[i] = array[i] & 255
  2368. }
  2369. return buf
  2370. }
  2371. function fromArrayBuffer (that, array, byteOffset, length) {
  2372. if (byteOffset < 0 || array.byteLength < byteOffset) {
  2373. throw new RangeError('\'offset\' is out of bounds')
  2374. }
  2375. if (array.byteLength < byteOffset + (length || 0)) {
  2376. throw new RangeError('\'length\' is out of bounds')
  2377. }
  2378. var buf
  2379. if (byteOffset === undefined && length === undefined) {
  2380. buf = new Uint8Array(array)
  2381. } else if (length === undefined) {
  2382. buf = new Uint8Array(array, byteOffset)
  2383. } else {
  2384. buf = new Uint8Array(array, byteOffset, length)
  2385. }
  2386. if (Buffer.TYPED_ARRAY_SUPPORT) {
  2387. // Return an augmented `Uint8Array` instance, for best performance
  2388. buf.__proto__ = Buffer.prototype
  2389. } else {
  2390. // Fallback: Return an object instance of the Buffer class
  2391. buf = fromArrayLike(that, buf)
  2392. }
  2393. return buf
  2394. }
  2395. function fromObject (that, obj) {
  2396. if (Buffer.isBuffer(obj)) {
  2397. var len = checked(obj.length) | 0
  2398. var buf = createBuffer(that, len)
  2399. if (buf.length === 0) {
  2400. return buf
  2401. }
  2402. obj.copy(buf, 0, 0, len)
  2403. return buf
  2404. }
  2405. if (obj) {
  2406. if ((typeof ArrayBuffer !== 'undefined' &&
  2407. obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
  2408. if (typeof obj.length !== 'number' || isnan(obj.length)) {
  2409. return createBuffer(that, 0)
  2410. }
  2411. return fromArrayLike(that, obj)
  2412. }
  2413. if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
  2414. return fromArrayLike(that, obj.data)
  2415. }
  2416. }
  2417. throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
  2418. }
  2419. function utf8ToBytes (string, units) {
  2420. units = units || Infinity
  2421. var codePoint
  2422. var length = string.length
  2423. var leadSurrogate = null
  2424. var bytes = []
  2425. for (var i = 0; i < length; ++i) {
  2426. codePoint = string.charCodeAt(i)
  2427. // is surrogate component
  2428. if (codePoint > 0xD7FF && codePoint < 0xE000) {
  2429. // last char was a lead
  2430. if (!leadSurrogate) {
  2431. // no lead yet
  2432. if (codePoint > 0xDBFF) {
  2433. // unexpected trail
  2434. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  2435. continue
  2436. } else if (i + 1 === length) {
  2437. // unpaired lead
  2438. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  2439. continue
  2440. }
  2441. // valid lead
  2442. leadSurrogate = codePoint
  2443. continue
  2444. }
  2445. // 2 leads in a row
  2446. if (codePoint < 0xDC00) {
  2447. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  2448. leadSurrogate = codePoint
  2449. continue
  2450. }
  2451. // valid surrogate pair
  2452. codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
  2453. } else if (leadSurrogate) {
  2454. // valid bmp char, but last char was a lead
  2455. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  2456. }
  2457. leadSurrogate = null
  2458. // encode utf8
  2459. if (codePoint < 0x80) {
  2460. if ((units -= 1) < 0) break
  2461. bytes.push(codePoint)
  2462. } else if (codePoint < 0x800) {
  2463. if ((units -= 2) < 0) break
  2464. bytes.push(
  2465. codePoint >> 0x6 | 0xC0,
  2466. codePoint & 0x3F | 0x80
  2467. )
  2468. } else if (codePoint < 0x10000) {
  2469. if ((units -= 3) < 0) break
  2470. bytes.push(
  2471. codePoint >> 0xC | 0xE0,
  2472. codePoint >> 0x6 & 0x3F | 0x80,
  2473. codePoint & 0x3F | 0x80
  2474. )
  2475. } else if (codePoint < 0x110000) {
  2476. if ((units -= 4) < 0) break
  2477. bytes.push(
  2478. codePoint >> 0x12 | 0xF0,
  2479. codePoint >> 0xC & 0x3F | 0x80,
  2480. codePoint >> 0x6 & 0x3F | 0x80,
  2481. codePoint & 0x3F | 0x80
  2482. )
  2483. } else {
  2484. throw new Error('Invalid code point')
  2485. }
  2486. }
  2487. return bytes
  2488. }
  2489. function byteLength (string) {
  2490. if (Buffer.isBuffer(string)) {
  2491. return string.length
  2492. }
  2493. if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
  2494. (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
  2495. return string.byteLength
  2496. }
  2497. if (typeof string !== 'string') {
  2498. string = '' + string
  2499. }
  2500. var len = string.length
  2501. if (len === 0) return 0
  2502. return utf8ToBytes(string).length
  2503. }
  2504. function blitBuffer (src, dst, offset, length) {
  2505. for (var i = 0; i < length; ++i) {
  2506. if ((i + offset >= dst.length) || (i >= src.length)) break
  2507. dst[i + offset] = src[i]
  2508. }
  2509. return i
  2510. }
  2511. function utf8Write (buf, string, offset, length) {
  2512. return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  2513. }
  2514. function from (that, value, offset, length) {
  2515. if (typeof value === 'number') {
  2516. throw new TypeError('"value" argument must not be a number')
  2517. }
  2518. if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
  2519. return fromArrayBuffer(that, value, offset, length)
  2520. }
  2521. if (typeof value === 'string') {
  2522. return fromString(that, value, offset)
  2523. }
  2524. return fromObject(that, value)
  2525. }
  2526. Buffer.prototype.write = function write (string, offset, length) {
  2527. // Buffer#write(string)
  2528. if (offset === undefined) {
  2529. length = this.length
  2530. offset = 0
  2531. // Buffer#write(string, encoding)
  2532. } else if (length === undefined && typeof offset === 'string') {
  2533. length = this.length
  2534. offset = 0
  2535. // Buffer#write(string, offset[, length])
  2536. } else if (isFinite(offset)) {
  2537. offset = offset | 0
  2538. if (isFinite(length)) {
  2539. length = length | 0
  2540. } else {
  2541. length = undefined
  2542. }
  2543. }
  2544. var remaining = this.length - offset
  2545. if (length === undefined || length > remaining) length = remaining
  2546. if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
  2547. throw new RangeError('Attempt to write outside buffer bounds')
  2548. }
  2549. return utf8Write(this, string, offset, length)
  2550. }
  2551. Buffer.prototype.slice = function slice (start, end) {
  2552. var len = this.length
  2553. start = ~~start
  2554. end = end === undefined ? len : ~~end
  2555. if (start < 0) {
  2556. start += len
  2557. if (start < 0) start = 0
  2558. } else if (start > len) {
  2559. start = len
  2560. }
  2561. if (end < 0) {
  2562. end += len
  2563. if (end < 0) end = 0
  2564. } else if (end > len) {
  2565. end = len
  2566. }
  2567. if (end < start) end = start
  2568. var newBuf
  2569. if (Buffer.TYPED_ARRAY_SUPPORT) {
  2570. newBuf = this.subarray(start, end)
  2571. // Return an augmented `Uint8Array` instance
  2572. newBuf.__proto__ = Buffer.prototype
  2573. } else {
  2574. var sliceLen = end - start
  2575. newBuf = new Buffer(sliceLen, undefined)
  2576. for (var i = 0; i < sliceLen; ++i) {
  2577. newBuf[i] = this[i + start]
  2578. }
  2579. }
  2580. return newBuf
  2581. }
  2582. Buffer.prototype.copy = function copy (target, targetStart, start, end) {
  2583. if (!start) start = 0
  2584. if (!end && end !== 0) end = this.length
  2585. if (targetStart >= target.length) targetStart = target.length
  2586. if (!targetStart) targetStart = 0
  2587. if (end > 0 && end < start) end = start
  2588. // Copy 0 bytes; we're done
  2589. if (end === start) return 0
  2590. if (target.length === 0 || this.length === 0) return 0
  2591. // Fatal error conditions
  2592. if (targetStart < 0) {
  2593. throw new RangeError('targetStart out of bounds')
  2594. }
  2595. if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
  2596. if (end < 0) throw new RangeError('sourceEnd out of bounds')
  2597. // Are we oob?
  2598. if (end > this.length) end = this.length
  2599. if (target.length - targetStart < end - start) {
  2600. end = target.length - targetStart + start
  2601. }
  2602. var len = end - start
  2603. var i
  2604. if (this === target && start < targetStart && targetStart < end) {
  2605. // descending copy from end
  2606. for (i = len - 1; i >= 0; --i) {
  2607. target[i + targetStart] = this[i + start]
  2608. }
  2609. } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
  2610. // ascending copy from start
  2611. for (i = 0; i < len; ++i) {
  2612. target[i + targetStart] = this[i + start]
  2613. }
  2614. } else {
  2615. Uint8Array.prototype.set.call(
  2616. target,
  2617. this.subarray(start, start + len),
  2618. targetStart
  2619. )
  2620. }
  2621. return len
  2622. }
  2623. Buffer.prototype.fill = function fill (val, start, end) {
  2624. // Handle string cases:
  2625. if (typeof val === 'string') {
  2626. if (typeof start === 'string') {
  2627. start = 0
  2628. end = this.length
  2629. } else if (typeof end === 'string') {
  2630. end = this.length
  2631. }
  2632. if (val.length === 1) {
  2633. var code = val.charCodeAt(0)
  2634. if (code < 256) {
  2635. val = code
  2636. }
  2637. }
  2638. } else if (typeof val === 'number') {
  2639. val = val & 255
  2640. }
  2641. // Invalid ranges are not set to a default, so can range check early.
  2642. if (start < 0 || this.length < start || this.length < end) {
  2643. throw new RangeError('Out of range index')
  2644. }
  2645. if (end <= start) {
  2646. return this
  2647. }
  2648. start = start >>> 0
  2649. end = end === undefined ? this.length : end >>> 0
  2650. if (!val) val = 0
  2651. var i
  2652. if (typeof val === 'number') {
  2653. for (i = start; i < end; ++i) {
  2654. this[i] = val
  2655. }
  2656. } else {
  2657. var bytes = Buffer.isBuffer(val)
  2658. ? val
  2659. : new Buffer(val)
  2660. var len = bytes.length
  2661. for (i = 0; i < end - start; ++i) {
  2662. this[i + start] = bytes[i % len]
  2663. }
  2664. }
  2665. return this
  2666. }
  2667. Buffer.concat = function concat (list, length) {
  2668. if (!isArray(list)) {
  2669. throw new TypeError('"list" argument must be an Array of Buffers')
  2670. }
  2671. if (list.length === 0) {
  2672. return createBuffer(null, 0)
  2673. }
  2674. var i
  2675. if (length === undefined) {
  2676. length = 0
  2677. for (i = 0; i < list.length; ++i) {
  2678. length += list[i].length
  2679. }
  2680. }
  2681. var buffer = allocUnsafe(null, length)
  2682. var pos = 0
  2683. for (i = 0; i < list.length; ++i) {
  2684. var buf = list[i]
  2685. if (!Buffer.isBuffer(buf)) {
  2686. throw new TypeError('"list" argument must be an Array of Buffers')
  2687. }
  2688. buf.copy(buffer, pos)
  2689. pos += buf.length
  2690. }
  2691. return buffer
  2692. }
  2693. Buffer.byteLength = byteLength
  2694. Buffer.prototype._isBuffer = true
  2695. Buffer.isBuffer = function isBuffer (b) {
  2696. return !!(b != null && b._isBuffer)
  2697. }
  2698. module.exports = Buffer
  2699. },{"isarray":30}],29:[function(require,module,exports){
  2700. 'use strict';
  2701. /******************************************************************************
  2702. * Created 2008-08-19.
  2703. *
  2704. * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.
  2705. *
  2706. * Copyright (C) 2008
  2707. * Wyatt Baldwin <self@wyattbaldwin.com>
  2708. * All rights reserved
  2709. *
  2710. * Licensed under the MIT license.
  2711. *
  2712. * http://www.opensource.org/licenses/mit-license.php
  2713. *
  2714. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2715. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2716. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2717. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2718. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2719. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  2720. * THE SOFTWARE.
  2721. *****************************************************************************/
  2722. var dijkstra = {
  2723. single_source_shortest_paths: function(graph, s, d) {
  2724. // Predecessor map for each node that has been encountered.
  2725. // node ID => predecessor node ID
  2726. var predecessors = {};
  2727. // Costs of shortest paths from s to all nodes encountered.
  2728. // node ID => cost
  2729. var costs = {};
  2730. costs[s] = 0;
  2731. // Costs of shortest paths from s to all nodes encountered; differs from
  2732. // `costs` in that it provides easy access to the node that currently has
  2733. // the known shortest path from s.
  2734. // XXX: Do we actually need both `costs` and `open`?
  2735. var open = dijkstra.PriorityQueue.make();
  2736. open.push(s, 0);
  2737. var closest,
  2738. u, v,
  2739. cost_of_s_to_u,
  2740. adjacent_nodes,
  2741. cost_of_e,
  2742. cost_of_s_to_u_plus_cost_of_e,
  2743. cost_of_s_to_v,
  2744. first_visit;
  2745. while (!open.empty()) {
  2746. // In the nodes remaining in graph that have a known cost from s,
  2747. // find the node, u, that currently has the shortest path from s.
  2748. closest = open.pop();
  2749. u = closest.value;
  2750. cost_of_s_to_u = closest.cost;
  2751. // Get nodes adjacent to u...
  2752. adjacent_nodes = graph[u] || {};
  2753. // ...and explore the edges that connect u to those nodes, updating
  2754. // the cost of the shortest paths to any or all of those nodes as
  2755. // necessary. v is the node across the current edge from u.
  2756. for (v in adjacent_nodes) {
  2757. if (adjacent_nodes.hasOwnProperty(v)) {
  2758. // Get the cost of the edge running from u to v.
  2759. cost_of_e = adjacent_nodes[v];
  2760. // Cost of s to u plus the cost of u to v across e--this is *a*
  2761. // cost from s to v that may or may not be less than the current
  2762. // known cost to v.
  2763. cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;
  2764. // If we haven't visited v yet OR if the current known cost from s to
  2765. // v is greater than the new cost we just found (cost of s to u plus
  2766. // cost of u to v across e), update v's cost in the cost list and
  2767. // update v's predecessor in the predecessor list (it's now u).
  2768. cost_of_s_to_v = costs[v];
  2769. first_visit = (typeof costs[v] === 'undefined');
  2770. if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
  2771. costs[v] = cost_of_s_to_u_plus_cost_of_e;
  2772. open.push(v, cost_of_s_to_u_plus_cost_of_e);
  2773. predecessors[v] = u;
  2774. }
  2775. }
  2776. }
  2777. }
  2778. if (typeof d !== 'undefined' && typeof costs[d] === 'undefined') {
  2779. var msg = ['Could not find a path from ', s, ' to ', d, '.'].join('');
  2780. throw new Error(msg);
  2781. }
  2782. return predecessors;
  2783. },
  2784. extract_shortest_path_from_predecessor_list: function(predecessors, d) {
  2785. var nodes = [];
  2786. var u = d;
  2787. var predecessor;
  2788. while (u) {
  2789. nodes.push(u);
  2790. predecessor = predecessors[u];
  2791. u = predecessors[u];
  2792. }
  2793. nodes.reverse();
  2794. return nodes;
  2795. },
  2796. find_path: function(graph, s, d) {
  2797. var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);
  2798. return dijkstra.extract_shortest_path_from_predecessor_list(
  2799. predecessors, d);
  2800. },
  2801. /**
  2802. * A very naive priority queue implementation.
  2803. */
  2804. PriorityQueue: {
  2805. make: function (opts) {
  2806. var T = dijkstra.PriorityQueue,
  2807. t = {},
  2808. key;
  2809. opts = opts || {};
  2810. for (key in T) {
  2811. if (T.hasOwnProperty(key)) {
  2812. t[key] = T[key];
  2813. }
  2814. }
  2815. t.queue = [];
  2816. t.sorter = opts.sorter || T.default_sorter;
  2817. return t;
  2818. },
  2819. default_sorter: function (a, b) {
  2820. return a.cost - b.cost;
  2821. },
  2822. /**
  2823. * Add a new item to the queue and ensure the highest priority element
  2824. * is at the front of the queue.
  2825. */
  2826. push: function (value, cost) {
  2827. var item = {value: value, cost: cost};
  2828. this.queue.push(item);
  2829. this.queue.sort(this.sorter);
  2830. },
  2831. /**
  2832. * Return the highest priority element in the queue.
  2833. */
  2834. pop: function () {
  2835. return this.queue.shift();
  2836. },
  2837. empty: function () {
  2838. return this.queue.length === 0;
  2839. }
  2840. }
  2841. };
  2842. // node.js module exports
  2843. if (typeof module !== 'undefined') {
  2844. module.exports = dijkstra;
  2845. }
  2846. },{}],30:[function(require,module,exports){
  2847. var toString = {}.toString;
  2848. module.exports = Array.isArray || function (arr) {
  2849. return toString.call(arr) == '[object Array]';
  2850. };
  2851. },{}]},{},[24])(24)
  2852. });
  2853. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvY2FuLXByb21pc2UuanMiLCJsaWIvY29yZS9hbGlnbm1lbnQtcGF0dGVybi5qcyIsImxpYi9jb3JlL2FscGhhbnVtZXJpYy1kYXRhLmpzIiwibGliL2NvcmUvYml0LWJ1ZmZlci5qcyIsImxpYi9jb3JlL2JpdC1tYXRyaXguanMiLCJsaWIvY29yZS9ieXRlLWRhdGEuanMiLCJsaWIvY29yZS9lcnJvci1jb3JyZWN0aW9uLWNvZGUuanMiLCJsaWIvY29yZS9lcnJvci1jb3JyZWN0aW9uLWxldmVsLmpzIiwibGliL2NvcmUvZmluZGVyLXBhdHRlcm4uanMiLCJsaWIvY29yZS9mb3JtYXQtaW5mby5qcyIsImxpYi9jb3JlL2dhbG9pcy1maWVsZC5qcyIsImxpYi9jb3JlL2thbmppLWRhdGEuanMiLCJsaWIvY29yZS9tYXNrLXBhdHRlcm4uanMiLCJsaWIvY29yZS9tb2RlLmpzIiwibGliL2NvcmUvbnVtZXJpYy1kYXRhLmpzIiwibGliL2NvcmUvcG9seW5vbWlhbC5qcyIsImxpYi9jb3JlL3FyY29kZS5qcyIsImxpYi9jb3JlL3JlZWQtc29sb21vbi1lbmNvZGVyLmpzIiwibGliL2NvcmUvcmVnZXguanMiLCJsaWIvY29yZS9zZWdtZW50cy5qcyIsImxpYi9jb3JlL3V0aWxzLmpzIiwibGliL2NvcmUvdmVyc2lvbi1jaGVjay5qcyIsImxpYi9jb3JlL3ZlcnNpb24uanMiLCJsaWIvaW5kZXguanMiLCJsaWIvcmVuZGVyZXIvY2FudmFzLmpzIiwibGliL3JlbmRlcmVyL3N2Zy10YWcuanMiLCJsaWIvcmVuZGVyZXIvdXRpbHMuanMiLCJsaWIvdXRpbHMvdHlwZWRhcnJheS1idWZmZXIuanMiLCJub2RlX21vZHVsZXMvZGlqa3N0cmFqcy9kaWprc3RyYS5qcyIsIm5vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25mQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBjYW4tcHJvbWlzZSBoYXMgYSBjcmFzaCBpbiBzb21lIHZlcnNpb25zIG9mIHJlYWN0IG5hdGl2ZSB0aGF0IGRvbnQgaGF2ZVxuLy8gc3RhbmRhcmQgZ2xvYmFsIG9iamVjdHNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zb2xkYWlyL25vZGUtcXJjb2RlL2lzc3Vlcy8xNTdcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0eXBlb2YgUHJvbWlzZSA9PT0gJ2Z1bmN0aW9uJyAmJiBQcm9taXNlLnByb3RvdHlwZSAmJiBQcm9taXNlLnByb3RvdHlwZS50aGVuXG59XG4iLCIvKipcbiAqIEFsaWdubWVudCBwYXR0ZXJuIGFyZSBmaXhlZCByZWZlcmVuY2UgcGF0dGVybiBpbiBkZWZpbmVkIHBvc2l0aW9uc1xuICogaW4gYSBtYXRyaXggc3ltYm9sb2d5LCB3aGljaCBlbmFibGVzIHRoZSBkZWNvZGUgc29mdHdhcmUgdG8gcmUtc3luY2hyb25pc2VcbiAqIHRoZSBjb29yZGluYXRlIG1hcHBpbmcgb2YgdGhlIGltYWdlIG1vZHVsZXMgaW4gdGhlIGV2ZW50IG9mIG1vZGVyYXRlIGFtb3VudHNcbiAqIG9mIGRpc3RvcnRpb24gb2YgdGhlIGltYWdlLlxuICpcbiAqIEFsaWdubWVudCBwYXR0ZXJucyBhcmUgcHJlc2VudCBvbmx5IGluIFFSIENvZGUgc3ltYm9scyBvZiB2ZXJzaW9uIDIgb3IgbGFyZ2VyXG4gKiBhbmQgdGhlaXIgbnVtYmVyIGRlcGVuZHMgb24gdGhlIHN5bWJvbCB2ZXJzaW9uLlxuICovXG5cbnZhciBnZXRTeW1ib2xTaXplID0gcmVxdWlyZSgnLi91dGlscycpLmdldFN5bWJvbFNpemVcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHJvdy9jb2x1bW4gY29vcmRpbmF0ZXMgb2YgdGhlIGNlbnRlciBtb2R1bGUgb2YgZWFjaCBhbGlnbm1lbnQgcGF0dGVyblxuICogZm9yIHRoZSBzcGVjaWZpZWQgUVIgQ29kZSB2ZXJzaW9uLlxuICpcbiAqIFRoZSBhbGlnbm1lbnQgcGF0dGVybnMgYXJlIHBvc2l0aW9uZWQgc3ltbWV0cmljYWxseSBvbiBlaXRoZXIgc2lkZSBvZiB0aGUgZGlhZ29uYWxcbiAqIHJ1bm5pbmcgZnJvbSB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBzeW1ib2wgdG8gdGhlIGJvdHRvbSByaWdodCBjb3JuZXIuXG4gKlxuICogU2luY2UgcG9zaXRpb25zIGFyZSBzaW1tZXRyaWNhbCBvbmx5IGhhbGYgb2YgdGhlIGNvb3JkaW5hdGVzIGFyZSByZXR1cm5lZC5cbiAqIEVhY2ggaXRlbSBvZiB0aGUgYXJyYXkgd2lsbCByZXByZXNlbnQgaW4gdHVybiB0aGUgeCBhbmQgeSBjb29yZGluYXRlLlxuICogQHNlZSB7QGxpbmsgZ2V0UG9zaXRpb25zfVxuICpcbiAqIEBwYXJhbSAge051bWJlcn0gdmVyc2lvbiBRUiBDb2RlIHZlcnNpb25cbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgICBBcnJheSBvZiBjb29yZGluYXRlXG4gKi9cbmV4cG9ydHMuZ2V0Um93Q29sQ29vcmRzID0gZnVuY3Rpb24gZ2V0Um93Q29sQ29vcmRzICh2ZXJzaW9uKSB7XG4gIGlmICh2ZXJzaW9uID09PSAxKSByZXR1cm4gW11cblxuICB2YXIgcG9zQ291bnQgPSBNYXRoLmZsb29yKHZlcnNpb24gLyA3KSArIDJcbiAgdmFyIHNpemUgPSBnZXRTeW1ib2xTaXplKHZlcnNpb24pXG4gIHZhciBpbnRlcnZhbHMgPSBzaXplID09PSAxNDUgPyAyNiA6IE1hdGguY2VpbCgoc2l6ZSAtIDEzKSAvICgyICogcG9zQ291bnQgLSAyKSkgKiAyXG4gIHZhciBwb3NpdGlvbnMgPSBbc2l6ZSAtIDddIC8vIExhc3QgY29vcmQgaXMgYWx3YXlzIChzaXplIC0gNylcblxuICBmb3IgKHZhciBpID0gMTsgaSA8IHBvc0NvdW50IC0gMTsgaSsrKSB7XG4gICAgcG9zaXRpb25zW2ldID0gcG9zaXRpb25zW2kgLSAxXSAtIGludGVydmFsc1xuICB9XG5cbiAgcG9zaXRpb25zLnB1c2goNikgLy8gRmlyc3QgY29vcmQgaXMgYWx3YXlzIDZcblxuICByZXR1cm4gcG9zaXRpb25zLnJldmVyc2UoKVxufVxuXG4vKipcbiAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcG9zaXRpb25zIG9mIGVhY2ggYWxpZ25tZW50IHBhdHRlcm4uXG4gKiBFYWNoIGFycmF5J3MgZWxlbWVudCByZXByZXNlbnQgdGhlIGNlbnRlciBwb2ludCBvZiB0aGUgcGF0dGVybiBhcyAoeCwgeSkgY29vcmRpbmF0ZXNcbiAqXG4gKiBDb29yZGluYXRlcyBhcmUgY2FsY3VsYXRlZCBleHBhbmRpbmcgdGhlIHJvdy9jb2x1bW4gY29vcmRpbmF0ZXMgcmV0dXJuZWQgYnkge0BsaW5rIGdldFJvd0NvbENvb3Jkc31cbiAqIGFuZCBmaWx0ZXJpbmcgb3V0IHRoZSBpdGVtcyB0aGF0IG92ZXJsYXBzIHdpdGggZmluZGVyIHBhdHRlcm5cbiAqXG4gKiBAZXhhbXBsZVxuICogRm9yIGEgVmVyc2lvbiA3IHN5bWJvbCB7QGxpbmsgZ2V0Um93Q29sQ29vcmRzfSByZXR1cm5zIHZhbHVlcyA2LCAyMiBhbmQgMzguXG4gKiBUaGUgYWxpZ25tZW50IHBhdHRlcm5zLCB0aGVyZWZvcmUsIGFyZSB0byBiZSBjZW50ZXJlZCBvbiAocm93LCBjb2x1bW4pXG4gKiBwb3NpdGlvbnMgKDYsMjIpLCAoMjIsNiksICgyMiwyMiksICgyMiwzOCksICgzOCwyMiksICgzOCwzOCkuXG4gKiBOb3RlIHRoYXQgdGhlIGNvb3JkaW5hdGVzICg2LDYpLCAoNiwzOCksICgzOCw2KSBhcmUgb2NjdXBpZWQgYnkgZmluZGVyIHBhdHRlcm5zXG4gKiBhbmQgYXJlIG5vdCB0aGVyZWZvcmUgdXNlZCBmb3IgYWxpZ25tZW50IHBhdHRlcm5zLlxuICpcbiAqIHZhciBwb3MgPSBnZXRQb3NpdGlvbnMoNylcbiAqIC8vIFtbNiwyMl0sIFsyMiw2XSwgWzIyLDIyXSwgWzIyLDM4XSwgWzM4LDIyXSwgWzM4LDM4XV1cbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gUVIgQ29kZSB2ZXJzaW9uXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgICAgQXJyYXkgb2YgY29vcmRpbmF0ZXNcbiAqL1xuZXhwb3J0cy5nZXRQb3NpdGlvbnMgPSBmdW5jdGlvbiBnZXRQb3NpdGlvbnMgKHZlcnNpb24pIHtcbiAgdmFyIGNvb3JkcyA9IFtdXG4gIHZhciBwb3MgPSBleHBvcnRzLmdldFJvd0NvbENvb3Jkcyh2ZXJzaW9uKVxuICB2YXIgcG9zTGVuZ3RoID0gcG9zLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG9zTGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHBvc0xlbmd0aDsgaisrKSB7XG4gICAgICAvLyBTa2lwIGlmIHBvc2l0aW9uIGlzIG9jY3VwaWVkIGJ5IGZpbmRlciBwYXR0ZXJuc1xuICAgICAgaWYgKChpID09PSAwICYmIGogPT09IDApIHx8ICAgICAgICAgICAgIC8vIHRvcC1sZWZ0XG4gICAgICAgICAgKGkgPT09IDAgJiYgaiA9PT0gcG9zTGVuZ3RoIC0gMSkgfHwgLy8gYm90dG9tLWxlZnRcbiAgICAgICAgICAoaSA9PT0gcG9zTGVuZ3RoIC0gMSAmJiBqID09PSAwKSkgeyAvLyB0b3AtcmlnaHRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29vcmRzLnB1c2goW3Bvc1tpXSwgcG9zW2pdXSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29vcmRzXG59XG4iLCJ2YXIgTW9kZSA9IHJlcXVpcmUoJy4vbW9kZScpXG5cbi8qKlxuICogQXJyYXkgb2YgY2hhcmFjdGVycyBhdmFpbGFibGUgaW4gYWxwaGFudW1lcmljIG1vZGVcbiAqXG4gKiBBcyBwZXIgUVIgQ29kZSBzcGVjaWZpY2F0aW9uLCB0byBlYWNoIGNoYXJhY3RlclxuICogaXMgYXNzaWduZWQgYSB2YWx1ZSBmcm9tIDAgdG8gNDQgd2hpY2ggaW4gdGhpcyBjYXNlIGNvaW5jaWRlc1xuICogd2l0aCB0aGUgYXJyYXkgaW5kZXhcbiAqXG4gKiBAdHlwZSB7QXJyYXl9XG4gKi9cbnZhciBBTFBIQV9OVU1fQ0hBUlMgPSBbXG4gICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JyxcbiAgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywgJ00nLFxuICAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywgJ1knLCAnWicsXG4gICcgJywgJyQnLCAnJScsICcqJywgJysnLCAnLScsICcuJywgJy8nLCAnOidcbl1cblxuZnVuY3Rpb24gQWxwaGFudW1lcmljRGF0YSAoZGF0YSkge1xuICB0aGlzLm1vZGUgPSBNb2RlLkFMUEhBTlVNRVJJQ1xuICB0aGlzLmRhdGEgPSBkYXRhXG59XG5cbkFscGhhbnVtZXJpY0RhdGEuZ2V0Qml0c0xlbmd0aCA9IGZ1bmN0aW9uIGdldEJpdHNMZW5ndGggKGxlbmd0aCkge1xuICByZXR1cm4gMTEgKiBNYXRoLmZsb29yKGxlbmd0aCAvIDIpICsgNiAqIChsZW5ndGggJSAyKVxufVxuXG5BbHBoYW51bWVyaWNEYXRhLnByb3RvdHlwZS5nZXRMZW5ndGggPSBmdW5jdGlvbiBnZXRMZW5ndGggKCkge1xuICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aFxufVxuXG5BbHBoYW51bWVyaWNEYXRhLnByb3RvdHlwZS5nZXRCaXRzTGVuZ3RoID0gZnVuY3Rpb24gZ2V0Qml0c0xlbmd0aCAoKSB7XG4gIHJldHVybiBBbHBoYW51bWVyaWNEYXRhLmdldEJpdHNMZW5ndGgodGhpcy5kYXRhLmxlbmd0aClcbn1cblxuQWxwaGFudW1lcmljRGF0YS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoYml0QnVmZmVyKSB7XG4gIHZhciBpXG5cbiAgLy8gSW5wdXQgZGF0YSBjaGFyYWN0ZXJzIGFyZSBkaXZpZGVkIGludG8gZ3JvdXBzIG9mIHR3byBjaGFyYWN0ZXJzXG4gIC8vIGFuZCBlbmNvZGVkIGFzIDExLWJpdCBiaW5hcnkgY29kZXMuXG4gIGZvciAoaSA9IDA7IGkgKyAyIDw9IHRoaXMuZGF0YS5sZW5ndGg7IGkgKz0gMikge1xuICAgIC8vIFRoZSBjaGFyYWN0ZXIgdmFsdWUgb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBtdWx0aXBsaWVkIGJ5IDQ1XG4gICAgdmFyIHZhbHVlID0gQUxQSEFfTlVNX0NIQVJTLmluZGV4T2YodGhpcy5kYXRhW2ldKSAqIDQ1XG5cbiAgICAvLyBUaGUgY2hhcmFjdGVyIHZhbHVlIG9mIHRoZSBzZWNvbmQgZGlnaXQgaXMgYWRkZWQgdG8gdGhlIHByb2R1Y3RcbiAgICB2YWx1ZSArPSBBTFBIQV9OVU1fQ0hBUlMuaW5kZXhPZih0aGlzLmRhdGFbaSArIDFdKVxuXG4gICAgLy8gVGhlIHN1bSBpcyB0aGVuIHN0b3JlZCBhcyAxMS1iaXQgYmluYXJ5IG51bWJlclxuICAgIGJpdEJ1ZmZlci5wdXQodmFsdWUsIDExKVxuICB9XG5cbiAgLy8gSWYgdGhlIG51bWJlciBvZiBpbnB1dCBkYXRhIGNoYXJhY3RlcnMgaXMgbm90IGEgbXVsdGlwbGUgb2YgdHdvLFxuICAvLyB0aGUgY2hhcmFjdGVyIHZhbHVlIG9mIHRoZSBmaW5hbCBjaGFyYWN0ZXIgaXMgZW5jb2RlZCBhcyBhIDYtYml0IGJpbmFyeSBudW1iZXIuXG4gIGlmICh0aGlzLmRhdGEubGVuZ3RoICUgMikge1xuICAgIGJpdEJ1ZmZlci5wdXQoQUxQSEFfTlVNX0NIQVJTLmluZGV4T2YodGhpcy5kYXRhW2ldKSwgNilcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFscGhhbnVtZXJpY0RhdGFcbiIsImZ1bmN0aW9uIEJpdEJ1ZmZlciAoKSB7XG4gIHRoaXMuYnVmZmVyID0gW11cbiAgdGhpcy5sZW5ndGggPSAwXG59XG5cbkJpdEJ1ZmZlci5wcm90b3R5cGUgPSB7XG5cbiAgZ2V0OiBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgYnVmSW5kZXggPSBNYXRoLmZsb29yKGluZGV4IC8gOClcbiAgICByZXR1cm4gKCh0aGlzLmJ1ZmZlcltidWZJbmRleF0gPj4+ICg3IC0gaW5kZXggJSA4KSkgJiAxKSA9PT0gMVxuICB9LFxuXG4gIHB1dDogZnVuY3Rpb24gKG51bSwgbGVuZ3RoKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5wdXRCaXQoKChudW0gPj4+IChsZW5ndGggLSBpIC0gMSkpICYgMSkgPT09IDEpXG4gICAgfVxuICB9LFxuXG4gIGdldExlbmd0aEluQml0czogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmxlbmd0aFxuICB9LFxuXG4gIHB1dEJpdDogZnVuY3Rpb24gKGJpdCkge1xuICAgIHZhciBidWZJbmRleCA9IE1hdGguZmxvb3IodGhpcy5sZW5ndGggLyA4KVxuICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggPD0gYnVmSW5kZXgpIHtcbiAgICAgIHRoaXMuYnVmZmVyLnB1c2goMClcbiAgICB9XG5cbiAgICBpZiAoYml0KSB7XG4gICAgICB0aGlzLmJ1ZmZlcltidWZJbmRleF0gfD0gKDB4ODAgPj4+ICh0aGlzLmxlbmd0aCAlIDgpKVxuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoKytcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJpdEJ1ZmZlclxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2J1ZmZlcicpXG5cbi8qKlxuICogSGVscGVyIGNsYXNzIHRvIGhhbmRsZSBRUiBDb2RlIHN5bWJvbCBtb2R1bGVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHNpemUgU3ltYm9sIHNpemVcbiAqL1xuZnVuY3Rpb24gQml0TWF0cml4IChzaXplKSB7XG4gIGlmICghc2l6ZSB8fCBzaXplIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQml0TWF0cml4IHNpemUgbXVzdCBiZSBkZWZpbmVkIGFuZCBncmVhdGVyIHRoYW4gMCcpXG4gIH1cblxuICB0aGlzLnNpemUgPSBzaXplXG4gIHRoaXMuZGF0YSA9IG5ldyBCdWZmZXIoc2l6ZSAqIHNpemUpXG4gIHRoaXMuZGF0YS5maWxsKDApXG4gIHRoaXMucmVzZXJ2ZWRCaXQgPSBuZXcgQnVmZmVyKHNpemUgKiBzaXplKVxuICB0aGlzLnJlc2VydmVkQml0LmZpbGwoMClcbn1cblxuLyoqXG4gKiBTZXQgYml0IHZhbHVlIGF0IHNwZWNpZmllZCBsb2NhdGlvblxuICogSWYgcmVzZXJ2ZWQgZmxhZyBpcyBzZXQsIHRoaXMgYml0IHdpbGwgYmUgaWdub3JlZCBkdXJpbmcgbWFza2luZyBwcm9jZXNzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9ICByb3dcbiAqIEBwYXJhbSB7TnVtYmVyfSAgY29sXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHZhbHVlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJlc2VydmVkXG4gKi9cbkJpdE1hdHJpeC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHJvdywgY29sLCB2YWx1ZSwgcmVzZXJ2ZWQpIHtcbiAgdmFyIGluZGV4ID0gcm93ICogdGhpcy5zaXplICsgY29sXG4gIHRoaXMuZGF0YVtpbmRleF0gPSB2YWx1ZVxuICBpZiAocmVzZXJ2ZWQpIHRoaXMucmVzZXJ2ZWRCaXRbaW5kZXhdID0gdHJ1ZVxufVxuXG4vKipcbiAqIFJldHVybnMgYml0IHZhbHVlIGF0IHNwZWNpZmllZCBsb2NhdGlvblxuICpcbiAqIEBwYXJhbSAge051bWJlcn0gIHJvd1xuICogQHBhcmFtICB7TnVtYmVyfSAgY29sXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5CaXRNYXRyaXgucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChyb3csIGNvbCkge1xuICByZXR1cm4gdGhpcy5kYXRhW3JvdyAqIHRoaXMuc2l6ZSArIGNvbF1cbn1cblxuLyoqXG4gKiBBcHBsaWVzIHhvciBvcGVyYXRvciBhdCBzcGVjaWZpZWQgbG9jYXRpb25cbiAqICh1c2VkIGR1cmluZyBtYXNraW5nIHByb2Nlc3MpXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9ICByb3dcbiAqIEBwYXJhbSB7TnVtYmVyfSAgY29sXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHZhbHVlXG4gKi9cbkJpdE1hdHJpeC5wcm90b3R5cGUueG9yID0gZnVuY3Rpb24gKHJvdywgY29sLCB2YWx1ZSkge1xuICB0aGlzLmRhdGFbcm93ICogdGhpcy5zaXplICsgY29sXSBePSB2YWx1ZVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGJpdCBhdCBzcGVjaWZpZWQgbG9jYXRpb24gaXMgcmVzZXJ2ZWRcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gICByb3dcbiAqIEBwYXJhbSB7TnVtYmVyfSAgIGNvbFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuQml0TWF0cml4LnByb3RvdHlwZS5pc1Jlc2VydmVkID0gZnVuY3Rpb24gKHJvdywgY29sKSB7XG4gIHJldHVybiB0aGlzLnJlc2VydmVkQml0W3JvdyAqIHRoaXMuc2l6ZSArIGNvbF1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBCaXRNYXRyaXhcbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCcuLi91dGlscy9idWZmZXInKVxudmFyIE1vZGUgPSByZXF1aXJlKCcuL21vZGUnKVxuXG5mdW5jdGlvbiBCeXRlRGF0YSAoZGF0YSkge1xuICB0aGlzLm1vZGUgPSBNb2RlLkJZVEVcbiAgdGhpcy5kYXRhID0gbmV3IEJ1ZmZlcihkYXRhKVxufVxuXG5CeXRlRGF0YS5nZXRCaXRzTGVuZ3RoID0gZnVuY3Rpb24gZ2V0Qml0c0xlbmd0aCAobGVuZ3RoKSB7XG4gIHJldHVybiBsZW5ndGggKiA4XG59XG5cbkJ5dGVEYXRhLnByb3RvdHlwZS5nZXRMZW5ndGggPSBmdW5jdGlvbiBnZXRMZW5ndGggKCkge1xuICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aFxufVxuXG5CeXRlRGF0YS5wcm90b3R5cGUuZ2V0Qml0c0xlbmd0aCA9IGZ1bmN0aW9uIGdldEJpdHNMZW5ndGggKCkge1xuICByZXR1cm4gQnl0ZURhdGEuZ2V0Qml0c0xlbmd0aCh0aGlzLmRhdGEubGVuZ3RoKVxufVxuXG5CeXRlRGF0YS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYml0QnVmZmVyKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5kYXRhLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGJpdEJ1ZmZlci5wdXQodGhpcy5kYXRhW2ldLCA4KVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQnl0ZURhdGFcbiIsInZhciBFQ0xldmVsID0gcmVxdWlyZSgnLi9lcnJvci1jb3JyZWN0aW9uLWxldmVsJylcclxuXHJcbnZhciBFQ19CTE9DS1NfVEFCTEUgPSBbXHJcbi8vIEwgIE0gIFEgIEhcclxuICAxLCAxLCAxLCAxLFxyXG4gIDEsIDEsIDEsIDEsXHJcbiAgMSwgMSwgMiwgMixcclxuICAxLCAyLCAyLCA0LFxyXG4gIDEsIDIsIDQsIDQsXHJcbiAgMiwgNCwgNCwgNCxcclxuICAyLCA0LCA2LCA1LFxyXG4gIDIsIDQsIDYsIDYsXHJcbiAgMiwgNSwgOCwgOCxcclxuICA0LCA1LCA4LCA4LFxyXG4gIDQsIDUsIDgsIDExLFxyXG4gIDQsIDgsIDEwLCAxMSxcclxuICA0LCA5LCAxMiwgMTYsXHJcbiAgNCwgOSwgMTYsIDE2LFxyXG4gIDYsIDEwLCAxMiwgMTgsXHJcbiAgNiwgMTAsIDE3LCAxNixcclxuICA2LCAxMSwgMTYsIDE5LFxyXG4gIDYsIDEzLCAxOCwgMjEsXHJcbiAgNywgMTQsIDIxLCAyNSxcclxuICA4LCAxNiwgMjAsIDI1LFxyXG4gIDgsIDE3LCAyMywgMjUsXHJcbiAgOSwgMTcsIDIzLCAzNCxcclxuICA5LCAxOCwgMjUsIDMwLFxyXG4gIDEwLCAyMCwgMjcsIDMyLFxyXG4gIDEyLCAyMSwgMjksIDM1LFxyXG4gIDEyLCAyMywgMzQsIDM3LFxyXG4gIDEyLCAyNSwgMzQsIDQwLFxyXG4gIDEzLCAyNiwgMzUsIDQyLFxyXG4gIDE0LCAyOCwgMzgsIDQ1LFxyXG4gIDE1LCAyOSwgNDAsIDQ4LFxyXG4gIDE2LCAzMSwgNDMsIDUxLFxyXG4gIDE3LCAzMywgNDUsIDU0LFxyXG4gIDE4LCAzNSwgNDgsIDU3LFxyXG4gIDE5LCAzNywgNTEsIDYwLFxyXG4gIDE5LCAzOCwgNTMsIDYzLFxyXG4gIDIwLCA0MCwgNTYsIDY2LFxyXG4gIDIxLCA0MywgNTksIDcwLFxyXG4gIDIyLCA0NSwgNjIsIDc0LFxyXG4gIDI0LCA0NywgNjUsIDc3LFxyXG4gIDI1LCA0OSwgNjgsIDgxXHJcbl1cclxuXHJcbnZhciBFQ19DT0RFV09SRFNfVEFCTEUgPSBbXHJcbi8vIEwgIE0gIFEgIEhcclxuICA3LCAxMCwgMTMsIDE3LFxyXG4gIDEwLCAxNiwgMjIsIDI4LFxyXG4gIDE1LCAyNiwgMzYsIDQ0LFxyXG4gIDIwLCAzNiwgNTIsIDY0LFxyXG4gIDI2LCA0OCwgNzIsIDg4LFxyXG4gIDM2LCA2NCwgOTYsIDExMixcclxuICA0MCwgNzIsIDEwOCwgMTMwLFxyXG4gIDQ4LCA4OCwgMTMyLCAxNTYsXHJcbiAgNjAsIDExMCwgMTYwLCAxOTIsXHJcbiAgNzIsIDEzMCwgMTkyLCAyMjQsXHJcbiAgODAsIDE1MCwgMjI0LCAyNjQsXHJcbiAgOTYsIDE3NiwgMjYwLCAzMDgsXHJcbiAgMTA0LCAxOTgsIDI4OCwgMzUyLFxyXG4gIDEyMCwgMjE2LCAzMjAsIDM4NCxcclxuICAxMzIsIDI0MCwgMzYwLCA0MzIsXHJcbiAgMTQ0LCAyODAsIDQwOCwgNDgwLFxyXG4gIDE2OCwgMzA4LCA0NDgsIDUzMixcclxuICAxODAsIDMzOCwgNTA0LCA1ODgsXHJcbiAgMTk2LCAzNjQsIDU0NiwgNjUwLFxyXG4gIDIyNCwgNDE2LCA2MDAsIDcwMCxcclxuICAyMjQsIDQ0MiwgNjQ0LCA3NTAsXHJcbiAgMjUyLCA0NzYsIDY5MCwgODE2LFxyXG4gIDI3MCwgNTA0LCA3NTAsIDkwMCxcclxuICAzMDAsIDU2MCwgODEwLCA5NjAsXHJcbiAgMzEyLCA1ODgsIDg3MCwgMTA1MCxcclxuICAzMzYsIDY0NCwgOTUyLCAxMTEwLFxyXG4gIDM2MCwgNzAwLCAxMDIwLCAxMjAwLFxyXG4gIDM5MCwgNzI4LCAxMDUwLCAxMjYwLFxyXG4gIDQyMCwgNzg0LCAxMTQwLCAxMzUwLFxyXG4gIDQ1MCwgODEyLCAxMjAwLCAxNDQwLFxyXG4gIDQ4MCwgODY4LCAxMjkwLCAxNTMwLFxyXG4gIDUxMCwgOTI0LCAxMzUwLCAxNjIwLFxyXG4gIDU0MCwgOTgwLCAxNDQwLCAxNzEwLFxyXG4gIDU3MCwgMTAzNiwgMTUzMCwgMTgwMCxcclxuICA1NzAsIDEwNjQsIDE1OTAsIDE4OTAsXHJcbiAgNjAwLCAxMTIwLCAxNjgwLCAxOTgwLFxyXG4gIDYzMCwgMTIwNCwgMTc3MCwgMjEwMCxcclxuICA2NjAsIDEyNjAsIDE4NjAsIDIyMjAsXHJcbiAgNzIwLCAxMzE2LCAxOTUwLCAyMzEwLFxyXG4gIDc1MCwgMTM3MiwgMjA0MCwgMjQzMFxyXG5dXHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVycm9yIGNvcnJlY3Rpb24gYmxvY2sgdGhhdCB0aGUgUVIgQ29kZSBzaG91bGQgY29udGFpblxyXG4gKiBmb3IgdGhlIHNwZWNpZmllZCB2ZXJzaW9uIGFuZCBlcnJvciBjb3JyZWN0aW9uIGxldmVsLlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gICAgICAgICAgICAgIFFSIENvZGUgdmVyc2lvblxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGVycm9yQ29ycmVjdGlvbkxldmVsIEVycm9yIGNvcnJlY3Rpb24gbGV2ZWxcclxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgICAgICAgICAgICAgICBOdW1iZXIgb2YgZXJyb3IgY29ycmVjdGlvbiBibG9ja3NcclxuICovXHJcbmV4cG9ydHMuZ2V0QmxvY2tzQ291bnQgPSBmdW5jdGlvbiBnZXRCbG9ja3NDb3VudCAodmVyc2lvbiwgZXJyb3JDb3JyZWN0aW9uTGV2ZWwpIHtcclxuICBzd2l0Y2ggKGVycm9yQ29ycmVjdGlvbkxldmVsKSB7XHJcbiAgICBjYXNlIEVDTGV2ZWwuTDpcclxuICAgICAgcmV0dXJuIEVDX0JMT0NLU19UQUJMRVsodmVyc2lvbiAtIDEpICogNCArIDBdXHJcbiAgICBjYXNlIEVDTGV2ZWwuTTpcclxuICAgICAgcmV0dXJuIEVDX0JMT0NLU19UQUJMRVsodmVyc2lvbiAtIDEpICogNCArIDFdXHJcbiAgICBjYXNlIEVDTGV2ZWwuUTpcclxuICAgICAgcmV0dXJuIEVDX0JMT0NLU19UQUJMRVsodmVyc2lvbiAtIDEpICogNCArIDJdXHJcbiAgICBjYXNlIEVDTGV2ZWwuSDpcclxuICAgICAgcmV0dXJuIEVDX0JMT0NLU19UQUJMRVsodmVyc2lvbiAtIDEpICogNCArIDNdXHJcbiAgICBkZWZhdWx0OlxyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVycm9yIGNvcnJlY3Rpb24gY29kZXdvcmRzIHRvIHVzZSBmb3IgdGhlIHNwZWNpZmllZFxyXG4gKiB2ZXJzaW9uIGFuZCBlcnJvciBjb3JyZWN0aW9uIGxldmVsLlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gICAgICAgICAgICAgIFFSIENvZGUgdmVyc2lvblxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGVycm9yQ29ycmVjdGlvbkxldmVsIEVycm9yIGNvcnJlY3Rpb24gbGV2ZWxcclxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgICAgICAgICAgICAgICBOdW1iZXIgb2YgZXJyb3IgY29ycmVjdGlvbiBjb2Rld29yZHNcclxuICovXHJcbmV4cG9ydHMuZ2V0VG90YWxDb2Rld29yZHNDb3VudCA9IGZ1bmN0aW9uIGdldFRvdGFsQ29kZXdvcmRzQ291bnQgKHZlcnNpb24sIGVycm9yQ29ycmVjdGlvbkxldmVsKSB7XHJcbiAgc3dpdGNoIChlcnJvckNvcnJlY3Rpb25MZXZlbCkge1xyXG4gICAgY2FzZSBFQ0xldmVsLkw6XHJcbiAgICAgIHJldHVybiBFQ19DT0RFV09SRFNfVEFCTEVbKHZlcnNpb24gLSAxKSAqIDQgKyAwXVxyXG4gICAgY2FzZSBFQ0xldmVsLk06XHJcbiAgICAgIHJldHVybiBFQ19DT0RFV09SRFNfVEFCTEVbKHZlcnNpb24gLSAxKSAqIDQgKyAxXVxyXG4gICAgY2FzZSBFQ0xldmVsLlE6XHJcbiAgICAgIHJldHVybiBFQ19DT0RFV09SRFNfVEFCTEVbKHZlcnNpb24gLSAxKSAqIDQgKyAyXVxyXG4gICAgY2FzZSBFQ0xldmVsLkg6XHJcbiAgICAgIHJldHVybiBFQ19DT0RFV09SRFNfVEFCTEVbKHZlcnNpb24gLSAxKSAqIDQgKyAzXVxyXG4gICAgZGVmYXVsdDpcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZFxyXG4gIH1cclxufVxyXG4iLCJleHBvcnRzLkwgPSB7IGJpdDogMSB9XG5leHBvcnRzLk0gPSB7IGJpdDogMCB9XG5leHBvcnRzLlEgPSB7IGJpdDogMyB9XG5leHBvcnRzLkggPSB7IGJpdDogMiB9XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHN0cmluZykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtIGlzIG5vdCBhIHN0cmluZycpXG4gIH1cblxuICB2YXIgbGNTdHIgPSBzdHJpbmcudG9Mb3dlckNhc2UoKVxuXG4gIHN3aXRjaCAobGNTdHIpIHtcbiAgICBjYXNlICdsJzpcbiAgICBjYXNlICdsb3cnOlxuICAgICAgcmV0dXJuIGV4cG9ydHMuTFxuXG4gICAgY2FzZSAnbSc6XG4gICAgY2FzZSAnbWVkaXVtJzpcbiAgICAgIHJldHVybiBleHBvcnRzLk1cblxuICAgIGNhc2UgJ3EnOlxuICAgIGNhc2UgJ3F1YXJ0aWxlJzpcbiAgICAgIHJldHVybiBleHBvcnRzLlFcblxuICAgIGNhc2UgJ2gnOlxuICAgIGNhc2UgJ2hpZ2gnOlxuICAgICAgcmV0dXJuIGV4cG9ydHMuSFxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBFQyBMZXZlbDogJyArIHN0cmluZylcbiAgfVxufVxuXG5leHBvcnRzLmlzVmFsaWQgPSBmdW5jdGlvbiBpc1ZhbGlkIChsZXZlbCkge1xuICByZXR1cm4gbGV2ZWwgJiYgdHlwZW9mIGxldmVsLmJpdCAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICBsZXZlbC5iaXQgPj0gMCAmJiBsZXZlbC5iaXQgPCA0XG59XG5cbmV4cG9ydHMuZnJvbSA9IGZ1bmN0aW9uIGZyb20gKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKGV4cG9ydHMuaXNWYWxpZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodmFsdWUpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZGVmYXVsdFZhbHVlXG4gIH1cbn1cbiIsInZhciBnZXRTeW1ib2xTaXplID0gcmVxdWlyZSgnLi91dGlscycpLmdldFN5bWJvbFNpemVcbnZhciBGSU5ERVJfUEFUVEVSTl9TSVpFID0gN1xuXG4vKipcbiAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcG9zaXRpb25zIG9mIGVhY2ggZmluZGVyIHBhdHRlcm4uXG4gKiBFYWNoIGFycmF5J3MgZWxlbWVudCByZXByZXNlbnQgdGhlIHRvcC1sZWZ0IHBvaW50IG9mIHRoZSBwYXR0ZXJuIGFzICh4LCB5KSBjb29yZGluYXRlc1xuICpcbiAqIEBwYXJhbSAge051bWJlcn0gdmVyc2lvbiBRUiBDb2RlIHZlcnNpb25cbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgICBBcnJheSBvZiBjb29yZGluYXRlc1xuICovXG5leHBvcnRzLmdldFBvc2l0aW9ucyA9IGZ1bmN0aW9uIGdldFBvc2l0aW9ucyAodmVyc2lvbikge1xuICB2YXIgc2l6ZSA9IGdldFN5bWJvbFNpemUodmVyc2lvbilcblxuICByZXR1cm4gW1xuICAgIC8vIHRvcC1sZWZ0XG4gICAgWzAsIDBdLFxuICAgIC8vIHRvcC1yaWdodFxuICAgIFtzaXplIC0gRklOREVSX1BBVFRFUk5fU0laRSwgMF0sXG4gICAgLy8gYm90dG9tLWxlZnRcbiAgICBbMCwgc2l6ZSAtIEZJTkRFUl9QQVRURVJOX1NJWkVdXG4gIF1cbn1cbiIsInZhciBVdGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKVxuXG52YXIgRzE1ID0gKDEgPDwgMTApIHwgKDEgPDwgOCkgfCAoMSA8PCA1KSB8ICgxIDw8IDQpIHwgKDEgPDwgMikgfCAoMSA8PCAxKSB8ICgxIDw8IDApXG52YXIgRzE1X01BU0sgPSAoMSA8PCAxNCkgfCAoMSA8PCAxMikgfCAoMSA8PCAxMCkgfCAoMSA8PCA0KSB8ICgxIDw8IDEpXG52YXIgRzE1X0JDSCA9IFV0aWxzLmdldEJDSERpZ2l0KEcxNSlcblxuLyoqXG4gKiBSZXR1cm5zIGZvcm1hdCBpbmZvcm1hdGlvbiB3aXRoIHJlbGF0aXZlIGVycm9yIGNvcnJlY3Rpb24gYml0c1xuICpcbiAqIFRoZSBmb3JtYXQgaW5mb3JtYXRpb24gaXMgYSAxNS1iaXQgc2VxdWVuY2UgY29udGFpbmluZyA1IGRhdGEgYml0cyxcbiAqIHdpdGggMTAgZXJyb3IgY29ycmVjdGlvbiBiaXRzIGNhbGN1bGF0ZWQgdXNpbmcgdGhlICgxNSwgNSkgQkNIIGNvZGUuXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSBlcnJvckNvcnJlY3Rpb25MZXZlbCBFcnJvciBjb3JyZWN0aW9uIGxldmVsXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IG1hc2sgICAgICAgICAgICAgICAgIE1hc2sgcGF0dGVyblxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgICAgICAgICAgICAgICBFbmNvZGVkIGZvcm1hdCBpbmZvcm1hdGlvbiBiaXRzXG4gKi9cbmV4cG9ydHMuZ2V0RW5jb2RlZEJpdHMgPSBmdW5jdGlvbiBnZXRFbmNvZGVkQml0cyAoZXJyb3JDb3JyZWN0aW9uTGV2ZWwsIG1hc2spIHtcbiAgdmFyIGRhdGEgPSAoKGVycm9yQ29ycmVjdGlvbkxldmVsLmJpdCA8PCAzKSB8IG1hc2spXG4gIHZhciBkID0gZGF0YSA8PCAxMFxuXG4gIHdoaWxlIChVdGlscy5nZXRCQ0hEaWdpdChkKSAtIEcxNV9CQ0ggPj0gMCkge1xuICAgIGQgXj0gKEcxNSA8PCAoVXRpbHMuZ2V0QkNIRGlnaXQoZCkgLSBHMTVfQkNIKSlcbiAgfVxuXG4gIC8vIHhvciBmaW5hbCBkYXRhIHdpdGggbWFzayBwYXR0ZXJuIGluIG9yZGVyIHRvIGVuc3VyZSB0aGF0XG4gIC8vIG5vIGNvbWJpbmF0aW9uIG9mIEVycm9yIENvcnJlY3Rpb24gTGV2ZWwgYW5kIGRhdGEgbWFzayBwYXR0ZXJuXG4gIC8vIHdpbGwgcmVzdWx0IGluIGFuIGFsbC16ZXJvIGRhdGEgc3RyaW5nXG4gIHJldHVybiAoKGRhdGEgPDwgMTApIHwgZCkgXiBHMTVfTUFTS1xufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2J1ZmZlcicpXG5cbnZhciBFWFBfVEFCTEVcbnZhciBMT0dfVEFCTEVcblxuaWYgKEJ1ZmZlci5hbGxvYykge1xuICBFWFBfVEFCTEUgPSBCdWZmZXIuYWxsb2MoNTEyKVxuICBMT0dfVEFCTEUgPSBCdWZmZXIuYWxsb2MoMjU2KVxufSBlbHNlIHtcbiAgRVhQX1RBQkxFID0gbmV3IEJ1ZmZlcig1MTIpXG4gIExPR19UQUJMRSA9IG5ldyBCdWZmZXIoMjU2KVxufVxuLyoqXG4gKiBQcmVjb21wdXRlIHRoZSBsb2cgYW5kIGFudGktbG9nIHRhYmxlcyBmb3IgZmFzdGVyIGNvbXB1dGF0aW9uIGxhdGVyXG4gKlxuICogRm9yIGVhY2ggcG9zc2libGUgdmFsdWUgaW4gdGhlIGdhbG9pcyBmaWVsZCAyXjgsIHdlIHdpbGwgcHJlLWNvbXB1dGVcbiAqIHRoZSBsb2dhcml0aG0gYW5kIGFudGktbG9nYXJpdGhtIChleHBvbmVudGlhbCkgb2YgdGhpcyB2YWx1ZVxuICpcbiAqIHJlZiB7QGxpbmsgaHR0cHM6Ly9lbi53aWtpdmVyc2l0eS5vcmcvd2lraS9SZWVkJUUyJTgwJTkzU29sb21vbl9jb2Rlc19mb3JfY29kZXJzI0ludHJvZHVjdGlvbl90b19tYXRoZW1hdGljYWxfZmllbGRzfVxuICovXG47KGZ1bmN0aW9uIGluaXRUYWJsZXMgKCkge1xuICB2YXIgeCA9IDFcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTU7IGkrKykge1xuICAgIEVYUF9UQUJMRVtpXSA9IHhcbiAgICBMT0dfVEFCTEVbeF0gPSBpXG5cbiAgICB4IDw8PSAxIC8vIG11bHRpcGx5IGJ5IDJcblxuICAgIC8vIFRoZSBRUiBjb2RlIHNwZWNpZmljYXRpb24gc2F5cyB0byB1c2UgYnl0ZS13aXNlIG1vZHVsbyAxMDAwMTExMDEgYXJpdGhtZXRpYy5cbiAgICAvLyBUaGlzIG1lYW5zIHRoYXQgd2hlbiBhIG51bWJlciBpcyAyNTYgb3IgbGFyZ2VyLCBpdCBzaG91bGQgYmUgWE9SZWQgd2l0aCAweDExRC5cbiAgICBpZiAoeCAmIDB4MTAwKSB7IC8vIHNpbWlsYXIgdG8geCA+PSAyNTYsIGJ1dCBhIGxvdCBmYXN0ZXIgKGJlY2F1c2UgMHgxMDAgPT0gMjU2KVxuICAgICAgeCBePSAweDExRFxuICAgIH1cbiAgfVxuXG4gIC8vIE9wdGltaXphdGlvbjogZG91YmxlIHRoZSBzaXplIG9mIHRoZSBhbnRpLWxvZyB0YWJsZSBzbyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gbW9kIDI1NSB0b1xuICAvLyBzdGF5IGluc2lkZSB0aGUgYm91bmRzIChiZWNhdXNlIHdlIHdpbGwgbWFpbmx5IHVzZSB0aGlzIHRhYmxlIGZvciB0aGUgbXVsdGlwbGljYXRpb24gb2ZcbiAgLy8gdHdvIEdGIG51bWJlcnMsIG5vIG1vcmUpLlxuICAvLyBAc2VlIHtAbGluayBtdWx9XG4gIGZvciAoaSA9IDI1NTsgaSA8IDUxMjsgaSsrKSB7XG4gICAgRVhQX1RBQkxFW2ldID0gRVhQX1RBQkxFW2kgLSAyNTVdXG4gIH1cbn0oKSlcblxuLyoqXG4gKiBSZXR1cm5zIGxvZyB2YWx1ZSBvZiBuIGluc2lkZSBHYWxvaXMgRmllbGRcbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IG5cbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbiBsb2cgKG4pIHtcbiAgaWYgKG4gPCAxKSB0aHJvdyBuZXcgRXJyb3IoJ2xvZygnICsgbiArICcpJylcbiAgcmV0dXJuIExPR19UQUJMRVtuXVxufVxuXG4vKipcbiAqIFJldHVybnMgYW50aS1sb2cgdmFsdWUgb2YgbiBpbnNpZGUgR2Fsb2lzIEZpZWxkXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSBuXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cbmV4cG9ydHMuZXhwID0gZnVuY3Rpb24gZXhwIChuKSB7XG4gIHJldHVybiBFWFBfVEFCTEVbbl1cbn1cblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBudW1iZXIgaW5zaWRlIEdhbG9pcyBGaWVsZFxuICpcbiAqIEBwYXJhbSAge051bWJlcn0geFxuICogQHBhcmFtICB7TnVtYmVyfSB5XG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cbmV4cG9ydHMubXVsID0gZnVuY3Rpb24gbXVsICh4LCB5KSB7XG4gIGlmICh4ID09PSAwIHx8IHkgPT09IDApIHJldHVybiAwXG5cbiAgLy8gc2hvdWxkIGJlIEVYUF9UQUJMRVsoTE9HX1RBQkxFW3hdICsgTE9HX1RBQkxFW3ldKSAlIDI1NV0gaWYgRVhQX1RBQkxFIHdhc24ndCBvdmVyc2l6ZWRcbiAgLy8gQHNlZSB7QGxpbmsgaW5pdFRhYmxlc31cbiAgcmV0dXJuIEVYUF9UQUJMRVtMT0dfVEFCTEVbeF0gKyBMT0dfVEFCTEVbeV1dXG59XG4iLCJ2YXIgTW9kZSA9IHJlcXVpcmUoJy4vbW9kZScpXG52YXIgVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcblxuZnVuY3Rpb24gS2FuamlEYXRhIChkYXRhKSB7XG4gIHRoaXMubW9kZSA9IE1vZGUuS0FOSklcbiAgdGhpcy5kYXRhID0gZGF0YVxufVxuXG5LYW5qaURhdGEuZ2V0Qml0c0xlbmd0aCA9IGZ1bmN0aW9uIGdldEJpdHNMZW5ndGggKGxlbmd0aCkge1xuICByZXR1cm4gbGVuZ3RoICogMTNcbn1cblxuS2FuamlEYXRhLnByb3RvdHlwZS5nZXRMZW5ndGggPSBmdW5jdGlvbiBnZXRMZW5ndGggKCkge1xuICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aFxufVxuXG5LYW5qaURhdGEucHJvdG90eXBlLmdldEJpdHNMZW5ndGggPSBmdW5jdGlvbiBnZXRCaXRzTGVuZ3RoICgpIHtcbiAgcmV0dXJuIEthbmppRGF0YS5nZXRCaXRzTGVuZ3RoKHRoaXMuZGF0YS5sZW5ndGgpXG59XG5cbkthbmppRGF0YS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYml0QnVmZmVyKSB7XG4gIHZhciBpXG5cbiAgLy8gSW4gdGhlIFNoaWZ0IEpJUyBzeXN0ZW0sIEthbmppIGNoYXJhY3RlcnMgYXJlIHJlcHJlc2VudGVkIGJ5IGEgdHdvIGJ5dGUgY29tYmluYXRpb24uXG4gIC8vIFRoZXNlIGJ5dGUgdmFsdWVzIGFyZSBzaGlmdGVkIGZyb20gdGhlIEpJUyBYIDAyMDggdmFsdWVzLlxuICAvLyBKSVMgWCAwMjA4IGdpdmVzIGRldGFpbHMgb2YgdGhlIHNoaWZ0IGNvZGVkIHJlcHJlc2VudGF0aW9uLlxuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHZhbHVlID0gVXRpbHMudG9TSklTKHRoaXMuZGF0YVtpXSlcblxuICAgIC8vIEZvciBjaGFyYWN0ZXJzIHdpdGggU2hpZnQgSklTIHZhbHVlcyBmcm9tIDB4ODE0MCB0byAweDlGRkM6XG4gICAgaWYgKHZhbHVlID49IDB4ODE0MCAmJiB2YWx1ZSA8PSAweDlGRkMpIHtcbiAgICAgIC8vIFN1YnRyYWN0IDB4ODE0MCBmcm9tIFNoaWZ0IEpJUyB2YWx1ZVxuICAgICAgdmFsdWUgLT0gMHg4MTQwXG5cbiAgICAvLyBGb3IgY2hhcmFjdGVycyB3aXRoIFNoaWZ0IEpJUyB2YWx1ZXMgZnJvbSAweEUwNDAgdG8gMHhFQkJGXG4gICAgfSBlbHNlIGlmICh2YWx1ZSA+PSAweEUwNDAgJiYgdmFsdWUgPD0gMHhFQkJGKSB7XG4gICAgICAvLyBTdWJ0cmFjdCAweEMxNDAgZnJvbSBTaGlmdCBKSVMgdmFsdWVcbiAgICAgIHZhbHVlIC09IDB4QzE0MFxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdJbnZhbGlkIFNKSVMgY2hhcmFjdGVyOiAnICsgdGhpcy5kYXRhW2ldICsgJ1xcbicgK1xuICAgICAgICAnTWFrZSBzdXJlIHlvdXIgY2hhcnNldCBpcyBVVEYtOCcpXG4gICAgfVxuXG4gICAgLy8gTXVsdGlwbHkgbW9zdCBzaWduaWZpY2FudCBieXRlIG9mIHJlc3VsdCBieSAweEMwXG4gICAgLy8gYW5kIGFkZCBsZWFzdCBzaWduaWZpY2FudCBieXRlIHRvIHByb2R1Y3RcbiAgICB2YWx1ZSA9ICgoKHZhbHVlID4+PiA4KSAmIDB4ZmYpICogMHhDMCkgKyAodmFsdWUgJiAweGZmKVxuXG4gICAgLy8gQ29udmVydCByZXN1bHQgdG8gYSAxMy1iaXQgYmluYXJ5IHN0cmluZ1xuICAgIGJpdEJ1ZmZlci5wdXQodmFsdWUsIDEzKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gS2FuamlEYXRhXG4iLCIvKipcbiAqIERhdGEgbWFzayBwYXR0ZXJuIHJlZmVyZW5jZVxuICogQHR5cGUge09iamVjdH1cbiAqL1xuZXhwb3J0cy5QYXR0ZXJucyA9IHtcbiAgUEFUVEVSTjAwMDogMCxcbiAgUEFUVEVSTjAwMTogMSxcbiAgUEFUVEVSTjAxMDogMixcbiAgUEFUVEVSTjAxMTogMyxcbiAgUEFUVEVSTjEwMDogNCxcbiAgUEFUVEVSTjEwMTogNSxcbiAgUEFUVEVSTjExMDogNixcbiAgUEFUVEVSTjExMTogN1xufVxuXG4vKipcbiAqIFdlaWdodGVkIHBlbmFsdHkgc2NvcmVzIGZvciB0aGUgdW5kZXNpcmFibGUgZmVhdHVyZXNcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbnZhciBQZW5hbHR5U2NvcmVzID0ge1xuICBOMTogMyxcbiAgTjI6IDMsXG4gIE4zOiA0MCxcbiAgTjQ6IDEwXG59XG5cbi8qKlxuICogQ2hlY2sgaWYgbWFzayBwYXR0ZXJuIHZhbHVlIGlzIHZhbGlkXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSAgbWFzayAgICBNYXNrIHBhdHRlcm5cbiAqIEByZXR1cm4ge0Jvb2xlYW59ICAgICAgICAgdHJ1ZSBpZiB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydHMuaXNWYWxpZCA9IGZ1bmN0aW9uIGlzVmFsaWQgKG1hc2spIHtcbiAgcmV0dXJuIG1hc2sgIT0gbnVsbCAmJiBtYXNrICE9PSAnJyAmJiAhaXNOYU4obWFzaykgJiYgbWFzayA+PSAwICYmIG1hc2sgPD0gN1xufVxuXG4vKipcbiAqIFJldHVybnMgbWFzayBwYXR0ZXJuIGZyb20gYSB2YWx1ZS5cbiAqIElmIHZhbHVlIGlzIG5vdCB2YWxpZCwgcmV0dXJucyB1bmRlZmluZWRcbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ8U3RyaW5nfSB2YWx1ZSAgICAgICAgTWFzayBwYXR0ZXJuIHZhbHVlXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgICAgICAgICAgICAgVmFsaWQgbWFzayBwYXR0ZXJuIG9yIHVuZGVmaW5lZFxuICovXG5leHBvcnRzLmZyb20gPSBmdW5jdGlvbiBmcm9tICh2YWx1ZSkge1xuICByZXR1cm4gZXhwb3J0cy5pc1ZhbGlkKHZhbHVlKSA/IHBhcnNlSW50KHZhbHVlLCAxMCkgOiB1bmRlZmluZWRcbn1cblxuLyoqXG4qIEZpbmQgYWRqYWNlbnQgbW9kdWxlcyBpbiByb3cvY29sdW1uIHdpdGggdGhlIHNhbWUgY29sb3JcbiogYW5kIGFzc2lnbiBhIHBlbmFsdHkgdmFsdWUuXG4qXG4qIFBvaW50czogTjEgKyBpXG4qIGkgaXMgdGhlIGFtb3VudCBieSB3aGljaCB0aGUgbnVtYmVyIG9mIGFkamFjZW50IG1vZHVsZXMgb2YgdGhlIHNhbWUgY29sb3IgZXhjZWVkcyA1XG4qL1xuZXhwb3J0cy5nZXRQZW5hbHR5TjEgPSBmdW5jdGlvbiBnZXRQZW5hbHR5TjEgKGRhdGEpIHtcbiAgdmFyIHNpemUgPSBkYXRhLnNpemVcbiAgdmFyIHBvaW50cyA9IDBcbiAgdmFyIHNhbWVDb3VudENvbCA9IDBcbiAgdmFyIHNhbWVDb3VudFJvdyA9IDBcbiAgdmFyIGxhc3RDb2wgPSBudWxsXG4gIHZhciBsYXN0Um93ID0gbnVsbFxuXG4gIGZvciAodmFyIHJvdyA9IDA7IHJvdyA8IHNpemU7IHJvdysrKSB7XG4gICAgc2FtZUNvdW50Q29sID0gc2FtZUNvdW50Um93ID0gMFxuICAgIGxhc3RDb2wgPSBsYXN0Um93ID0gbnVsbFxuXG4gICAgZm9yICh2YXIgY29sID0gMDsgY29sIDwgc2l6ZTsgY29sKyspIHtcbiAgICAgIHZhciBtb2R1bGUgPSBkYXRhLmdldChyb3csIGNvbClcbiAgICAgIGlmIChtb2R1bGUgPT09IGxhc3RDb2wpIHtcbiAgICAgICAgc2FtZUNvdW50Q29sKytcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzYW1lQ291bnRDb2wgPj0gNSkgcG9pbnRzICs9IFBlbmFsdHlTY29yZXMuTjEgKyAoc2FtZUNvdW50Q29sIC0gNSlcbiAgICAgICAgbGFzdENvbCA9IG1vZHVsZVxuICAgICAgICBzYW1lQ291bnRDb2wgPSAxXG4gICAgICB9XG5cbiAgICAgIG1vZHVsZSA9IGRhdGEuZ2V0KGNvbCwgcm93KVxuICAgICAgaWYgKG1vZHVsZSA9PT0gbGFzdFJvdykge1xuICAgICAgICBzYW1lQ291bnRSb3crK1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNhbWVDb3VudFJvdyA+PSA1KSBwb2ludHMgKz0gUGVuYWx0eVNjb3Jlcy5OMSArIChzYW1lQ291bnRSb3cgLSA1KVxuICAgICAgICBsYXN0Um93ID0gbW9kdWxlXG4gICAgICAgIHNhbWVDb3VudFJvdyA9IDFcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2FtZUNvdW50Q29sID49IDUpIHBvaW50cyArPSBQZW5hbHR5U2NvcmVzLk4xICsgKHNhbWVDb3VudENvbCAtIDUpXG4gICAgaWYgKHNhbWVDb3VudFJvdyA+PSA1KSBwb2ludHMgKz0gUGVuYWx0eVNjb3Jlcy5OMSArIChzYW1lQ291bnRSb3cgLSA1KVxuICB9XG5cbiAgcmV0dXJuIHBvaW50c1xufVxuXG4vKipcbiAqIEZpbmQgMngyIGJsb2NrcyB3aXRoIHRoZSBzYW1lIGNvbG9yIGFuZCBhc3NpZ24gYSBwZW5hbHR5IHZhbHVlXG4gKlxuICogUG9pbnRzOiBOMiAqIChtIC0gMSkgKiAobiAtIDEpXG4gKi9cbmV4cG9ydHMuZ2V0UGVuYWx0eU4yID0gZnVuY3Rpb24gZ2V0UGVuYWx0eU4yIChkYXRhKSB7XG4gIHZhciBzaXplID0gZGF0YS5zaXplXG4gIHZhciBwb2ludHMgPSAwXG5cbiAgZm9yICh2YXIgcm93ID0gMDsgcm93IDwgc2l6ZSAtIDE7IHJvdysrKSB7XG4gICAgZm9yICh2YXIgY29sID0gMDsgY29sIDwgc2l6ZSAtIDE7IGNvbCsrKSB7XG4gICAgICB2YXIgbGFzdCA9IGRhdGEuZ2V0KHJvdywgY29sKSArXG4gICAgICAgIGRhdGEuZ2V0KHJvdywgY29sICsgMSkgK1xuICAgICAgICBkYXRhLmdldChyb3cgKyAxLCBjb2wpICtcbiAgICAgICAgZGF0YS5nZXQocm93ICsgMSwgY29sICsgMSlcblxuICAgICAgaWYgKGxhc3QgPT09IDQgfHwgbGFzdCA9PT0gMCkgcG9pbnRzKytcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcG9pbnRzICogUGVuYWx0eVNjb3Jlcy5OMlxufVxuXG4vKipcbiAqIEZpbmQgMToxOjM6MToxIHJhdGlvIChkYXJrOmxpZ2h0OmRhcms6bGlnaHQ6ZGFyaykgcGF0dGVybiBpbiByb3cvY29sdW1uLFxuICogcHJlY2VkZWQgb3IgZm9sbG93ZWQgYnkgbGlnaHQgYXJlYSA0IG1vZHVsZXMgd2lkZVxuICpcbiAqIFBvaW50czogTjMgKiBudW1iZXIgb2YgcGF0dGVybiBmb3VuZFxuICovXG5leHBvcnRzLmdldFBlbmFsdHlOMyA9IGZ1bmN0aW9uIGdldFBlbmFsdHlOMyAoZGF0YSkge1xuICB2YXIgc2l6ZSA9IGRhdGEuc2l6ZVxuICB2YXIgcG9pbnRzID0gMFxuICB2YXIgYml0c0NvbCA9IDBcbiAgdmFyIGJpdHNSb3cgPSAwXG5cbiAgZm9yICh2YXIgcm93ID0gMDsgcm93IDwgc2l6ZTsgcm93KyspIHtcbiAgICBiaXRzQ29sID0gYml0c1JvdyA9IDBcbiAgICBmb3IgKHZhciBjb2wgPSAwOyBjb2wgPCBzaXplOyBjb2wrKykge1xuICAgICAgYml0c0NvbCA9ICgoYml0c0NvbCA8PCAxKSAmIDB4N0ZGKSB8IGRhdGEuZ2V0KHJvdywgY29sKVxuICAgICAgaWYgKGNvbCA+PSAxMCAmJiAoYml0c0NvbCA9PT0gMHg1RDAgfHwgYml0c0NvbCA9PT0gMHgwNUQpKSBwb2ludHMrK1xuXG4gICAgICBiaXRzUm93ID0gKChiaXRzUm93IDw8IDEpICYgMHg3RkYpIHwgZGF0YS5nZXQoY29sLCByb3cpXG4gICAgICBpZiAoY29sID49IDEwICYmIChiaXRzUm93ID09PSAweDVEMCB8fCBiaXRzUm93ID09PSAweDA1RCkpIHBvaW50cysrXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBvaW50cyAqIFBlbmFsdHlTY29yZXMuTjNcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgcHJvcG9ydGlvbiBvZiBkYXJrIG1vZHVsZXMgaW4gZW50aXJlIHN5bWJvbFxuICpcbiAqIFBvaW50czogTjQgKiBrXG4gKlxuICogayBpcyB0aGUgcmF0aW5nIG9mIHRoZSBkZXZpYXRpb24gb2YgdGhlIHByb3BvcnRpb24gb2YgZGFyayBtb2R1bGVzXG4gKiBpbiB0aGUgc3ltYm9sIGZyb20gNTAlIGluIHN0ZXBzIG9mIDUlXG4gKi9cbmV4cG9ydHMuZ2V0UGVuYWx0eU40ID0gZnVuY3Rpb24gZ2V0UGVuYWx0eU40IChkYXRhKSB7XG4gIHZhciBkYXJrQ291bnQgPSAwXG4gIHZhciBtb2R1bGVzQ291bnQgPSBkYXRhLmRhdGEubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb2R1bGVzQ291bnQ7IGkrKykgZGFya0NvdW50ICs9IGRhdGEuZGF0YVtpXVxuXG4gIHZhciBrID0gTWF0aC5hYnMoTWF0aC5jZWlsKChkYXJrQ291bnQgKiAxMDAgLyBtb2R1bGVzQ291bnQpIC8gNSkgLSAxMClcblxuICByZXR1cm4gayAqIFBlbmFsdHlTY29yZXMuTjRcbn1cblxuLyoqXG4gKiBSZXR1cm4gbWFzayB2YWx1ZSBhdCBnaXZlbiBwb3NpdGlvblxuICpcbiAqIEBwYXJhbSAge051bWJlcn0gbWFza1BhdHRlcm4gUGF0dGVybiByZWZlcmVuY2UgdmFsdWVcbiAqIEBwYXJhbSAge051bWJlcn0gaSAgICAgICAgICAgUm93XG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGogICAgICAgICAgIENvbHVtblxuICogQHJldHVybiB7Qm9vbGVhbn0gICAgICAgICAgICBNYXNrIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGdldE1hc2tBdCAobWFza1BhdHRlcm4sIGksIGopIHtcbiAgc3dpdGNoIChtYXNrUGF0dGVybikge1xuICAgIGNhc2UgZXhwb3J0cy5QYXR0ZXJucy5QQVRURVJOMDAwOiByZXR1cm4gKGkgKyBqKSAlIDIgPT09IDBcbiAgICBjYXNlIGV4cG9ydHMuUGF0dGVybnMuUEFUVEVSTjAwMTogcmV0dXJuIGkgJSAyID09PSAwXG4gICAgY2FzZSBleHBvcnRzLlBhdHRlcm5zLlBBVFRFUk4wMTA6IHJldHVybiBqICUgMyA9PT0gMFxuICAgIGNhc2UgZXhwb3J0cy5QYXR0ZXJucy5QQVRURVJOMDExOiByZXR1cm4gKGkgKyBqKSAlIDMgPT09IDBcbiAgICBjYXNlIGV4cG9ydHMuUGF0dGVybnMuUEFUVEVSTjEwMDogcmV0dXJuIChNYXRoLmZsb29yKGkgLyAyKSArIE1hdGguZmxvb3IoaiAvIDMpKSAlIDIgPT09IDBcbiAgICBjYXNlIGV4cG9ydHMuUGF0dGVybnMuUEFUVEVSTjEwMTogcmV0dXJuIChpICogaikgJSAyICsgKGkgKiBqKSAlIDMgPT09IDBcbiAgICBjYXNlIGV4cG9ydHMuUGF0dGVybnMuUEFUVEVSTjExMDogcmV0dXJuICgoaSAqIGopICUgMiArIChpICogaikgJSAzKSAlIDIgPT09IDBcbiAgICBjYXNlIGV4cG9ydHMuUGF0dGVybnMuUEFUVEVSTjExMTogcmV0dXJuICgoaSAqIGopICUgMyArIChpICsgaikgJSAyKSAlIDIgPT09IDBcblxuICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignYmFkIG1hc2tQYXR0ZXJuOicgKyBtYXNrUGF0dGVybilcbiAgfVxufVxuXG4vKipcbiAqIEFwcGx5IGEgbWFzayBwYXR0ZXJuIHRvIGEgQml0TWF0cml4XG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSAgICBwYXR0ZXJuIFBhdHRlcm4gcmVmZXJlbmNlIG51bWJlclxuICogQHBhcmFtICB7Qml0TWF0cml4fSBkYXRhICAgIEJpdE1hdHJpeCBkYXRhXG4gKi9cbmV4cG9ydHMuYXBwbHlNYXNrID0gZnVuY3Rpb24gYXBwbHlNYXNrIChwYXR0ZXJuLCBkYXRhKSB7XG4gIHZhciBzaXplID0gZGF0YS5zaXplXG5cbiAgZm9yICh2YXIgY29sID0gMDsgY29sIDwgc2l6ZTsgY29sKyspIHtcbiAgICBmb3IgKHZhciByb3cgPSAwOyByb3cgPCBzaXplOyByb3crKykge1xuICAgICAgaWYgKGRhdGEuaXNSZXNlcnZlZChyb3csIGNvbCkpIGNvbnRpbnVlXG4gICAgICBkYXRhLnhvcihyb3csIGNvbCwgZ2V0TWFza0F0KHBhdHRlcm4sIHJvdywgY29sKSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiZXN0IG1hc2sgcGF0dGVybiBmb3IgZGF0YVxuICpcbiAqIEBwYXJhbSAge0JpdE1hdHJpeH0gZGF0YVxuICogQHJldHVybiB7TnVtYmVyfSBNYXNrIHBhdHRlcm4gcmVmZXJlbmNlIG51bWJlclxuICovXG5leHBvcnRzLmdldEJlc3RNYXNrID0gZnVuY3Rpb24gZ2V0QmVzdE1hc2sgKGRhdGEsIHNldHVwRm9ybWF0RnVuYykge1xuICB2YXIgbnVtUGF0dGVybnMgPSBPYmplY3Qua2V5cyhleHBvcnRzLlBhdHRlcm5zKS5sZW5ndGhcbiAgdmFyIGJlc3RQYXR0ZXJuID0gMFxuICB2YXIgbG93ZXJQZW5hbHR5ID0gSW5maW5pdHlcblxuICBmb3IgKHZhciBwID0gMDsgcCA8IG51bVBhdHRlcm5zOyBwKyspIHtcbiAgICBzZXR1cEZvcm1hdEZ1bmMocClcbiAgICBleHBvcnRzLmFwcGx5TWFzayhwLCBkYXRhKVxuXG4gICAgLy8gQ2FsY3VsYXRlIHBlbmFsdHlcbiAgICB2YXIgcGVuYWx0eSA9XG4gICAgICBleHBvcnRzLmdldFBlbmFsdHlOMShkYXRhKSArXG4gICAgICBleHBvcnRzLmdldFBlbmFsdHlOMihkYXRhKSArXG4gICAgICBleHBvcnRzLmdldFBlbmFsdHlOMyhkYXRhKSArXG4gICAgICBleHBvcnRzLmdldFBlbmFsdHlONChkYXRhKVxuXG4gICAgLy8gVW5kbyBwcmV2aW91c2x5IGFwcGxpZWQgbWFza1xuICAgIGV4cG9ydHMuYXBwbHlNYXNrKHAsIGRhdGEpXG5cbiAgICBpZiAocGVuYWx0eSA8IGxvd2VyUGVuYWx0eSkge1xuICAgICAgbG93ZXJQZW5hbHR5ID0gcGVuYWx0eVxuICAgICAgYmVzdFBhdHRlcm4gPSBwXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJlc3RQYXR0ZXJuXG59XG4iLCJ2YXIgVmVyc2lvbkNoZWNrID0gcmVxdWlyZSgnLi92ZXJzaW9uLWNoZWNrJylcbnZhciBSZWdleCA9IHJlcXVpcmUoJy4vcmVnZXgnKVxuXG4vKipcbiAqIE51bWVyaWMgbW9kZSBlbmNvZGVzIGRhdGEgZnJvbSB0aGUgZGVjaW1hbCBkaWdpdCBzZXQgKDAgLSA5KVxuICogKGJ5dGUgdmFsdWVzIDMwSEVYIHRvIDM5SEVYKS5cbiAqIE5vcm1hbGx5LCAzIGRhdGEgY2hhcmFjdGVycyBhcmUgcmVwcmVzZW50ZWQgYnkgMTAgYml0cy5cbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5leHBvcnRzLk5VTUVSSUMgPSB7XG4gIGlkOiAnTnVtZXJpYycsXG4gIGJpdDogMSA8PCAwLFxuICBjY0JpdHM6IFsxMCwgMTIsIDE0XVxufVxuXG4vKipcbiAqIEFscGhhbnVtZXJpYyBtb2RlIGVuY29kZXMgZGF0YSBmcm9tIGEgc2V0IG9mIDQ1IGNoYXJhY3RlcnMsXG4gKiBpLmUuIDEwIG51bWVyaWMgZGlnaXRzICgwIC0gOSksXG4gKiAgICAgIDI2IGFscGhhYmV0aWMgY2hhcmFjdGVycyAoQSAtIFopLFxuICogICBhbmQgOSBzeW1ib2xzIChTUCwgJCwgJSwgKiwgKywgLSwgLiwgLywgOikuXG4gKiBOb3JtYWxseSwgdHdvIGlucHV0IGNoYXJhY3RlcnMgYXJlIHJlcHJlc2VudGVkIGJ5IDExIGJpdHMuXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuZXhwb3J0cy5BTFBIQU5VTUVSSUMgPSB7XG4gIGlkOiAnQWxwaGFudW1lcmljJyxcbiAgYml0OiAxIDw8IDEsXG4gIGNjQml0czogWzksIDExLCAxM11cbn1cblxuLyoqXG4gKiBJbiBieXRlIG1vZGUsIGRhdGEgaXMgZW5jb2RlZCBhdCA4IGJpdHMgcGVyIGNoYXJhY3Rlci5cbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5leHBvcnRzLkJZVEUgPSB7XG4gIGlkOiAnQnl0ZScsXG4gIGJpdDogMSA8PCAyLFxuICBjY0JpdHM6IFs4LCAxNiwgMTZdXG59XG5cbi8qKlxuICogVGhlIEthbmppIG1vZGUgZWZmaWNpZW50bHkgZW5jb2RlcyBLYW5qaSBjaGFyYWN0ZXJzIGluIGFjY29yZGFuY2Ugd2l0aFxuICogdGhlIFNoaWZ0IEpJUyBzeXN0ZW0gYmFzZWQgb24gSklTIFggMDIwOC5cbiAqIFRoZSBTaGlmdCBKSVMgdmFsdWVzIGFyZSBzaGlmdGVkIGZyb20gdGhlIEpJUyBYIDAyMDggdmFsdWVzLlxuICogSklTIFggMDIwOCBnaXZlcyBkZXRhaWxzIG9mIHRoZSBzaGlmdCBjb2RlZCByZXByZXNlbnRhdGlvbi5cbiAqIEVhY2ggdHdvLWJ5dGUgY2hhcmFjdGVyIHZhbHVlIGlzIGNvbXBhY3RlZCB0byBhIDEzLWJpdCBiaW5hcnkgY29kZXdvcmQuXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuZXhwb3J0cy5LQU5KSSA9IHtcbiAgaWQ6ICdLYW5qaScsXG4gIGJpdDogMSA8PCAzLFxuICBjY0JpdHM6IFs4LCAxMCwgMTJdXG59XG5cbi8qKlxuICogTWl4ZWQgbW9kZSB3aWxsIGNvbnRhaW4gYSBzZXF1ZW5jZXMgb2YgZGF0YSBpbiBhIGNvbWJpbmF0aW9uIG9mIGFueSBvZlxuICogdGhlIG1vZGVzIGRlc2NyaWJlZCBhYm92ZVxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbmV4cG9ydHMuTUlYRUQgPSB7XG4gIGJpdDogLTFcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gc3RvcmUgdGhlIGRhdGEgbGVuZ3RoXG4gKiBhY2NvcmRpbmcgdG8gUVIgQ29kZSBzcGVjaWZpY2F0aW9ucy5cbiAqXG4gKiBAcGFyYW0gIHtNb2RlfSAgIG1vZGUgICAgRGF0YSBtb2RlXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gUVIgQ29kZSB2ZXJzaW9uXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgTnVtYmVyIG9mIGJpdHNcbiAqL1xuZXhwb3J0cy5nZXRDaGFyQ291bnRJbmRpY2F0b3IgPSBmdW5jdGlvbiBnZXRDaGFyQ291bnRJbmRpY2F0b3IgKG1vZGUsIHZlcnNpb24pIHtcbiAgaWYgKCFtb2RlLmNjQml0cykgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1vZGU6ICcgKyBtb2RlKVxuXG4gIGlmICghVmVyc2lvbkNoZWNrLmlzVmFsaWQodmVyc2lvbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdmVyc2lvbjogJyArIHZlcnNpb24pXG4gIH1cblxuICBpZiAodmVyc2lvbiA+PSAxICYmIHZlcnNpb24gPCAxMCkgcmV0dXJuIG1vZGUuY2NCaXRzWzBdXG4gIGVsc2UgaWYgKHZlcnNpb24gPCAyNykgcmV0dXJuIG1vZGUuY2NCaXRzWzFdXG4gIHJldHVybiBtb2RlLmNjQml0c1syXVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIG1vc3QgZWZmaWNpZW50IG1vZGUgdG8gc3RvcmUgdGhlIHNwZWNpZmllZCBkYXRhXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBkYXRhU3RyIElucHV0IGRhdGEgc3RyaW5nXG4gKiBAcmV0dXJuIHtNb2RlfSAgICAgICAgICAgQmVzdCBtb2RlXG4gKi9cbmV4cG9ydHMuZ2V0QmVzdE1vZGVGb3JEYXRhID0gZnVuY3Rpb24gZ2V0QmVzdE1vZGVGb3JEYXRhIChkYXRhU3RyKSB7XG4gIGlmIChSZWdleC50ZXN0TnVtZXJpYyhkYXRhU3RyKSkgcmV0dXJuIGV4cG9ydHMuTlVNRVJJQ1xuICBlbHNlIGlmIChSZWdleC50ZXN0QWxwaGFudW1lcmljKGRhdGFTdHIpKSByZXR1cm4gZXhwb3J0cy5BTFBIQU5VTUVSSUNcbiAgZWxzZSBpZiAoUmVnZXgudGVzdEthbmppKGRhdGFTdHIpKSByZXR1cm4gZXhwb3J0cy5LQU5KSVxuICBlbHNlIHJldHVybiBleHBvcnRzLkJZVEVcbn1cblxuLyoqXG4gKiBSZXR1cm4gbW9kZSBuYW1lIGFzIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7TW9kZX0gbW9kZSBNb2RlIG9iamVjdFxuICogQHJldHVybnMge1N0cmluZ30gIE1vZGUgbmFtZVxuICovXG5leHBvcnRzLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKG1vZGUpIHtcbiAgaWYgKG1vZGUgJiYgbW9kZS5pZCkgcmV0dXJuIG1vZGUuaWRcbiAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1vZGUnKVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGlucHV0IHBhcmFtIGlzIGEgdmFsaWQgbW9kZSBvYmplY3RcbiAqXG4gKiBAcGFyYW0gICB7TW9kZX0gICAgbW9kZSBNb2RlIG9iamVjdFxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdmFsaWQgbW9kZSwgZmFsc2Ugb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydHMuaXNWYWxpZCA9IGZ1bmN0aW9uIGlzVmFsaWQgKG1vZGUpIHtcbiAgcmV0dXJuIG1vZGUgJiYgbW9kZS5iaXQgJiYgbW9kZS5jY0JpdHNcbn1cblxuLyoqXG4gKiBHZXQgbW9kZSBvYmplY3QgZnJvbSBpdHMgbmFtZVxuICpcbiAqIEBwYXJhbSAgIHtTdHJpbmd9IHN0cmluZyBNb2RlIG5hbWVcbiAqIEByZXR1cm5zIHtNb2RlfSAgICAgICAgICBNb2RlIG9iamVjdFxuICovXG5mdW5jdGlvbiBmcm9tU3RyaW5nIChzdHJpbmcpIHtcbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbSBpcyBub3QgYSBzdHJpbmcnKVxuICB9XG5cbiAgdmFyIGxjU3RyID0gc3RyaW5nLnRvTG93ZXJDYXNlKClcblxuICBzd2l0Y2ggKGxjU3RyKSB7XG4gICAgY2FzZSAnbnVtZXJpYyc6XG4gICAgICByZXR1cm4gZXhwb3J0cy5OVU1FUklDXG4gICAgY2FzZSAnYWxwaGFudW1lcmljJzpcbiAgICAgIHJldHVybiBleHBvcnRzLkFMUEhBTlVNRVJJQ1xuICAgIGNhc2UgJ2thbmppJzpcbiAgICAgIHJldHVybiBleHBvcnRzLktBTkpJXG4gICAgY2FzZSAnYnl0ZSc6XG4gICAgICByZXR1cm4gZXhwb3J0cy5CWVRFXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtb2RlOiAnICsgc3RyaW5nKVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBtb2RlIGZyb20gYSB2YWx1ZS5cbiAqIElmIHZhbHVlIGlzIG5vdCBhIHZhbGlkIG1vZGUsIHJldHVybnMgZGVmYXVsdFZhbHVlXG4gKlxuICogQHBhcmFtICB7TW9kZXxTdHJpbmd9IHZhbHVlICAgICAgICBFbmNvZGluZyBtb2RlXG4gKiBAcGFyYW0gIHtNb2RlfSAgICAgICAgZGVmYXVsdFZhbHVlIEZhbGxiYWNrIHZhbHVlXG4gKiBAcmV0dXJuIHtNb2RlfSAgICAgICAgICAgICAgICAgICAgIEVuY29kaW5nIG1vZGVcbiAqL1xuZXhwb3J0cy5mcm9tID0gZnVuY3Rpb24gZnJvbSAodmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAoZXhwb3J0cy5pc1ZhbGlkKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh2YWx1ZSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBkZWZhdWx0VmFsdWVcbiAgfVxufVxuIiwidmFyIE1vZGUgPSByZXF1aXJlKCcuL21vZGUnKVxuXG5mdW5jdGlvbiBOdW1lcmljRGF0YSAoZGF0YSkge1xuICB0aGlzLm1vZGUgPSBNb2RlLk5VTUVSSUNcbiAgdGhpcy5kYXRhID0gZGF0YS50b1N0cmluZygpXG59XG5cbk51bWVyaWNEYXRhLmdldEJpdHNMZW5ndGggPSBmdW5jdGlvbiBnZXRCaXRzTGVuZ3RoIChsZW5ndGgpIHtcbiAgcmV0dXJuIDEwICogTWF0aC5mbG9vcihsZW5ndGggLyAzKSArICgobGVuZ3RoICUgMykgPyAoKGxlbmd0aCAlIDMpICogMyArIDEpIDogMClcbn1cblxuTnVtZXJpY0RhdGEucHJvdG90eXBlLmdldExlbmd0aCA9IGZ1bmN0aW9uIGdldExlbmd0aCAoKSB7XG4gIHJldHVybiB0aGlzLmRhdGEubGVuZ3RoXG59XG5cbk51bWVyaWNEYXRhLnByb3RvdHlwZS5nZXRCaXRzTGVuZ3RoID0gZnVuY3Rpb24gZ2V0Qml0c0xlbmd0aCAoKSB7XG4gIHJldHVybiBOdW1lcmljRGF0YS5nZXRCaXRzTGVuZ3RoKHRoaXMuZGF0YS5sZW5ndGgpXG59XG5cbk51bWVyaWNEYXRhLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChiaXRCdWZmZXIpIHtcbiAgdmFyIGksIGdyb3VwLCB2YWx1ZVxuXG4gIC8vIFRoZSBpbnB1dCBkYXRhIHN0cmluZyBpcyBkaXZpZGVkIGludG8gZ3JvdXBzIG9mIHRocmVlIGRpZ2l0cyxcbiAgLy8gYW5kIGVhY2ggZ3JvdXAgaXMgY29udmVydGVkIHRvIGl0cyAxMC1iaXQgYmluYXJ5IGVxdWl2YWxlbnQuXG4gIGZvciAoaSA9IDA7IGkgKyAzIDw9IHRoaXMuZGF0YS5sZW5ndGg7IGkgKz0gMykge1xuICAgIGdyb3VwID0gdGhpcy5kYXRhLnN1YnN0cihpLCAzKVxuICAgIHZhbHVlID0gcGFyc2VJbnQoZ3JvdXAsIDEwKVxuXG4gICAgYml0QnVmZmVyLnB1dCh2YWx1ZSwgMTApXG4gIH1cblxuICAvLyBJZiB0aGUgbnVtYmVyIG9mIGlucHV0IGRpZ2l0cyBpcyBub3QgYW4gZXhhY3QgbXVsdGlwbGUgb2YgdGhyZWUsXG4gIC8vIHRoZSBmaW5hbCBvbmUgb3IgdHdvIGRpZ2l0cyBhcmUgY29udmVydGVkIHRvIDQgb3IgNyBiaXRzIHJlc3BlY3RpdmVseS5cbiAgdmFyIHJlbWFpbmluZ051bSA9IHRoaXMuZGF0YS5sZW5ndGggLSBpXG4gIGlmIChyZW1haW5pbmdOdW0gPiAwKSB7XG4gICAgZ3JvdXAgPSB0aGlzLmRhdGEuc3Vic3RyKGkpXG4gICAgdmFsdWUgPSBwYXJzZUludChncm91cCwgMTApXG5cbiAgICBiaXRCdWZmZXIucHV0KHZhbHVlLCByZW1haW5pbmdOdW0gKiAzICsgMSlcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE51bWVyaWNEYXRhXG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSgnLi4vdXRpbHMvYnVmZmVyJylcbnZhciBHRiA9IHJlcXVpcmUoJy4vZ2Fsb2lzLWZpZWxkJylcblxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBwb2x5bm9taWFscyBpbnNpZGUgR2Fsb2lzIEZpZWxkXG4gKlxuICogQHBhcmFtICB7QnVmZmVyfSBwMSBQb2x5bm9taWFsXG4gKiBAcGFyYW0gIHtCdWZmZXJ9IHAyIFBvbHlub21pYWxcbiAqIEByZXR1cm4ge0J1ZmZlcn0gICAgUHJvZHVjdCBvZiBwMSBhbmQgcDJcbiAqL1xuZXhwb3J0cy5tdWwgPSBmdW5jdGlvbiBtdWwgKHAxLCBwMikge1xuICB2YXIgY29lZmYgPSBuZXcgQnVmZmVyKHAxLmxlbmd0aCArIHAyLmxlbmd0aCAtIDEpXG4gIGNvZWZmLmZpbGwoMClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHAxLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBwMi5sZW5ndGg7IGorKykge1xuICAgICAgY29lZmZbaSArIGpdIF49IEdGLm11bChwMVtpXSwgcDJbal0pXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvZWZmXG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSByZW1haW5kZXIgb2YgcG9seW5vbWlhbHMgZGl2aXNpb25cbiAqXG4gKiBAcGFyYW0gIHtCdWZmZXJ9IGRpdmlkZW50IFBvbHlub21pYWxcbiAqIEBwYXJhbSAge0J1ZmZlcn0gZGl2aXNvciAgUG9seW5vbWlhbFxuICogQHJldHVybiB7QnVmZmVyfSAgICAgICAgICBSZW1haW5kZXJcbiAqL1xuZXhwb3J0cy5tb2QgPSBmdW5jdGlvbiBtb2QgKGRpdmlkZW50LCBkaXZpc29yKSB7XG4gIHZhciByZXN1bHQgPSBuZXcgQnVmZmVyKGRpdmlkZW50KVxuXG4gIHdoaWxlICgocmVzdWx0Lmxlbmd0aCAtIGRpdmlzb3IubGVuZ3RoKSA+PSAwKSB7XG4gICAgdmFyIGNvZWZmID0gcmVzdWx0WzBdXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpdmlzb3IubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdFtpXSBePSBHRi5tdWwoZGl2aXNvcltpXSwgY29lZmYpXG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGFsbCB6ZXJvcyBmcm9tIGJ1ZmZlciBoZWFkXG4gICAgdmFyIG9mZnNldCA9IDBcbiAgICB3aGlsZSAob2Zmc2V0IDwgcmVzdWx0Lmxlbmd0aCAmJiByZXN1bHRbb2Zmc2V0XSA9PT0gMCkgb2Zmc2V0KytcbiAgICByZXN1bHQgPSByZXN1bHQuc2xpY2Uob2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIEdlbmVyYXRlIGFuIGlycmVkdWNpYmxlIGdlbmVyYXRvciBwb2x5bm9taWFsIG9mIHNwZWNpZmllZCBkZWdyZWVcbiAqICh1c2VkIGJ5IFJlZWQtU29sb21vbiBlbmNvZGVyKVxuICpcbiAqIEBwYXJhbSAge051bWJlcn0gZGVncmVlIERlZ3JlZSBvZiB0aGUgZ2VuZXJhdG9yIHBvbHlub21pYWxcbiAqIEByZXR1cm4ge0J1ZmZlcn0gICAgICAgIEJ1ZmZlciBjb250YWluaW5nIHBvbHlub21pYWwgY29lZmZpY2llbnRzXG4gKi9cbmV4cG9ydHMuZ2VuZXJhdGVFQ1BvbHlub21pYWwgPSBmdW5jdGlvbiBnZW5lcmF0ZUVDUG9seW5vbWlhbCAoZGVncmVlKSB7XG4gIHZhciBwb2x5ID0gbmV3IEJ1ZmZlcihbMV0pXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGVncmVlOyBpKyspIHtcbiAgICBwb2x5ID0gZXhwb3J0cy5tdWwocG9seSwgWzEsIEdGLmV4cChpKV0pXG4gIH1cblxuICByZXR1cm4gcG9seVxufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2J1ZmZlcicpXG52YXIgVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcbnZhciBFQ0xldmVsID0gcmVxdWlyZSgnLi9lcnJvci1jb3JyZWN0aW9uLWxldmVsJylcbnZhciBCaXRCdWZmZXIgPSByZXF1aXJlKCcuL2JpdC1idWZmZXInKVxudmFyIEJpdE1hdHJpeCA9IHJlcXVpcmUoJy4vYml0LW1hdHJpeCcpXG52YXIgQWxpZ25tZW50UGF0dGVybiA9IHJlcXVpcmUoJy4vYWxpZ25tZW50LXBhdHRlcm4nKVxudmFyIEZpbmRlclBhdHRlcm4gPSByZXF1aXJlKCcuL2ZpbmRlci1wYXR0ZXJuJylcbnZhciBNYXNrUGF0dGVybiA9IHJlcXVpcmUoJy4vbWFzay1wYXR0ZXJuJylcbnZhciBFQ0NvZGUgPSByZXF1aXJlKCcuL2Vycm9yLWNvcnJlY3Rpb24tY29kZScpXG52YXIgUmVlZFNvbG9tb25FbmNvZGVyID0gcmVxdWlyZSgnLi9yZWVkLXNvbG9tb24tZW5jb2RlcicpXG52YXIgVmVyc2lvbiA9IHJlcXVpcmUoJy4vdmVyc2lvbicpXG52YXIgRm9ybWF0SW5mbyA9IHJlcXVpcmUoJy4vZm9ybWF0LWluZm8nKVxudmFyIE1vZGUgPSByZXF1aXJlKCcuL21vZGUnKVxudmFyIFNlZ21lbnRzID0gcmVxdWlyZSgnLi9zZWdtZW50cycpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG4vKipcbiAqIFFSQ29kZSBmb3IgSmF2YVNjcmlwdFxuICpcbiAqIG1vZGlmaWVkIGJ5IFJ5YW4gRGF5IGZvciBub2RlanMgc3VwcG9ydFxuICogQ29weXJpZ2h0IChjKSAyMDExIFJ5YW4gRGF5XG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlOlxuICogICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuICpcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBRUkNvZGUgZm9yIEphdmFTY3JpcHRcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgS2F6dWhpa28gQXJhc2Vcbi8vXG4vLyBVUkw6IGh0dHA6Ly93d3cuZC1wcm9qZWN0LmNvbS9cbi8vXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2U6XG4vLyAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4vL1xuLy8gVGhlIHdvcmQgXCJRUiBDb2RlXCIgaXMgcmVnaXN0ZXJlZCB0cmFkZW1hcmsgb2Zcbi8vIERFTlNPIFdBVkUgSU5DT1JQT1JBVEVEXG4vLyAgIGh0dHA6Ly93d3cuZGVuc28td2F2ZS5jb20vcXJjb2RlL2ZhcXBhdGVudC1lLmh0bWxcbi8vXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKi9cblxuLyoqXG4gKiBBZGQgZmluZGVyIHBhdHRlcm5zIGJpdHMgdG8gbWF0cml4XG4gKlxuICogQHBhcmFtICB7Qml0TWF0cml4fSBtYXRyaXggIE1vZHVsZXMgbWF0cml4XG4gKiBAcGFyYW0gIHtOdW1iZXJ9ICAgIHZlcnNpb24gUVIgQ29kZSB2ZXJzaW9uXG4gKi9cbmZ1bmN0aW9uIHNldHVwRmluZGVyUGF0dGVybiAobWF0cml4LCB2ZXJzaW9uKSB7XG4gIHZhciBzaXplID0gbWF0cml4LnNpemVcbiAgdmFyIHBvcyA9IEZpbmRlclBhdHRlcm4uZ2V0UG9zaXRpb25zKHZlcnNpb24pXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcm93ID0gcG9zW2ldWzBdXG4gICAgdmFyIGNvbCA9IHBvc1tpXVsxXVxuXG4gICAgZm9yICh2YXIgciA9IC0xOyByIDw9IDc7IHIrKykge1xuICAgICAgaWYgKHJvdyArIHIgPD0gLTEgfHwgc2l6ZSA8PSByb3cgKyByKSBjb250aW51ZVxuXG4gICAgICBmb3IgKHZhciBjID0gLTE7IGMgPD0gNzsgYysrKSB7XG4gICAgICAgIGlmIChjb2wgKyBjIDw9IC0xIHx8IHNpemUgPD0gY29sICsgYykgY29udGludWVcblxuICAgICAgICBpZiAoKHIgPj0gMCAmJiByIDw9IDYgJiYgKGMgPT09IDAgfHwgYyA9PT0gNikpIHx8XG4gICAgICAgICAgKGMgPj0gMCAmJiBjIDw9IDYgJiYgKHIgPT09IDAgfHwgciA9PT0gNikpIHx8XG4gICAgICAgICAgKHIgPj0gMiAmJiByIDw9IDQgJiYgYyA+PSAyICYmIGMgPD0gNCkpIHtcbiAgICAgICAgICBtYXRyaXguc2V0KHJvdyArIHIsIGNvbCArIGMsIHRydWUsIHRydWUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF0cml4LnNldChyb3cgKyByLCBjb2wgKyBjLCBmYWxzZSwgdHJ1ZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFkZCB0aW1pbmcgcGF0dGVybiBiaXRzIHRvIG1hdHJpeFxuICpcbiAqIE5vdGU6IHRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHtAbGluayBzZXR1cEFsaWdubWVudFBhdHRlcm59XG4gKlxuICogQHBhcmFtICB7Qml0TWF0cml4fSBtYXRyaXggTW9kdWxlcyBtYXRyaXhcbiAqL1xuZnVuY3Rpb24gc2V0dXBUaW1pbmdQYXR0ZXJuIChtYXRyaXgpIHtcbiAgdmFyIHNpemUgPSBtYXRyaXguc2l6ZVxuXG4gIGZvciAodmFyIHIgPSA4OyByIDwgc2l6ZSAtIDg7IHIrKykge1xuICAgIHZhciB2YWx1ZSA9IHIgJSAyID09PSAwXG4gICAgbWF0cml4LnNldChyLCA2LCB2YWx1ZSwgdHJ1ZSlcbiAgICBtYXRyaXguc2V0KDYsIHIsIHZhbHVlLCB0cnVlKVxuICB9XG59XG5cbi8qKlxuICogQWRkIGFsaWdubWVudCBwYXR0ZXJucyBiaXRzIHRvIG1hdHJpeFxuICpcbiAqIE5vdGU6IHRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgYWZ0ZXIge0BsaW5rIHNldHVwVGltaW5nUGF0dGVybn1cbiAqXG4gKiBAcGFyYW0gIHtCaXRNYXRyaXh9IG1hdHJpeCAgTW9kdWxlcyBtYXRyaXhcbiAqIEBwYXJhbSAge051bWJlcn0gICAgdmVyc2lvbiBRUiBDb2RlIHZlcnNpb25cbiAqL1xuZnVuY3Rpb24gc2V0dXBBbGlnbm1lbnRQYXR0ZXJuIChtYXRyaXgsIHZlcnNpb24pIHtcbiAgdmFyIHBvcyA9IEFsaWdubWVudFBhdHRlcm4uZ2V0UG9zaXRpb25zKHZlcnNpb24pXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcm93ID0gcG9zW2ldWzBdXG4gICAgdmFyIGNvbCA9IHBvc1tpXVsxXVxuXG4gICAgZm9yICh2YXIgciA9IC0yOyByIDw9IDI7IHIrKykge1xuICAgICAgZm9yICh2YXIgYyA9IC0yOyBjIDw9IDI7IGMrKykge1xuICAgICAgICBpZiAociA9PT0gLTIgfHwgciA9PT0gMiB8fCBjID09PSAtMiB8fCBjID09PSAyIHx8XG4gICAgICAgICAgKHIgPT09IDAgJiYgYyA9PT0gMCkpIHtcbiAgICAgICAgICBtYXRyaXguc2V0KHJvdyArIHIsIGNvbCArIGMsIHRydWUsIHRydWUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF0cml4LnNldChyb3cgKyByLCBjb2wgKyBjLCBmYWxzZSwgdHJ1ZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFkZCB2ZXJzaW9uIGluZm8gYml0cyB0byBtYXRyaXhcbiAqXG4gKiBAcGFyYW0gIHtCaXRNYXRyaXh9IG1hdHJpeCAgTW9kdWxlcyBtYXRyaXhcbiAqIEBwYXJhbSAge051bWJlcn0gICAgdmVyc2lvbiBRUiBDb2RlIHZlcnNpb25cbiAqL1xuZnVuY3Rpb24gc2V0dXBWZXJzaW9uSW5mbyAobWF0cml4LCB2ZXJzaW9uKSB7XG4gIHZhciBzaXplID0gbWF0cml4LnNpemVcbiAgdmFyIGJpdHMgPSBWZXJzaW9uLmdldEVuY29kZWRCaXRzKHZlcnNpb24pXG4gIHZhciByb3csIGNvbCwgbW9kXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxODsgaSsrKSB7XG4gICAgcm93ID0gTWF0aC5mbG9vcihpIC8gMylcbiAgICBjb2wgPSBpICUgMyArIHNpemUgLSA4IC0gM1xuICAgIG1vZCA9ICgoYml0cyA+PiBpKSAmIDEpID09PSAxXG5cbiAgICBtYXRyaXguc2V0KHJvdywgY29sLCBtb2QsIHRydWUpXG4gICAgbWF0cml4LnNldChjb2wsIHJvdywgbW9kLCB0cnVlKVxuICB9XG59XG5cbi8qKlxuICogQWRkIGZvcm1hdCBpbmZvIGJpdHMgdG8gbWF0cml4XG4gKlxuICogQHBhcmFtICB7Qml0TWF0cml4fSBtYXRyaXggICAgICAgICAgICAgICBNb2R1bGVzIG1hdHJpeFxuICogQHBhcmFtICB7RXJyb3JDb3JyZWN0aW9uTGV2ZWx9ICAgIGVycm9yQ29ycmVjdGlvbkxldmVsIEVycm9yIGNvcnJlY3Rpb24gbGV2ZWxcbiAqIEBwYXJhbSAge051bWJlcn0gICAgbWFza1BhdHRlcm4gICAgICAgICAgTWFzayBwYXR0ZXJuIHJlZmVyZW5jZSB2YWx1ZVxuICovXG5mdW5jdGlvbiBzZXR1cEZvcm1hdEluZm8gKG1hdHJpeCwgZXJyb3JDb3JyZWN0aW9uTGV2ZWwsIG1hc2tQYXR0ZXJuKSB7XG4gIHZhciBzaXplID0gbWF0cml4LnNpemVcbiAgdmFyIGJpdHMgPSBGb3JtYXRJbmZvLmdldEVuY29kZWRCaXRzKGVycm9yQ29ycmVjdGlvbkxldmVsLCBtYXNrUGF0dGVybilcbiAgdmFyIGksIG1vZFxuXG4gIGZvciAoaSA9IDA7IGkgPCAxNTsgaSsrKSB7XG4gICAgbW9kID0gKChiaXRzID4+IGkpICYgMSkgPT09IDFcblxuICAgIC8vIHZlcnRpY2FsXG4gICAgaWYgKGkgPCA2KSB7XG4gICAgICBtYXRyaXguc2V0KGksIDgsIG1vZCwgdHJ1ZSlcbiAgICB9IGVsc2UgaWYgKGkgPCA4KSB7XG4gICAgICBtYXRyaXguc2V0KGkgKyAxLCA4LCBtb2QsIHRydWUpXG4gICAgfSBlbHNlIHtcbiAgICAgIG1hdHJpeC5zZXQoc2l6ZSAtIDE1ICsgaSwgOCwgbW9kLCB0cnVlKVxuICAgIH1cblxuICAgIC8vIGhvcml6b250YWxcbiAgICBpZiAoaSA8IDgpIHtcbiAgICAgIG1hdHJpeC5zZXQoOCwgc2l6ZSAtIGkgLSAxLCBtb2QsIHRydWUpXG4gICAgfSBlbHNlIGlmIChpIDwgOSkge1xuICAgICAgbWF0cml4LnNldCg4LCAxNSAtIGkgLSAxICsgMSwgbW9kLCB0cnVlKVxuICAgIH0gZWxzZSB7XG4gICAgICBtYXRyaXguc2V0KDgsIDE1IC0gaSAtIDEsIG1vZCwgdHJ1ZSlcbiAgICB9XG4gIH1cblxuICAvLyBmaXhlZCBtb2R1bGVcbiAgbWF0cml4LnNldChzaXplIC0gOCwgOCwgMSwgdHJ1ZSlcbn1cblxuLyoqXG4gKiBBZGQgZW5jb2RlZCBkYXRhIGJpdHMgdG8gbWF0cml4XG4gKlxuICogQHBhcmFtICB7Qml0TWF0cml4fSBtYXRyaXggTW9kdWxlcyBtYXRyaXhcbiAqIEBwYXJhbSAge0J1ZmZlcn0gICAgZGF0YSAgIERhdGEgY29kZXdvcmRzXG4gKi9cbmZ1bmN0aW9uIHNldHVwRGF0YSAobWF0cml4LCBkYXRhKSB7XG4gIHZhciBzaXplID0gbWF0cml4LnNpemVcbiAgdmFyIGluYyA9IC0xXG4gIHZhciByb3cgPSBzaXplIC0gMVxuICB2YXIgYml0SW5kZXggPSA3XG4gIHZhciBieXRlSW5kZXggPSAwXG5cbiAgZm9yICh2YXIgY29sID0gc2l6ZSAtIDE7IGNvbCA+IDA7IGNvbCAtPSAyKSB7XG4gICAgaWYgKGNvbCA9PT0gNikgY29sLS1cblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBmb3IgKHZhciBjID0gMDsgYyA8IDI7IGMrKykge1xuICAgICAgICBpZiAoIW1hdHJpeC5pc1Jlc2VydmVkKHJvdywgY29sIC0gYykpIHtcbiAgICAgICAgICB2YXIgZGFyayA9IGZhbHNlXG5cbiAgICAgICAgICBpZiAoYnl0ZUluZGV4IDwgZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRhcmsgPSAoKChkYXRhW2J5dGVJbmRleF0gPj4+IGJpdEluZGV4KSAmIDEpID09PSAxKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG1hdHJpeC5zZXQocm93LCBjb2wgLSBjLCBkYXJrKVxuICAgICAgICAgIGJpdEluZGV4LS1cblxuICAgICAgICAgIGlmIChiaXRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIGJ5dGVJbmRleCsrXG4gICAgICAgICAgICBiaXRJbmRleCA9IDdcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcm93ICs9IGluY1xuXG4gICAgICBpZiAocm93IDwgMCB8fCBzaXplIDw9IHJvdykge1xuICAgICAgICByb3cgLT0gaW5jXG4gICAgICAgIGluYyA9IC1pbmNcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGUgZW5jb2RlZCBjb2Rld29yZHMgZnJvbSBkYXRhIGlucHV0XG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSAgIHZlcnNpb24gICAgICAgICAgICAgIFFSIENvZGUgdmVyc2lvblxuICogQHBhcmFtICB7RXJyb3JDb3JyZWN0aW9uTGV2ZWx9ICAgZXJyb3JDb3JyZWN0aW9uTGV2ZWwgRXJyb3IgY29ycmVjdGlvbiBsZXZlbFxuICogQHBhcmFtICB7Qnl0ZURhdGF9IGRhdGEgICAgICAgICAgICAgICAgIERhdGEgaW5wdXRcbiAqIEByZXR1cm4ge0J1ZmZlcn0gICAgICAgICAgICAgICAgICAgICAgICBCdWZmZXIgY29udGFpbmluZyBlbmNvZGVkIGNvZGV3b3Jkc1xuICovXG5mdW5jdGlvbiBjcmVhdGVEYXRhICh2ZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbCwgc2VnbWVudHMpIHtcbiAgLy8gUHJlcGFyZSBkYXRhIGJ1ZmZlclxuICB2YXIgYnVmZmVyID0gbmV3IEJpdEJ1ZmZlcigpXG5cbiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuICAgIC8vIHByZWZpeCBkYXRhIHdpdGggbW9kZSBpbmRpY2F0b3IgKDQgYml0cylcbiAgICBidWZmZXIucHV0KGRhdGEubW9kZS5iaXQsIDQpXG5cbiAgICAvLyBQcmVmaXggZGF0YSB3aXRoIGNoYXJhY3RlciBjb3VudCBpbmRpY2F0b3IuXG4gICAgLy8gVGhlIGNoYXJhY3RlciBjb3VudCBpbmRpY2F0b3IgaXMgYSBzdHJpbmcgb2YgYml0cyB0aGF0IHJlcHJlc2VudHMgdGhlXG4gICAgLy8gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBhcmUgYmVpbmcgZW5jb2RlZC5cbiAgICAvLyBUaGUgY2hhcmFjdGVyIGNvdW50IGluZGljYXRvciBtdXN0IGJlIHBsYWNlZCBhZnRlciB0aGUgbW9kZSBpbmRpY2F0b3JcbiAgICAvLyBhbmQgbXVzdCBiZSBhIGNlcnRhaW4gbnVtYmVyIG9mIGJpdHMgbG9uZywgZGVwZW5kaW5nIG9uIHRoZSBRUiB2ZXJzaW9uXG4gICAgLy8gYW5kIGRhdGEgbW9kZVxuICAgIC8vIEBzZWUge0BsaW5rIE1vZGUuZ2V0Q2hhckNvdW50SW5kaWNhdG9yfS5cbiAgICBidWZmZXIucHV0KGRhdGEuZ2V0TGVuZ3RoKCksIE1vZGUuZ2V0Q2hhckNvdW50SW5kaWNhdG9yKGRhdGEubW9kZSwgdmVyc2lvbikpXG5cbiAgICAvLyBhZGQgYmluYXJ5IGRhdGEgc2VxdWVuY2UgdG8gYnVmZmVyXG4gICAgZGF0YS53cml0ZShidWZmZXIpXG4gIH0pXG5cbiAgLy8gQ2FsY3VsYXRlIHJlcXVpcmVkIG51bWJlciBvZiBiaXRzXG4gIHZhciB0b3RhbENvZGV3b3JkcyA9IFV0aWxzLmdldFN5bWJvbFRvdGFsQ29kZXdvcmRzKHZlcnNpb24pXG4gIHZhciBlY1RvdGFsQ29kZXdvcmRzID0gRUNDb2RlLmdldFRvdGFsQ29kZXdvcmRzQ291bnQodmVyc2lvbiwgZXJyb3JDb3JyZWN0aW9uTGV2ZWwpXG4gIHZhciBkYXRhVG90YWxDb2Rld29yZHNCaXRzID0gKHRvdGFsQ29kZXdvcmRzIC0gZWNUb3RhbENvZGV3b3JkcykgKiA4XG5cbiAgLy8gQWRkIGEgdGVybWluYXRvci5cbiAgLy8gSWYgdGhlIGJpdCBzdHJpbmcgaXMgc2hvcnRlciB0aGFuIHRoZSB0b3RhbCBudW1iZXIgb2YgcmVxdWlyZWQgYml0cyxcbiAgLy8gYSB0ZXJtaW5hdG9yIG9mIHVwIHRvIGZvdXIgMHMgbXVzdCBiZSBhZGRlZCB0byB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgc3RyaW5nLlxuICAvLyBJZiB0aGUgYml0IHN0cmluZyBpcyBtb3JlIHRoYW4gZm91ciBiaXRzIHNob3J0ZXIgdGhhbiB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIGJpdHMsXG4gIC8vIGFkZCBmb3VyIDBzIHRvIHRoZSBlbmQuXG4gIGlmIChidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCkgKyA0IDw9IGRhdGFUb3RhbENvZGV3b3Jkc0JpdHMpIHtcbiAgICBidWZmZXIucHV0KDAsIDQpXG4gIH1cblxuICAvLyBJZiB0aGUgYml0IHN0cmluZyBpcyBmZXdlciB0aGFuIGZvdXIgYml0cyBzaG9ydGVyLCBhZGQgb25seSB0aGUgbnVtYmVyIG9mIDBzIHRoYXRcbiAgLy8gYXJlIG5lZWRlZCB0byByZWFjaCB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIGJpdHMuXG5cbiAgLy8gQWZ0ZXIgYWRkaW5nIHRoZSB0ZXJtaW5hdG9yLCBpZiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIHN0cmluZyBpcyBub3QgYSBtdWx0aXBsZSBvZiA4LFxuICAvLyBwYWQgdGhlIHN0cmluZyBvbiB0aGUgcmlnaHQgd2l0aCAwcyB0byBtYWtlIHRoZSBzdHJpbmcncyBsZW5ndGggYSBtdWx0aXBsZSBvZiA4LlxuICB3aGlsZSAoYnVmZmVyLmdldExlbmd0aEluQml0cygpICUgOCAhPT0gMCkge1xuICAgIGJ1ZmZlci5wdXRCaXQoMClcbiAgfVxuXG4gIC8vIEFkZCBwYWQgYnl0ZXMgaWYgdGhlIHN0cmluZyBpcyBzdGlsbCBzaG9ydGVyIHRoYW4gdGhlIHRvdGFsIG51bWJlciBvZiByZXF1aXJlZCBiaXRzLlxuICAvLyBFeHRlbmQgdGhlIGJ1ZmZlciB0byBmaWxsIHRoZSBkYXRhIGNhcGFjaXR5IG9mIHRoZSBzeW1ib2wgY29ycmVzcG9uZGluZyB0b1xuICAvLyB0aGUgVmVyc2lvbiBhbmQgRXJyb3IgQ29ycmVjdGlvbiBMZXZlbCBieSBhZGRpbmcgdGhlIFBhZCBDb2Rld29yZHMgMTExMDExMDAgKDB4RUMpXG4gIC8vIGFuZCAwMDAxMDAwMSAoMHgxMSkgYWx0ZXJuYXRlbHkuXG4gIHZhciByZW1haW5pbmdCeXRlID0gKGRhdGFUb3RhbENvZGV3b3Jkc0JpdHMgLSBidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCkpIC8gOFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJlbWFpbmluZ0J5dGU7IGkrKykge1xuICAgIGJ1ZmZlci5wdXQoaSAlIDIgPyAweDExIDogMHhFQywgOClcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVDb2Rld29yZHMoYnVmZmVyLCB2ZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbClcbn1cblxuLyoqXG4gKiBFbmNvZGUgaW5wdXQgZGF0YSB3aXRoIFJlZWQtU29sb21vbiBhbmQgcmV0dXJuIGNvZGV3b3JkcyB3aXRoXG4gKiByZWxhdGl2ZSBlcnJvciBjb3JyZWN0aW9uIGJpdHNcbiAqXG4gKiBAcGFyYW0gIHtCaXRCdWZmZXJ9IGJpdEJ1ZmZlciAgICAgICAgICAgIERhdGEgdG8gZW5jb2RlXG4gKiBAcGFyYW0gIHtOdW1iZXJ9ICAgIHZlcnNpb24gICAgICAgICAgICAgIFFSIENvZGUgdmVyc2lvblxuICogQHBhcmFtICB7RXJyb3JDb3JyZWN0aW9uTGV2ZWx9IGVycm9yQ29ycmVjdGlvbkxldmVsIEVycm9yIGNvcnJlY3Rpb24gbGV2ZWxcbiAqIEByZXR1cm4ge0J1ZmZlcn0gICAgICAgICAgICAgICAgICAgICAgICAgQnVmZmVyIGNvbnRhaW5pbmcgZW5jb2RlZCBjb2Rld29yZHNcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ29kZXdvcmRzIChiaXRCdWZmZXIsIHZlcnNpb24sIGVycm9yQ29ycmVjdGlvbkxldmVsKSB7XG4gIC8vIFRvdGFsIGNvZGV3b3JkcyBmb3IgdGhpcyBRUiBjb2RlIHZlcnNpb24gKERhdGEgKyBFcnJvciBjb3JyZWN0aW9uKVxuICB2YXIgdG90YWxDb2Rld29yZHMgPSBVdGlscy5nZXRTeW1ib2xUb3RhbENvZGV3b3Jkcyh2ZXJzaW9uKVxuXG4gIC8vIFRvdGFsIG51bWJlciBvZiBlcnJvciBjb3JyZWN0aW9uIGNvZGV3b3Jkc1xuICB2YXIgZWNUb3RhbENvZGV3b3JkcyA9IEVDQ29kZS5nZXRUb3RhbENvZGV3b3Jkc0NvdW50KHZlcnNpb24sIGVycm9yQ29ycmVjdGlvbkxldmVsKVxuXG4gIC8vIFRvdGFsIG51bWJlciBvZiBkYXRhIGNvZGV3b3Jkc1xuICB2YXIgZGF0YVRvdGFsQ29kZXdvcmRzID0gdG90YWxDb2Rld29yZHMgLSBlY1RvdGFsQ29kZXdvcmRzXG5cbiAgLy8gVG90YWwgbnVtYmVyIG9mIGJsb2Nrc1xuICB2YXIgZWNUb3RhbEJsb2NrcyA9IEVDQ29kZS5nZXRCbG9ja3NDb3VudCh2ZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbClcblxuICAvLyBDYWxjdWxhdGUgaG93IG1hbnkgYmxvY2tzIGVhY2ggZ3JvdXAgc2hvdWxkIGNvbnRhaW5cbiAgdmFyIGJsb2Nrc0luR3JvdXAyID0gdG90YWxDb2Rld29yZHMgJSBlY1RvdGFsQmxvY2tzXG4gIHZhciBibG9ja3NJbkdyb3VwMSA9IGVjVG90YWxCbG9ja3MgLSBibG9ja3NJbkdyb3VwMlxuXG4gIHZhciB0b3RhbENvZGV3b3Jkc0luR3JvdXAxID0gTWF0aC5mbG9vcih0b3RhbENvZGV3b3JkcyAvIGVjVG90YWxCbG9ja3MpXG5cbiAgdmFyIGRhdGFDb2Rld29yZHNJbkdyb3VwMSA9IE1hdGguZmxvb3IoZGF0YVRvdGFsQ29kZXdvcmRzIC8gZWNUb3RhbEJsb2NrcylcbiAgdmFyIGRhdGFDb2Rld29yZHNJbkdyb3VwMiA9IGRhdGFDb2Rld29yZHNJbkdyb3VwMSArIDFcblxuICAvLyBOdW1iZXIgb2YgRUMgY29kZXdvcmRzIGlzIHRoZSBzYW1lIGZvciBib3RoIGdyb3Vwc1xuICB2YXIgZWNDb3VudCA9IHRvdGFsQ29kZXdvcmRzSW5Hcm91cDEgLSBkYXRhQ29kZXdvcmRzSW5Hcm91cDFcblxuICAvLyBJbml0aWFsaXplIGEgUmVlZC1Tb2xvbW9uIGVuY29kZXIgd2l0aCBhIGdlbmVyYXRvciBwb2x5bm9taWFsIG9mIGRlZ3JlZSBlY0NvdW50XG4gIHZhciBycyA9IG5ldyBSZWVkU29sb21vbkVuY29kZXIoZWNDb3VudClcblxuICB2YXIgb2Zmc2V0ID0gMFxuICB2YXIgZGNEYXRhID0gbmV3IEFycmF5KGVjVG90YWxCbG9ja3MpXG4gIHZhciBlY0RhdGEgPSBuZXcgQXJyYXkoZWNUb3RhbEJsb2NrcylcbiAgdmFyIG1heERhdGFTaXplID0gMFxuICB2YXIgYnVmZmVyID0gbmV3IEJ1ZmZlcihiaXRCdWZmZXIuYnVmZmVyKVxuXG4gIC8vIERpdmlkZSB0aGUgYnVmZmVyIGludG8gdGhlIHJlcXVpcmVkIG51bWJlciBvZiBibG9ja3NcbiAgZm9yICh2YXIgYiA9IDA7IGIgPCBlY1RvdGFsQmxvY2tzOyBiKyspIHtcbiAgICB2YXIgZGF0YVNpemUgPSBiIDwgYmxvY2tzSW5Hcm91cDEgPyBkYXRhQ29kZXdvcmRzSW5Hcm91cDEgOiBkYXRhQ29kZXdvcmRzSW5Hcm91cDJcblxuICAgIC8vIGV4dHJhY3QgYSBibG9jayBvZiBkYXRhIGZyb20gYnVmZmVyXG4gICAgZGNEYXRhW2JdID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZGF0YVNpemUpXG5cbiAgICAvLyBDYWxjdWxhdGUgRUMgY29kZXdvcmRzIGZvciB0aGlzIGRhdGEgYmxvY2tcbiAgICBlY0RhdGFbYl0gPSBycy5lbmNvZGUoZGNEYXRhW2JdKVxuXG4gICAgb2Zmc2V0ICs9IGRhdGFTaXplXG4gICAgbWF4RGF0YVNpemUgPSBNYXRoLm1heChtYXhEYXRhU2l6ZSwgZGF0YVNpemUpXG4gIH1cblxuICAvLyBDcmVhdGUgZmluYWwgZGF0YVxuICAvLyBJbnRlcmxlYXZlIHRoZSBkYXRhIGFuZCBlcnJvciBjb3JyZWN0aW9uIGNvZGV3b3JkcyBmcm9tIGVhY2ggYmxvY2tcbiAgdmFyIGRhdGEgPSBuZXcgQnVmZmVyKHRvdGFsQ29kZXdvcmRzKVxuICB2YXIgaW5kZXggPSAwXG4gIHZhciBpLCByXG5cbiAgLy8gQWRkIGRhdGEgY29kZXdvcmRzXG4gIGZvciAoaSA9IDA7IGkgPCBtYXhEYXRhU2l6ZTsgaSsrKSB7XG4gICAgZm9yIChyID0gMDsgciA8IGVjVG90YWxCbG9ja3M7IHIrKykge1xuICAgICAgaWYgKGkgPCBkY0RhdGFbcl0ubGVuZ3RoKSB7XG4gICAgICAgIGRhdGFbaW5kZXgrK10gPSBkY0RhdGFbcl1baV1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBBcHBlZCBFQyBjb2Rld29yZHNcbiAgZm9yIChpID0gMDsgaSA8IGVjQ291bnQ7IGkrKykge1xuICAgIGZvciAociA9IDA7IHIgPCBlY1RvdGFsQmxvY2tzOyByKyspIHtcbiAgICAgIGRhdGFbaW5kZXgrK10gPSBlY0RhdGFbcl1baV1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGF0YVxufVxuXG4vKipcbiAqIEJ1aWxkIFFSIENvZGUgc3ltYm9sXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBkYXRhICAgICAgICAgICAgICAgICBJbnB1dCBzdHJpbmdcbiAqIEBwYXJhbSAge051bWJlcn0gdmVyc2lvbiAgICAgICAgICAgICAgUVIgQ29kZSB2ZXJzaW9uXG4gKiBAcGFyYW0gIHtFcnJvckNvcnJldGlvbkxldmVsfSBlcnJvckNvcnJlY3Rpb25MZXZlbCBFcnJvciBsZXZlbFxuICogQHBhcmFtICB7TWFza1BhdHRlcm59IG1hc2tQYXR0ZXJuICAgICBNYXNrIHBhdHRlcm5cbiAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGNvbnRhaW5pbmcgc3ltYm9sIGRhdGFcbiAqL1xuZnVuY3Rpb24gY3JlYXRlU3ltYm9sIChkYXRhLCB2ZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbCwgbWFza1BhdHRlcm4pIHtcbiAgdmFyIHNlZ21lbnRzXG5cbiAgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICBzZWdtZW50cyA9IFNlZ21lbnRzLmZyb21BcnJheShkYXRhKVxuICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIHZhciBlc3RpbWF0ZWRWZXJzaW9uID0gdmVyc2lvblxuXG4gICAgaWYgKCFlc3RpbWF0ZWRWZXJzaW9uKSB7XG4gICAgICB2YXIgcmF3U2VnbWVudHMgPSBTZWdtZW50cy5yYXdTcGxpdChkYXRhKVxuXG4gICAgICAvLyBFc3RpbWF0ZSBiZXN0IHZlcnNpb24gdGhhdCBjYW4gY29udGFpbiByYXcgc3BsaXR0ZWQgc2VnbWVudHNcbiAgICAgIGVzdGltYXRlZFZlcnNpb24gPSBWZXJzaW9uLmdldEJlc3RWZXJzaW9uRm9yRGF0YShyYXdTZWdtZW50cyxcbiAgICAgICAgZXJyb3JDb3JyZWN0aW9uTGV2ZWwpXG4gICAgfVxuXG4gICAgLy8gQnVpbGQgb3B0aW1pemVkIHNlZ21lbnRzXG4gICAgLy8gSWYgZXN0aW1hdGVkIHZlcnNpb24gaXMgdW5kZWZpbmVkLCB0cnkgd2l0aCB0aGUgaGlnaGVzdCB2ZXJzaW9uXG4gICAgc2VnbWVudHMgPSBTZWdtZW50cy5mcm9tU3RyaW5nKGRhdGEsIGVzdGltYXRlZFZlcnNpb24gfHwgNDApXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEnKVxuICB9XG5cbiAgLy8gR2V0IHRoZSBtaW4gdmVyc2lvbiB0aGF0IGNhbiBjb250YWluIGRhdGFcbiAgdmFyIGJlc3RWZXJzaW9uID0gVmVyc2lvbi5nZXRCZXN0VmVyc2lvbkZvckRhdGEoc2VnbWVudHMsXG4gICAgICBlcnJvckNvcnJlY3Rpb25MZXZlbClcblxuICAvLyBJZiBubyB2ZXJzaW9uIGlzIGZvdW5kLCBkYXRhIGNhbm5vdCBiZSBzdG9yZWRcbiAgaWYgKCFiZXN0VmVyc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGFtb3VudCBvZiBkYXRhIGlzIHRvbyBiaWcgdG8gYmUgc3RvcmVkIGluIGEgUVIgQ29kZScpXG4gIH1cblxuICAvLyBJZiBub3Qgc3BlY2lmaWVkLCB1c2UgbWluIHZlcnNpb24gYXMgZGVmYXVsdFxuICBpZiAoIXZlcnNpb24pIHtcbiAgICB2ZXJzaW9uID0gYmVzdFZlcnNpb25cblxuICAvLyBDaGVjayBpZiB0aGUgc3BlY2lmaWVkIHZlcnNpb24gY2FuIGNvbnRhaW4gdGhlIGRhdGFcbiAgfSBlbHNlIGlmICh2ZXJzaW9uIDwgYmVzdFZlcnNpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1xcbicgK1xuICAgICAgJ1RoZSBjaG9zZW4gUVIgQ29kZSB2ZXJzaW9uIGNhbm5vdCBjb250YWluIHRoaXMgYW1vdW50IG9mIGRhdGEuXFxuJyArXG4gICAgICAnTWluaW11bSB2ZXJzaW9uIHJlcXVpcmVkIHRvIHN0b3JlIGN1cnJlbnQgZGF0YSBpczogJyArIGJlc3RWZXJzaW9uICsgJy5cXG4nXG4gICAgKVxuICB9XG5cbiAgdmFyIGRhdGFCaXRzID0gY3JlYXRlRGF0YSh2ZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbCwgc2VnbWVudHMpXG5cbiAgLy8gQWxsb2NhdGUgbWF0cml4IGJ1ZmZlclxuICB2YXIgbW9kdWxlQ291bnQgPSBVdGlscy5nZXRTeW1ib2xTaXplKHZlcnNpb24pXG4gIHZhciBtb2R1bGVzID0gbmV3IEJpdE1hdHJpeChtb2R1bGVDb3VudClcblxuICAvLyBBZGQgZnVuY3Rpb24gbW9kdWxlc1xuICBzZXR1cEZpbmRlclBhdHRlcm4obW9kdWxlcywgdmVyc2lvbilcbiAgc2V0dXBUaW1pbmdQYXR0ZXJuKG1vZHVsZXMpXG4gIHNldHVwQWxpZ25tZW50UGF0dGVybihtb2R1bGVzLCB2ZXJzaW9uKVxuXG4gIC8vIEFkZCB0ZW1wb3JhcnkgZHVtbXkgYml0cyBmb3IgZm9ybWF0IGluZm8ganVzdCB0byBzZXQgdGhlbSBhcyByZXNlcnZlZC5cbiAgLy8gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudCB0aGVzZSBiaXRzIGZyb20gYmVpbmcgbWFza2VkIGJ5IHtAbGluayBNYXNrUGF0dGVybi5hcHBseU1hc2t9XG4gIC8vIHNpbmNlIHRoZSBtYXNraW5nIG9wZXJhdGlvbiBtdXN0IGJlIHBlcmZvcm1lZCBvbmx5IG9uIHRoZSBlbmNvZGluZyByZWdpb24uXG4gIC8vIFRoZXNlIGJsb2NrcyB3aWxsIGJlIHJlcGxhY2VkIHdpdGggY29ycmVjdCB2YWx1ZXMgbGF0ZXIgaW4gY29kZS5cbiAgc2V0dXBGb3JtYXRJbmZvKG1vZHVsZXMsIGVycm9yQ29ycmVjdGlvbkxldmVsLCAwKVxuXG4gIGlmICh2ZXJzaW9uID49IDcpIHtcbiAgICBzZXR1cFZlcnNpb25JbmZvKG1vZHVsZXMsIHZlcnNpb24pXG4gIH1cblxuICAvLyBBZGQgZGF0YSBjb2Rld29yZHNcbiAgc2V0dXBEYXRhKG1vZHVsZXMsIGRhdGFCaXRzKVxuXG4gIGlmIChpc05hTihtYXNrUGF0dGVybikpIHtcbiAgICAvLyBGaW5kIGJlc3QgbWFzayBwYXR0ZXJuXG4gICAgbWFza1BhdHRlcm4gPSBNYXNrUGF0dGVybi5nZXRCZXN0TWFzayhtb2R1bGVzLFxuICAgICAgc2V0dXBGb3JtYXRJbmZvLmJpbmQobnVsbCwgbW9kdWxlcywgZXJyb3JDb3JyZWN0aW9uTGV2ZWwpKVxuICB9XG5cbiAgLy8gQXBwbHkgbWFzayBwYXR0ZXJuXG4gIE1hc2tQYXR0ZXJuLmFwcGx5TWFzayhtYXNrUGF0dGVybiwgbW9kdWxlcylcblxuICAvLyBSZXBsYWNlIGZvcm1hdCBpbmZvIGJpdHMgd2l0aCBjb3JyZWN0IHZhbHVlc1xuICBzZXR1cEZvcm1hdEluZm8obW9kdWxlcywgZXJyb3JDb3JyZWN0aW9uTGV2ZWwsIG1hc2tQYXR0ZXJuKVxuXG4gIHJldHVybiB7XG4gICAgbW9kdWxlczogbW9kdWxlcyxcbiAgICB2ZXJzaW9uOiB2ZXJzaW9uLFxuICAgIGVycm9yQ29ycmVjdGlvbkxldmVsOiBlcnJvckNvcnJlY3Rpb25MZXZlbCxcbiAgICBtYXNrUGF0dGVybjogbWFza1BhdHRlcm4sXG4gICAgc2VnbWVudHM6IHNlZ21lbnRzXG4gIH1cbn1cblxuLyoqXG4gKiBRUiBDb2RlXG4gKlxuICogQHBhcmFtIHtTdHJpbmcgfCBBcnJheX0gZGF0YSAgICAgICAgICAgICAgICAgSW5wdXQgZGF0YVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgY29uZmlndXJhdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLnZlcnNpb24gICAgICAgICAgICAgIFFSIENvZGUgdmVyc2lvblxuICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMuZXJyb3JDb3JyZWN0aW9uTGV2ZWwgRXJyb3IgY29ycmVjdGlvbiBsZXZlbFxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9ucy50b1NKSVNGdW5jICAgICAgICAgSGVscGVyIGZ1bmMgdG8gY29udmVydCB1dGY4IHRvIHNqaXNcbiAqL1xuZXhwb3J0cy5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUgKGRhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAndW5kZWZpbmVkJyB8fCBkYXRhID09PSAnJykge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gaW5wdXQgdGV4dCcpXG4gIH1cblxuICB2YXIgZXJyb3JDb3JyZWN0aW9uTGV2ZWwgPSBFQ0xldmVsLk1cbiAgdmFyIHZlcnNpb25cbiAgdmFyIG1hc2tcblxuICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gVXNlIGhpZ2hlciBlcnJvciBjb3JyZWN0aW9uIGxldmVsIGFzIGRlZmF1bHRcbiAgICBlcnJvckNvcnJlY3Rpb25MZXZlbCA9IEVDTGV2ZWwuZnJvbShvcHRpb25zLmVycm9yQ29ycmVjdGlvbkxldmVsLCBFQ0xldmVsLk0pXG4gICAgdmVyc2lvbiA9IFZlcnNpb24uZnJvbShvcHRpb25zLnZlcnNpb24pXG4gICAgbWFzayA9IE1hc2tQYXR0ZXJuLmZyb20ob3B0aW9ucy5tYXNrUGF0dGVybilcblxuICAgIGlmIChvcHRpb25zLnRvU0pJU0Z1bmMpIHtcbiAgICAgIFV0aWxzLnNldFRvU0pJU0Z1bmN0aW9uKG9wdGlvbnMudG9TSklTRnVuYylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3JlYXRlU3ltYm9sKGRhdGEsIHZlcnNpb24sIGVycm9yQ29ycmVjdGlvbkxldmVsLCBtYXNrKVxufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2J1ZmZlcicpXG52YXIgUG9seW5vbWlhbCA9IHJlcXVpcmUoJy4vcG9seW5vbWlhbCcpXG5cbmZ1bmN0aW9uIFJlZWRTb2xvbW9uRW5jb2RlciAoZGVncmVlKSB7XG4gIHRoaXMuZ2VuUG9seSA9IHVuZGVmaW5lZFxuICB0aGlzLmRlZ3JlZSA9IGRlZ3JlZVxuXG4gIGlmICh0aGlzLmRlZ3JlZSkgdGhpcy5pbml0aWFsaXplKHRoaXMuZGVncmVlKVxufVxuXG4vKipcbiAqIEluaXRpYWxpemUgdGhlIGVuY29kZXIuXG4gKiBUaGUgaW5wdXQgcGFyYW0gc2hvdWxkIGNvcnJlc3BvbmQgdG8gdGhlIG51bWJlciBvZiBlcnJvciBjb3JyZWN0aW9uIGNvZGV3b3Jkcy5cbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGRlZ3JlZVxuICovXG5SZWVkU29sb21vbkVuY29kZXIucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiBpbml0aWFsaXplIChkZWdyZWUpIHtcbiAgLy8gY3JlYXRlIGFuIGlycmVkdWNpYmxlIGdlbmVyYXRvciBwb2x5bm9taWFsXG4gIHRoaXMuZGVncmVlID0gZGVncmVlXG4gIHRoaXMuZ2VuUG9seSA9IFBvbHlub21pYWwuZ2VuZXJhdGVFQ1BvbHlub21pYWwodGhpcy5kZWdyZWUpXG59XG5cbi8qKlxuICogRW5jb2RlcyBhIGNodW5rIG9mIGRhdGFcbiAqXG4gKiBAcGFyYW0gIHtCdWZmZXJ9IGRhdGEgQnVmZmVyIGNvbnRhaW5pbmcgaW5wdXQgZGF0YVxuICogQHJldHVybiB7QnVmZmVyfSAgICAgIEJ1ZmZlciBjb250YWluaW5nIGVuY29kZWQgZGF0YVxuICovXG5SZWVkU29sb21vbkVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZSAoZGF0YSkge1xuICBpZiAoIXRoaXMuZ2VuUG9seSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRW5jb2RlciBub3QgaW5pdGlhbGl6ZWQnKVxuICB9XG5cbiAgLy8gQ2FsY3VsYXRlIEVDIGZvciB0aGlzIGRhdGEgYmxvY2tcbiAgLy8gZXh0ZW5kcyBkYXRhIHNpemUgdG8gZGF0YStnZW5Qb2x5IHNpemVcbiAgdmFyIHBhZCA9IG5ldyBCdWZmZXIodGhpcy5kZWdyZWUpXG4gIHBhZC5maWxsKDApXG4gIHZhciBwYWRkZWREYXRhID0gQnVmZmVyLmNvbmNhdChbZGF0YSwgcGFkXSwgZGF0YS5sZW5ndGggKyB0aGlzLmRlZ3JlZSlcblxuICAvLyBUaGUgZXJyb3IgY29ycmVjdGlvbiBjb2Rld29yZHMgYXJlIHRoZSByZW1haW5kZXIgYWZ0ZXIgZGl2aWRpbmcgdGhlIGRhdGEgY29kZXdvcmRzXG4gIC8vIGJ5IGEgZ2VuZXJhdG9yIHBvbHlub21pYWxcbiAgdmFyIHJlbWFpbmRlciA9IFBvbHlub21pYWwubW9kKHBhZGRlZERhdGEsIHRoaXMuZ2VuUG9seSlcblxuICAvLyByZXR1cm4gRUMgZGF0YSBibG9ja3MgKGxhc3QgbiBieXRlLCB3aGVyZSBuIGlzIHRoZSBkZWdyZWUgb2YgZ2VuUG9seSlcbiAgLy8gSWYgY29lZmZpY2llbnRzIG51bWJlciBpbiByZW1haW5kZXIgYXJlIGxlc3MgdGhhbiBnZW5Qb2x5IGRlZ3JlZSxcbiAgLy8gcGFkIHdpdGggMHMgdG8gdGhlIGxlZnQgdG8gcmVhY2ggdGhlIG5lZWRlZCBudW1iZXIgb2YgY29lZmZpY2llbnRzXG4gIHZhciBzdGFydCA9IHRoaXMuZGVncmVlIC0gcmVtYWluZGVyLmxlbmd0aFxuICBpZiAoc3RhcnQgPiAwKSB7XG4gICAgdmFyIGJ1ZmYgPSBuZXcgQnVmZmVyKHRoaXMuZGVncmVlKVxuICAgIGJ1ZmYuZmlsbCgwKVxuICAgIHJlbWFpbmRlci5jb3B5KGJ1ZmYsIHN0YXJ0KVxuXG4gICAgcmV0dXJuIGJ1ZmZcbiAgfVxuXG4gIHJldHVybiByZW1haW5kZXJcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZWVkU29sb21vbkVuY29kZXJcbiIsInZhciBudW1lcmljID0gJ1swLTldKydcbnZhciBhbHBoYW51bWVyaWMgPSAnW0EtWiAkJSorXFxcXC0uLzpdKydcbnZhciBrYW5qaSA9ICcoPzpbdTMwMDAtdTMwM0ZdfFt1MzA0MC11MzA5Rl18W3UzMEEwLXUzMEZGXXwnICtcbiAgJ1t1RkYwMC11RkZFRl18W3U0RTAwLXU5RkFGXXxbdTI2MDUtdTI2MDZdfFt1MjE5MC11MjE5NV18dTIwM0J8JyArXG4gICdbdTIwMTB1MjAxNXUyMDE4dTIwMTl1MjAyNXUyMDI2dTIwMUN1MjAxRHUyMjI1dTIyNjBdfCcgK1xuICAnW3UwMzkxLXUwNDUxXXxbdTAwQTd1MDBBOHUwMEIxdTAwQjR1MDBEN3UwMEY3XSkrJ1xua2FuamkgPSBrYW5qaS5yZXBsYWNlKC91L2csICdcXFxcdScpXG5cbnZhciBieXRlID0gJyg/Oig/IVtBLVowLTkgJCUqK1xcXFwtLi86XXwnICsga2FuamkgKyAnKSg/Oi58W1xcclxcbl0pKSsnXG5cbmV4cG9ydHMuS0FOSkkgPSBuZXcgUmVnRXhwKGthbmppLCAnZycpXG5leHBvcnRzLkJZVEVfS0FOSkkgPSBuZXcgUmVnRXhwKCdbXkEtWjAtOSAkJSorXFxcXC0uLzpdKycsICdnJylcbmV4cG9ydHMuQllURSA9IG5ldyBSZWdFeHAoYnl0ZSwgJ2cnKVxuZXhwb3J0cy5OVU1FUklDID0gbmV3IFJlZ0V4cChudW1lcmljLCAnZycpXG5leHBvcnRzLkFMUEhBTlVNRVJJQyA9IG5ldyBSZWdFeHAoYWxwaGFudW1lcmljLCAnZycpXG5cbnZhciBURVNUX0tBTkpJID0gbmV3IFJlZ0V4cCgnXicgKyBrYW5qaSArICckJylcbnZhciBURVNUX05VTUVSSUMgPSBuZXcgUmVnRXhwKCdeJyArIG51bWVyaWMgKyAnJCcpXG52YXIgVEVTVF9BTFBIQU5VTUVSSUMgPSBuZXcgUmVnRXhwKCdeW0EtWjAtOSAkJSorXFxcXC0uLzpdKyQnKVxuXG5leHBvcnRzLnRlc3RLYW5qaSA9IGZ1bmN0aW9uIHRlc3RLYW5qaSAoc3RyKSB7XG4gIHJldHVybiBURVNUX0tBTkpJLnRlc3Qoc3RyKVxufVxuXG5leHBvcnRzLnRlc3ROdW1lcmljID0gZnVuY3Rpb24gdGVzdE51bWVyaWMgKHN0cikge1xuICByZXR1cm4gVEVTVF9OVU1FUklDLnRlc3Qoc3RyKVxufVxuXG5leHBvcnRzLnRlc3RBbHBoYW51bWVyaWMgPSBmdW5jdGlvbiB0ZXN0QWxwaGFudW1lcmljIChzdHIpIHtcbiAgcmV0dXJuIFRFU1RfQUxQSEFOVU1FUklDLnRlc3Qoc3RyKVxufVxuIiwidmFyIE1vZGUgPSByZXF1aXJlKCcuL21vZGUnKVxudmFyIE51bWVyaWNEYXRhID0gcmVxdWlyZSgnLi9udW1lcmljLWRhdGEnKVxudmFyIEFscGhhbnVtZXJpY0RhdGEgPSByZXF1aXJlKCcuL2FscGhhbnVtZXJpYy1kYXRhJylcbnZhciBCeXRlRGF0YSA9IHJlcXVpcmUoJy4vYnl0ZS1kYXRhJylcbnZhciBLYW5qaURhdGEgPSByZXF1aXJlKCcuL2thbmppLWRhdGEnKVxudmFyIFJlZ2V4ID0gcmVxdWlyZSgnLi9yZWdleCcpXG52YXIgVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcbnZhciBkaWprc3RyYSA9IHJlcXVpcmUoJ2RpamtzdHJhanMnKVxuXG4vKipcbiAqIFJldHVybnMgVVRGOCBieXRlIGxlbmd0aFxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gc3RyIElucHV0IHN0cmluZ1xuICogQHJldHVybiB7TnVtYmVyfSAgICAgTnVtYmVyIG9mIGJ5dGVcbiAqL1xuZnVuY3Rpb24gZ2V0U3RyaW5nQnl0ZUxlbmd0aCAoc3RyKSB7XG4gIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSkubGVuZ3RoXG59XG5cbi8qKlxuICogR2V0IGEgbGlzdCBvZiBzZWdtZW50cyBvZiB0aGUgc3BlY2lmaWVkIG1vZGVcbiAqIGZyb20gYSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0gIHtNb2RlfSAgIG1vZGUgU2VnbWVudCBtb2RlXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHN0ciAgU3RyaW5nIHRvIHByb2Nlc3NcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICBBcnJheSBvZiBvYmplY3Qgd2l0aCBzZWdtZW50cyBkYXRhXG4gKi9cbmZ1bmN0aW9uIGdldFNlZ21lbnRzIChyZWdleCwgbW9kZSwgc3RyKSB7XG4gIHZhciBzZWdtZW50cyA9IFtdXG4gIHZhciByZXN1bHRcblxuICB3aGlsZSAoKHJlc3VsdCA9IHJlZ2V4LmV4ZWMoc3RyKSkgIT09IG51bGwpIHtcbiAgICBzZWdtZW50cy5wdXNoKHtcbiAgICAgIGRhdGE6IHJlc3VsdFswXSxcbiAgICAgIGluZGV4OiByZXN1bHQuaW5kZXgsXG4gICAgICBtb2RlOiBtb2RlLFxuICAgICAgbGVuZ3RoOiByZXN1bHRbMF0ubGVuZ3RoXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBzZWdtZW50c1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIGEgc2VyaWVzIG9mIHNlZ21lbnRzIHdpdGggdGhlIGFwcHJvcHJpYXRlXG4gKiBtb2RlcyBmcm9tIGEgc3RyaW5nXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBkYXRhU3RyIElucHV0IHN0cmluZ1xuICogQHJldHVybiB7QXJyYXl9ICAgICAgICAgIEFycmF5IG9mIG9iamVjdCB3aXRoIHNlZ21lbnRzIGRhdGFcbiAqL1xuZnVuY3Rpb24gZ2V0U2VnbWVudHNGcm9tU3RyaW5nIChkYXRhU3RyKSB7XG4gIHZhciBudW1TZWdzID0gZ2V0U2VnbWVudHMoUmVnZXguTlVNRVJJQywgTW9kZS5OVU1FUklDLCBkYXRhU3RyKVxuICB2YXIgYWxwaGFOdW1TZWdzID0gZ2V0U2VnbWVudHMoUmVnZXguQUxQSEFOVU1FUklDLCBNb2RlLkFMUEhBTlVNRVJJQywgZGF0YVN0cilcbiAgdmFyIGJ5dGVTZWdzXG4gIHZhciBrYW5qaVNlZ3NcblxuICBpZiAoVXRpbHMuaXNLYW5qaU1vZGVFbmFibGVkKCkpIHtcbiAgICBieXRlU2VncyA9IGdldFNlZ21lbnRzKFJlZ2V4LkJZVEUsIE1vZGUuQllURSwgZGF0YVN0cilcbiAgICBrYW5qaVNlZ3MgPSBnZXRTZWdtZW50cyhSZWdleC5LQU5KSSwgTW9kZS5LQU5KSSwgZGF0YVN0cilcbiAgfSBlbHNlIHtcbiAgICBieXRlU2VncyA9IGdldFNlZ21lbnRzKFJlZ2V4LkJZVEVfS0FOSkksIE1vZGUuQllURSwgZGF0YVN0cilcbiAgICBrYW5qaVNlZ3MgPSBbXVxuICB9XG5cbiAgdmFyIHNlZ3MgPSBudW1TZWdzLmNvbmNhdChhbHBoYU51bVNlZ3MsIGJ5dGVTZWdzLCBrYW5qaVNlZ3MpXG5cbiAgcmV0dXJuIHNlZ3NcbiAgICAuc29ydChmdW5jdGlvbiAoczEsIHMyKSB7XG4gICAgICByZXR1cm4gczEuaW5kZXggLSBzMi5pbmRleFxuICAgIH0pXG4gICAgLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhOiBvYmouZGF0YSxcbiAgICAgICAgbW9kZTogb2JqLm1vZGUsXG4gICAgICAgIGxlbmd0aDogb2JqLmxlbmd0aFxuICAgICAgfVxuICAgIH0pXG59XG5cbi8qKlxuICogUmV0dXJucyBob3cgbWFueSBiaXRzIGFyZSBuZWVkZWQgdG8gZW5jb2RlIGEgc3RyaW5nIG9mXG4gKiBzcGVjaWZpZWQgbGVuZ3RoIHdpdGggdGhlIHNwZWNpZmllZCBtb2RlXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSBsZW5ndGggU3RyaW5nIGxlbmd0aFxuICogQHBhcmFtICB7TW9kZX0gbW9kZSAgICAgU2VnbWVudCBtb2RlXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICBCaXQgbGVuZ3RoXG4gKi9cbmZ1bmN0aW9uIGdldFNlZ21lbnRCaXRzTGVuZ3RoIChsZW5ndGgsIG1vZGUpIHtcbiAgc3dpdGNoIChtb2RlKSB7XG4gICAgY2FzZSBNb2RlLk5VTUVSSUM6XG4gICAgICByZXR1cm4gTnVtZXJpY0RhdGEuZ2V0Qml0c0xlbmd0aChsZW5ndGgpXG4gICAgY2FzZSBNb2RlLkFMUEhBTlVNRVJJQzpcbiAgICAgIHJldHVybiBBbHBoYW51bWVyaWNEYXRhLmdldEJpdHNMZW5ndGgobGVuZ3RoKVxuICAgIGNhc2UgTW9kZS5LQU5KSTpcbiAgICAgIHJldHVybiBLYW5qaURhdGEuZ2V0Qml0c0xlbmd0aChsZW5ndGgpXG4gICAgY2FzZSBNb2RlLkJZVEU6XG4gICAgICByZXR1cm4gQnl0ZURhdGEuZ2V0Qml0c0xlbmd0aChsZW5ndGgpXG4gIH1cbn1cblxuLyoqXG4gKiBNZXJnZXMgYWRqYWNlbnQgc2VnbWVudHMgd2hpY2ggaGF2ZSB0aGUgc2FtZSBtb2RlXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IHNlZ3MgQXJyYXkgb2Ygb2JqZWN0IHdpdGggc2VnbWVudHMgZGF0YVxuICogQHJldHVybiB7QXJyYXl9ICAgICAgQXJyYXkgb2Ygb2JqZWN0IHdpdGggc2VnbWVudHMgZGF0YVxuICovXG5mdW5jdGlvbiBtZXJnZVNlZ21lbnRzIChzZWdzKSB7XG4gIHJldHVybiBzZWdzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBjdXJyKSB7XG4gICAgdmFyIHByZXZTZWcgPSBhY2MubGVuZ3RoIC0gMSA+PSAwID8gYWNjW2FjYy5sZW5ndGggLSAxXSA6IG51bGxcbiAgICBpZiAocHJldlNlZyAmJiBwcmV2U2VnLm1vZGUgPT09IGN1cnIubW9kZSkge1xuICAgICAgYWNjW2FjYy5sZW5ndGggLSAxXS5kYXRhICs9IGN1cnIuZGF0YVxuICAgICAgcmV0dXJuIGFjY1xuICAgIH1cblxuICAgIGFjYy5wdXNoKGN1cnIpXG4gICAgcmV0dXJuIGFjY1xuICB9LCBbXSlcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBsaXN0IG9mIGFsbCBwb3NzaWJsZSBub2RlcyBjb21iaW5hdGlvbiB3aGljaFxuICogd2lsbCBiZSB1c2VkIHRvIGJ1aWxkIGEgc2VnbWVudHMgZ3JhcGguXG4gKlxuICogTm9kZXMgYXJlIGRpdmlkZWQgYnkgZ3JvdXBzLiBFYWNoIGdyb3VwIHdpbGwgY29udGFpbiBhIGxpc3Qgb2YgYWxsIHRoZSBtb2Rlc1xuICogaW4gd2hpY2ggaXMgcG9zc2libGUgdG8gZW5jb2RlIHRoZSBnaXZlbiB0ZXh0LlxuICpcbiAqIEZvciBleGFtcGxlIHRoZSB0ZXh0ICcxMjM0NScgY2FuIGJlIGVuY29kZWQgYXMgTnVtZXJpYywgQWxwaGFudW1lcmljIG9yIEJ5dGUuXG4gKiBUaGUgZ3JvdXAgZm9yICcxMjM0NScgd2lsbCBjb250YWluIHRoZW4gMyBvYmplY3RzLCBvbmUgZm9yIGVhY2hcbiAqIHBvc3NpYmxlIGVuY29kaW5nIG1vZGUuXG4gKlxuICogRWFjaCBub2RlIHJlcHJlc2VudHMgYSBwb3NzaWJsZSBzZWdtZW50LlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBzZWdzIEFycmF5IG9mIG9iamVjdCB3aXRoIHNlZ21lbnRzIGRhdGFcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgIEFycmF5IG9mIG9iamVjdCB3aXRoIHNlZ21lbnRzIGRhdGFcbiAqL1xuZnVuY3Rpb24gYnVpbGROb2RlcyAoc2Vncykge1xuICB2YXIgbm9kZXMgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc2VnID0gc2Vnc1tpXVxuXG4gICAgc3dpdGNoIChzZWcubW9kZSkge1xuICAgICAgY2FzZSBNb2RlLk5VTUVSSUM6XG4gICAgICAgIG5vZGVzLnB1c2goW3NlZyxcbiAgICAgICAgICB7IGRhdGE6IHNlZy5kYXRhLCBtb2RlOiBNb2RlLkFMUEhBTlVNRVJJQywgbGVuZ3RoOiBzZWcubGVuZ3RoIH0sXG4gICAgICAgICAgeyBkYXRhOiBzZWcuZGF0YSwgbW9kZTogTW9kZS5CWVRFLCBsZW5ndGg6IHNlZy5sZW5ndGggfVxuICAgICAgICBdKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBNb2RlLkFMUEhBTlVNRVJJQzpcbiAgICAgICAgbm9kZXMucHVzaChbc2VnLFxuICAgICAgICAgIHsgZGF0YTogc2VnLmRhdGEsIG1vZGU6IE1vZGUuQllURSwgbGVuZ3RoOiBzZWcubGVuZ3RoIH1cbiAgICAgICAgXSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgTW9kZS5LQU5KSTpcbiAgICAgICAgbm9kZXMucHVzaChbc2VnLFxuICAgICAgICAgIHsgZGF0YTogc2VnLmRhdGEsIG1vZGU6IE1vZGUuQllURSwgbGVuZ3RoOiBnZXRTdHJpbmdCeXRlTGVuZ3RoKHNlZy5kYXRhKSB9XG4gICAgICAgIF0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIE1vZGUuQllURTpcbiAgICAgICAgbm9kZXMucHVzaChbXG4gICAgICAgICAgeyBkYXRhOiBzZWcuZGF0YSwgbW9kZTogTW9kZS5CWVRFLCBsZW5ndGg6IGdldFN0cmluZ0J5dGVMZW5ndGgoc2VnLmRhdGEpIH1cbiAgICAgICAgXSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbm9kZXNcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBncmFwaCBmcm9tIGEgbGlzdCBvZiBub2Rlcy5cbiAqIEFsbCBzZWdtZW50cyBpbiBlYWNoIG5vZGUgZ3JvdXAgd2lsbCBiZSBjb25uZWN0ZWQgd2l0aCBhbGwgdGhlIHNlZ21lbnRzIG9mXG4gKiB0aGUgbmV4dCBncm91cCBhbmQgc28gb24uXG4gKlxuICogQXQgZWFjaCBjb25uZWN0aW9uIHdpbGwgYmUgYXNzaWduZWQgYSB3ZWlnaHQgZGVwZW5kaW5nIG9uIHRoZVxuICogc2VnbWVudCdzIGJ5dGUgbGVuZ3RoLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBub2RlcyAgICBBcnJheSBvZiBvYmplY3Qgd2l0aCBzZWdtZW50cyBkYXRhXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gUVIgQ29kZSB2ZXJzaW9uXG4gKiBAcmV0dXJuIHtPYmplY3R9ICAgICAgICAgR3JhcGggb2YgYWxsIHBvc3NpYmxlIHNlZ21lbnRzXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkR3JhcGggKG5vZGVzLCB2ZXJzaW9uKSB7XG4gIHZhciB0YWJsZSA9IHt9XG4gIHZhciBncmFwaCA9IHsnc3RhcnQnOiB7fX1cbiAgdmFyIHByZXZOb2RlSWRzID0gWydzdGFydCddXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBub2RlR3JvdXAgPSBub2Rlc1tpXVxuICAgIHZhciBjdXJyZW50Tm9kZUlkcyA9IFtdXG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IG5vZGVHcm91cC5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIG5vZGUgPSBub2RlR3JvdXBbal1cbiAgICAgIHZhciBrZXkgPSAnJyArIGkgKyBqXG5cbiAgICAgIGN1cnJlbnROb2RlSWRzLnB1c2goa2V5KVxuICAgICAgdGFibGVba2V5XSA9IHsgbm9kZTogbm9kZSwgbGFzdENvdW50OiAwIH1cbiAgICAgIGdyYXBoW2tleV0gPSB7fVxuXG4gICAgICBmb3IgKHZhciBuID0gMDsgbiA8IHByZXZOb2RlSWRzLmxlbmd0aDsgbisrKSB7XG4gICAgICAgIHZhciBwcmV2Tm9kZUlkID0gcHJldk5vZGVJZHNbbl1cblxuICAgICAgICBpZiAodGFibGVbcHJldk5vZGVJZF0gJiYgdGFibGVbcHJldk5vZGVJZF0ubm9kZS5tb2RlID09PSBub2RlLm1vZGUpIHtcbiAgICAgICAgICBncmFwaFtwcmV2Tm9kZUlkXVtrZXldID1cbiAgICAgICAgICAgIGdldFNlZ21lbnRCaXRzTGVuZ3RoKHRhYmxlW3ByZXZOb2RlSWRdLmxhc3RDb3VudCArIG5vZGUubGVuZ3RoLCBub2RlLm1vZGUpIC1cbiAgICAgICAgICAgIGdldFNlZ21lbnRCaXRzTGVuZ3RoKHRhYmxlW3ByZXZOb2RlSWRdLmxhc3RDb3VudCwgbm9kZS5tb2RlKVxuXG4gICAgICAgICAgdGFibGVbcHJldk5vZGVJZF0ubGFzdENvdW50ICs9IG5vZGUubGVuZ3RoXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRhYmxlW3ByZXZOb2RlSWRdKSB0YWJsZVtwcmV2Tm9kZUlkXS5sYXN0Q291bnQgPSBub2RlLmxlbmd0aFxuXG4gICAgICAgICAgZ3JhcGhbcHJldk5vZGVJZF1ba2V5XSA9IGdldFNlZ21lbnRCaXRzTGVuZ3RoKG5vZGUubGVuZ3RoLCBub2RlLm1vZGUpICtcbiAgICAgICAgICAgIDQgKyBNb2RlLmdldENoYXJDb3VudEluZGljYXRvcihub2RlLm1vZGUsIHZlcnNpb24pIC8vIHN3aXRjaCBjb3N0XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcmV2Tm9kZUlkcyA9IGN1cnJlbnROb2RlSWRzXG4gIH1cblxuICBmb3IgKG4gPSAwOyBuIDwgcHJldk5vZGVJZHMubGVuZ3RoOyBuKyspIHtcbiAgICBncmFwaFtwcmV2Tm9kZUlkc1tuXV1bJ2VuZCddID0gMFxuICB9XG5cbiAgcmV0dXJuIHsgbWFwOiBncmFwaCwgdGFibGU6IHRhYmxlIH1cbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBzZWdtZW50IGZyb20gYSBzcGVjaWZpZWQgZGF0YSBhbmQgbW9kZS5cbiAqIElmIGEgbW9kZSBpcyBub3Qgc3BlY2lmaWVkLCB0aGUgbW9yZSBzdWl0YWJsZSB3aWxsIGJlIHVzZWQuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBkYXRhICAgICAgICAgICAgIElucHV0IGRhdGFcbiAqIEBwYXJhbSAge01vZGUgfCBTdHJpbmd9IG1vZGVzSGludCBEYXRhIG1vZGVcbiAqIEByZXR1cm4ge1NlZ21lbnR9ICAgICAgICAgICAgICAgICBTZWdtZW50XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkU2luZ2xlU2VnbWVudCAoZGF0YSwgbW9kZXNIaW50KSB7XG4gIHZhciBtb2RlXG4gIHZhciBiZXN0TW9kZSA9IE1vZGUuZ2V0QmVzdE1vZGVGb3JEYXRhKGRhdGEpXG5cbiAgbW9kZSA9IE1vZGUuZnJvbShtb2Rlc0hpbnQsIGJlc3RNb2RlKVxuXG4gIC8vIE1ha2Ugc3VyZSBkYXRhIGNhbiBiZSBlbmNvZGVkXG4gIGlmIChtb2RlICE9PSBNb2RlLkJZVEUgJiYgbW9kZS5iaXQgPCBiZXN0TW9kZS5iaXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1wiJyArIGRhdGEgKyAnXCInICtcbiAgICAgICcgY2Fubm90IGJlIGVuY29kZWQgd2l0aCBtb2RlICcgKyBNb2RlLnRvU3RyaW5nKG1vZGUpICtcbiAgICAgICcuXFxuIFN1Z2dlc3RlZCBtb2RlIGlzOiAnICsgTW9kZS50b1N0cmluZyhiZXN0TW9kZSkpXG4gIH1cblxuICAvLyBVc2UgTW9kZS5CWVRFIGlmIEthbmppIHN1cHBvcnQgaXMgZGlzYWJsZWRcbiAgaWYgKG1vZGUgPT09IE1vZGUuS0FOSkkgJiYgIVV0aWxzLmlzS2FuamlNb2RlRW5hYmxlZCgpKSB7XG4gICAgbW9kZSA9IE1vZGUuQllURVxuICB9XG5cbiAgc3dpdGNoIChtb2RlKSB7XG4gICAgY2FzZSBNb2RlLk5VTUVSSUM6XG4gICAgICByZXR1cm4gbmV3IE51bWVyaWNEYXRhKGRhdGEpXG5cbiAgICBjYXNlIE1vZGUuQUxQSEFOVU1FUklDOlxuICAgICAgcmV0dXJuIG5ldyBBbHBoYW51bWVyaWNEYXRhKGRhdGEpXG5cbiAgICBjYXNlIE1vZGUuS0FOSkk6XG4gICAgICByZXR1cm4gbmV3IEthbmppRGF0YShkYXRhKVxuXG4gICAgY2FzZSBNb2RlLkJZVEU6XG4gICAgICByZXR1cm4gbmV3IEJ5dGVEYXRhKGRhdGEpXG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBsaXN0IG9mIHNlZ21lbnRzIGZyb20gYW4gYXJyYXkuXG4gKiBBcnJheSBjYW4gY29udGFpbiBTdHJpbmdzIG9yIE9iamVjdHMgd2l0aCBzZWdtZW50J3MgaW5mby5cbiAqXG4gKiBGb3IgZWFjaCBpdGVtIHdoaWNoIGlzIGEgc3RyaW5nLCB3aWxsIGJlIGdlbmVyYXRlZCBhIHNlZ21lbnQgd2l0aCB0aGUgZ2l2ZW5cbiAqIHN0cmluZyBhbmQgdGhlIG1vcmUgYXBwcm9wcmlhdGUgZW5jb2RpbmcgbW9kZS5cbiAqXG4gKiBGb3IgZWFjaCBpdGVtIHdoaWNoIGlzIGFuIG9iamVjdCwgd2lsbCBiZSBnZW5lcmF0ZWQgYSBzZWdtZW50IHdpdGggdGhlIGdpdmVuXG4gKiBkYXRhIGFuZCBtb2RlLlxuICogT2JqZWN0cyBtdXN0IGNvbnRhaW4gYXQgbGVhc3QgdGhlIHByb3BlcnR5IFwiZGF0YVwiLlxuICogSWYgcHJvcGVydHkgXCJtb2RlXCIgaXMgbm90IHByZXNlbnQsIHRoZSBtb3JlIHN1aXRhYmxlIG1vZGUgd2lsbCBiZSB1c2VkLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBhcnJheSBBcnJheSBvZiBvYmplY3RzIHdpdGggc2VnbWVudHMgZGF0YVxuICogQHJldHVybiB7QXJyYXl9ICAgICAgIEFycmF5IG9mIFNlZ21lbnRzXG4gKi9cbmV4cG9ydHMuZnJvbUFycmF5ID0gZnVuY3Rpb24gZnJvbUFycmF5IChhcnJheSkge1xuICByZXR1cm4gYXJyYXkucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHNlZykge1xuICAgIGlmICh0eXBlb2Ygc2VnID09PSAnc3RyaW5nJykge1xuICAgICAgYWNjLnB1c2goYnVpbGRTaW5nbGVTZWdtZW50KHNlZywgbnVsbCkpXG4gICAgfSBlbHNlIGlmIChzZWcuZGF0YSkge1xuICAgICAgYWNjLnB1c2goYnVpbGRTaW5nbGVTZWdtZW50KHNlZy5kYXRhLCBzZWcubW9kZSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIGFjY1xuICB9LCBbXSlcbn1cblxuLyoqXG4gKiBCdWlsZHMgYW4gb3B0aW1pemVkIHNlcXVlbmNlIG9mIHNlZ21lbnRzIGZyb20gYSBzdHJpbmcsXG4gKiB3aGljaCB3aWxsIHByb2R1Y2UgdGhlIHNob3J0ZXN0IHBvc3NpYmxlIGJpdHN0cmVhbS5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGRhdGEgICAgSW5wdXQgc3RyaW5nXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gUVIgQ29kZSB2ZXJzaW9uXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgICAgQXJyYXkgb2Ygc2VnbWVudHNcbiAqL1xuZXhwb3J0cy5mcm9tU3RyaW5nID0gZnVuY3Rpb24gZnJvbVN0cmluZyAoZGF0YSwgdmVyc2lvbikge1xuICB2YXIgc2VncyA9IGdldFNlZ21lbnRzRnJvbVN0cmluZyhkYXRhLCBVdGlscy5pc0thbmppTW9kZUVuYWJsZWQoKSlcblxuICB2YXIgbm9kZXMgPSBidWlsZE5vZGVzKHNlZ3MpXG4gIHZhciBncmFwaCA9IGJ1aWxkR3JhcGgobm9kZXMsIHZlcnNpb24pXG4gIHZhciBwYXRoID0gZGlqa3N0cmEuZmluZF9wYXRoKGdyYXBoLm1hcCwgJ3N0YXJ0JywgJ2VuZCcpXG5cbiAgdmFyIG9wdGltaXplZFNlZ3MgPSBbXVxuICBmb3IgKHZhciBpID0gMTsgaSA8IHBhdGgubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgb3B0aW1pemVkU2Vncy5wdXNoKGdyYXBoLnRhYmxlW3BhdGhbaV1dLm5vZGUpXG4gIH1cblxuICByZXR1cm4gZXhwb3J0cy5mcm9tQXJyYXkobWVyZ2VTZWdtZW50cyhvcHRpbWl6ZWRTZWdzKSlcbn1cblxuLyoqXG4gKiBTcGxpdHMgYSBzdHJpbmcgaW4gdmFyaW91cyBzZWdtZW50cyB3aXRoIHRoZSBtb2RlcyB3aGljaFxuICogYmVzdCByZXByZXNlbnQgdGhlaXIgY29udGVudC5cbiAqIFRoZSBwcm9kdWNlZCBzZWdtZW50cyBhcmUgZmFyIGZyb20gYmVpbmcgb3B0aW1pemVkLlxuICogVGhlIG91dHB1dCBvZiB0aGlzIGZ1bmN0aW9uIGlzIG9ubHkgdXNlZCB0byBlc3RpbWF0ZSBhIFFSIENvZGUgdmVyc2lvblxuICogd2hpY2ggbWF5IGNvbnRhaW4gdGhlIGRhdGEuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBkYXRhIElucHV0IHN0cmluZ1xuICogQHJldHVybiB7QXJyYXl9ICAgICAgIEFycmF5IG9mIHNlZ21lbnRzXG4gKi9cbmV4cG9ydHMucmF3U3BsaXQgPSBmdW5jdGlvbiByYXdTcGxpdCAoZGF0YSkge1xuICByZXR1cm4gZXhwb3J0cy5mcm9tQXJyYXkoXG4gICAgZ2V0U2VnbWVudHNGcm9tU3RyaW5nKGRhdGEsIFV0aWxzLmlzS2FuamlNb2RlRW5hYmxlZCgpKVxuICApXG59XG4iLCJ2YXIgdG9TSklTRnVuY3Rpb25cbnZhciBDT0RFV09SRFNfQ09VTlQgPSBbXG4gIDAsIC8vIE5vdCB1c2VkXG4gIDI2LCA0NCwgNzAsIDEwMCwgMTM0LCAxNzIsIDE5NiwgMjQyLCAyOTIsIDM0NixcbiAgNDA0LCA0NjYsIDUzMiwgNTgxLCA2NTUsIDczMywgODE1LCA5MDEsIDk5MSwgMTA4NSxcbiAgMTE1NiwgMTI1OCwgMTM2NCwgMTQ3NCwgMTU4OCwgMTcwNiwgMTgyOCwgMTkyMSwgMjA1MSwgMjE4NSxcbiAgMjMyMywgMjQ2NSwgMjYxMSwgMjc2MSwgMjg3NiwgMzAzNCwgMzE5NiwgMzM2MiwgMzUzMiwgMzcwNlxuXVxuXG4vKipcbiAqIFJldHVybnMgdGhlIFFSIENvZGUgc2l6ZSBmb3IgdGhlIHNwZWNpZmllZCB2ZXJzaW9uXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSB2ZXJzaW9uIFFSIENvZGUgdmVyc2lvblxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgIHNpemUgb2YgUVIgY29kZVxuICovXG5leHBvcnRzLmdldFN5bWJvbFNpemUgPSBmdW5jdGlvbiBnZXRTeW1ib2xTaXplICh2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbikgdGhyb3cgbmV3IEVycm9yKCdcInZlcnNpb25cIiBjYW5ub3QgYmUgbnVsbCBvciB1bmRlZmluZWQnKVxuICBpZiAodmVyc2lvbiA8IDEgfHwgdmVyc2lvbiA+IDQwKSB0aHJvdyBuZXcgRXJyb3IoJ1widmVyc2lvblwiIHNob3VsZCBiZSBpbiByYW5nZSBmcm9tIDEgdG8gNDAnKVxuICByZXR1cm4gdmVyc2lvbiAqIDQgKyAxN1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBjb2Rld29yZHMgdXNlZCB0byBzdG9yZSBkYXRhIGFuZCBFQyBpbmZvcm1hdGlvbi5cbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IHZlcnNpb24gUVIgQ29kZSB2ZXJzaW9uXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgRGF0YSBsZW5ndGggaW4gYml0c1xuICovXG5leHBvcnRzLmdldFN5bWJvbFRvdGFsQ29kZXdvcmRzID0gZnVuY3Rpb24gZ2V0U3ltYm9sVG90YWxDb2Rld29yZHMgKHZlcnNpb24pIHtcbiAgcmV0dXJuIENPREVXT1JEU19DT1VOVFt2ZXJzaW9uXVxufVxuXG4vKipcbiAqIEVuY29kZSBkYXRhIHdpdGggQm9zZS1DaGF1ZGh1cmktSG9jcXVlbmdoZW1cbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGRhdGEgVmFsdWUgdG8gZW5jb2RlXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgRW5jb2RlZCB2YWx1ZVxuICovXG5leHBvcnRzLmdldEJDSERpZ2l0ID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIGRpZ2l0ID0gMFxuXG4gIHdoaWxlIChkYXRhICE9PSAwKSB7XG4gICAgZGlnaXQrK1xuICAgIGRhdGEgPj4+PSAxXG4gIH1cblxuICByZXR1cm4gZGlnaXRcbn1cblxuZXhwb3J0cy5zZXRUb1NKSVNGdW5jdGlvbiA9IGZ1bmN0aW9uIHNldFRvU0pJU0Z1bmN0aW9uIChmKSB7XG4gIGlmICh0eXBlb2YgZiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcignXCJ0b1NKSVNGdW5jXCIgaXMgbm90IGEgdmFsaWQgZnVuY3Rpb24uJylcbiAgfVxuXG4gIHRvU0pJU0Z1bmN0aW9uID0gZlxufVxuXG5leHBvcnRzLmlzS2FuamlNb2RlRW5hYmxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHR5cGVvZiB0b1NKSVNGdW5jdGlvbiAhPT0gJ3VuZGVmaW5lZCdcbn1cblxuZXhwb3J0cy50b1NKSVMgPSBmdW5jdGlvbiB0b1NKSVMgKGthbmppKSB7XG4gIHJldHVybiB0b1NKSVNGdW5jdGlvbihrYW5qaSlcbn1cbiIsIi8qKlxuICogQ2hlY2sgaWYgUVIgQ29kZSB2ZXJzaW9uIGlzIHZhbGlkXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSAgdmVyc2lvbiBRUiBDb2RlIHZlcnNpb25cbiAqIEByZXR1cm4ge0Jvb2xlYW59ICAgICAgICAgdHJ1ZSBpZiB2YWxpZCB2ZXJzaW9uLCBmYWxzZSBvdGhlcndpc2VcbiAqL1xuZXhwb3J0cy5pc1ZhbGlkID0gZnVuY3Rpb24gaXNWYWxpZCAodmVyc2lvbikge1xuICByZXR1cm4gIWlzTmFOKHZlcnNpb24pICYmIHZlcnNpb24gPj0gMSAmJiB2ZXJzaW9uIDw9IDQwXG59XG4iLCJ2YXIgVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcbnZhciBFQ0NvZGUgPSByZXF1aXJlKCcuL2Vycm9yLWNvcnJlY3Rpb24tY29kZScpXG52YXIgRUNMZXZlbCA9IHJlcXVpcmUoJy4vZXJyb3ItY29ycmVjdGlvbi1sZXZlbCcpXG52YXIgTW9kZSA9IHJlcXVpcmUoJy4vbW9kZScpXG52YXIgVmVyc2lvbkNoZWNrID0gcmVxdWlyZSgnLi92ZXJzaW9uLWNoZWNrJylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpXG5cbi8vIEdlbmVyYXRvciBwb2x5bm9taWFsIHVzZWQgdG8gZW5jb2RlIHZlcnNpb24gaW5mb3JtYXRpb25cbnZhciBHMTggPSAoMSA8PCAxMikgfCAoMSA8PCAxMSkgfCAoMSA8PCAxMCkgfCAoMSA8PCA5KSB8ICgxIDw8IDgpIHwgKDEgPDwgNSkgfCAoMSA8PCAyKSB8ICgxIDw8IDApXG52YXIgRzE4X0JDSCA9IFV0aWxzLmdldEJDSERpZ2l0KEcxOClcblxuZnVuY3Rpb24gZ2V0QmVzdFZlcnNpb25Gb3JEYXRhTGVuZ3RoIChtb2RlLCBsZW5ndGgsIGVycm9yQ29ycmVjdGlvbkxldmVsKSB7XG4gIGZvciAodmFyIGN1cnJlbnRWZXJzaW9uID0gMTsgY3VycmVudFZlcnNpb24gPD0gNDA7IGN1cnJlbnRWZXJzaW9uKyspIHtcbiAgICBpZiAobGVuZ3RoIDw9IGV4cG9ydHMuZ2V0Q2FwYWNpdHkoY3VycmVudFZlcnNpb24sIGVycm9yQ29ycmVjdGlvbkxldmVsLCBtb2RlKSkge1xuICAgICAgcmV0dXJuIGN1cnJlbnRWZXJzaW9uXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBnZXRSZXNlcnZlZEJpdHNDb3VudCAobW9kZSwgdmVyc2lvbikge1xuICAvLyBDaGFyYWN0ZXIgY291bnQgaW5kaWNhdG9yICsgbW9kZSBpbmRpY2F0b3IgYml0c1xuICByZXR1cm4gTW9kZS5nZXRDaGFyQ291bnRJbmRpY2F0b3IobW9kZSwgdmVyc2lvbikgKyA0XG59XG5cbmZ1bmN0aW9uIGdldFRvdGFsQml0c0Zyb21EYXRhQXJyYXkgKHNlZ21lbnRzLCB2ZXJzaW9uKSB7XG4gIHZhciB0b3RhbEJpdHMgPSAwXG5cbiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YSkge1xuICAgIHZhciByZXNlcnZlZEJpdHMgPSBnZXRSZXNlcnZlZEJpdHNDb3VudChkYXRhLm1vZGUsIHZlcnNpb24pXG4gICAgdG90YWxCaXRzICs9IHJlc2VydmVkQml0cyArIGRhdGEuZ2V0Qml0c0xlbmd0aCgpXG4gIH0pXG5cbiAgcmV0dXJuIHRvdGFsQml0c1xufVxuXG5mdW5jdGlvbiBnZXRCZXN0VmVyc2lvbkZvck1peGVkRGF0YSAoc2VnbWVudHMsIGVycm9yQ29ycmVjdGlvbkxldmVsKSB7XG4gIGZvciAodmFyIGN1cnJlbnRWZXJzaW9uID0gMTsgY3VycmVudFZlcnNpb24gPD0gNDA7IGN1cnJlbnRWZXJzaW9uKyspIHtcbiAgICB2YXIgbGVuZ3RoID0gZ2V0VG90YWxCaXRzRnJvbURhdGFBcnJheShzZWdtZW50cywgY3VycmVudFZlcnNpb24pXG4gICAgaWYgKGxlbmd0aCA8PSBleHBvcnRzLmdldENhcGFjaXR5KGN1cnJlbnRWZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbCwgTW9kZS5NSVhFRCkpIHtcbiAgICAgIHJldHVybiBjdXJyZW50VmVyc2lvblxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHZlcnNpb24gbnVtYmVyIGZyb20gYSB2YWx1ZS5cbiAqIElmIHZhbHVlIGlzIG5vdCBhIHZhbGlkIHZlcnNpb24sIHJldHVybnMgZGVmYXVsdFZhbHVlXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfFN0cmluZ30gdmFsdWUgICAgICAgIFFSIENvZGUgdmVyc2lvblxuICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgZGVmYXVsdFZhbHVlIEZhbGxiYWNrIHZhbHVlXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgICAgICAgICAgICAgUVIgQ29kZSB2ZXJzaW9uIG51bWJlclxuICovXG5leHBvcnRzLmZyb20gPSBmdW5jdGlvbiBmcm9tICh2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmIChWZXJzaW9uQ2hlY2suaXNWYWxpZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUsIDEwKVxuICB9XG5cbiAgcmV0dXJuIGRlZmF1bHRWYWx1ZVxufVxuXG4vKipcbiAqIFJldHVybnMgaG93IG11Y2ggZGF0YSBjYW4gYmUgc3RvcmVkIHdpdGggdGhlIHNwZWNpZmllZCBRUiBjb2RlIHZlcnNpb25cbiAqIGFuZCBlcnJvciBjb3JyZWN0aW9uIGxldmVsXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSB2ZXJzaW9uICAgICAgICAgICAgICBRUiBDb2RlIHZlcnNpb24gKDEtNDApXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGVycm9yQ29ycmVjdGlvbkxldmVsIEVycm9yIGNvcnJlY3Rpb24gbGV2ZWxcbiAqIEBwYXJhbSAge01vZGV9ICAgbW9kZSAgICAgICAgICAgICAgICAgRGF0YSBtb2RlXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgICAgICAgICAgICAgIFF1YW50aXR5IG9mIHN0b3JhYmxlIGRhdGFcbiAqL1xuZXhwb3J0cy5nZXRDYXBhY2l0eSA9IGZ1bmN0aW9uIGdldENhcGFjaXR5ICh2ZXJzaW9uLCBlcnJvckNvcnJlY3Rpb25MZXZlbCwgbW9kZSkge1xuICBpZiAoIVZlcnNpb25DaGVjay5pc1ZhbGlkKHZlcnNpb24pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFFSIENvZGUgdmVyc2lvbicpXG4gIH1cblxuICAvLyBVc2UgQnl0ZSBtb2RlIGFzIGRlZmF1bHRcbiAgaWYgKHR5cGVvZiBtb2RlID09PSAndW5kZWZpbmVkJykgbW9kZSA9IE1vZGUuQllURVxuXG4gIC8vIFRvdGFsIGNvZGV3b3JkcyBmb3IgdGhpcyBRUiBjb2RlIHZlcnNpb24gKERhdGEgKyBFcnJvciBjb3JyZWN0aW9uKVxuICB2YXIgdG90YWxDb2Rld29yZHMgPSBVdGlscy5nZXRTeW1ib2xUb3RhbENvZGV3b3Jkcyh2ZXJzaW9uKVxuXG4gIC8vIFRvdGFsIG51bWJlciBvZiBlcnJvciBjb3JyZWN0aW9uIGNvZGV3b3Jkc1xuICB2YXIgZWNUb3RhbENvZGV3b3JkcyA9IEVDQ29kZS5nZXRUb3RhbENvZGV3b3Jkc0NvdW50KHZlcnNpb24sIGVycm9yQ29ycmVjdGlvbkxldmVsKVxuXG4gIC8vIFRvdGFsIG51bWJlciBvZiBkYXRhIGNvZGV3b3Jkc1xuICB2YXIgZGF0YVRvdGFsQ29kZXdvcmRzQml0cyA9ICh0b3RhbENvZGV3b3JkcyAtIGVjVG90YWxDb2Rld29yZHMpICogOFxuXG4gIGlmIChtb2RlID09PSBNb2RlLk1JWEVEKSByZXR1cm4gZGF0YVRvdGFsQ29kZXdvcmRzQml0c1xuXG4gIHZhciB1c2FibGVCaXRzID0gZGF0YVRvdGFsQ29kZXdvcmRzQml0cyAtIGdldFJlc2VydmVkQml0c0NvdW50KG1vZGUsIHZlcnNpb24pXG5cbiAgLy8gUmV0dXJuIG1heCBudW1iZXIgb2Ygc3RvcmFibGUgY29kZXdvcmRzXG4gIHN3aXRjaCAobW9kZSkge1xuICAgIGNhc2UgTW9kZS5OVU1FUklDOlxuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKHVzYWJsZUJpdHMgLyAxMCkgKiAzKVxuXG4gICAgY2FzZSBNb2RlLkFMUEhBTlVNRVJJQzpcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKCh1c2FibGVCaXRzIC8gMTEpICogMilcblxuICAgIGNhc2UgTW9kZS5LQU5KSTpcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKHVzYWJsZUJpdHMgLyAxMylcblxuICAgIGNhc2UgTW9kZS5CWVRFOlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcih1c2FibGVCaXRzIC8gOClcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIG1pbmltdW0gdmVyc2lvbiBuZWVkZWQgdG8gY29udGFpbiB0aGUgYW1vdW50IG9mIGRhdGFcbiAqXG4gKiBAcGFyYW0gIHtTZWdtZW50fSBkYXRhICAgICAgICAgICAgICAgICAgICBTZWdtZW50IG9mIGRhdGFcbiAqIEBwYXJhbSAge051bWJlcn0gW2Vycm9yQ29ycmVjdGlvbkxldmVsPUhdIEVycm9yIGNvcnJlY3Rpb24gbGV2ZWxcbiAqIEBwYXJhbSAge01vZGV9IG1vZGUgICAgICAgICAgICAgICAgICAgICAgIERhdGEgbW9kZVxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgICAgICAgICAgICAgICAgICAgUVIgQ29kZSB2ZXJzaW9uXG4gKi9cbmV4cG9ydHMuZ2V0QmVzdFZlcnNpb25Gb3JEYXRhID0gZnVuY3Rpb24gZ2V0QmVzdFZlcnNpb25Gb3JEYXRhIChkYXRhLCBlcnJvckNvcnJlY3Rpb25MZXZlbCkge1xuICB2YXIgc2VnXG5cbiAgdmFyIGVjbCA9IEVDTGV2ZWwuZnJvbShlcnJvckNvcnJlY3Rpb25MZXZlbCwgRUNMZXZlbC5NKVxuXG4gIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgaWYgKGRhdGEubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIGdldEJlc3RWZXJzaW9uRm9yTWl4ZWREYXRhKGRhdGEsIGVjbClcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAxXG4gICAgfVxuXG4gICAgc2VnID0gZGF0YVswXVxuICB9IGVsc2Uge1xuICAgIHNlZyA9IGRhdGFcbiAgfVxuXG4gIHJldHVybiBnZXRCZXN0VmVyc2lvbkZvckRhdGFMZW5ndGgoc2VnLm1vZGUsIHNlZy5nZXRMZW5ndGgoKSwgZWNsKVxufVxuXG4vKipcbiAqIFJldHVybnMgdmVyc2lvbiBpbmZvcm1hdGlvbiB3aXRoIHJlbGF0aXZlIGVycm9yIGNvcnJlY3Rpb24gYml0c1xuICpcbiAqIFRoZSB2ZXJzaW9uIGluZm9ybWF0aW9uIGlzIGluY2x1ZGVkIGluIFFSIENvZGUgc3ltYm9scyBvZiB2ZXJzaW9uIDcgb3IgbGFyZ2VyLlxuICogSXQgY29uc2lzdHMgb2YgYW4gMTgtYml0IHNlcXVlbmNlIGNvbnRhaW5pbmcgNiBkYXRhIGJpdHMsXG4gKiB3aXRoIDEyIGVycm9yIGNvcnJlY3Rpb24gYml0cyBjYWxjdWxhdGVkIHVzaW5nIHRoZSAoMTgsIDYpIEdvbGF5IGNvZGUuXG4gKlxuICogQHBhcmFtICB7TnVtYmVyfSB2ZXJzaW9uIFFSIENvZGUgdmVyc2lvblxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgIEVuY29kZWQgdmVyc2lvbiBpbmZvIGJpdHNcbiAqL1xuZXhwb3J0cy5nZXRFbmNvZGVkQml0cyA9IGZ1bmN0aW9uIGdldEVuY29kZWRCaXRzICh2ZXJzaW9uKSB7XG4gIGlmICghVmVyc2lvbkNoZWNrLmlzVmFsaWQodmVyc2lvbikgfHwgdmVyc2lvbiA8IDcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUVIgQ29kZSB2ZXJzaW9uJylcbiAgfVxuXG4gIHZhciBkID0gdmVyc2lvbiA8PCAxMlxuXG4gIHdoaWxlIChVdGlscy5nZXRCQ0hEaWdpdChkKSAtIEcxOF9CQ0ggPj0gMCkge1xuICAgIGQgXj0gKEcxOCA8PCAoVXRpbHMuZ2V0QkNIRGlnaXQoZCkgLSBHMThfQkNIKSlcbiAgfVxuXG4gIHJldHVybiAodmVyc2lvbiA8PCAxMikgfCBkXG59XG4iLCJcbnZhciBjYW5Qcm9taXNlID0gcmVxdWlyZSgnLi9jYW4tcHJvbWlzZScpXG5cbnZhciBRUkNvZGUgPSByZXF1aXJlKCcuL2NvcmUvcXJjb2RlJylcbnZhciBDYW52YXNSZW5kZXJlciA9IHJlcXVpcmUoJy4vcmVuZGVyZXIvY2FudmFzJylcbnZhciBTdmdSZW5kZXJlciA9IHJlcXVpcmUoJy4vcmVuZGVyZXIvc3ZnLXRhZy5qcycpXG5cbmZ1bmN0aW9uIHJlbmRlckNhbnZhcyAocmVuZGVyRnVuYywgY2FudmFzLCB0ZXh0LCBvcHRzLCBjYikge1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICB2YXIgYXJnc051bSA9IGFyZ3MubGVuZ3RoXG4gIHZhciBpc0xhc3RBcmdDYiA9IHR5cGVvZiBhcmdzW2FyZ3NOdW0gLSAxXSA9PT0gJ2Z1bmN0aW9uJ1xuXG4gIGlmICghaXNMYXN0QXJnQ2IgJiYgIWNhblByb21pc2UoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FsbGJhY2sgcmVxdWlyZWQgYXMgbGFzdCBhcmd1bWVudCcpXG4gIH1cblxuICBpZiAoaXNMYXN0QXJnQ2IpIHtcbiAgICBpZiAoYXJnc051bSA8IDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVG9vIGZldyBhcmd1bWVudHMgcHJvdmlkZWQnKVxuICAgIH1cblxuICAgIGlmIChhcmdzTnVtID09PSAyKSB7XG4gICAgICBjYiA9IHRleHRcbiAgICAgIHRleHQgPSBjYW52YXNcbiAgICAgIGNhbnZhcyA9IG9wdHMgPSB1bmRlZmluZWRcbiAgICB9IGVsc2UgaWYgKGFyZ3NOdW0gPT09IDMpIHtcbiAgICAgIGlmIChjYW52YXMuZ2V0Q29udGV4dCAmJiB0eXBlb2YgY2IgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNiID0gb3B0c1xuICAgICAgICBvcHRzID0gdW5kZWZpbmVkXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYiA9IG9wdHNcbiAgICAgICAgb3B0cyA9IHRleHRcbiAgICAgICAgdGV4dCA9IGNhbnZhc1xuICAgICAgICBjYW52YXMgPSB1bmRlZmluZWRcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGFyZ3NOdW0gPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RvbyBmZXcgYXJndW1lbnRzIHByb3ZpZGVkJylcbiAgICB9XG5cbiAgICBpZiAoYXJnc051bSA9PT0gMSkge1xuICAgICAgdGV4dCA9IGNhbnZhc1xuICAgICAgY2FudmFzID0gb3B0cyA9IHVuZGVmaW5lZFxuICAgIH0gZWxzZSBpZiAoYXJnc051bSA9PT0gMiAmJiAhY2FudmFzLmdldENvbnRleHQpIHtcbiAgICAgIG9wdHMgPSB0ZXh0XG4gICAgICB0ZXh0ID0gY2FudmFzXG4gICAgICBjYW52YXMgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIGRhdGEgPSBRUkNvZGUuY3JlYXRlKHRleHQsIG9wdHMpXG4gICAgICAgIHJlc29sdmUocmVuZGVyRnVuYyhkYXRhLCBjYW52YXMsIG9wdHMpKVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZWplY3QoZSlcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgdHJ5IHtcbiAgICB2YXIgZGF0YSA9IFFSQ29kZS5jcmVhdGUodGV4dCwgb3B0cylcbiAgICBjYihudWxsLCByZW5kZXJGdW5jKGRhdGEsIGNhbnZhcywgb3B0cykpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjYihlKVxuICB9XG59XG5cbmV4cG9ydHMuY3JlYXRlID0gUVJDb2RlLmNyZWF0ZVxuZXhwb3J0cy50b0NhbnZhcyA9IHJlbmRlckNhbnZhcy5iaW5kKG51bGwsIENhbnZhc1JlbmRlcmVyLnJlbmRlcilcbmV4cG9ydHMudG9EYXRhVVJMID0gcmVuZGVyQ2FudmFzLmJpbmQobnVsbCwgQ2FudmFzUmVuZGVyZXIucmVuZGVyVG9EYXRhVVJMKVxuXG4vLyBvbmx5IHN2ZyBmb3Igbm93LlxuZXhwb3J0cy50b1N0cmluZyA9IHJlbmRlckNhbnZhcy5iaW5kKG51bGwsIGZ1bmN0aW9uIChkYXRhLCBfLCBvcHRzKSB7XG4gIHJldHVybiBTdmdSZW5kZXJlci5yZW5kZXIoZGF0YSwgb3B0cylcbn0pXG4iLCJ2YXIgVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcblxuZnVuY3Rpb24gY2xlYXJDYW52YXMgKGN0eCwgY2FudmFzLCBzaXplKSB7XG4gIGN0eC5jbGVhclJlY3QoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KVxuXG4gIGlmICghY2FudmFzLnN0eWxlKSBjYW52YXMuc3R5bGUgPSB7fVxuICBjYW52YXMuaGVpZ2h0ID0gc2l6ZVxuICBjYW52YXMud2lkdGggPSBzaXplXG4gIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBzaXplICsgJ3B4J1xuICBjYW52YXMuc3R5bGUud2lkdGggPSBzaXplICsgJ3B4J1xufVxuXG5mdW5jdGlvbiBnZXRDYW52YXNFbGVtZW50ICgpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJylcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignWW91IG5lZWQgdG8gc3BlY2lmeSBhIGNhbnZhcyBlbGVtZW50JylcbiAgfVxufVxuXG5leHBvcnRzLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlciAocXJEYXRhLCBjYW52YXMsIG9wdGlvbnMpIHtcbiAgdmFyIG9wdHMgPSBvcHRpb25zXG4gIHZhciBjYW52YXNFbCA9IGNhbnZhc1xuXG4gIGlmICh0eXBlb2Ygb3B0cyA9PT0gJ3VuZGVmaW5lZCcgJiYgKCFjYW52YXMgfHwgIWNhbnZhcy5nZXRDb250ZXh0KSkge1xuICAgIG9wdHMgPSBjYW52YXNcbiAgICBjYW52YXMgPSB1bmRlZmluZWRcbiAgfVxuXG4gIGlmICghY2FudmFzKSB7XG4gICAgY2FudmFzRWwgPSBnZXRDYW52YXNFbGVtZW50KClcbiAgfVxuXG4gIG9wdHMgPSBVdGlscy5nZXRPcHRpb25zKG9wdHMpXG4gIHZhciBzaXplID0gVXRpbHMuZ2V0SW1hZ2VXaWR0aChxckRhdGEubW9kdWxlcy5zaXplLCBvcHRzKVxuXG4gIHZhciBjdHggPSBjYW52YXNFbC5nZXRDb250ZXh0KCcyZCcpXG4gIHZhciBpbWFnZSA9IGN0eC5jcmVhdGVJbWFnZURhdGEoc2l6ZSwgc2l6ZSlcbiAgVXRpbHMucXJUb0ltYWdlRGF0YShpbWFnZS5kYXRhLCBxckRhdGEsIG9wdHMpXG5cbiAgY2xlYXJDYW52YXMoY3R4LCBjYW52YXNFbCwgc2l6ZSlcbiAgY3R4LnB1dEltYWdlRGF0YShpbWFnZSwgMCwgMClcblxuICByZXR1cm4gY2FudmFzRWxcbn1cblxuZXhwb3J0cy5yZW5kZXJUb0RhdGFVUkwgPSBmdW5jdGlvbiByZW5kZXJUb0RhdGFVUkwgKHFyRGF0YSwgY2FudmFzLCBvcHRpb25zKSB7XG4gIHZhciBvcHRzID0gb3B0aW9uc1xuXG4gIGlmICh0eXBlb2Ygb3B0cyA9PT0gJ3VuZGVmaW5lZCcgJiYgKCFjYW52YXMgfHwgIWNhbnZhcy5nZXRDb250ZXh0KSkge1xuICAgIG9wdHMgPSBjYW52YXNcbiAgICBjYW52YXMgPSB1bmRlZmluZWRcbiAgfVxuXG4gIGlmICghb3B0cykgb3B0cyA9IHt9XG5cbiAgdmFyIGNhbnZhc0VsID0gZXhwb3J0cy5yZW5kZXIocXJEYXRhLCBjYW52YXMsIG9wdHMpXG5cbiAgdmFyIHR5cGUgPSBvcHRzLnR5cGUgfHwgJ2ltYWdlL3BuZydcbiAgdmFyIHJlbmRlcmVyT3B0cyA9IG9wdHMucmVuZGVyZXJPcHRzIHx8IHt9XG5cbiAgcmV0dXJuIGNhbnZhc0VsLnRvRGF0YVVSTCh0eXBlLCByZW5kZXJlck9wdHMucXVhbGl0eSlcbn1cbiIsInZhciBVdGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKVxuXG5mdW5jdGlvbiBnZXRDb2xvckF0dHJpYiAoY29sb3IsIGF0dHJpYikge1xuICB2YXIgYWxwaGEgPSBjb2xvci5hIC8gMjU1XG4gIHZhciBzdHIgPSBhdHRyaWIgKyAnPVwiJyArIGNvbG9yLmhleCArICdcIidcblxuICByZXR1cm4gYWxwaGEgPCAxXG4gICAgPyBzdHIgKyAnICcgKyBhdHRyaWIgKyAnLW9wYWNpdHk9XCInICsgYWxwaGEudG9GaXhlZCgyKS5zbGljZSgxKSArICdcIidcbiAgICA6IHN0clxufVxuXG5mdW5jdGlvbiBzdmdDbWQgKGNtZCwgeCwgeSkge1xuICB2YXIgc3RyID0gY21kICsgeFxuICBpZiAodHlwZW9mIHkgIT09ICd1bmRlZmluZWQnKSBzdHIgKz0gJyAnICsgeVxuXG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gcXJUb1BhdGggKGRhdGEsIHNpemUsIG1hcmdpbikge1xuICB2YXIgcGF0aCA9ICcnXG4gIHZhciBtb3ZlQnkgPSAwXG4gIHZhciBuZXdSb3cgPSBmYWxzZVxuICB2YXIgbGluZUxlbmd0aCA9IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY29sID0gTWF0aC5mbG9vcihpICUgc2l6ZSlcbiAgICB2YXIgcm93ID0gTWF0aC5mbG9vcihpIC8gc2l6ZSlcblxuICAgIGlmICghY29sICYmICFuZXdSb3cpIG5ld1JvdyA9IHRydWVcblxuICAgIGlmIChkYXRhW2ldKSB7XG4gICAgICBsaW5lTGVuZ3RoKytcblxuICAgICAgaWYgKCEoaSA+IDAgJiYgY29sID4gMCAmJiBkYXRhW2kgLSAxXSkpIHtcbiAgICAgICAgcGF0aCArPSBuZXdSb3dcbiAgICAgICAgICA/IHN2Z0NtZCgnTScsIGNvbCArIG1hcmdpbiwgMC41ICsgcm93ICsgbWFyZ2luKVxuICAgICAgICAgIDogc3ZnQ21kKCdtJywgbW92ZUJ5LCAwKVxuXG4gICAgICAgIG1vdmVCeSA9IDBcbiAgICAgICAgbmV3Um93ID0gZmFsc2VcbiAgICAgIH1cblxuICAgICAgaWYgKCEoY29sICsgMSA8IHNpemUgJiYgZGF0YVtpICsgMV0pKSB7XG4gICAgICAgIHBhdGggKz0gc3ZnQ21kKCdoJywgbGluZUxlbmd0aClcbiAgICAgICAgbGluZUxlbmd0aCA9IDBcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbW92ZUJ5KytcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcGF0aFxufVxuXG5leHBvcnRzLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlciAocXJEYXRhLCBvcHRpb25zLCBjYikge1xuICB2YXIgb3B0cyA9IFV0aWxzLmdldE9wdGlvbnMob3B0aW9ucylcbiAgdmFyIHNpemUgPSBxckRhdGEubW9kdWxlcy5zaXplXG4gIHZhciBkYXRhID0gcXJEYXRhLm1vZHVsZXMuZGF0YVxuICB2YXIgcXJjb2Rlc2l6ZSA9IHNpemUgKyBvcHRzLm1hcmdpbiAqIDJcblxuICB2YXIgYmcgPSAhb3B0cy5jb2xvci5saWdodC5hXG4gICAgPyAnJ1xuICAgIDogJzxwYXRoICcgKyBnZXRDb2xvckF0dHJpYihvcHRzLmNvbG9yLmxpZ2h0LCAnZmlsbCcpICtcbiAgICAgICcgZD1cIk0wIDBoJyArIHFyY29kZXNpemUgKyAndicgKyBxcmNvZGVzaXplICsgJ0gwelwiLz4nXG5cbiAgdmFyIHBhdGggPVxuICAgICc8cGF0aCAnICsgZ2V0Q29sb3JBdHRyaWIob3B0cy5jb2xvci5kYXJrLCAnc3Ryb2tlJykgK1xuICAgICcgZD1cIicgKyBxclRvUGF0aChkYXRhLCBzaXplLCBvcHRzLm1hcmdpbikgKyAnXCIvPidcblxuICB2YXIgdmlld0JveCA9ICd2aWV3Qm94PVwiJyArICcwIDAgJyArIHFyY29kZXNpemUgKyAnICcgKyBxcmNvZGVzaXplICsgJ1wiJ1xuXG4gIHZhciB3aWR0aCA9ICFvcHRzLndpZHRoID8gJycgOiAnd2lkdGg9XCInICsgb3B0cy53aWR0aCArICdcIiBoZWlnaHQ9XCInICsgb3B0cy53aWR0aCArICdcIiAnXG5cbiAgdmFyIHN2Z1RhZyA9ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAnICsgd2lkdGggKyB2aWV3Qm94ICsgJyBzaGFwZS1yZW5kZXJpbmc9XCJjcmlzcEVkZ2VzXCI+JyArIGJnICsgcGF0aCArICc8L3N2Zz5cXG4nXG5cbiAgaWYgKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiKG51bGwsIHN2Z1RhZylcbiAgfVxuXG4gIHJldHVybiBzdmdUYWdcbn1cbiIsImZ1bmN0aW9uIGhleDJyZ2JhIChoZXgpIHtcbiAgaWYgKHR5cGVvZiBoZXggPT09ICdudW1iZXInKSB7XG4gICAgaGV4ID0gaGV4LnRvU3RyaW5nKClcbiAgfVxuXG4gIGlmICh0eXBlb2YgaGV4ICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29sb3Igc2hvdWxkIGJlIGRlZmluZWQgYXMgaGV4IHN0cmluZycpXG4gIH1cblxuICB2YXIgaGV4Q29kZSA9IGhleC5zbGljZSgpLnJlcGxhY2UoJyMnLCAnJykuc3BsaXQoJycpXG4gIGlmIChoZXhDb2RlLmxlbmd0aCA8IDMgfHwgaGV4Q29kZS5sZW5ndGggPT09IDUgfHwgaGV4Q29kZS5sZW5ndGggPiA4KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBjb2xvcjogJyArIGhleClcbiAgfVxuXG4gIC8vIENvbnZlcnQgZnJvbSBzaG9ydCB0byBsb25nIGZvcm0gKGZmZiAtPiBmZmZmZmYpXG4gIGlmIChoZXhDb2RlLmxlbmd0aCA9PT0gMyB8fCBoZXhDb2RlLmxlbmd0aCA9PT0gNCkge1xuICAgIGhleENvZGUgPSBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCBoZXhDb2RlLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgcmV0dXJuIFtjLCBjXVxuICAgIH0pKVxuICB9XG5cbiAgLy8gQWRkIGRlZmF1bHQgYWxwaGEgdmFsdWVcbiAgaWYgKGhleENvZGUubGVuZ3RoID09PSA2KSBoZXhDb2RlLnB1c2goJ0YnLCAnRicpXG5cbiAgdmFyIGhleFZhbHVlID0gcGFyc2VJbnQoaGV4Q29kZS5qb2luKCcnKSwgMTYpXG5cbiAgcmV0dXJuIHtcbiAgICByOiAoaGV4VmFsdWUgPj4gMjQpICYgMjU1LFxuICAgIGc6IChoZXhWYWx1ZSA+PiAxNikgJiAyNTUsXG4gICAgYjogKGhleFZhbHVlID4+IDgpICYgMjU1LFxuICAgIGE6IGhleFZhbHVlICYgMjU1LFxuICAgIGhleDogJyMnICsgaGV4Q29kZS5zbGljZSgwLCA2KS5qb2luKCcnKVxuICB9XG59XG5cbmV4cG9ydHMuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uIGdldE9wdGlvbnMgKG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge31cbiAgaWYgKCFvcHRpb25zLmNvbG9yKSBvcHRpb25zLmNvbG9yID0ge31cblxuICB2YXIgbWFyZ2luID0gdHlwZW9mIG9wdGlvbnMubWFyZ2luID09PSAndW5kZWZpbmVkJyB8fFxuICAgIG9wdGlvbnMubWFyZ2luID09PSBudWxsIHx8XG4gICAgb3B0aW9ucy5tYXJnaW4gPCAwID8gNCA6IG9wdGlvbnMubWFyZ2luXG5cbiAgdmFyIHdpZHRoID0gb3B0aW9ucy53aWR0aCAmJiBvcHRpb25zLndpZHRoID49IDIxID8gb3B0aW9ucy53aWR0aCA6IHVuZGVmaW5lZFxuICB2YXIgc2NhbGUgPSBvcHRpb25zLnNjYWxlIHx8IDRcblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBzY2FsZTogd2lkdGggPyA0IDogc2NhbGUsXG4gICAgbWFyZ2luOiBtYXJnaW4sXG4gICAgY29sb3I6IHtcbiAgICAgIGRhcms6IGhleDJyZ2JhKG9wdGlvbnMuY29sb3IuZGFyayB8fCAnIzAwMDAwMGZmJyksXG4gICAgICBsaWdodDogaGV4MnJnYmEob3B0aW9ucy5jb2xvci5saWdodCB8fCAnI2ZmZmZmZmZmJylcbiAgICB9LFxuICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICByZW5kZXJlck9wdHM6IG9wdGlvbnMucmVuZGVyZXJPcHRzIHx8IHt9XG4gIH1cbn1cblxuZXhwb3J0cy5nZXRTY2FsZSA9IGZ1bmN0aW9uIGdldFNjYWxlIChxclNpemUsIG9wdHMpIHtcbiAgcmV0dXJuIG9wdHMud2lkdGggJiYgb3B0cy53aWR0aCA+PSBxclNpemUgKyBvcHRzLm1hcmdpbiAqIDJcbiAgICA/IG9wdHMud2lkdGggLyAocXJTaXplICsgb3B0cy5tYXJnaW4gKiAyKVxuICAgIDogb3B0cy5zY2FsZVxufVxuXG5leHBvcnRzLmdldEltYWdlV2lkdGggPSBmdW5jdGlvbiBnZXRJbWFnZVdpZHRoIChxclNpemUsIG9wdHMpIHtcbiAgdmFyIHNjYWxlID0gZXhwb3J0cy5nZXRTY2FsZShxclNpemUsIG9wdHMpXG4gIHJldHVybiBNYXRoLmZsb29yKChxclNpemUgKyBvcHRzLm1hcmdpbiAqIDIpICogc2NhbGUpXG59XG5cbmV4cG9ydHMucXJUb0ltYWdlRGF0YSA9IGZ1bmN0aW9uIHFyVG9JbWFnZURhdGEgKGltZ0RhdGEsIHFyLCBvcHRzKSB7XG4gIHZhciBzaXplID0gcXIubW9kdWxlcy5zaXplXG4gIHZhciBkYXRhID0gcXIubW9kdWxlcy5kYXRhXG4gIHZhciBzY2FsZSA9IGV4cG9ydHMuZ2V0U2NhbGUoc2l6ZSwgb3B0cylcbiAgdmFyIHN5bWJvbFNpemUgPSBNYXRoLmZsb29yKChzaXplICsgb3B0cy5tYXJnaW4gKiAyKSAqIHNjYWxlKVxuICB2YXIgc2NhbGVkTWFyZ2luID0gb3B0cy5tYXJnaW4gKiBzY2FsZVxuICB2YXIgcGFsZXR0ZSA9IFtvcHRzLmNvbG9yLmxpZ2h0LCBvcHRzLmNvbG9yLmRhcmtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzeW1ib2xTaXplOyBpKyspIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bWJvbFNpemU7IGorKykge1xuICAgICAgdmFyIHBvc0RzdCA9IChpICogc3ltYm9sU2l6ZSArIGopICogNFxuICAgICAgdmFyIHB4Q29sb3IgPSBvcHRzLmNvbG9yLmxpZ2h0XG5cbiAgICAgIGlmIChpID49IHNjYWxlZE1hcmdpbiAmJiBqID49IHNjYWxlZE1hcmdpbiAmJlxuICAgICAgICBpIDwgc3ltYm9sU2l6ZSAtIHNjYWxlZE1hcmdpbiAmJiBqIDwgc3ltYm9sU2l6ZSAtIHNjYWxlZE1hcmdpbikge1xuICAgICAgICB2YXIgaVNyYyA9IE1hdGguZmxvb3IoKGkgLSBzY2FsZWRNYXJnaW4pIC8gc2NhbGUpXG4gICAgICAgIHZhciBqU3JjID0gTWF0aC5mbG9vcigoaiAtIHNjYWxlZE1hcmdpbikgLyBzY2FsZSlcbiAgICAgICAgcHhDb2xvciA9IHBhbGV0dGVbZGF0YVtpU3JjICogc2l6ZSArIGpTcmNdID8gMSA6IDBdXG4gICAgICB9XG5cbiAgICAgIGltZ0RhdGFbcG9zRHN0KytdID0gcHhDb2xvci5yXG4gICAgICBpbWdEYXRhW3Bvc0RzdCsrXSA9IHB4Q29sb3IuZ1xuICAgICAgaW1nRGF0YVtwb3NEc3QrK10gPSBweENvbG9yLmJcbiAgICAgIGltZ0RhdGFbcG9zRHN0XSA9IHB4Q29sb3IuYVxuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBhIHN1YnNldCBvZiBub2RlLmpzIEJ1ZmZlciBtZXRob2RzIGZvciB0aGUgYnJvd3Nlci5cbiAqIEJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgLy8gQ2FuIHR5cGVkIGFycmF5IGluc3RhbmNlcyBiZSBhdWdtZW50ZWQ/XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHtfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH19XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDJcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gdHlwZWRBcnJheVN1cHBvcnQoKVxuXG52YXIgS19NQVhfTEVOR1RIID0gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgb2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG5cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcblxuICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgJiZcbiAgICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwgS19NQVhfTEVOR1RIYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBLX01BWF9MRU5HVEgudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gaXNuYW4gKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2YWwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdmFyIGJ1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgYnVmID0gdGhhdFxuICAgIGlmIChidWYgPT09IG51bGwpIHtcbiAgICAgIGJ1ZiA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICBidWYubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG5cbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICBidWZbaV0gPSAwXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nICh0aGF0LCBzdHJpbmcpIHtcbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IGJ1Zi53cml0ZShzdHJpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICBidWYgPSBidWYuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgYnVmW2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICB2YXIgYnVmXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBidWYgPSBmcm9tQXJyYXlMaWtlKHRoYXQsIGJ1ZilcbiAgfVxuXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHZhciBidWYgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBidWZcbiAgICB9XG5cbiAgICBvYmouY29weShidWYsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gYnVmXG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIEFycmF5LmlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGZyb20gKHRoYXQsIHZhbHVlLCBvZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgb2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBvZmZzZXQpXG4gIH1cblxuICByZXR1cm4gZnJvbU9iamVjdCh0aGF0LCB2YWx1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICB9IGVsc2Uge1xuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyArK2kpIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCkge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogbmV3IEJ1ZmZlcih2YWwpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihudWxsLCAwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gYWxsb2NVbnNhZmUobnVsbCwgbGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyXG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIENyZWF0ZWQgMjAwOC0wOC0xOS5cbiAqXG4gKiBEaWprc3RyYSBwYXRoLWZpbmRpbmcgZnVuY3Rpb25zLiBBZGFwdGVkIGZyb20gdGhlIERpamtzdGFyIFB5dGhvbiBwcm9qZWN0LlxuICpcbiAqIENvcHlyaWdodCAoQykgMjAwOFxuICogICBXeWF0dCBCYWxkd2luIDxzZWxmQHd5YXR0YmFsZHdpbi5jb20+XG4gKiAgIEFsbCByaWdodHMgcmVzZXJ2ZWRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4gKlxuICogICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICogVEhFIFNPRlRXQVJFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xudmFyIGRpamtzdHJhID0ge1xuICBzaW5nbGVfc291cmNlX3Nob3J0ZXN0X3BhdGhzOiBmdW5jdGlvbihncmFwaCwgcywgZCkge1xuICAgIC8vIFByZWRlY2Vzc29yIG1hcCBmb3IgZWFjaCBub2RlIHRoYXQgaGFzIGJlZW4gZW5jb3VudGVyZWQuXG4gICAgLy8gbm9kZSBJRCA9PiBwcmVkZWNlc3NvciBub2RlIElEXG4gICAgdmFyIHByZWRlY2Vzc29ycyA9IHt9O1xuXG4gICAgLy8gQ29zdHMgb2Ygc2hvcnRlc3QgcGF0aHMgZnJvbSBzIHRvIGFsbCBub2RlcyBlbmNvdW50ZXJlZC5cbiAgICAvLyBub2RlIElEID0+IGNvc3RcbiAgICB2YXIgY29zdHMgPSB7fTtcbiAgICBjb3N0c1tzXSA9IDA7XG5cbiAgICAvLyBDb3N0cyBvZiBzaG9ydGVzdCBwYXRocyBmcm9tIHMgdG8gYWxsIG5vZGVzIGVuY291bnRlcmVkOyBkaWZmZXJzIGZyb21cbiAgICAvLyBgY29zdHNgIGluIHRoYXQgaXQgcHJvdmlkZXMgZWFzeSBhY2Nlc3MgdG8gdGhlIG5vZGUgdGhhdCBjdXJyZW50bHkgaGFzXG4gICAgLy8gdGhlIGtub3duIHNob3J0ZXN0IHBhdGggZnJvbSBzLlxuICAgIC8vIFhYWDogRG8gd2UgYWN0dWFsbHkgbmVlZCBib3RoIGBjb3N0c2AgYW5kIGBvcGVuYD9cbiAgICB2YXIgb3BlbiA9IGRpamtzdHJhLlByaW9yaXR5UXVldWUubWFrZSgpO1xuICAgIG9wZW4ucHVzaChzLCAwKTtcblxuICAgIHZhciBjbG9zZXN0LFxuICAgICAgICB1LCB2LFxuICAgICAgICBjb3N0X29mX3NfdG9fdSxcbiAgICAgICAgYWRqYWNlbnRfbm9kZXMsXG4gICAgICAgIGNvc3Rfb2ZfZSxcbiAgICAgICAgY29zdF9vZl9zX3RvX3VfcGx1c19jb3N0X29mX2UsXG4gICAgICAgIGNvc3Rfb2Zfc190b192LFxuICAgICAgICBmaXJzdF92aXNpdDtcbiAgICB3aGlsZSAoIW9wZW4uZW1wdHkoKSkge1xuICAgICAgLy8gSW4gdGhlIG5vZGVzIHJlbWFpbmluZyBpbiBncmFwaCB0aGF0IGhhdmUgYSBrbm93biBjb3N0IGZyb20gcyxcbiAgICAgIC8vIGZpbmQgdGhlIG5vZGUsIHUsIHRoYXQgY3VycmVudGx5IGhhcyB0aGUgc2hvcnRlc3QgcGF0aCBmcm9tIHMuXG4gICAgICBjbG9zZXN0ID0gb3Blbi5wb3AoKTtcbiAgICAgIHUgPSBjbG9zZXN0LnZhbHVlO1xuICAgICAgY29zdF9vZl9zX3RvX3UgPSBjbG9zZXN0LmNvc3Q7XG5cbiAgICAgIC8vIEdldCBub2RlcyBhZGphY2VudCB0byB1Li4uXG4gICAgICBhZGphY2VudF9ub2RlcyA9IGdyYXBoW3VdIHx8IHt9O1xuXG4gICAgICAvLyAuLi5hbmQgZXhwbG9yZSB0aGUgZWRnZXMgdGhhdCBjb25uZWN0IHUgdG8gdGhvc2Ugbm9kZXMsIHVwZGF0aW5nXG4gICAgICAvLyB0aGUgY29zdCBvZiB0aGUgc2hvcnRlc3QgcGF0aHMgdG8gYW55IG9yIGFsbCBvZiB0aG9zZSBub2RlcyBhc1xuICAgICAgLy8gbmVjZXNzYXJ5LiB2IGlzIHRoZSBub2RlIGFjcm9zcyB0aGUgY3VycmVudCBlZGdlIGZyb20gdS5cbiAgICAgIGZvciAodiBpbiBhZGphY2VudF9ub2Rlcykge1xuICAgICAgICBpZiAoYWRqYWNlbnRfbm9kZXMuaGFzT3duUHJvcGVydHkodikpIHtcbiAgICAgICAgICAvLyBHZXQgdGhlIGNvc3Qgb2YgdGhlIGVkZ2UgcnVubmluZyBmcm9tIHUgdG8gdi5cbiAgICAgICAgICBjb3N0X29mX2UgPSBhZGphY2VudF9ub2Rlc1t2XTtcblxuICAgICAgICAgIC8vIENvc3Qgb2YgcyB0byB1IHBsdXMgdGhlIGNvc3Qgb2YgdSB0byB2IGFjcm9zcyBlLS10aGlzIGlzICphKlxuICAgICAgICAgIC8vIGNvc3QgZnJvbSBzIHRvIHYgdGhhdCBtYXkgb3IgbWF5IG5vdCBiZSBsZXNzIHRoYW4gdGhlIGN1cnJlbnRcbiAgICAgICAgICAvLyBrbm93biBjb3N0IHRvIHYuXG4gICAgICAgICAgY29zdF9vZl9zX3RvX3VfcGx1c19jb3N0X29mX2UgPSBjb3N0X29mX3NfdG9fdSArIGNvc3Rfb2ZfZTtcblxuICAgICAgICAgIC8vIElmIHdlIGhhdmVuJ3QgdmlzaXRlZCB2IHlldCBPUiBpZiB0aGUgY3VycmVudCBrbm93biBjb3N0IGZyb20gcyB0b1xuICAgICAgICAgIC8vIHYgaXMgZ3JlYXRlciB0aGFuIHRoZSBuZXcgY29zdCB3ZSBqdXN0IGZvdW5kIChjb3N0IG9mIHMgdG8gdSBwbHVzXG4gICAgICAgICAgLy8gY29zdCBvZiB1IHRvIHYgYWNyb3NzIGUpLCB1cGRhdGUgdidzIGNvc3QgaW4gdGhlIGNvc3QgbGlzdCBhbmRcbiAgICAgICAgICAvLyB1cGRhdGUgdidzIHByZWRlY2Vzc29yIGluIHRoZSBwcmVkZWNlc3NvciBsaXN0IChpdCdzIG5vdyB1KS5cbiAgICAgICAgICBjb3N0X29mX3NfdG9fdiA9IGNvc3RzW3ZdO1xuICAgICAgICAgIGZpcnN0X3Zpc2l0ID0gKHR5cGVvZiBjb3N0c1t2XSA9PT0gJ3VuZGVmaW5lZCcpO1xuICAgICAgICAgIGlmIChmaXJzdF92aXNpdCB8fCBjb3N0X29mX3NfdG9fdiA+IGNvc3Rfb2Zfc190b191X3BsdXNfY29zdF9vZl9lKSB7XG4gICAgICAgICAgICBjb3N0c1t2XSA9IGNvc3Rfb2Zfc190b191X3BsdXNfY29zdF9vZl9lO1xuICAgICAgICAgICAgb3Blbi5wdXNoKHYsIGNvc3Rfb2Zfc190b191X3BsdXNfY29zdF9vZl9lKTtcbiAgICAgICAgICAgIHByZWRlY2Vzc29yc1t2XSA9IHU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29zdHNbZF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgbXNnID0gWydDb3VsZCBub3QgZmluZCBhIHBhdGggZnJvbSAnLCBzLCAnIHRvICcsIGQsICcuJ10uam9pbignJyk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJlZGVjZXNzb3JzO1xuICB9LFxuXG4gIGV4dHJhY3Rfc2hvcnRlc3RfcGF0aF9mcm9tX3ByZWRlY2Vzc29yX2xpc3Q6IGZ1bmN0aW9uKHByZWRlY2Vzc29ycywgZCkge1xuICAgIHZhciBub2RlcyA9IFtdO1xuICAgIHZhciB1ID0gZDtcbiAgICB2YXIgcHJlZGVjZXNzb3I7XG4gICAgd2hpbGUgKHUpIHtcbiAgICAgIG5vZGVzLnB1c2godSk7XG4gICAgICBwcmVkZWNlc3NvciA9IHByZWRlY2Vzc29yc1t1XTtcbiAgICAgIHUgPSBwcmVkZWNlc3NvcnNbdV07XG4gICAgfVxuICAgIG5vZGVzLnJldmVyc2UoKTtcbiAgICByZXR1cm4gbm9kZXM7XG4gIH0sXG5cbiAgZmluZF9wYXRoOiBmdW5jdGlvbihncmFwaCwgcywgZCkge1xuICAgIHZhciBwcmVkZWNlc3NvcnMgPSBkaWprc3RyYS5zaW5nbGVfc291cmNlX3Nob3J0ZXN0X3BhdGhzKGdyYXBoLCBzLCBkKTtcbiAgICByZXR1cm4gZGlqa3N0cmEuZXh0cmFjdF9zaG9ydGVzdF9wYXRoX2Zyb21fcHJlZGVjZXNzb3JfbGlzdChcbiAgICAgIHByZWRlY2Vzc29ycywgZCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEEgdmVyeSBuYWl2ZSBwcmlvcml0eSBxdWV1ZSBpbXBsZW1lbnRhdGlvbi5cbiAgICovXG4gIFByaW9yaXR5UXVldWU6IHtcbiAgICBtYWtlOiBmdW5jdGlvbiAob3B0cykge1xuICAgICAgdmFyIFQgPSBkaWprc3RyYS5Qcmlvcml0eVF1ZXVlLFxuICAgICAgICAgIHQgPSB7fSxcbiAgICAgICAgICBrZXk7XG4gICAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICAgIGZvciAoa2V5IGluIFQpIHtcbiAgICAgICAgaWYgKFQuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgIHRba2V5XSA9IFRba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdC5xdWV1ZSA9IFtdO1xuICAgICAgdC5zb3J0ZXIgPSBvcHRzLnNvcnRlciB8fCBULmRlZmF1bHRfc29ydGVyO1xuICAgICAgcmV0dXJuIHQ7XG4gICAgfSxcblxuICAgIGRlZmF1bHRfc29ydGVyOiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEuY29zdCAtIGIuY29zdDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgbmV3IGl0ZW0gdG8gdGhlIHF1ZXVlIGFuZCBlbnN1cmUgdGhlIGhpZ2hlc3QgcHJpb3JpdHkgZWxlbWVudFxuICAgICAqIGlzIGF0IHRoZSBmcm9udCBvZiB0aGUgcXVldWUuXG4gICAgICovXG4gICAgcHVzaDogZnVuY3Rpb24gKHZhbHVlLCBjb3N0KSB7XG4gICAgICB2YXIgaXRlbSA9IHt2YWx1ZTogdmFsdWUsIGNvc3Q6IGNvc3R9O1xuICAgICAgdGhpcy5xdWV1ZS5wdXNoKGl0ZW0pO1xuICAgICAgdGhpcy5xdWV1ZS5zb3J0KHRoaXMuc29ydGVyKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBoaWdoZXN0IHByaW9yaXR5IGVsZW1lbnQgaW4gdGhlIHF1ZXVlLlxuICAgICAqL1xuICAgIHBvcDogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRoaXMucXVldWUuc2hpZnQoKTtcbiAgICB9LFxuXG4gICAgZW1wdHk6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMDtcbiAgICB9XG4gIH1cbn07XG5cblxuLy8gbm9kZS5qcyBtb2R1bGUgZXhwb3J0c1xuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gZGlqa3N0cmE7XG59XG4iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdfQ==