aurora.js 322 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023
  1. //请了解比特流
  2. (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.AV = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  3. // document.addEventListener('touchstart', function() {
  4. // console.log("我主动的play()了");
  5. // // players.play();
  6. // // players.startPlaying();
  7. // // var messageData = new Uint8Array(se)
  8. // // player.decode(messageData);
  9. // // return this.asset.start(false);
  10. // this.playing = true;
  11. // // this.play();
  12. // console.log("this.playing",this.playing)
  13. // });
  14. (function() {
  15. var Asset, BufferSource, Decoder, Demuxer, EventEmitter, FileSource, HTTPSource,
  16. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  17. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  18. hasProp = {}.hasOwnProperty;
  19. EventEmitter = require('./core/events');
  20. HTTPSource = require('./sources/node/http');
  21. console.log(HTTPSource)
  22. FileSource = require('./sources/node/file');
  23. BufferSource = require('./sources/buffer');
  24. Demuxer = require('./demuxer');
  25. Decoder = require('./decoder');
  26. Asset = (function(superClass) {
  27. extend(Asset, superClass);
  28. function Asset(source) {
  29. this.source = source;
  30. this._decode = bind(this._decode, this);
  31. this.findDecoder = bind(this.findDecoder, this);
  32. this.probe = bind(this.probe, this);
  33. this.buffered = 0;
  34. this.duration = null;
  35. this.format = null;
  36. this.metadata = null;
  37. this.active = false;
  38. this.demuxer = null;
  39. this.decoder = null;
  40. this.source.once('data', this.probe);
  41. this.source.on('error', (function(_this) {
  42. return function(err) {
  43. _this.emit('error', err);
  44. return _this.stop();
  45. };
  46. })(this));
  47. this.source.on('progress', (function(_this) {
  48. return function(buffered) {
  49. _this.buffered = buffered;
  50. return _this.emit('buffer', _this.buffered);
  51. };
  52. })(this));
  53. }
  54. Asset.fromURL = function(url, opts) {
  55. return new Asset(new HTTPSource(url, opts));
  56. };
  57. Asset.fromFile = function(file) {
  58. return new Asset(new FileSource(file));
  59. };
  60. Asset.fromBuffer = function(buffer) {
  61. return new Asset(new BufferSource(buffer));
  62. };
  63. Asset.prototype.start = function(decode) {
  64. if (this.active) {
  65. return;
  66. }
  67. if (decode != null) {
  68. this.shouldDecode = decode;
  69. }
  70. if (this.shouldDecode == null) {
  71. this.shouldDecode = true;
  72. }
  73. this.active = true;
  74. this.source.start();
  75. if (this.decoder && this.shouldDecode) {
  76. return this._decode();
  77. }
  78. };
  79. Asset.prototype.stop = function() {
  80. if (!this.active) {
  81. return;
  82. }
  83. this.active = false;
  84. return this.source.pause();
  85. };
  86. Asset.prototype.get = function(event, callback) {
  87. if (event !== 'format' && event !== 'duration' && event !== 'metadata') {
  88. return;
  89. }
  90. if (this[event] != null) {
  91. return callback(this[event]);
  92. } else {
  93. this.once(event, (function(_this) {
  94. return function(value) {
  95. _this.stop();
  96. return callback(value);
  97. };
  98. })(this));
  99. return this.start();
  100. }
  101. };
  102. Asset.prototype.decodePacket = function() {
  103. return this.decoder.decode();
  104. };
  105. Asset.prototype.decodeToBuffer = function(callback) {
  106. var chunks, dataHandler, length;
  107. length = 0;
  108. chunks = [];
  109. this.on('data', dataHandler = function(chunk) {
  110. length += chunk.length;
  111. return chunks.push(chunk);
  112. });
  113. this.once('end', function() {
  114. var buf, chunk, j, len, offset;
  115. buf = new Float32Array(length);
  116. offset = 0;
  117. for (j = 0, len = chunks.length; j < len; j++) {
  118. chunk = chunks[j];
  119. buf.set(chunk, offset);
  120. offset += chunk.length;
  121. }
  122. this.off('data', dataHandler);
  123. return callback(buf);
  124. });
  125. return this.start();
  126. };
  127. Asset.prototype.probe = function(chunk) {
  128. var demuxer;
  129. if (!this.active) {
  130. return;
  131. }
  132. demuxer = Demuxer.find(chunk);
  133. if (!demuxer) {
  134. return this.emit('error', 'A demuxer for this container was not found.');
  135. }
  136. this.demuxer = new demuxer(this.source, chunk);
  137. this.demuxer.on('format', this.findDecoder);
  138. this.demuxer.on('duration', (function(_this) {
  139. return function(duration) {
  140. _this.duration = duration;
  141. return _this.emit('duration', _this.duration);
  142. };
  143. })(this));
  144. this.demuxer.on('metadata', (function(_this) {
  145. return function(metadata) {
  146. _this.metadata = metadata;
  147. return _this.emit('metadata', _this.metadata);
  148. };
  149. })(this));
  150. return this.demuxer.on('error', (function(_this) {
  151. return function(err) {
  152. _this.emit('error', err);
  153. return _this.stop();
  154. };
  155. })(this));
  156. };
  157. Asset.prototype.findDecoder = function(format) {
  158. var decoder, div;
  159. this.format = format;
  160. if (!this.active) {
  161. return;
  162. }
  163. this.emit('format', this.format);
  164. decoder = Decoder.find(this.format.formatID);
  165. if (!decoder) {
  166. return this.emit('error', "A decoder for " + this.format.formatID + " was not found.");
  167. }
  168. this.decoder = new decoder(this.demuxer, this.format);
  169. if (this.format.floatingPoint) {
  170. this.decoder.on('data', (function(_this) {
  171. return function(buffer) {
  172. return _this.emit('data', buffer);
  173. };
  174. })(this));
  175. } else {
  176. div = Math.pow(2, this.format.bitsPerChannel - 1);
  177. this.decoder.on('data', (function(_this) {
  178. return function(buffer) {
  179. var buf, i, j, len, sample;
  180. buf = new Float32Array(buffer.length);
  181. for (i = j = 0, len = buffer.length; j < len; i = ++j) {
  182. sample = buffer[i];
  183. buf[i] = sample / div;
  184. }
  185. return _this.emit('data', buf);
  186. };
  187. })(this));
  188. }
  189. this.decoder.on('error', (function(_this) {
  190. return function(err) {
  191. _this.emit('error', err);
  192. return _this.stop();
  193. };
  194. })(this));
  195. this.decoder.on('end', (function(_this) {
  196. return function() {
  197. return _this.emit('end');
  198. };
  199. })(this));
  200. this.emit('decodeStart');
  201. if (this.shouldDecode) {
  202. return this._decode();
  203. }
  204. };
  205. Asset.prototype._decode = function() {
  206. while (this.decoder.decode() && this.active) {
  207. continue;
  208. }
  209. if (this.active) {
  210. return this.decoder.once('data', this._decode);
  211. }
  212. };
  213. Asset.prototype.destroy = function() {
  214. var ref, ref1, ref2;
  215. this.stop();
  216. if ((ref = this.demuxer) != null) {
  217. ref.off();
  218. }
  219. if ((ref1 = this.decoder) != null) {
  220. ref1.off();
  221. }
  222. if ((ref2 = this.source) != null) {
  223. ref2.off();
  224. }
  225. return this.off();
  226. };
  227. return Asset;
  228. })(EventEmitter);
  229. module.exports = Asset;
  230. }).call(this);
  231. },{"./core/events":8,"./decoder":11,"./demuxer":14,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],2:[function(require,module,exports){
  232. (function() {
  233. var key, ref, val;
  234. ref = require('./aurora_base');
  235. for (key in ref) {
  236. val = ref[key];
  237. exports[key] = val;
  238. }
  239. require('./demuxers/caf');
  240. require('./demuxers/m4a');
  241. require('./demuxers/aiff');
  242. require('./demuxers/wave');
  243. require('./demuxers/au');
  244. require('./decoders/lpcm');
  245. require('./decoders/xlaw');
  246. }).call(this);
  247. },{"./aurora_base":3,"./decoders/lpcm":12,"./decoders/xlaw":13,"./demuxers/aiff":15,"./demuxers/au":16,"./demuxers/caf":17,"./demuxers/m4a":18,"./demuxers/wave":19}],3:[function(require,module,exports){
  248. // 模块生成
  249. (function() {
  250. exports.Base = require('./core/base');
  251. exports.Buffer = require('./core/buffer');
  252. exports.BufferList = require('./core/bufferlist');
  253. exports.Stream = require('./core/stream');
  254. exports.Bitstream = require('./core/bitstream');
  255. exports.EventEmitter = require('./core/events');
  256. exports.UnderflowError = require('./core/underflow');
  257. exports.HTTPSource = require('./sources/node/http');
  258. exports.FileSource = require('./sources/node/file');
  259. exports.BufferSource = require('./sources/buffer');
  260. exports.Demuxer = require('./demuxer');
  261. exports.Decoder = require('./decoder');
  262. exports.AudioDevice = require('./device');
  263. exports.Asset = require('./asset');
  264. exports.Player = require('./player');
  265. exports.Filter = require('./filter');
  266. exports.VolumeFilter = require('./filters/volume');
  267. exports.BalanceFilter = require('./filters/balance');
  268. }).call(this);
  269. },{"./asset":1,"./core/base":4,"./core/bitstream":5,"./core/buffer":6,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10,"./decoder":11,"./demuxer":14,"./device":20,"./filter":24,"./filters/balance":25,"./filters/volume":26,"./player":27,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],4:[function(require,module,exports){
  270. (function() {
  271. var Base,
  272. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  273. hasProp = {}.hasOwnProperty,
  274. indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  275. Base = (function() {
  276. var fnTest;
  277. function Base() {}
  278. fnTest = /\b_super\b/;
  279. Base.extend = function(prop) {
  280. var Class, _super, fn, key, keys, ref;
  281. Class = (function(superClass) {
  282. extend(Class, superClass);
  283. function Class() {
  284. return Class.__super__.constructor.apply(this, arguments);
  285. }
  286. return Class;
  287. })(this);
  288. if (typeof prop === 'function') {
  289. keys = Object.keys(Class.prototype);
  290. prop.call(Class, Class);
  291. prop = {};
  292. ref = Class.prototype;
  293. for (key in ref) {
  294. fn = ref[key];
  295. if (indexOf.call(keys, key) < 0) {
  296. prop[key] = fn;
  297. }
  298. }
  299. }
  300. _super = Class.__super__;
  301. for (key in prop) {
  302. fn = prop[key];
  303. if (typeof fn === 'function' && fnTest.test(fn)) {
  304. (function(key, fn) {
  305. return Class.prototype[key] = function() {
  306. var ret, tmp;
  307. tmp = this._super;
  308. this._super = _super[key];
  309. ret = fn.apply(this, arguments);
  310. this._super = tmp;
  311. return ret;
  312. };
  313. })(key, fn);
  314. } else {
  315. Class.prototype[key] = fn;
  316. }
  317. }
  318. return Class;
  319. };
  320. return Base;
  321. })();
  322. module.exports = Base;
  323. }).call(this);
  324. },{}],5:[function(require,module,exports){
  325. (function() {
  326. var Bitstream;
  327. Bitstream = (function() {
  328. function Bitstream(stream) {
  329. this.stream = stream;
  330. this.bitPosition = 0;
  331. }
  332. Bitstream.prototype.copy = function() {
  333. var result;
  334. result = new Bitstream(this.stream.copy());
  335. result.bitPosition = this.bitPosition;
  336. return result;
  337. };
  338. Bitstream.prototype.offset = function() {
  339. return 8 * this.stream.offset + this.bitPosition;
  340. };
  341. Bitstream.prototype.available = function(bits) {
  342. return this.stream.available((bits + 8 - this.bitPosition) / 8);
  343. };
  344. Bitstream.prototype.advance = function(bits) {
  345. var pos;
  346. pos = this.bitPosition + bits;
  347. this.stream.advance(pos >> 3);
  348. return this.bitPosition = pos & 7;
  349. };
  350. Bitstream.prototype.rewind = function(bits) {
  351. var pos;
  352. pos = this.bitPosition - bits;
  353. this.stream.rewind(Math.abs(pos >> 3));
  354. return this.bitPosition = pos & 7;
  355. };
  356. Bitstream.prototype.seek = function(offset) {
  357. var curOffset;
  358. curOffset = this.offset();
  359. if (offset > curOffset) {
  360. return this.advance(offset - curOffset);
  361. } else if (offset < curOffset) {
  362. return this.rewind(curOffset - offset);
  363. }
  364. };
  365. Bitstream.prototype.align = function() {
  366. if (this.bitPosition !== 0) {
  367. this.bitPosition = 0;
  368. return this.stream.advance(1);
  369. }
  370. };
  371. //Bitstream原型读取
  372. Bitstream.prototype.read = function(bits, signed) {
  373. var a, a0, a1, a2, a3, a4, mBits;
  374. if (bits === 0) {
  375. return 0;
  376. }
  377. mBits = bits + this.bitPosition;
  378. if (mBits <= 8) {
  379. a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
  380. } else if (mBits <= 16) {
  381. a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
  382. } else if (mBits <= 24) {
  383. a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
  384. } else if (mBits <= 32) {
  385. a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
  386. } else if (mBits <= 40) {
  387. a0 = this.stream.peekUInt8(0) * 0x0100000000;
  388. a1 = this.stream.peekUInt8(1) << 24 >>> 0;
  389. a2 = this.stream.peekUInt8(2) << 16;
  390. a3 = this.stream.peekUInt8(3) << 8;
  391. a4 = this.stream.peekUInt8(4);
  392. a = a0 + a1 + a2 + a3 + a4;
  393. a %= Math.pow(2, 40 - this.bitPosition);
  394. a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
  395. } else {
  396. throw new Error("Too many bits!");
  397. }
  398. if (signed) {
  399. if (mBits < 32) {
  400. if (a >>> (bits - 1)) {
  401. a = ((1 << bits >>> 0) - a) * -1;
  402. }
  403. } else {
  404. if (a / Math.pow(2, bits - 1) | 0) {
  405. a = (Math.pow(2, bits) - a) * -1;
  406. }
  407. }
  408. }
  409. this.advance(bits);
  410. return a;
  411. };
  412. // 每一段的查
  413. Bitstream.prototype.peek = function(bits, signed) {
  414. var a, a0, a1, a2, a3, a4, mBits;
  415. if (bits === 0) {
  416. return 0;
  417. }
  418. mBits = bits + this.bitPosition;
  419. if (mBits <= 8) {
  420. a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
  421. } else if (mBits <= 16) {
  422. a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
  423. } else if (mBits <= 24) {
  424. a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
  425. } else if (mBits <= 32) {
  426. a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
  427. } else if (mBits <= 40) {
  428. a0 = this.stream.peekUInt8(0) * 0x0100000000;
  429. a1 = this.stream.peekUInt8(1) << 24 >>> 0;
  430. a2 = this.stream.peekUInt8(2) << 16;
  431. a3 = this.stream.peekUInt8(3) << 8;
  432. a4 = this.stream.peekUInt8(4);
  433. a = a0 + a1 + a2 + a3 + a4;
  434. a %= Math.pow(2, 40 - this.bitPosition);
  435. a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
  436. } else {
  437. throw new Error("Too many bits!");
  438. }
  439. if (signed) {
  440. if (mBits < 32) {
  441. if (a >>> (bits - 1)) {
  442. a = ((1 << bits >>> 0) - a) * -1;
  443. }
  444. } else {
  445. if (a / Math.pow(2, bits - 1) | 0) {
  446. a = (Math.pow(2, bits) - a) * -1;
  447. }
  448. }
  449. }
  450. return a;
  451. };
  452. //读LSB 8 16 24 32 等
  453. Bitstream.prototype.readLSB = function(bits, signed) {
  454. var a, mBits;
  455. if (bits === 0) {
  456. return 0;
  457. }
  458. if (bits > 40) {
  459. throw new Error("Too many bits!");
  460. }
  461. mBits = bits + this.bitPosition;
  462. a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
  463. if (mBits > 8) {
  464. a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
  465. }
  466. if (mBits > 16) {
  467. a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
  468. }
  469. if (mBits > 24) {
  470. a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
  471. }
  472. if (mBits > 32) {
  473. a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
  474. }
  475. if (mBits >= 32) {
  476. a %= Math.pow(2, bits);
  477. } else {
  478. a &= (1 << bits) - 1;
  479. }
  480. if (signed) {
  481. if (mBits < 32) {
  482. if (a >>> (bits - 1)) {
  483. a = ((1 << bits >>> 0) - a) * -1;
  484. }
  485. } else {
  486. if (a / Math.pow(2, bits - 1) | 0) {
  487. a = (Math.pow(2, bits) - a) * -1;
  488. }
  489. }
  490. }
  491. this.advance(bits);
  492. return a;
  493. };
  494. Bitstream.prototype.peekLSB = function(bits, signed) {
  495. var a, mBits;
  496. if (bits === 0) {
  497. return 0;
  498. }
  499. if (bits > 40) {
  500. throw new Error("Too many bits!");
  501. }
  502. mBits = bits + this.bitPosition;
  503. a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
  504. if (mBits > 8) {
  505. a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
  506. }
  507. if (mBits > 16) {
  508. a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
  509. }
  510. if (mBits > 24) {
  511. a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
  512. }
  513. if (mBits > 32) {
  514. a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
  515. }
  516. if (mBits >= 32) {
  517. a %= Math.pow(2, bits);
  518. } else {
  519. a &= (1 << bits) - 1;
  520. }
  521. if (signed) {
  522. if (mBits < 32) {
  523. if (a >>> (bits - 1)) {
  524. a = ((1 << bits >>> 0) - a) * -1;
  525. }
  526. } else {
  527. if (a / Math.pow(2, bits - 1) | 0) {
  528. a = (Math.pow(2, bits) - a) * -1;
  529. }
  530. }
  531. }
  532. return a;
  533. };
  534. return Bitstream;
  535. })();
  536. module.exports = Bitstream;
  537. }).call(this);
  538. },{}],6:[function(require,module,exports){
  539. (function (global){
  540. (function() {
  541. var AVBuffer;
  542. AVBuffer = (function() {
  543. var BlobBuilder, URL;
  544. function AVBuffer(input) {
  545. var ref;
  546. if (input instanceof Uint8Array) {
  547. this.data = input;
  548. } else if (input instanceof ArrayBuffer || Array.isArray(input) || typeof input === 'number' || ((ref = global.Buffer) != null ? ref.isBuffer(input) : void 0)) {
  549. this.data = new Uint8Array(input);
  550. } else if (input.buffer instanceof ArrayBuffer) {
  551. this.data = new Uint8Array(input.buffer, input.byteOffset, input.length * input.BYTES_PER_ELEMENT);
  552. } else if (input instanceof AVBuffer) {
  553. this.data = input.data;
  554. } else {
  555. throw new Error("Constructing buffer with unknown type.构造未知类型的缓冲区");
  556. }
  557. this.length = this.data.length;
  558. this.next = null;
  559. this.prev = null;
  560. }
  561. AVBuffer.allocate = function(size) {
  562. return new AVBuffer(size);
  563. };
  564. AVBuffer.prototype.copy = function() {
  565. return new AVBuffer(new Uint8Array(this.data));
  566. };
  567. AVBuffer.prototype.slice = function(position, length) {
  568. if (length == null) {
  569. length = this.length;
  570. }
  571. if (position === 0 && length >= this.length) {
  572. return new AVBuffer(this.data);
  573. } else {
  574. return new AVBuffer(this.data.subarray(position, position + length));
  575. }
  576. };
  577. BlobBuilder = global.BlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder;
  578. URL = global.URL || global.webkitURL || global.mozURL;
  579. AVBuffer.makeBlob = function(data, type) {
  580. var bb;
  581. if (type == null) {
  582. type = 'application/octet-stream';
  583. }
  584. try {
  585. return new Blob([data], {
  586. type: type
  587. });
  588. } catch (undefined) {}
  589. if (BlobBuilder != null) {
  590. bb = new BlobBuilder;
  591. bb.append(data);
  592. return bb.getBlob(type);
  593. }
  594. return null;
  595. };
  596. AVBuffer.makeBlobURL = function(data, type) {
  597. return URL != null ? URL.createObjectURL(this.makeBlob(data, type)) : void 0;
  598. };
  599. AVBuffer.revokeBlobURL = function(url) {
  600. return URL != null ? URL.revokeObjectURL(url) : void 0;
  601. };
  602. AVBuffer.prototype.toBlob = function() {
  603. return AVBuffer.makeBlob(this.data.buffer);
  604. };
  605. AVBuffer.prototype.toBlobURL = function() {
  606. return AVBuffer.makeBlobURL(this.data.buffer);
  607. };
  608. return AVBuffer;
  609. })();
  610. module.exports = AVBuffer;
  611. }).call(this);
  612. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  613. },{}],7:[function(require,module,exports){
  614. (function() {
  615. var BufferList;
  616. BufferList = (function() {
  617. function BufferList() {
  618. this.first = null;
  619. this.last = null;
  620. this.numBuffers = 0;
  621. this.availableBytes = 0;
  622. this.availableBuffers = 0;
  623. }
  624. BufferList.prototype.copy = function() {
  625. var result;
  626. result = new BufferList;
  627. result.first = this.first;
  628. result.last = this.last;
  629. result.numBuffers = this.numBuffers;
  630. result.availableBytes = this.availableBytes;
  631. result.availableBuffers = this.availableBuffers;
  632. return result;
  633. };
  634. BufferList.prototype.append = function(buffer) {
  635. var ref;
  636. buffer.prev = this.last;
  637. if ((ref = this.last) != null) {
  638. ref.next = buffer;
  639. }
  640. this.last = buffer;
  641. if (this.first == null) {
  642. this.first = buffer;
  643. }
  644. this.availableBytes += buffer.length;
  645. this.availableBuffers++;
  646. return this.numBuffers++;
  647. };
  648. BufferList.prototype.advance = function() {
  649. if (this.first) {
  650. this.availableBytes -= this.first.length;
  651. this.availableBuffers--;
  652. this.first = this.first.next;
  653. return this.first != null;
  654. }
  655. return false;
  656. };
  657. BufferList.prototype.rewind = function() {
  658. var ref;
  659. if (this.first && !this.first.prev) {
  660. return false;
  661. }
  662. this.first = ((ref = this.first) != null ? ref.prev : void 0) || this.last;
  663. if (this.first) {
  664. this.availableBytes += this.first.length;
  665. this.availableBuffers++;
  666. }
  667. return this.first != null;
  668. };
  669. BufferList.prototype.reset = function() {
  670. var results;
  671. results = [];
  672. while (this.rewind()) {
  673. continue;
  674. }
  675. return results;
  676. };
  677. return BufferList;
  678. })();
  679. module.exports = BufferList;
  680. }).call(this);
  681. },{}],8:[function(require,module,exports){
  682. // Generated by CoffeeScript 1.10.0
  683. (function() {
  684. var Base, EventEmitter,
  685. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  686. hasProp = {}.hasOwnProperty,
  687. slice = [].slice;
  688. Base = require('./base');
  689. EventEmitter = (function(superClass) {
  690. extend(EventEmitter, superClass);
  691. function EventEmitter() {
  692. return EventEmitter.__super__.constructor.apply(this, arguments);
  693. }
  694. EventEmitter.prototype.on = function(event, fn) {
  695. var base;
  696. if (this.events == null) {
  697. this.events = {};
  698. }
  699. if ((base = this.events)[event] == null) {
  700. base[event] = [];
  701. }
  702. return this.events[event].push(fn);
  703. };
  704. EventEmitter.prototype.off = function(event, fn) {
  705. var events, index, ref;
  706. if (this.events == null) {
  707. return;
  708. }
  709. if ((ref = this.events) != null ? ref[event] : void 0) {
  710. if (fn != null) {
  711. index = this.events[event].indexOf(fn);
  712. if (~index) {
  713. return this.events[event].splice(index, 1);
  714. }
  715. } else {
  716. return this.events[event];
  717. }
  718. } else if (event == null) {
  719. return events = {};
  720. }
  721. };
  722. EventEmitter.prototype.once = function(event, fn) {
  723. var cb;
  724. return this.on(event, cb = function() {
  725. this.off(event, cb);
  726. return fn.apply(this, arguments);
  727. });
  728. };
  729. EventEmitter.prototype.emit = function() {
  730. var args, event, fn, i, len, ref, ref1;
  731. event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  732. if (!((ref = this.events) != null ? ref[event] : void 0)) {
  733. return;
  734. }
  735. ref1 = this.events[event].slice();
  736. for (i = 0, len = ref1.length; i < len; i++) {
  737. fn = ref1[i];
  738. fn.apply(this, args);
  739. }
  740. };
  741. return EventEmitter;
  742. })(Base);
  743. module.exports = EventEmitter;
  744. }).call(this);
  745. },{"./base":4}],9:[function(require,module,exports){
  746. // Generated by CoffeeScript 1.10.0
  747. (function() {
  748. var AVBuffer, BufferList, Stream, UnderflowError;
  749. BufferList = require('./bufferlist');
  750. AVBuffer = require('./buffer');
  751. UnderflowError = require('./underflow');
  752. Stream = (function() {
  753. var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8;
  754. buf = new ArrayBuffer(16);
  755. uint8 = new Uint8Array(buf);
  756. int8 = new Int8Array(buf);
  757. uint16 = new Uint16Array(buf);
  758. int16 = new Int16Array(buf);
  759. uint32 = new Uint32Array(buf);
  760. int32 = new Int32Array(buf);
  761. float32 = new Float32Array(buf);
  762. if (typeof Float64Array !== "undefined" && Float64Array !== null) {
  763. float64 = new Float64Array(buf);
  764. }
  765. nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
  766. function Stream(list1) {
  767. this.list = list1;
  768. this.localOffset = 0;
  769. this.offset = 0;
  770. }
  771. Stream.fromBuffer = function(buffer) {
  772. var list;
  773. list = new BufferList;
  774. list.append(buffer);
  775. return new Stream(list);
  776. };
  777. Stream.prototype.copy = function() {
  778. var result;
  779. result = new Stream(this.list.copy());
  780. result.localOffset = this.localOffset;
  781. result.offset = this.offset;
  782. return result;
  783. };
  784. Stream.prototype.available = function(bytes) {
  785. return bytes <= this.list.availableBytes - this.localOffset;
  786. };
  787. Stream.prototype.remainingBytes = function() {
  788. return this.list.availableBytes - this.localOffset;
  789. };
  790. Stream.prototype.advance = function(bytes) {
  791. if (!this.available(bytes)) {
  792. throw new UnderflowError();
  793. }
  794. this.localOffset += bytes;
  795. this.offset += bytes;
  796. while (this.list.first && this.localOffset >= this.list.first.length) {
  797. this.localOffset -= this.list.first.length;
  798. this.list.advance();
  799. }
  800. return this;
  801. };
  802. Stream.prototype.rewind = function(bytes) {
  803. if (bytes > this.offset) {
  804. throw new UnderflowError();
  805. }
  806. if (!this.list.first) {
  807. this.list.rewind();
  808. this.localOffset = this.list.first.length;
  809. }
  810. this.localOffset -= bytes;
  811. this.offset -= bytes;
  812. while (this.list.first.prev && this.localOffset < 0) {
  813. this.list.rewind();
  814. this.localOffset += this.list.first.length;
  815. }
  816. return this;
  817. };
  818. Stream.prototype.seek = function(position) {
  819. if (position > this.offset) {
  820. return this.advance(position - this.offset);
  821. } else if (position < this.offset) {
  822. return this.rewind(this.offset - position);
  823. }
  824. };
  825. Stream.prototype.readUInt8 = function() {
  826. var a;
  827. if (!this.available(1)) {
  828. throw new UnderflowError();
  829. }
  830. a = this.list.first.data[this.localOffset];
  831. this.localOffset += 1;
  832. this.offset += 1;
  833. if (this.localOffset === this.list.first.length) {
  834. this.localOffset = 0;
  835. this.list.advance();
  836. }
  837. return a;
  838. };
  839. Stream.prototype.peekUInt8 = function(offset) {
  840. var buffer;
  841. if (offset == null) {
  842. offset = 0;
  843. }
  844. if (!this.available(offset + 1)) {
  845. throw new UnderflowError();
  846. }
  847. offset = this.localOffset + offset;
  848. buffer = this.list.first;
  849. while (buffer) {
  850. if (buffer.length > offset) {
  851. return buffer.data[offset];
  852. }
  853. offset -= buffer.length;
  854. buffer = buffer.next;
  855. }
  856. return 0;
  857. };
  858. Stream.prototype.read = function(bytes, littleEndian) {
  859. var i, j, k, ref, ref1;
  860. if (littleEndian == null) {
  861. littleEndian = false;
  862. }
  863. if (littleEndian === nativeEndian) {
  864. for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
  865. uint8[i] = this.readUInt8();
  866. }
  867. } else {
  868. for (i = k = ref1 = bytes - 1; k >= 0; i = k += -1) {
  869. uint8[i] = this.readUInt8();
  870. }
  871. }
  872. };
  873. Stream.prototype.peek = function(bytes, offset, littleEndian) {
  874. var i, j, k, ref, ref1;
  875. if (littleEndian == null) {
  876. littleEndian = false;
  877. }
  878. if (littleEndian === nativeEndian) {
  879. for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
  880. uint8[i] = this.peekUInt8(offset + i);
  881. }
  882. } else {
  883. for (i = k = 0, ref1 = bytes; k < ref1; i = k += 1) {
  884. uint8[bytes - i - 1] = this.peekUInt8(offset + i);
  885. }
  886. }
  887. };
  888. Stream.prototype.readInt8 = function() {
  889. this.read(1);
  890. return int8[0];
  891. };
  892. Stream.prototype.peekInt8 = function(offset) {
  893. if (offset == null) {
  894. offset = 0;
  895. }
  896. this.peek(1, offset);
  897. return int8[0];
  898. };
  899. Stream.prototype.readUInt16 = function(littleEndian) {
  900. this.read(2, littleEndian);
  901. return uint16[0];
  902. };
  903. Stream.prototype.peekUInt16 = function(offset, littleEndian) {
  904. if (offset == null) {
  905. offset = 0;
  906. }
  907. this.peek(2, offset, littleEndian);
  908. return uint16[0];
  909. };
  910. Stream.prototype.readInt16 = function(littleEndian) {
  911. this.read(2, littleEndian);
  912. return int16[0];
  913. };
  914. Stream.prototype.peekInt16 = function(offset, littleEndian) {
  915. if (offset == null) {
  916. offset = 0;
  917. }
  918. this.peek(2, offset, littleEndian);
  919. return int16[0];
  920. };
  921. Stream.prototype.readUInt24 = function(littleEndian) {
  922. if (littleEndian) {
  923. return this.readUInt16(true) + (this.readUInt8() << 16);
  924. } else {
  925. return (this.readUInt16() << 8) + this.readUInt8();
  926. }
  927. };
  928. Stream.prototype.peekUInt24 = function(offset, littleEndian) {
  929. if (offset == null) {
  930. offset = 0;
  931. }
  932. if (littleEndian) {
  933. return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16);
  934. } else {
  935. return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2);
  936. }
  937. };
  938. Stream.prototype.readInt24 = function(littleEndian) {
  939. if (littleEndian) {
  940. return this.readUInt16(true) + (this.readInt8() << 16);
  941. } else {
  942. return (this.readInt16() << 8) + this.readUInt8();
  943. }
  944. };
  945. Stream.prototype.peekInt24 = function(offset, littleEndian) {
  946. if (offset == null) {
  947. offset = 0;
  948. }
  949. if (littleEndian) {
  950. return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16);
  951. } else {
  952. return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2);
  953. }
  954. };
  955. Stream.prototype.readUInt32 = function(littleEndian) {
  956. this.read(4, littleEndian);
  957. return uint32[0];
  958. };
  959. Stream.prototype.peekUInt32 = function(offset, littleEndian) {
  960. if (offset == null) {
  961. offset = 0;
  962. }
  963. this.peek(4, offset, littleEndian);
  964. return uint32[0];
  965. };
  966. Stream.prototype.readInt32 = function(littleEndian) {
  967. this.read(4, littleEndian);
  968. return int32[0];
  969. };
  970. Stream.prototype.peekInt32 = function(offset, littleEndian) {
  971. if (offset == null) {
  972. offset = 0;
  973. }
  974. this.peek(4, offset, littleEndian);
  975. return int32[0];
  976. };
  977. Stream.prototype.readFloat32 = function(littleEndian) {
  978. this.read(4, littleEndian);
  979. return float32[0];
  980. };
  981. Stream.prototype.peekFloat32 = function(offset, littleEndian) {
  982. if (offset == null) {
  983. offset = 0;
  984. }
  985. this.peek(4, offset, littleEndian);
  986. return float32[0];
  987. };
  988. Stream.prototype.readFloat64 = function(littleEndian) {
  989. this.read(8, littleEndian);
  990. if (float64) {
  991. return float64[0];
  992. } else {
  993. return float64Fallback();
  994. }
  995. };
  996. float64Fallback = function() {
  997. var exp, frac, high, low, out, sign;
  998. low = uint32[0], high = uint32[1];
  999. if (!high || high === 0x80000000) {
  1000. return 0.0;
  1001. }
  1002. sign = 1 - (high >>> 31) * 2;
  1003. exp = (high >>> 20) & 0x7ff;
  1004. frac = high & 0xfffff;
  1005. if (exp === 0x7ff) {
  1006. if (frac) {
  1007. return NaN;
  1008. }
  1009. return sign * Infinity;
  1010. }
  1011. exp -= 1023;
  1012. out = (frac | 0x100000) * Math.pow(2, exp - 20);
  1013. out += low * Math.pow(2, exp - 52);
  1014. return sign * out;
  1015. };
  1016. Stream.prototype.peekFloat64 = function(offset, littleEndian) {
  1017. if (offset == null) {
  1018. offset = 0;
  1019. }
  1020. this.peek(8, offset, littleEndian);
  1021. if (float64) {
  1022. return float64[0];
  1023. } else {
  1024. return float64Fallback();
  1025. }
  1026. };
  1027. Stream.prototype.readFloat80 = function(littleEndian) {
  1028. this.read(10, littleEndian);
  1029. return float80();
  1030. };
  1031. float80 = function() {
  1032. var a0, a1, exp, high, low, out, sign;
  1033. high = uint32[0], low = uint32[1];
  1034. a0 = uint8[9];
  1035. a1 = uint8[8];
  1036. sign = 1 - (a0 >>> 7) * 2;
  1037. exp = ((a0 & 0x7F) << 8) | a1;
  1038. if (exp === 0 && low === 0 && high === 0) {
  1039. return 0;
  1040. }
  1041. if (exp === 0x7fff) {
  1042. if (low === 0 && high === 0) {
  1043. return sign * Infinity;
  1044. }
  1045. return NaN;
  1046. }
  1047. exp -= 16383;
  1048. out = low * Math.pow(2, exp - 31);
  1049. out += high * Math.pow(2, exp - 63);
  1050. return sign * out;
  1051. };
  1052. Stream.prototype.peekFloat80 = function(offset, littleEndian) {
  1053. if (offset == null) {
  1054. offset = 0;
  1055. }
  1056. this.peek(10, offset, littleEndian);
  1057. return float80();
  1058. };
  1059. Stream.prototype.readBuffer = function(length) {
  1060. var i, j, ref, result, to;
  1061. result = AVBuffer.allocate(length);
  1062. to = result.data;
  1063. for (i = j = 0, ref = length; j < ref; i = j += 1) {
  1064. to[i] = this.readUInt8();
  1065. }
  1066. return result;
  1067. };
  1068. Stream.prototype.peekBuffer = function(offset, length) {
  1069. var i, j, ref, result, to;
  1070. if (offset == null) {
  1071. offset = 0;
  1072. }
  1073. result = AVBuffer.allocate(length);
  1074. to = result.data;
  1075. for (i = j = 0, ref = length; j < ref; i = j += 1) {
  1076. to[i] = this.peekUInt8(offset + i);
  1077. }
  1078. return result;
  1079. };
  1080. Stream.prototype.readSingleBuffer = function(length) {
  1081. var result;
  1082. result = this.list.first.slice(this.localOffset, length);
  1083. this.advance(result.length);
  1084. return result;
  1085. };
  1086. Stream.prototype.peekSingleBuffer = function(offset, length) {
  1087. var result;
  1088. result = this.list.first.slice(this.localOffset + offset, length);
  1089. return result;
  1090. };
  1091. Stream.prototype.readString = function(length, encoding) {
  1092. if (encoding == null) {
  1093. encoding = 'ascii';
  1094. }
  1095. return decodeString.call(this, 0, length, encoding, true);
  1096. };
  1097. Stream.prototype.peekString = function(offset, length, encoding) {
  1098. if (offset == null) {
  1099. offset = 0;
  1100. }
  1101. if (encoding == null) {
  1102. encoding = 'ascii';
  1103. }
  1104. return decodeString.call(this, offset, length, encoding, false);
  1105. };
  1106. decodeString = function(offset, length, encoding, advance) {
  1107. var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2;
  1108. encoding = encoding.toLowerCase();
  1109. nullEnd = length === null ? 0 : -1;
  1110. if (length == null) {
  1111. length = Infinity;
  1112. }
  1113. end = offset + length;
  1114. result = '';
  1115. switch (encoding) {
  1116. case 'ascii':
  1117. case 'latin1':
  1118. while (offset < end && (c = this.peekUInt8(offset++)) !== nullEnd) {
  1119. result += String.fromCharCode(c);
  1120. }
  1121. break;
  1122. case 'utf8':
  1123. case 'utf-8':
  1124. while (offset < end && (b1 = this.peekUInt8(offset++)) !== nullEnd) {
  1125. if ((b1 & 0x80) === 0) {
  1126. result += String.fromCharCode(b1);
  1127. } else if ((b1 & 0xe0) === 0xc0) {
  1128. b2 = this.peekUInt8(offset++) & 0x3f;
  1129. result += String.fromCharCode(((b1 & 0x1f) << 6) | b2);
  1130. } else if ((b1 & 0xf0) === 0xe0) {
  1131. b2 = this.peekUInt8(offset++) & 0x3f;
  1132. b3 = this.peekUInt8(offset++) & 0x3f;
  1133. result += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3);
  1134. } else if ((b1 & 0xf8) === 0xf0) {
  1135. b2 = this.peekUInt8(offset++) & 0x3f;
  1136. b3 = this.peekUInt8(offset++) & 0x3f;
  1137. b4 = this.peekUInt8(offset++) & 0x3f;
  1138. pt = (((b1 & 0x0f) << 18) | (b2 << 12) | (b3 << 6) | b4) - 0x10000;
  1139. result += String.fromCharCode(0xd800 + (pt >> 10), 0xdc00 + (pt & 0x3ff));
  1140. }
  1141. }
  1142. break;
  1143. case 'utf16-be':
  1144. case 'utf16be':
  1145. case 'utf16le':
  1146. case 'utf16-le':
  1147. case 'utf16bom':
  1148. case 'utf16-bom':
  1149. switch (encoding) {
  1150. case 'utf16be':
  1151. case 'utf16-be':
  1152. littleEndian = false;
  1153. break;
  1154. case 'utf16le':
  1155. case 'utf16-le':
  1156. littleEndian = true;
  1157. break;
  1158. case 'utf16bom':
  1159. case 'utf16-bom':
  1160. if (length < 2 || (bom = this.peekUInt16(offset)) === nullEnd) {
  1161. if (advance) {
  1162. this.advance(offset += 2);
  1163. }
  1164. return result;
  1165. }
  1166. littleEndian = bom === 0xfffe;
  1167. offset += 2;
  1168. }
  1169. while (offset < end && (w1 = this.peekUInt16(offset, littleEndian)) !== nullEnd) {
  1170. offset += 2;
  1171. if (w1 < 0xd800 || w1 > 0xdfff) {
  1172. result += String.fromCharCode(w1);
  1173. } else {
  1174. if (w1 > 0xdbff) {
  1175. throw new Error("Invalid utf16 sequence.");
  1176. }
  1177. w2 = this.peekUInt16(offset, littleEndian);
  1178. if (w2 < 0xdc00 || w2 > 0xdfff) {
  1179. throw new Error("Invalid utf16 sequence.");
  1180. }
  1181. result += String.fromCharCode(w1, w2);
  1182. offset += 2;
  1183. }
  1184. }
  1185. if (w1 === nullEnd) {
  1186. offset += 2;
  1187. }
  1188. break;
  1189. default:
  1190. throw new Error("Unknown encoding: " + encoding);
  1191. }
  1192. if (advance) {
  1193. this.advance(offset);
  1194. }
  1195. return result;
  1196. };
  1197. return Stream;
  1198. })();
  1199. module.exports = Stream;
  1200. }).call(this);
  1201. },{"./buffer":6,"./bufferlist":7,"./underflow":10}],10:[function(require,module,exports){
  1202. // Generated by CoffeeScript 1.10.0
  1203. (function() {
  1204. var UnderflowError,
  1205. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1206. hasProp = {}.hasOwnProperty;
  1207. UnderflowError = (function(superClass) {
  1208. extend(UnderflowError, superClass);
  1209. function UnderflowError() {
  1210. UnderflowError.__super__.constructor.apply(this, arguments);
  1211. this.name = 'UnderflowError';
  1212. this.stack = new Error().stack;
  1213. }
  1214. return UnderflowError;
  1215. })(Error);
  1216. module.exports = UnderflowError;
  1217. }).call(this);
  1218. },{}],11:[function(require,module,exports){
  1219. // Generated by CoffeeScript 1.10.0
  1220. (function() {
  1221. var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError,
  1222. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1223. hasProp = {}.hasOwnProperty;
  1224. EventEmitter = require('./core/events');
  1225. BufferList = require('./core/bufferlist');
  1226. Stream = require('./core/stream');
  1227. Bitstream = require('./core/bitstream');
  1228. UnderflowError = require('./core/underflow');
  1229. Decoder = (function(superClass) {
  1230. var codecs;
  1231. extend(Decoder, superClass);
  1232. function Decoder(demuxer, format) {
  1233. var list;
  1234. this.demuxer = demuxer;
  1235. this.format = format;
  1236. list = new BufferList;
  1237. this.stream = new Stream(list);
  1238. this.bitstream = new Bitstream(this.stream);
  1239. this.receivedFinalBuffer = false;
  1240. this.waiting = false;
  1241. this.demuxer.on('cookie', (function(_this) {
  1242. return function(cookie) {
  1243. var error, error1;
  1244. try {
  1245. return _this.setCookie(cookie);
  1246. } catch (error1) {
  1247. error = error1;
  1248. return _this.emit('error', error);
  1249. }
  1250. };
  1251. })(this));
  1252. this.demuxer.on('data', (function(_this) {
  1253. return function(chunk) {
  1254. list.append(chunk);
  1255. if (_this.waiting) {
  1256. return _this.decode();
  1257. }
  1258. };
  1259. })(this));
  1260. this.demuxer.on('end', (function(_this) {
  1261. return function() {
  1262. _this.receivedFinalBuffer = true;
  1263. if (_this.waiting) {
  1264. return _this.decode();
  1265. }
  1266. };
  1267. })(this));
  1268. this.init();
  1269. }
  1270. Decoder.prototype.init = function() {};
  1271. Decoder.prototype.setCookie = function(cookie) {};
  1272. Decoder.prototype.readChunk = function() {};
  1273. Decoder.prototype.decode = function() {
  1274. var error, error1, offset, packet;
  1275. this.waiting = !this.receivedFinalBuffer;
  1276. offset = this.bitstream.offset();
  1277. try {
  1278. packet = this.readChunk();
  1279. } catch (error1) {
  1280. error = error1;
  1281. if (!(error instanceof UnderflowError)) {
  1282. this.emit('error', error);
  1283. return false;
  1284. }
  1285. }
  1286. if (packet) {
  1287. this.emit('data', packet);
  1288. if (this.receivedFinalBuffer) {
  1289. this.emit('end');
  1290. }
  1291. return true;
  1292. } else if (!this.receivedFinalBuffer) {
  1293. this.bitstream.seek(offset);
  1294. this.waiting = true;
  1295. } else {
  1296. this.emit('end');
  1297. }
  1298. return false;
  1299. };
  1300. Decoder.prototype.seek = function(timestamp) {
  1301. var seekPoint;
  1302. seekPoint = this.demuxer.seek(timestamp);
  1303. this.stream.seek(seekPoint.offset);
  1304. return seekPoint.timestamp;
  1305. };
  1306. codecs = {};
  1307. Decoder.register = function(id, decoder) {
  1308. return codecs[id] = decoder;
  1309. };
  1310. Decoder.find = function(id) {
  1311. return codecs[id] || null;
  1312. };
  1313. return Decoder;
  1314. })(EventEmitter);
  1315. module.exports = Decoder;
  1316. }).call(this);
  1317. },{"./core/bitstream":5,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10}],12:[function(require,module,exports){
  1318. // Generated by CoffeeScript 1.10.0
  1319. (function() {
  1320. var Decoder, LPCMDecoder,
  1321. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  1322. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1323. hasProp = {}.hasOwnProperty;
  1324. Decoder = require('../decoder');
  1325. LPCMDecoder = (function(superClass) {
  1326. extend(LPCMDecoder, superClass);
  1327. function LPCMDecoder() {
  1328. this.readChunk = bind(this.readChunk, this);
  1329. return LPCMDecoder.__super__.constructor.apply(this, arguments);
  1330. }
  1331. Decoder.register('lpcm', LPCMDecoder);
  1332. LPCMDecoder.prototype.readChunk = function() {
  1333. var chunkSize, i, j, k, l, littleEndian, m, n, o, output, ref, ref1, ref2, ref3, ref4, ref5, samples, stream;
  1334. stream = this.stream;
  1335. littleEndian = this.format.littleEndian;
  1336. chunkSize = Math.min(4096, stream.remainingBytes());
  1337. samples = chunkSize / (this.format.bitsPerChannel / 8) | 0;
  1338. if (chunkSize < this.format.bitsPerChannel / 8) {
  1339. return null;
  1340. }
  1341. if (this.format.floatingPoint) {
  1342. switch (this.format.bitsPerChannel) {
  1343. case 32:
  1344. output = new Float32Array(samples);
  1345. for (i = j = 0, ref = samples; j < ref; i = j += 1) {
  1346. output[i] = stream.readFloat32(littleEndian);
  1347. }
  1348. break;
  1349. case 64:
  1350. output = new Float64Array(samples);
  1351. for (i = k = 0, ref1 = samples; k < ref1; i = k += 1) {
  1352. output[i] = stream.readFloat64(littleEndian);
  1353. }
  1354. break;
  1355. default:
  1356. throw new Error('Unsupported bit depth.不支持的位深度');
  1357. }
  1358. } else {
  1359. switch (this.format.bitsPerChannel) {
  1360. case 8:
  1361. output = new Int8Array(samples);
  1362. for (i = l = 0, ref2 = samples; l < ref2; i = l += 1) {
  1363. output[i] = stream.readInt8();
  1364. }
  1365. break;
  1366. case 16:
  1367. output = new Int16Array(samples);
  1368. for (i = m = 0, ref3 = samples; m < ref3; i = m += 1) {
  1369. output[i] = stream.readInt16(littleEndian);
  1370. }
  1371. break;
  1372. case 24:
  1373. output = new Int32Array(samples);
  1374. for (i = n = 0, ref4 = samples; n < ref4; i = n += 1) {
  1375. output[i] = stream.readInt24(littleEndian);
  1376. }
  1377. break;
  1378. case 32:
  1379. output = new Int32Array(samples);
  1380. for (i = o = 0, ref5 = samples; o < ref5; i = o += 1) {
  1381. output[i] = stream.readInt32(littleEndian);
  1382. }
  1383. break;
  1384. default:
  1385. throw new Error('Unsupported bit depth.');
  1386. }
  1387. }
  1388. return output;
  1389. };
  1390. return LPCMDecoder;
  1391. })(Decoder);
  1392. }).call(this);
  1393. },{"../decoder":11}],13:[function(require,module,exports){
  1394. // Generated by CoffeeScript 1.10.0
  1395. (function() {
  1396. var Decoder, XLAWDecoder,
  1397. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  1398. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1399. hasProp = {}.hasOwnProperty;
  1400. Decoder = require('../decoder');
  1401. XLAWDecoder = (function(superClass) {
  1402. var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT;
  1403. extend(XLAWDecoder, superClass);
  1404. function XLAWDecoder() {
  1405. this.readChunk = bind(this.readChunk, this);
  1406. return XLAWDecoder.__super__.constructor.apply(this, arguments);
  1407. }
  1408. Decoder.register('ulaw', XLAWDecoder);
  1409. Decoder.register('alaw', XLAWDecoder);
  1410. SIGN_BIT = 0x80;
  1411. QUANT_MASK = 0xf;
  1412. SEG_SHIFT = 4;
  1413. SEG_MASK = 0x70;
  1414. BIAS = 0x84;
  1415. XLAWDecoder.prototype.init = function() {
  1416. var i, j, k, seg, t, table, val;
  1417. this.format.bitsPerChannel = 16;
  1418. this.table = table = new Int16Array(256);
  1419. if (this.format.formatID === 'ulaw') {
  1420. for (i = j = 0; j < 256; i = ++j) {
  1421. val = ~i;
  1422. t = ((val & QUANT_MASK) << 3) + BIAS;
  1423. t <<= (val & SEG_MASK) >>> SEG_SHIFT;
  1424. table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS;
  1425. }
  1426. } else {
  1427. for (i = k = 0; k < 256; i = ++k) {
  1428. val = i ^ 0x55;
  1429. t = val & QUANT_MASK;
  1430. seg = (val & SEG_MASK) >>> SEG_SHIFT;
  1431. if (seg) {
  1432. t = (t + t + 1 + 32) << (seg + 2);
  1433. } else {
  1434. t = (t + t + 1) << 3;
  1435. }
  1436. table[i] = val & SIGN_BIT ? t : -t;
  1437. }
  1438. }
  1439. };
  1440. XLAWDecoder.prototype.readChunk = function() {
  1441. var i, j, output, ref, samples, stream, table;
  1442. stream = this.stream, table = this.table;
  1443. samples = Math.min(4096, this.stream.remainingBytes());
  1444. if (samples === 0) {
  1445. return;
  1446. }
  1447. output = new Int16Array(samples);
  1448. for (i = j = 0, ref = samples; j < ref; i = j += 1) {
  1449. output[i] = table[stream.readUInt8()];
  1450. }
  1451. return output;
  1452. };
  1453. return XLAWDecoder;
  1454. })(Decoder);
  1455. }).call(this);
  1456. },{"../decoder":11}],14:[function(require,module,exports){
  1457. // Generated by CoffeeScript 1.10.0
  1458. (function() {
  1459. var BufferList, Demuxer, EventEmitter, Stream,
  1460. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1461. hasProp = {}.hasOwnProperty;
  1462. EventEmitter = require('./core/events');
  1463. BufferList = require('./core/bufferlist');
  1464. Stream = require('./core/stream');
  1465. Demuxer = (function(superClass) {
  1466. var formats;
  1467. extend(Demuxer, superClass);
  1468. Demuxer.probe = function(buffer) {
  1469. return false;
  1470. };
  1471. function Demuxer(source, chunk) {
  1472. var list, received;
  1473. list = new BufferList;
  1474. list.append(chunk);
  1475. this.stream = new Stream(list);
  1476. received = false;
  1477. source.on('data', (function(_this) {
  1478. return function(chunk) {
  1479. var e, error;
  1480. received = true;
  1481. list.append(chunk);
  1482. try {
  1483. return _this.readChunk(chunk);
  1484. } catch (error) {
  1485. e = error;
  1486. return _this.emit('error', e);
  1487. }
  1488. };
  1489. })(this));
  1490. source.on('error', (function(_this) {
  1491. return function(err) {
  1492. return _this.emit('error', err);
  1493. };
  1494. })(this));
  1495. source.on('end', (function(_this) {
  1496. return function() {
  1497. if (!received) {
  1498. _this.readChunk(chunk);
  1499. }
  1500. return _this.emit('end');
  1501. };
  1502. })(this));
  1503. this.seekPoints = [];
  1504. this.init();
  1505. }
  1506. Demuxer.prototype.init = function() {};
  1507. Demuxer.prototype.readChunk = function(chunk) {};
  1508. Demuxer.prototype.addSeekPoint = function(offset, timestamp) {
  1509. var index;
  1510. index = this.searchTimestamp(timestamp);
  1511. return this.seekPoints.splice(index, 0, {
  1512. offset: offset,
  1513. timestamp: timestamp
  1514. });
  1515. };
  1516. Demuxer.prototype.searchTimestamp = function(timestamp, backward) {
  1517. var high, low, mid, time;
  1518. low = 0;
  1519. high = this.seekPoints.length;
  1520. if (high > 0 && this.seekPoints[high - 1].timestamp < timestamp) {
  1521. return high;
  1522. }
  1523. while (low < high) {
  1524. mid = (low + high) >> 1;
  1525. time = this.seekPoints[mid].timestamp;
  1526. if (time < timestamp) {
  1527. low = mid + 1;
  1528. } else if (time >= timestamp) {
  1529. high = mid;
  1530. }
  1531. }
  1532. if (high > this.seekPoints.length) {
  1533. high = this.seekPoints.length;
  1534. }
  1535. return high;
  1536. };
  1537. Demuxer.prototype.seek = function(timestamp) {
  1538. var index, seekPoint;
  1539. if (this.format && this.format.framesPerPacket > 0 && this.format.bytesPerPacket > 0) {
  1540. seekPoint = {
  1541. timestamp: timestamp,
  1542. offset: this.format.bytesPerPacket * timestamp / this.format.framesPerPacket
  1543. };
  1544. return seekPoint;
  1545. } else {
  1546. index = this.searchTimestamp(timestamp);
  1547. return this.seekPoints[index];
  1548. }
  1549. };
  1550. formats = [];
  1551. Demuxer.register = function(demuxer) {
  1552. return formats.push(demuxer);
  1553. };
  1554. Demuxer.find = function(buffer) {
  1555. var e, error, format, i, len, offset, stream;
  1556. stream = Stream.fromBuffer(buffer);
  1557. for (i = 0, len = formats.length; i < len; i++) {
  1558. format = formats[i];
  1559. offset = stream.offset;
  1560. try {
  1561. if (format.probe(stream)) {
  1562. return format;
  1563. }
  1564. } catch (error) {
  1565. e = error;
  1566. }
  1567. stream.seek(offset);
  1568. }
  1569. return null;
  1570. };
  1571. return Demuxer;
  1572. })(EventEmitter);
  1573. module.exports = Demuxer;
  1574. }).call(this);
  1575. },{"./core/bufferlist":7,"./core/events":8,"./core/stream":9}],15:[function(require,module,exports){
  1576. // Generated by CoffeeScript 1.10.0
  1577. (function() {
  1578. var AIFFDemuxer, Demuxer,
  1579. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1580. hasProp = {}.hasOwnProperty;
  1581. Demuxer = require('../demuxer');
  1582. AIFFDemuxer = (function(superClass) {
  1583. extend(AIFFDemuxer, superClass);
  1584. function AIFFDemuxer() {
  1585. return AIFFDemuxer.__super__.constructor.apply(this, arguments);
  1586. }
  1587. Demuxer.register(AIFFDemuxer);
  1588. AIFFDemuxer.probe = function(buffer) {
  1589. var ref;
  1590. return buffer.peekString(0, 4) === 'FORM' && ((ref = buffer.peekString(8, 4)) === 'AIFF' || ref === 'AIFC');
  1591. };
  1592. AIFFDemuxer.prototype.readChunk = function() {
  1593. var buffer, format, offset, ref;
  1594. if (!this.readStart && this.stream.available(12)) {
  1595. if (this.stream.readString(4) !== 'FORM') {
  1596. return this.emit('error', 'Invalid AIFF.');
  1597. }
  1598. this.fileSize = this.stream.readUInt32();
  1599. this.fileType = this.stream.readString(4);
  1600. this.readStart = true;
  1601. if ((ref = this.fileType) !== 'AIFF' && ref !== 'AIFC') {
  1602. return this.emit('error', 'Invalid AIFF.');
  1603. }
  1604. }
  1605. while (this.stream.available(1)) {
  1606. if (!this.readHeaders && this.stream.available(8)) {
  1607. this.type = this.stream.readString(4);
  1608. this.len = this.stream.readUInt32();
  1609. }
  1610. switch (this.type) {
  1611. case 'COMM':
  1612. if (!this.stream.available(this.len)) {
  1613. return;
  1614. }
  1615. this.format = {
  1616. formatID: 'lpcm',
  1617. channelsPerFrame: this.stream.readUInt16(),
  1618. sampleCount: this.stream.readUInt32(),
  1619. bitsPerChannel: this.stream.readUInt16(),
  1620. sampleRate: this.stream.readFloat80(),
  1621. framesPerPacket: 1,
  1622. littleEndian: false,
  1623. floatingPoint: false
  1624. };
  1625. this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
  1626. if (this.fileType === 'AIFC') {
  1627. format = this.stream.readString(4);
  1628. this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8;
  1629. this.format.floatingPoint = format === 'fl32' || format === 'fl64';
  1630. if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') {
  1631. format = 'lpcm';
  1632. }
  1633. this.format.formatID = format;
  1634. this.len -= 4;
  1635. }
  1636. this.stream.advance(this.len - 18);
  1637. this.emit('format', this.format);
  1638. this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0);
  1639. break;
  1640. case 'SSND':
  1641. if (!(this.readSSNDHeader && this.stream.available(4))) {
  1642. offset = this.stream.readUInt32();
  1643. this.stream.advance(4);
  1644. this.stream.advance(offset);
  1645. this.readSSNDHeader = true;
  1646. }
  1647. buffer = this.stream.readSingleBuffer(this.len);
  1648. this.len -= buffer.length;
  1649. this.readHeaders = this.len > 0;
  1650. this.emit('data', buffer);
  1651. break;
  1652. default:
  1653. if (!this.stream.available(this.len)) {
  1654. return;
  1655. }
  1656. this.stream.advance(this.len);
  1657. }
  1658. if (this.type !== 'SSND') {
  1659. this.readHeaders = false;
  1660. }
  1661. }
  1662. };
  1663. return AIFFDemuxer;
  1664. })(Demuxer);
  1665. }).call(this);
  1666. },{"../demuxer":14}],16:[function(require,module,exports){
  1667. // Generated by CoffeeScript 1.10.0
  1668. (function() {
  1669. var AUDemuxer, Demuxer,
  1670. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1671. hasProp = {}.hasOwnProperty;
  1672. Demuxer = require('../demuxer');
  1673. AUDemuxer = (function(superClass) {
  1674. var bps, formats;
  1675. extend(AUDemuxer, superClass);
  1676. function AUDemuxer() {
  1677. return AUDemuxer.__super__.constructor.apply(this, arguments);
  1678. }
  1679. Demuxer.register(AUDemuxer);
  1680. AUDemuxer.probe = function(buffer) {
  1681. return buffer.peekString(0, 4) === '.snd';
  1682. };
  1683. bps = [8, 8, 16, 24, 32, 32, 64];
  1684. bps[26] = 8;
  1685. formats = {
  1686. 1: 'ulaw',
  1687. 27: 'alaw'
  1688. };
  1689. AUDemuxer.prototype.readChunk = function() {
  1690. var bytes, dataSize, encoding, size;
  1691. if (!this.readHeader && this.stream.available(24)) {
  1692. if (this.stream.readString(4) !== '.snd') {
  1693. return this.emit('error', 'Invalid AU file.');
  1694. }
  1695. size = this.stream.readUInt32();
  1696. dataSize = this.stream.readUInt32();
  1697. encoding = this.stream.readUInt32();
  1698. this.format = {
  1699. formatID: formats[encoding] || 'lpcm',
  1700. littleEndian: false,
  1701. floatingPoint: encoding === 6 || encoding === 7,
  1702. bitsPerChannel: bps[encoding - 1],
  1703. sampleRate: this.stream.readUInt32(),
  1704. channelsPerFrame: this.stream.readUInt32(),
  1705. framesPerPacket: 1
  1706. };
  1707. if (this.format.bitsPerChannel == null) {
  1708. return this.emit('error', 'Unsupported encoding in AU file.');
  1709. }
  1710. this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
  1711. if (dataSize !== 0xffffffff) {
  1712. bytes = this.format.bitsPerChannel / 8;
  1713. this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
  1714. }
  1715. this.emit('format', this.format);
  1716. this.readHeader = true;
  1717. }
  1718. if (this.readHeader) {
  1719. while (this.stream.available(1)) {
  1720. this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes()));
  1721. }
  1722. }
  1723. };
  1724. return AUDemuxer;
  1725. })(Demuxer);
  1726. }).call(this);
  1727. },{"../demuxer":14}],17:[function(require,module,exports){
  1728. // Generated by CoffeeScript 1.10.0
  1729. (function() {
  1730. var CAFDemuxer, Demuxer, M4ADemuxer,
  1731. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1732. hasProp = {}.hasOwnProperty;
  1733. Demuxer = require('../demuxer');
  1734. M4ADemuxer = require('./m4a');
  1735. CAFDemuxer = (function(superClass) {
  1736. extend(CAFDemuxer, superClass);
  1737. function CAFDemuxer() {
  1738. return CAFDemuxer.__super__.constructor.apply(this, arguments);
  1739. }
  1740. Demuxer.register(CAFDemuxer);
  1741. CAFDemuxer.probe = function(buffer) {
  1742. return buffer.peekString(0, 4) === 'caff';
  1743. };
  1744. CAFDemuxer.prototype.readChunk = function() {
  1745. var buffer, byteOffset, cookie, entries, flags, i, j, k, key, metadata, offset, ref, ref1, sampleOffset, value;
  1746. if (!this.format && this.stream.available(64)) {
  1747. if (this.stream.readString(4) !== 'caff') {
  1748. return this.emit('error', "Invalid CAF, does not begin with 'caff'");
  1749. }
  1750. this.stream.advance(4);
  1751. if (this.stream.readString(4) !== 'desc') {
  1752. return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'");
  1753. }
  1754. if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) {
  1755. return this.emit('error', "Invalid 'desc' size, should be 32");
  1756. }
  1757. this.format = {};
  1758. this.format.sampleRate = this.stream.readFloat64();
  1759. this.format.formatID = this.stream.readString(4);
  1760. flags = this.stream.readUInt32();
  1761. if (this.format.formatID === 'lpcm') {
  1762. this.format.floatingPoint = Boolean(flags & 1);
  1763. this.format.littleEndian = Boolean(flags & 2);
  1764. }
  1765. this.format.bytesPerPacket = this.stream.readUInt32();
  1766. this.format.framesPerPacket = this.stream.readUInt32();
  1767. this.format.channelsPerFrame = this.stream.readUInt32();
  1768. this.format.bitsPerChannel = this.stream.readUInt32();
  1769. this.emit('format', this.format);
  1770. }
  1771. while (this.stream.available(1)) {
  1772. if (!this.headerCache) {
  1773. this.headerCache = {
  1774. type: this.stream.readString(4),
  1775. oversize: this.stream.readUInt32() !== 0,
  1776. size: this.stream.readUInt32()
  1777. };
  1778. if (this.headerCache.oversize) {
  1779. return this.emit('error', "Holy Shit, an oversized file, not supported in JS");
  1780. }
  1781. }
  1782. switch (this.headerCache.type) {
  1783. case 'kuki':
  1784. if (this.stream.available(this.headerCache.size)) {
  1785. if (this.format.formatID === 'aac ') {
  1786. console.log('aac')
  1787. offset = this.stream.offset + this.headerCache.size;
  1788. if (cookie = M4ADemuxer.readEsds(this.stream)) {
  1789. this.emit('cookie', cookie);
  1790. }
  1791. this.stream.seek(offset);
  1792. } else {
  1793. buffer = this.stream.readBuffer(this.headerCache.size);
  1794. this.emit('cookie', buffer);
  1795. }
  1796. this.headerCache = null;
  1797. }
  1798. break;
  1799. case 'pakt':
  1800. if (this.stream.available(this.headerCache.size)) {
  1801. if (this.stream.readUInt32() !== 0) {
  1802. return this.emit('error', 'Sizes greater than 32 bits are not supported.');
  1803. }
  1804. this.numPackets = this.stream.readUInt32();
  1805. if (this.stream.readUInt32() !== 0) {
  1806. return this.emit('error', 'Sizes greater than 32 bits are not supported.');
  1807. }
  1808. this.numFrames = this.stream.readUInt32();
  1809. this.primingFrames = this.stream.readUInt32();
  1810. this.remainderFrames = this.stream.readUInt32();
  1811. this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
  1812. this.sentDuration = true;
  1813. byteOffset = 0;
  1814. sampleOffset = 0;
  1815. for (i = j = 0, ref = this.numPackets; j < ref; i = j += 1) {
  1816. this.addSeekPoint(byteOffset, sampleOffset);
  1817. byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream);
  1818. sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream);
  1819. }
  1820. this.headerCache = null;
  1821. }
  1822. break;
  1823. case 'info':
  1824. entries = this.stream.readUInt32();
  1825. metadata = {};
  1826. for (i = k = 0, ref1 = entries; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) {
  1827. key = this.stream.readString(null);
  1828. value = this.stream.readString(null);
  1829. metadata[key] = value;
  1830. }
  1831. this.emit('metadata', metadata);
  1832. this.headerCache = null;
  1833. break;
  1834. case 'data':
  1835. if (!this.sentFirstDataChunk) {
  1836. this.stream.advance(4);
  1837. this.headerCache.size -= 4;
  1838. if (this.format.bytesPerPacket !== 0 && !this.sentDuration) {
  1839. this.numFrames = this.headerCache.size / this.format.bytesPerPacket;
  1840. this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
  1841. }
  1842. this.sentFirstDataChunk = true;
  1843. }
  1844. buffer = this.stream.readSingleBuffer(this.headerCache.size);
  1845. this.headerCache.size -= buffer.length;
  1846. this.emit('data', buffer);
  1847. if (this.headerCache.size <= 0) {
  1848. this.headerCache = null;
  1849. }
  1850. break;
  1851. default:
  1852. if (this.stream.available(this.headerCache.size)) {
  1853. this.stream.advance(this.headerCache.size);
  1854. this.headerCache = null;
  1855. }
  1856. }
  1857. }
  1858. };
  1859. return CAFDemuxer;
  1860. })(Demuxer);
  1861. }).call(this);
  1862. },{"../demuxer":14,"./m4a":18}],18:[function(require,module,exports){
  1863. // Generated by CoffeeScript 1.10.0
  1864. (function() {
  1865. var Demuxer, M4ADemuxer,
  1866. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  1867. hasProp = {}.hasOwnProperty,
  1868. indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  1869. Demuxer = require('../demuxer');
  1870. M4ADemuxer = (function(superClass) {
  1871. var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string;
  1872. extend(M4ADemuxer, superClass);
  1873. function M4ADemuxer() {
  1874. return M4ADemuxer.__super__.constructor.apply(this, arguments);
  1875. }
  1876. Demuxer.register(M4ADemuxer);
  1877. TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt '];
  1878. M4ADemuxer.probe = function(buffer) {
  1879. var ref;
  1880. return buffer.peekString(4, 4) === 'ftyp' && (ref = buffer.peekString(8, 4), indexOf.call(TYPES, ref) >= 0);
  1881. };
  1882. M4ADemuxer.prototype.init = function() {
  1883. this.atoms = [];
  1884. this.offsets = [];
  1885. this.track = null;
  1886. return this.tracks = [];
  1887. };
  1888. atoms = {};
  1889. containers = {};
  1890. atom = function(name, fn) {
  1891. var c, container, k, len1, ref;
  1892. c = [];
  1893. ref = name.split('.').slice(0, -1);
  1894. for (k = 0, len1 = ref.length; k < len1; k++) {
  1895. container = ref[k];
  1896. c.push(container);
  1897. containers[c.join('.')] = true;
  1898. }
  1899. if (atoms[name] == null) {
  1900. atoms[name] = {};
  1901. }
  1902. return atoms[name].fn = fn;
  1903. };
  1904. after = function(name, fn) {
  1905. if (atoms[name] == null) {
  1906. atoms[name] = {};
  1907. }
  1908. return atoms[name].after = fn;
  1909. };
  1910. M4ADemuxer.prototype.readChunk = function() {
  1911. var handler, path, type;
  1912. this["break"] = false;
  1913. while (this.stream.available(1) && !this["break"]) {
  1914. if (!this.readHeaders) {
  1915. if (!this.stream.available(8)) {
  1916. return;
  1917. }
  1918. this.len = this.stream.readUInt32() - 8;
  1919. this.type = this.stream.readString(4);
  1920. if (this.len === 0) {
  1921. continue;
  1922. }
  1923. this.atoms.push(this.type);
  1924. this.offsets.push(this.stream.offset + this.len);
  1925. this.readHeaders = true;
  1926. }
  1927. path = this.atoms.join('.');
  1928. handler = atoms[path];
  1929. if (handler != null ? handler.fn : void 0) {
  1930. if (!(this.stream.available(this.len) || path === 'mdat')) {
  1931. return;
  1932. }
  1933. handler.fn.call(this);
  1934. if (path in containers) {
  1935. this.readHeaders = false;
  1936. }
  1937. } else if (path in containers) {
  1938. this.readHeaders = false;
  1939. } else {
  1940. if (!this.stream.available(this.len)) {
  1941. return;
  1942. }
  1943. this.stream.advance(this.len);
  1944. }
  1945. while (this.stream.offset >= this.offsets[this.offsets.length - 1]) {
  1946. handler = atoms[this.atoms.join('.')];
  1947. if (handler != null ? handler.after : void 0) {
  1948. handler.after.call(this);
  1949. }
  1950. type = this.atoms.pop();
  1951. this.offsets.pop();
  1952. this.readHeaders = false;
  1953. }
  1954. }
  1955. };
  1956. atom('ftyp', function() {
  1957. var ref;
  1958. if (ref = this.stream.readString(4), indexOf.call(TYPES, ref) < 0) {
  1959. return this.emit('error', 'Not a valid M4A file.');
  1960. }
  1961. return this.stream.advance(this.len - 4);
  1962. });
  1963. atom('moov.trak', function() {
  1964. this.track = {};
  1965. return this.tracks.push(this.track);
  1966. });
  1967. atom('moov.trak.tkhd', function() {
  1968. this.stream.advance(4);
  1969. this.stream.advance(8);
  1970. this.track.id = this.stream.readUInt32();
  1971. return this.stream.advance(this.len - 16);
  1972. });
  1973. atom('moov.trak.mdia.hdlr', function() {
  1974. this.stream.advance(4);
  1975. this.stream.advance(4);
  1976. this.track.type = this.stream.readString(4);
  1977. this.stream.advance(12);
  1978. return this.stream.advance(this.len - 24);
  1979. });
  1980. atom('moov.trak.mdia.mdhd', function() {
  1981. this.stream.advance(4);
  1982. this.stream.advance(8);
  1983. this.track.timeScale = this.stream.readUInt32();
  1984. this.track.duration = this.stream.readUInt32();
  1985. return this.stream.advance(4);
  1986. });
  1987. BITS_PER_CHANNEL = {
  1988. ulaw: 8,
  1989. alaw: 8,
  1990. in24: 24,
  1991. in32: 32,
  1992. fl32: 32,
  1993. fl64: 64
  1994. };
  1995. atom('moov.trak.mdia.minf.stbl.stsd', function() {
  1996. var format, numEntries, ref, ref1, version;
  1997. this.stream.advance(4);
  1998. numEntries = this.stream.readUInt32();
  1999. if (this.track.type !== 'soun') {
  2000. return this.stream.advance(this.len - 8);
  2001. }
  2002. if (numEntries !== 1) {
  2003. return this.emit('error', "Only expecting one entry in sample description atom!");
  2004. }
  2005. this.stream.advance(4);
  2006. format = this.track.format = {};
  2007. format.formatID = this.stream.readString(4);
  2008. this.stream.advance(6);
  2009. this.stream.advance(2);
  2010. version = this.stream.readUInt16();
  2011. this.stream.advance(6);
  2012. format.channelsPerFrame = this.stream.readUInt16();
  2013. format.bitsPerChannel = this.stream.readUInt16();
  2014. this.stream.advance(4);
  2015. format.sampleRate = this.stream.readUInt16();
  2016. this.stream.advance(2);
  2017. if (version === 1) {
  2018. format.framesPerPacket = this.stream.readUInt32();
  2019. this.stream.advance(4);
  2020. format.bytesPerFrame = this.stream.readUInt32();
  2021. this.stream.advance(4);
  2022. } else if (version !== 0) {
  2023. this.emit('error', 'Unknown version in stsd atom');
  2024. }
  2025. if (BITS_PER_CHANNEL[format.formatID] != null) {
  2026. format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID];
  2027. }
  2028. format.floatingPoint = (ref = format.formatID) === 'fl32' || ref === 'fl64';
  2029. format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8;
  2030. if ((ref1 = format.formatID) === 'twos' || ref1 === 'sowt' || ref1 === 'in24' || ref1 === 'in32' || ref1 === 'fl32' || ref1 === 'fl64' || ref1 === 'raw ' || ref1 === 'NONE') {
  2031. return format.formatID = 'lpcm';
  2032. }
  2033. });
  2034. atom('moov.trak.mdia.minf.stbl.stsd.alac', function() {
  2035. this.stream.advance(4);
  2036. return this.track.cookie = this.stream.readBuffer(this.len - 4);
  2037. });
  2038. atom('moov.trak.mdia.minf.stbl.stsd.esds', function() {
  2039. var offset;
  2040. offset = this.stream.offset + this.len;
  2041. this.track.cookie = M4ADemuxer.readEsds(this.stream);
  2042. return this.stream.seek(offset);
  2043. });
  2044. atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() {
  2045. return this.track.format.littleEndian = !!this.stream.readUInt16();
  2046. });
  2047. M4ADemuxer.readDescrLen = function(stream) {
  2048. var c, count, len;
  2049. len = 0;
  2050. count = 4;
  2051. while (count--) {
  2052. c = stream.readUInt8();
  2053. len = (len << 7) | (c & 0x7f);
  2054. if (!(c & 0x80)) {
  2055. break;
  2056. }
  2057. }
  2058. return len;
  2059. };
  2060. M4ADemuxer.readEsds = function(stream) {
  2061. var codec_id, flags, len, tag;
  2062. stream.advance(4);
  2063. tag = stream.readUInt8();
  2064. len = M4ADemuxer.readDescrLen(stream);
  2065. if (tag === 0x03) {
  2066. stream.advance(2);
  2067. flags = stream.readUInt8();
  2068. if (flags & 0x80) {
  2069. stream.advance(2);
  2070. }
  2071. if (flags & 0x40) {
  2072. stream.advance(stream.readUInt8());
  2073. }
  2074. if (flags & 0x20) {
  2075. stream.advance(2);
  2076. }
  2077. } else {
  2078. stream.advance(2);
  2079. }
  2080. tag = stream.readUInt8();
  2081. len = M4ADemuxer.readDescrLen(stream);
  2082. if (tag === 0x04) {
  2083. codec_id = stream.readUInt8();
  2084. stream.advance(1);
  2085. stream.advance(3);
  2086. stream.advance(4);
  2087. stream.advance(4);
  2088. tag = stream.readUInt8();
  2089. len = M4ADemuxer.readDescrLen(stream);
  2090. if (tag === 0x05) {
  2091. return stream.readBuffer(len);
  2092. }
  2093. }
  2094. return null;
  2095. };
  2096. atom('moov.trak.mdia.minf.stbl.stts', function() {
  2097. var entries, i, k, ref;
  2098. this.stream.advance(4);
  2099. entries = this.stream.readUInt32();
  2100. this.track.stts = [];
  2101. for (i = k = 0, ref = entries; k < ref; i = k += 1) {
  2102. this.track.stts[i] = {
  2103. count: this.stream.readUInt32(),
  2104. duration: this.stream.readUInt32()
  2105. };
  2106. }
  2107. return this.setupSeekPoints();
  2108. });
  2109. atom('moov.trak.mdia.minf.stbl.stsc', function() {
  2110. var entries, i, k, ref;
  2111. this.stream.advance(4);
  2112. entries = this.stream.readUInt32();
  2113. this.track.stsc = [];
  2114. for (i = k = 0, ref = entries; k < ref; i = k += 1) {
  2115. this.track.stsc[i] = {
  2116. first: this.stream.readUInt32(),
  2117. count: this.stream.readUInt32(),
  2118. id: this.stream.readUInt32()
  2119. };
  2120. }
  2121. return this.setupSeekPoints();
  2122. });
  2123. atom('moov.trak.mdia.minf.stbl.stsz', function() {
  2124. var entries, i, k, ref;
  2125. this.stream.advance(4);
  2126. this.track.sampleSize = this.stream.readUInt32();
  2127. entries = this.stream.readUInt32();
  2128. if (this.track.sampleSize === 0 && entries > 0) {
  2129. this.track.sampleSizes = [];
  2130. for (i = k = 0, ref = entries; k < ref; i = k += 1) {
  2131. this.track.sampleSizes[i] = this.stream.readUInt32();
  2132. }
  2133. }
  2134. return this.setupSeekPoints();
  2135. });
  2136. atom('moov.trak.mdia.minf.stbl.stco', function() {
  2137. var entries, i, k, ref;
  2138. this.stream.advance(4);
  2139. entries = this.stream.readUInt32();
  2140. this.track.chunkOffsets = [];
  2141. for (i = k = 0, ref = entries; k < ref; i = k += 1) {
  2142. this.track.chunkOffsets[i] = this.stream.readUInt32();
  2143. }
  2144. return this.setupSeekPoints();
  2145. });
  2146. atom('moov.trak.tref.chap', function() {
  2147. var entries, i, k, ref;
  2148. entries = this.len >> 2;
  2149. this.track.chapterTracks = [];
  2150. for (i = k = 0, ref = entries; k < ref; i = k += 1) {
  2151. this.track.chapterTracks[i] = this.stream.readUInt32();
  2152. }
  2153. });
  2154. M4ADemuxer.prototype.setupSeekPoints = function() {
  2155. var i, j, k, l, len1, offset, position, ref, ref1, results, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp;
  2156. if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) {
  2157. return;
  2158. }
  2159. stscIndex = 0;
  2160. sttsIndex = 0;
  2161. sttsIndex = 0;
  2162. sttsSample = 0;
  2163. sampleIndex = 0;
  2164. offset = 0;
  2165. timestamp = 0;
  2166. this.track.seekPoints = [];
  2167. ref = this.track.chunkOffsets;
  2168. results = [];
  2169. for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
  2170. position = ref[i];
  2171. for (j = l = 0, ref1 = this.track.stsc[stscIndex].count; l < ref1; j = l += 1) {
  2172. this.track.seekPoints.push({
  2173. offset: offset,
  2174. position: position,
  2175. timestamp: timestamp
  2176. });
  2177. size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++];
  2178. offset += size;
  2179. position += size;
  2180. timestamp += this.track.stts[sttsIndex].duration;
  2181. if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) {
  2182. sttsSample = 0;
  2183. sttsIndex++;
  2184. }
  2185. }
  2186. if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) {
  2187. results.push(stscIndex++);
  2188. } else {
  2189. results.push(void 0);
  2190. }
  2191. }
  2192. return results;
  2193. };
  2194. after('moov', function() {
  2195. var k, len1, ref, track;
  2196. if (this.mdatOffset != null) {
  2197. this.stream.seek(this.mdatOffset - 8);
  2198. }
  2199. ref = this.tracks;
  2200. for (k = 0, len1 = ref.length; k < len1; k++) {
  2201. track = ref[k];
  2202. if (!(track.type === 'soun')) {
  2203. continue;
  2204. }
  2205. this.track = track;
  2206. break;
  2207. }
  2208. if (this.track.type !== 'soun') {
  2209. this.track = null;
  2210. return this.emit('error', 'No audio tracks in m4a file.');
  2211. }
  2212. this.emit('format', this.track.format);
  2213. this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0);
  2214. if (this.track.cookie) {
  2215. this.emit('cookie', this.track.cookie);
  2216. }
  2217. return this.seekPoints = this.track.seekPoints;
  2218. });
  2219. atom('mdat', function() {
  2220. var bytes, chunkSize, k, length, numSamples, offset, ref, sample, size;
  2221. if (!this.startedData) {
  2222. if (this.mdatOffset == null) {
  2223. this.mdatOffset = this.stream.offset;
  2224. }
  2225. if (this.tracks.length === 0) {
  2226. bytes = Math.min(this.stream.remainingBytes(), this.len);
  2227. this.stream.advance(bytes);
  2228. this.len -= bytes;
  2229. return;
  2230. }
  2231. this.chunkIndex = 0;
  2232. this.stscIndex = 0;
  2233. this.sampleIndex = 0;
  2234. this.tailOffset = 0;
  2235. this.tailSamples = 0;
  2236. this.startedData = true;
  2237. }
  2238. if (!this.readChapters) {
  2239. this.readChapters = this.parseChapters();
  2240. if (this["break"] = !this.readChapters) {
  2241. return;
  2242. }
  2243. this.stream.seek(this.mdatOffset);
  2244. }
  2245. offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset;
  2246. length = 0;
  2247. if (!this.stream.available(offset - this.stream.offset)) {
  2248. this["break"] = true;
  2249. return;
  2250. }
  2251. this.stream.seek(offset);
  2252. while (this.chunkIndex < this.track.chunkOffsets.length) {
  2253. numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples;
  2254. chunkSize = 0;
  2255. for (sample = k = 0, ref = numSamples; k < ref; sample = k += 1) {
  2256. size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex];
  2257. if (!this.stream.available(length + size)) {
  2258. break;
  2259. }
  2260. length += size;
  2261. chunkSize += size;
  2262. this.sampleIndex++;
  2263. }
  2264. if (sample < numSamples) {
  2265. this.tailOffset += chunkSize;
  2266. this.tailSamples += sample;
  2267. break;
  2268. } else {
  2269. this.chunkIndex++;
  2270. this.tailOffset = 0;
  2271. this.tailSamples = 0;
  2272. if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) {
  2273. this.stscIndex++;
  2274. }
  2275. if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) {
  2276. break;
  2277. }
  2278. }
  2279. }
  2280. if (length > 0) {
  2281. this.emit('data', this.stream.readBuffer(length));
  2282. return this["break"] = this.chunkIndex === this.track.chunkOffsets.length;
  2283. } else {
  2284. return this["break"] = true;
  2285. }
  2286. });
  2287. M4ADemuxer.prototype.parseChapters = function() {
  2288. var bom, id, k, len, len1, nextTimestamp, point, ref, ref1, ref2, ref3, title, track;
  2289. if (!(((ref = this.track.chapterTracks) != null ? ref.length : void 0) > 0)) {
  2290. return true;
  2291. }
  2292. id = this.track.chapterTracks[0];
  2293. ref1 = this.tracks;
  2294. for (k = 0, len1 = ref1.length; k < len1; k++) {
  2295. track = ref1[k];
  2296. if (track.id === id) {
  2297. break;
  2298. }
  2299. }
  2300. if (track.id !== id) {
  2301. this.emit('error', 'Chapter track does not exist.');
  2302. }
  2303. if (this.chapters == null) {
  2304. this.chapters = [];
  2305. }
  2306. while (this.chapters.length < track.seekPoints.length) {
  2307. point = track.seekPoints[this.chapters.length];
  2308. if (!this.stream.available(point.position - this.stream.offset + 32)) {
  2309. return false;
  2310. }
  2311. this.stream.seek(point.position);
  2312. len = this.stream.readUInt16();
  2313. title = null;
  2314. if (!this.stream.available(len)) {
  2315. return false;
  2316. }
  2317. if (len > 2) {
  2318. bom = this.stream.peekUInt16();
  2319. if (bom === 0xfeff || bom === 0xfffe) {
  2320. title = this.stream.readString(len, 'utf16-bom');
  2321. }
  2322. }
  2323. if (title == null) {
  2324. title = this.stream.readString(len, 'utf8');
  2325. }
  2326. nextTimestamp = (ref2 = (ref3 = track.seekPoints[this.chapters.length + 1]) != null ? ref3.timestamp : void 0) != null ? ref2 : track.duration;
  2327. this.chapters.push({
  2328. title: title,
  2329. timestamp: point.timestamp / track.timeScale * 1000 | 0,
  2330. duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0
  2331. });
  2332. }
  2333. this.emit('chapters', this.chapters);
  2334. return true;
  2335. };
  2336. atom('moov.udta.meta', function() {
  2337. this.metadata = {};
  2338. return this.stream.advance(4);
  2339. });
  2340. after('moov.udta.meta', function() {
  2341. return this.emit('metadata', this.metadata);
  2342. });
  2343. meta = function(field, name, fn) {
  2344. return atom("moov.udta.meta.ilst." + field + ".data", function() {
  2345. this.stream.advance(8);
  2346. this.len -= 8;
  2347. return fn.call(this, name);
  2348. });
  2349. };
  2350. string = function(field) {
  2351. return this.metadata[field] = this.stream.readString(this.len, 'utf8');
  2352. };
  2353. meta('©alb', 'album', string);
  2354. meta('©arg', 'arranger', string);
  2355. meta('©art', 'artist', string);
  2356. meta('©ART', 'artist', string);
  2357. meta('aART', 'albumArtist', string);
  2358. meta('catg', 'category', string);
  2359. meta('©com', 'composer', string);
  2360. meta('©cpy', 'copyright', string);
  2361. meta('cprt', 'copyright', string);
  2362. meta('©cmt', 'comments', string);
  2363. meta('©day', 'releaseDate', string);
  2364. meta('desc', 'description', string);
  2365. meta('©gen', 'genre', string);
  2366. meta('©grp', 'grouping', string);
  2367. meta('©isr', 'ISRC', string);
  2368. meta('keyw', 'keywords', string);
  2369. meta('©lab', 'recordLabel', string);
  2370. meta('ldes', 'longDescription', string);
  2371. meta('©lyr', 'lyrics', string);
  2372. meta('©nam', 'title', string);
  2373. meta('©phg', 'recordingCopyright', string);
  2374. meta('©prd', 'producer', string);
  2375. meta('©prf', 'performers', string);
  2376. meta('purd', 'purchaseDate', string);
  2377. meta('purl', 'podcastURL', string);
  2378. meta('©swf', 'songwriter', string);
  2379. meta('©too', 'encoder', string);
  2380. meta('©wrt', 'composer', string);
  2381. meta('covr', 'coverArt', function(field) {
  2382. return this.metadata[field] = this.stream.readBuffer(this.len);
  2383. });
  2384. genres = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall"];
  2385. meta('gnre', 'genre', function(field) {
  2386. return this.metadata[field] = genres[this.stream.readUInt16() - 1];
  2387. });
  2388. meta('tmpo', 'tempo', function(field) {
  2389. return this.metadata[field] = this.stream.readUInt16();
  2390. });
  2391. meta('rtng', 'rating', function(field) {
  2392. var rating;
  2393. rating = this.stream.readUInt8();
  2394. return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None';
  2395. });
  2396. diskTrack = function(field) {
  2397. this.stream.advance(2);
  2398. this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16();
  2399. return this.stream.advance(this.len - 6);
  2400. };
  2401. meta('disk', 'diskNumber', diskTrack);
  2402. meta('trkn', 'trackNumber', diskTrack);
  2403. bool = function(field) {
  2404. return this.metadata[field] = this.stream.readUInt8() === 1;
  2405. };
  2406. meta('cpil', 'compilation', bool);
  2407. meta('pcst', 'podcast', bool);
  2408. meta('pgap', 'gapless', bool);
  2409. return M4ADemuxer;
  2410. })(Demuxer);
  2411. module.exports = M4ADemuxer;
  2412. }).call(this);
  2413. },{"../demuxer":14}],19:[function(require,module,exports){
  2414. // Generated by CoffeeScript 1.10.0
  2415. (function() {
  2416. var Demuxer, WAVEDemuxer,
  2417. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2418. hasProp = {}.hasOwnProperty;
  2419. Demuxer = require('../demuxer');
  2420. WAVEDemuxer = (function(superClass) {
  2421. var formats;
  2422. extend(WAVEDemuxer, superClass);
  2423. function WAVEDemuxer() {
  2424. return WAVEDemuxer.__super__.constructor.apply(this, arguments);
  2425. }
  2426. Demuxer.register(WAVEDemuxer);
  2427. WAVEDemuxer.probe = function(buffer) {
  2428. return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE';
  2429. };
  2430. formats = {
  2431. 0x0001: 'lpcm',
  2432. 0x0003: 'lpcm',
  2433. 0x0006: 'alaw',
  2434. 0x0007: 'ulaw'
  2435. };
  2436. WAVEDemuxer.prototype.readChunk = function() {
  2437. var buffer, bytes, encoding;
  2438. if (!this.readStart && this.stream.available(12)) {
  2439. if (this.stream.readString(4) !== 'RIFF') {
  2440. return this.emit('error', 'Invalid WAV file.');
  2441. }
  2442. this.fileSize = this.stream.readUInt32(true);
  2443. this.readStart = true;
  2444. if (this.stream.readString(4) !== 'WAVE') {
  2445. return this.emit('error', 'Invalid WAV file.');
  2446. }
  2447. }
  2448. while (this.stream.available(1)) {
  2449. if (!this.readHeaders && this.stream.available(8)) {
  2450. this.type = this.stream.readString(4);
  2451. this.len = this.stream.readUInt32(true);
  2452. }
  2453. switch (this.type) {
  2454. case 'fmt ':
  2455. encoding = this.stream.readUInt16(true);
  2456. if (!(encoding in formats)) {
  2457. return this.emit('error', 'Unsupported format in WAV file.');
  2458. }
  2459. this.format = {
  2460. formatID: formats[encoding],
  2461. floatingPoint: encoding === 0x0003,
  2462. littleEndian: formats[encoding] === 'lpcm',
  2463. channelsPerFrame: this.stream.readUInt16(true),
  2464. sampleRate: this.stream.readUInt32(true),
  2465. framesPerPacket: 1
  2466. };
  2467. this.stream.advance(4);
  2468. this.stream.advance(2);
  2469. this.format.bitsPerChannel = this.stream.readUInt16(true);
  2470. this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
  2471. this.emit('format', this.format);
  2472. this.stream.advance(this.len - 16);
  2473. break;
  2474. case 'data':
  2475. if (!this.sentDuration) {
  2476. bytes = this.format.bitsPerChannel / 8;
  2477. this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
  2478. this.sentDuration = true;
  2479. }
  2480. buffer = this.stream.readSingleBuffer(this.len);
  2481. this.len -= buffer.length;
  2482. this.readHeaders = this.len > 0;
  2483. this.emit('data', buffer);
  2484. break;
  2485. default:
  2486. if (!this.stream.available(this.len)) {
  2487. return;
  2488. }
  2489. this.stream.advance(this.len);
  2490. }
  2491. if (this.type !== 'data') {
  2492. this.readHeaders = false;
  2493. }
  2494. }
  2495. };
  2496. return WAVEDemuxer;
  2497. })(Demuxer);
  2498. }).call(this);
  2499. },{"../demuxer":14}],20:[function(require,module,exports){
  2500. // Generated by CoffeeScript 1.10.0
  2501. (function() {
  2502. var AudioDevice, EventEmitter,
  2503. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  2504. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2505. hasProp = {}.hasOwnProperty;
  2506. EventEmitter = require('./core/events');
  2507. AudioDevice = (function(superClass) {
  2508. var devices;
  2509. extend(AudioDevice, superClass);
  2510. function AudioDevice(sampleRate1, channels1) {
  2511. this.sampleRate = sampleRate1;
  2512. this.channels = channels1;
  2513. this.updateTime = bind(this.updateTime, this);
  2514. this.playing = false;
  2515. this.currentTime = 0;
  2516. this._lastTime = 0;
  2517. }
  2518. AudioDevice.prototype.start = function() {
  2519. if (this.playing) {
  2520. return;
  2521. }
  2522. this.playing = true;
  2523. if (this.device == null) {
  2524. this.device = AudioDevice.create(this.sampleRate, this.channels);
  2525. }
  2526. if (!this.device) {
  2527. throw new Error("No supported audio device found.");
  2528. }
  2529. this._lastTime = this.device.getDeviceTime();
  2530. this._timer = setInterval(this.updateTime, 200);
  2531. return this.device.on('refill', this.refill = (function(_this) {
  2532. return function(buffer) {
  2533. return _this.emit('refill', buffer);
  2534. };
  2535. })(this));
  2536. };
  2537. AudioDevice.prototype.stop = function() {
  2538. if (!this.playing) {
  2539. return;
  2540. }
  2541. this.playing = false;
  2542. this.device.off('refill', this.refill);
  2543. return clearInterval(this._timer);
  2544. };
  2545. AudioDevice.prototype.destroy = function() {
  2546. var ref;
  2547. this.stop();
  2548. return (ref = this.device) != null ? ref.destroy() : void 0;
  2549. };
  2550. AudioDevice.prototype.seek = function(currentTime) {
  2551. this.currentTime = currentTime;
  2552. if (this.playing) {
  2553. this._lastTime = this.device.getDeviceTime();
  2554. }
  2555. return this.emit('timeUpdate', this.currentTime);
  2556. };
  2557. AudioDevice.prototype.updateTime = function() {
  2558. var time;
  2559. time = this.device.getDeviceTime();
  2560. this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0;
  2561. this._lastTime = time;
  2562. return this.emit('timeUpdate', this.currentTime);
  2563. };
  2564. devices = [];
  2565. AudioDevice.register = function(device) {
  2566. return devices.push(device);
  2567. };
  2568. AudioDevice.create = function(sampleRate, channels) {
  2569. var device, i, len;
  2570. for (i = 0, len = devices.length; i < len; i++) {
  2571. device = devices[i];
  2572. if (device.supported) {
  2573. return new device(sampleRate, channels);
  2574. }
  2575. }
  2576. return null;
  2577. };
  2578. return AudioDevice;
  2579. })(EventEmitter);
  2580. module.exports = AudioDevice;
  2581. }).call(this);
  2582. },{"./core/events":8}],21:[function(require,module,exports){
  2583. // Generated by CoffeeScript 1.10.0
  2584. (function() {
  2585. var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice,
  2586. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  2587. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2588. hasProp = {}.hasOwnProperty;
  2589. EventEmitter = require('../core/events');
  2590. AudioDevice = require('../device');
  2591. AVBuffer = require('../core/buffer');
  2592. MozillaAudioDevice = (function(superClass) {
  2593. var createTimer, destroyTimer;
  2594. extend(MozillaAudioDevice, superClass);
  2595. AudioDevice.register(MozillaAudioDevice);
  2596. MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio;
  2597. function MozillaAudioDevice(sampleRate, channels) {
  2598. this.sampleRate = sampleRate;
  2599. this.channels = channels;
  2600. this.refill = bind(this.refill, this);
  2601. this.audio = new Audio;
  2602. this.audio.mozSetup(this.channels, this.sampleRate);
  2603. this.writePosition = 0;
  2604. this.prebufferSize = this.sampleRate / 2;
  2605. this.tail = null;
  2606. this.timer = createTimer(this.refill, 100);
  2607. console.log('createTimer>>>',createTimer)
  2608. }
  2609. MozillaAudioDevice.prototype.refill = function() {
  2610. var available, buffer, currentPosition, written;
  2611. if (this.tail) {
  2612. written = this.audio.mozWriteAudio(this.tail);
  2613. this.writePosition += written;
  2614. if (this.writePosition < this.tail.length) {
  2615. this.tail = this.tail.subarray(written);
  2616. } else {
  2617. this.tail = null;
  2618. }
  2619. }
  2620. currentPosition = this.audio.mozCurrentSampleOffset();
  2621. available = currentPosition + this.prebufferSize - this.writePosition;
  2622. if (available > 0) {
  2623. buffer = new Float32Array(available);
  2624. this.emit('refill', buffer);
  2625. written = this.audio.mozWriteAudio(buffer);
  2626. if (written < buffer.length) {
  2627. this.tail = buffer.subarray(written);
  2628. }
  2629. this.writePosition += written;
  2630. }
  2631. };
  2632. MozillaAudioDevice.prototype.destroy = function() {
  2633. return destroyTimer(this.timer);
  2634. };
  2635. MozillaAudioDevice.prototype.getDeviceTime = function() {
  2636. return this.audio.mozCurrentSampleOffset() / this.channels;
  2637. };
  2638. createTimer = function(fn, interval) {
  2639. var url, worker;
  2640. url = AVBuffer.makeBlobURL("setInterval(function() { postMessage('ping'); }, " + interval + ");");
  2641. if (url == null) {
  2642. return setInterval(fn, interval);
  2643. }
  2644. worker = new Worker(url);
  2645. worker.onmessage = fn;
  2646. worker.url = url;
  2647. return worker;
  2648. };
  2649. destroyTimer = function(timer) {
  2650. if (timer.terminate) {
  2651. timer.terminate();
  2652. return URL.revokeObjectURL(timer.url);
  2653. } else {
  2654. return clearInterval(timer);
  2655. }
  2656. };
  2657. return MozillaAudioDevice;
  2658. })(EventEmitter);
  2659. }).call(this);
  2660. },{"../core/buffer":6,"../core/events":8,"../device":20}],22:[function(require,module,exports){
  2661. //JavaScript Audio Resampler
  2662. //Copyright (C) 2011-2015 Grant Galitz
  2663. //Released to Public Domain
  2664. function Resampler(fromSampleRate, toSampleRate, channels, inputBufferLength) {
  2665. this.fromSampleRate = +fromSampleRate;
  2666. this.toSampleRate = +toSampleRate;
  2667. this.channels = channels | 0;
  2668. this.inputBufferLength = inputBufferLength;
  2669. this.initialize();
  2670. }
  2671. Resampler.prototype.initialize = function () {
  2672. //Perform some checks:
  2673. if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) {
  2674. if (this.fromSampleRate == this.toSampleRate) {
  2675. //Setup a resampler bypass:
  2676. this.resampler = this.bypassResampler; //Resampler just returns what was passed through.
  2677. this.ratioWeight = 1;
  2678. } else {
  2679. this.ratioWeight = this.fromSampleRate / this.toSampleRate;
  2680. if (this.fromSampleRate < this.toSampleRate) {
  2681. /*
  2682. Use generic linear interpolation if upsampling,
  2683. as linear interpolation produces a gradient that we want
  2684. and works fine with two input sample points per output in this case.
  2685. */
  2686. this.compileLinearInterpolationFunction();
  2687. this.lastWeight = 1;
  2688. } else {
  2689. /*
  2690. Custom resampler I wrote that doesn't skip samples
  2691. like standard linear interpolation in high downsampling.
  2692. This is more accurate than linear interpolation on downsampling.
  2693. */
  2694. this.compileMultiTapFunction();
  2695. this.tailExists = false;
  2696. this.lastWeight = 0;
  2697. }
  2698. var outputBufferSize = (Math.ceil(this.inputBufferLength * this.toSampleRate / this.fromSampleRate / this.channels * 1.01) * this.channels) + this.channels;
  2699. this.outputBuffer = new Float32Array(outputBufferSize);
  2700. this.lastOutput = new Float32Array(this.channels);
  2701. }
  2702. } else {
  2703. throw(new Error("Invalid settings specified for the resampler."));
  2704. }
  2705. };
  2706. Resampler.prototype.compileLinearInterpolationFunction = function () {
  2707. var toCompile = "var outputOffset = 0;\
  2708. var bufferLength = buffer.length;\
  2709. if (bufferLength > 0) {\
  2710. var weight = this.lastWeight;\
  2711. var firstWeight = 0;\
  2712. var secondWeight = 0;\
  2713. var sourceOffset = 0;\
  2714. var outputOffset = 0;\
  2715. var outputBuffer = this.outputBuffer;\
  2716. for (; weight < 1; weight += " + this.ratioWeight + ") {\
  2717. secondWeight = weight % 1;\
  2718. firstWeight = 1 - secondWeight;";
  2719. for (var channel = 0; channel < this.channels; ++channel) {
  2720. toCompile += "outputBuffer[outputOffset++] = (this.lastOutput[" + channel + "] * firstWeight) + (buffer[" + channel + "] * secondWeight);";
  2721. }
  2722. toCompile += "}\
  2723. weight -= 1;\
  2724. for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; sourceOffset < bufferLength;) {\
  2725. secondWeight = weight % 1;\
  2726. firstWeight = 1 - secondWeight;";
  2727. for (var channel = 0; channel < this.channels; ++channel) {
  2728. toCompile += "outputBuffer[outputOffset++] = (buffer[sourceOffset" + ((channel > 0) ? (" + " + channel) : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + channel) + "] * secondWeight);";
  2729. }
  2730. toCompile += "weight += " + this.ratioWeight + ";\
  2731. sourceOffset = Math.floor(weight) * " + this.channels + ";\
  2732. }";
  2733. for (var channel = 0; channel < this.channels; ++channel) {
  2734. toCompile += "this.lastOutput[" + channel + "] = buffer[sourceOffset++];";
  2735. }
  2736. toCompile += "this.lastWeight = weight % 1;\
  2737. }\
  2738. return this.outputBuffer;";
  2739. this.resampler = Function("buffer", toCompile);
  2740. };
  2741. Resampler.prototype.compileMultiTapFunction = function () {
  2742. var toCompile = "var outputOffset = 0;\
  2743. var bufferLength = buffer.length;\
  2744. if (bufferLength > 0) {\
  2745. var weight = 0;";
  2746. for (var channel = 0; channel < this.channels; ++channel) {
  2747. toCompile += "var output" + channel + " = 0;"
  2748. }
  2749. toCompile += "var actualPosition = 0;\
  2750. var amountToNext = 0;\
  2751. var alreadyProcessedTail = !this.tailExists;\
  2752. this.tailExists = false;\
  2753. var outputBuffer = this.outputBuffer;\
  2754. var currentPosition = 0;\
  2755. do {\
  2756. if (alreadyProcessedTail) {\
  2757. weight = " + this.ratioWeight + ";";
  2758. for (channel = 0; channel < this.channels; ++channel) {
  2759. toCompile += "output" + channel + " = 0;"
  2760. }
  2761. toCompile += "}\
  2762. else {\
  2763. weight = this.lastWeight;";
  2764. for (channel = 0; channel < this.channels; ++channel) {
  2765. toCompile += "output" + channel + " = this.lastOutput[" + channel + "];"
  2766. }
  2767. toCompile += "alreadyProcessedTail = true;\
  2768. }\
  2769. while (weight > 0 && actualPosition < bufferLength) {\
  2770. amountToNext = 1 + actualPosition - currentPosition;\
  2771. if (weight >= amountToNext) {";
  2772. for (channel = 0; channel < this.channels; ++channel) {
  2773. toCompile += "output" + channel + " += buffer[actualPosition++] * amountToNext;"
  2774. }
  2775. toCompile += "currentPosition = actualPosition;\
  2776. weight -= amountToNext;\
  2777. }\
  2778. else {";
  2779. for (channel = 0; channel < this.channels; ++channel) {
  2780. toCompile += "output" + channel + " += buffer[actualPosition" + ((channel > 0) ? (" + " + channel) : "") + "] * weight;"
  2781. }
  2782. toCompile += "currentPosition += weight;\
  2783. weight = 0;\
  2784. break;\
  2785. }\
  2786. }\
  2787. if (weight <= 0) {";
  2788. for (channel = 0; channel < this.channels; ++channel) {
  2789. toCompile += "outputBuffer[outputOffset++] = output" + channel + " / " + this.ratioWeight + ";"
  2790. }
  2791. toCompile += "}\
  2792. else {\
  2793. this.lastWeight = weight;";
  2794. for (channel = 0; channel < this.channels; ++channel) {
  2795. toCompile += "this.lastOutput[" + channel + "] = output" + channel + ";"
  2796. }
  2797. toCompile += "this.tailExists = true;\
  2798. break;\
  2799. }\
  2800. } while (actualPosition < bufferLength);\
  2801. }\
  2802. return this.outputBuffer;";
  2803. this.resampler = Function("buffer", toCompile);
  2804. };
  2805. Resampler.prototype.bypassResampler = function (inputBuffer) {
  2806. return inputBuffer;
  2807. };
  2808. module.exports = Resampler;
  2809. },{}],23:[function(require,module,exports){
  2810. (function (global){
  2811. // Generated by CoffeeScript 1.10.0
  2812. (function() {
  2813. var AudioDevice, EventEmitter, Resampler, WebAudioDevice,
  2814. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  2815. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2816. hasProp = {}.hasOwnProperty;
  2817. EventEmitter = require('../core/events');
  2818. AudioDevice = require('../device');
  2819. Resampler = require('./resampler');
  2820. WebAudioDevice = (function(superClass) {
  2821. var AudioContext, createProcessor, sharedContext;
  2822. extend(WebAudioDevice, superClass);
  2823. AudioDevice.register(WebAudioDevice);
  2824. // TEED 生成音频上下文
  2825. AudioContext = global.AudioContext || global.webkitAudioContext;
  2826. console.log("AudioContext>>>>>",AudioContext)
  2827. WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function');
  2828. sharedContext = null;
  2829. // 网络音频设备
  2830. function WebAudioDevice(sampleRate, channels1) {
  2831. this.sampleRate = sampleRate;
  2832. this.channels = channels1;
  2833. this.refill = bind(this.refill, this);
  2834. this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext;
  2835. this.deviceSampleRate = this.context.sampleRate;
  2836. this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels);
  2837. this.bufferSize += this.bufferSize % this.channels;
  2838. if (this.deviceSampleRate !== this.sampleRate) {
  2839. this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, this.bufferSize);
  2840. }
  2841. this.node = this.context[createProcessor](4096, this.channels, this.channels);
  2842. this.node.onaudioprocess = this.refill;
  2843. this.node.connect(this.context.destination);
  2844. }
  2845. WebAudioDevice.prototype.refill = function(event) {
  2846. var channelCount, channels, data, i, j, k, l, n, outputBuffer, ref, ref1, ref2;
  2847. outputBuffer = event.outputBuffer;
  2848. channelCount = outputBuffer.numberOfChannels;
  2849. channels = new Array(channelCount);
  2850. for (i = j = 0, ref = channelCount; j < ref; i = j += 1) {
  2851. channels[i] = outputBuffer.getChannelData(i);
  2852. }
  2853. data = new Float32Array(this.bufferSize);
  2854. this.emit('refill', data);
  2855. if (this.resampler) {
  2856. data = this.resampler.resampler(data);
  2857. }
  2858. for (i = k = 0, ref1 = outputBuffer.length; k < ref1; i = k += 1) {
  2859. for (n = l = 0, ref2 = channelCount; l < ref2; n = l += 1) {
  2860. channels[n][i] = data[i * channelCount + n];
  2861. }
  2862. }
  2863. };
  2864. WebAudioDevice.prototype.destroy = function() {
  2865. return this.node.disconnect(0);
  2866. };
  2867. WebAudioDevice.prototype.getDeviceTime = function() {
  2868. return this.context.currentTime * this.sampleRate;
  2869. };
  2870. return WebAudioDevice;
  2871. })(EventEmitter);
  2872. }).call(this);
  2873. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  2874. },{"../core/events":8,"../device":20,"./resampler":22}],24:[function(require,module,exports){
  2875. // Generated by CoffeeScript 1.10.0
  2876. (function() {
  2877. var Filter;
  2878. Filter = (function() {
  2879. function Filter(context, key) {
  2880. if (context && key) {
  2881. Object.defineProperty(this, 'value', {
  2882. get: function() {
  2883. return context[key];
  2884. }
  2885. });
  2886. }
  2887. }
  2888. Filter.prototype.process = function(buffer) {};
  2889. return Filter;
  2890. })();
  2891. module.exports = Filter;
  2892. }).call(this);
  2893. },{}],25:[function(require,module,exports){
  2894. // Generated by CoffeeScript 1.10.0
  2895. (function() {
  2896. var BalanceFilter, Filter,
  2897. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2898. hasProp = {}.hasOwnProperty;
  2899. Filter = require('../filter');
  2900. BalanceFilter = (function(superClass) {
  2901. extend(BalanceFilter, superClass);
  2902. function BalanceFilter() {
  2903. return BalanceFilter.__super__.constructor.apply(this, arguments);
  2904. }
  2905. BalanceFilter.prototype.process = function(buffer) {
  2906. var i, j, pan, ref;
  2907. if (this.value === 0) {
  2908. return;
  2909. }
  2910. pan = Math.max(-50, Math.min(50, this.value));
  2911. for (i = j = 0, ref = buffer.length; j < ref; i = j += 2) {
  2912. buffer[i] *= Math.min(1, (50 - pan) / 50);
  2913. buffer[i + 1] *= Math.min(1, (50 + pan) / 50);
  2914. }
  2915. };
  2916. return BalanceFilter;
  2917. })(Filter);
  2918. module.exports = BalanceFilter;
  2919. }).call(this);
  2920. },{"../filter":24}],26:[function(require,module,exports){
  2921. // Generated by CoffeeScript 1.10.0
  2922. (function() {
  2923. var Filter, VolumeFilter,
  2924. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2925. hasProp = {}.hasOwnProperty;
  2926. Filter = require('../filter');
  2927. VolumeFilter = (function(superClass) {
  2928. extend(VolumeFilter, superClass);
  2929. function VolumeFilter() {
  2930. return VolumeFilter.__super__.constructor.apply(this, arguments);
  2931. }
  2932. VolumeFilter.prototype.process = function(buffer) {
  2933. var i, j, ref, vol;
  2934. if (this.value >= 100) {
  2935. return;
  2936. }
  2937. vol = Math.max(0, Math.min(100, this.value)) / 100;
  2938. for (i = j = 0, ref = buffer.length; j < ref; i = j += 1) {
  2939. buffer[i] *= vol;
  2940. }
  2941. };
  2942. return VolumeFilter;
  2943. })(Filter);
  2944. module.exports = VolumeFilter;
  2945. }).call(this);
  2946. },{"../filter":24}],27:[function(require,module,exports){
  2947. // Generated by CoffeeScript 1.10.0
  2948. (function() {
  2949. var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter,
  2950. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  2951. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  2952. hasProp = {}.hasOwnProperty;
  2953. EventEmitter = require('./core/events');
  2954. Asset = require('./asset');
  2955. VolumeFilter = require('./filters/volume');
  2956. BalanceFilter = require('./filters/balance');
  2957. Queue = require('./queue');
  2958. AudioDevice = require('./device');
  2959. Player = (function(superClass) {
  2960. extend(Player, superClass);
  2961. // 请看音频上下文的文档 了解 这个作用是 播放音频 TDDE
  2962. function Player(asset) {
  2963. console.log("asset",asset);
  2964. this.asset = asset;
  2965. this.startPlaying = bind(this.startPlaying, this);
  2966. this.playing = false;
  2967. this.buffered = 0;
  2968. this.currentTime = 0;
  2969. this.duration = 0;
  2970. this.volume = 100;
  2971. this.pan = 0;
  2972. this.metadata = {};
  2973. this.filters = [new VolumeFilter(this, 'volume'), new BalanceFilter(this, 'pan')];
  2974. this.asset.on('buffer', (function(_this) {
  2975. return function(buffered) {
  2976. _this.buffered = buffered;
  2977. return _this.emit('buffer', _this.buffered);
  2978. };
  2979. })(this));
  2980. this.asset.on('decodeStart', (function(_this) {
  2981. return function() {
  2982. _this.queue = new Queue(_this.asset);
  2983. return _this.queue.once('ready', _this.startPlaying);
  2984. };
  2985. })(this));
  2986. this.asset.on('format', (function(_this) {
  2987. return function(format) {
  2988. _this.format = format;
  2989. return _this.emit('format', _this.format);
  2990. };
  2991. })(this));
  2992. this.asset.on('metadata', (function(_this) {
  2993. return function(metadata) {
  2994. _this.metadata = metadata;
  2995. return _this.emit('metadata', _this.metadata);
  2996. };
  2997. })(this));
  2998. this.asset.on('duration', (function(_this) {
  2999. return function(duration) {
  3000. _this.duration = duration;
  3001. return _this.emit('duration', _this.duration);
  3002. };
  3003. })(this));
  3004. this.asset.on('error', (function(_this) {
  3005. return function(error) {
  3006. return _this.emit('error', error);
  3007. };
  3008. })(this));
  3009. }
  3010. //来自URL
  3011. Player.fromURL = function(url, opts) {
  3012. return new Player(Asset.fromURL(url, opts));
  3013. };
  3014. //来自文件 封装 可以读取 aac 本地文件
  3015. Player.fromFile = function(file) {
  3016. return new Player(Asset.fromFile(file));
  3017. };
  3018. //每一块
  3019. Player.fromBuffer = function(buffer) {
  3020. return new Player(Asset.fromBuffer(buffer));
  3021. };
  3022. //预载
  3023. Player.prototype.preload = function() {
  3024. if (!this.asset) {
  3025. return;
  3026. }
  3027. this.startedPreloading = true;
  3028. return this.asset.start(false);
  3029. console.log("!this.asset==========",!this.asset,this.asset);
  3030. };
  3031. Player.prototype.play = function() {
  3032. var ref;
  3033. if (this.playing) {
  3034. return;
  3035. }
  3036. if (!this.startedPreloading) {
  3037. this.preload();
  3038. console.log("!this.startedPreloading",!this.startedPreloading);
  3039. }
  3040. // this.playing = true;
  3041. return (ref = this.device) != null ? ref.start() : void 0;
  3042. };
  3043. Player.prototype.pause = function() {
  3044. var ref;
  3045. if (!this.playing) {
  3046. return;
  3047. }
  3048. this.playing = false;
  3049. return (ref = this.device) != null ? ref.stop() : void 0;
  3050. };
  3051. Player.prototype.togglePlayback = function() {
  3052. if (this.playing) {
  3053. return this.pause();
  3054. } else {
  3055. return this.play();
  3056. }
  3057. };
  3058. Player.prototype.stop = function() {
  3059. var ref;
  3060. this.pause();
  3061. this.asset.stop();
  3062. return (ref = this.device) != null ? ref.destroy() : void 0;
  3063. };
  3064. Player.prototype.seek = function(timestamp) {
  3065. var ref;
  3066. if ((ref = this.device) != null) {
  3067. ref.stop();
  3068. }
  3069. this.queue.once('ready', (function(_this) {
  3070. return function() {
  3071. var ref1, ref2;
  3072. if ((ref1 = _this.device) != null) {
  3073. ref1.seek(_this.currentTime);
  3074. }
  3075. if (_this.playing) {
  3076. return (ref2 = _this.device) != null ? ref2.start() : void 0;
  3077. }
  3078. };
  3079. })(this));
  3080. timestamp = (timestamp / 1000) * this.format.sampleRate;
  3081. timestamp = this.asset.decoder.seek(timestamp);
  3082. this.currentTime = timestamp / this.format.sampleRate * 1000 | 0;
  3083. this.queue.reset();
  3084. return this.currentTime;
  3085. };
  3086. Player.prototype.startPlaying = function() {
  3087. var frame, frameOffset;
  3088. frame = this.queue.read();
  3089. frameOffset = 0;
  3090. this.device = new AudioDevice(this.format.sampleRate, this.format.channelsPerFrame);
  3091. this.device.on('timeUpdate', (function(_this) {
  3092. return function(currentTime) {
  3093. _this.currentTime = currentTime;
  3094. return _this.emit('progress', _this.currentTime);
  3095. };
  3096. })(this));
  3097. this.refill = (function(_this) {
  3098. return function(buffer) {
  3099. var bufferOffset, filter, i, j, k, len, max, ref, ref1;
  3100. if (!_this.playing) {
  3101. return;
  3102. }
  3103. if (!frame) {
  3104. frame = _this.queue.read();
  3105. frameOffset = 0;
  3106. }
  3107. bufferOffset = 0;
  3108. while (frame && bufferOffset < buffer.length) {
  3109. max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset);
  3110. for (i = j = 0, ref = max; j < ref; i = j += 1) {
  3111. buffer[bufferOffset++] = frame[frameOffset++];
  3112. }
  3113. if (frameOffset === frame.length) {
  3114. frame = _this.queue.read();
  3115. frameOffset = 0;
  3116. }
  3117. }
  3118. ref1 = _this.filters;
  3119. for (k = 0, len = ref1.length; k < len; k++) {
  3120. filter = ref1[k];
  3121. filter.process(buffer);
  3122. }
  3123. if (!frame) {
  3124. if (_this.queue.ended) {
  3125. _this.currentTime = _this.duration;
  3126. _this.emit('progress', _this.currentTime);
  3127. _this.emit('end');
  3128. _this.stop();
  3129. } else {
  3130. _this.device.stop();
  3131. }
  3132. }
  3133. };
  3134. })(this);
  3135. this.device.on('refill', this.refill);
  3136. if (this.playing) {
  3137. this.device.start();
  3138. }
  3139. return this.emit('ready');
  3140. };
  3141. Player.prototype.destroy = function() {
  3142. var ref, ref1;
  3143. this.stop();
  3144. if ((ref = this.device) != null) {
  3145. ref.off();
  3146. }
  3147. if ((ref1 = this.asset) != null) {
  3148. ref1.destroy();
  3149. }
  3150. return this.off();
  3151. };
  3152. return Player;
  3153. })(EventEmitter);
  3154. module.exports = Player;
  3155. }).call(this);
  3156. },{"./asset":1,"./core/events":8,"./device":20,"./filters/balance":25,"./filters/volume":26,"./queue":28}],28:[function(require,module,exports){
  3157. // Generated by CoffeeScript 1.10.0
  3158. (function() {
  3159. var EventEmitter, Queue,
  3160. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  3161. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  3162. hasProp = {}.hasOwnProperty;
  3163. EventEmitter = require('./core/events');
  3164. Queue = (function(superClass) {
  3165. extend(Queue, superClass);
  3166. function Queue(asset) {
  3167. this.asset = asset;
  3168. this.write = bind(this.write, this);
  3169. this.readyMark = 64;
  3170. this.finished = false;
  3171. this.buffering = true;
  3172. this.ended = false;
  3173. this.buffers = [];
  3174. this.asset.on('data', this.write);
  3175. this.asset.on('end', (function(_this) {
  3176. return function() {
  3177. return _this.ended = true;
  3178. };
  3179. })(this));
  3180. this.asset.decodePacket();
  3181. }
  3182. Queue.prototype.write = function(buffer) {
  3183. if (buffer) {
  3184. this.buffers.push(buffer);
  3185. }
  3186. if (this.buffering) {
  3187. if (this.buffers.length >= this.readyMark || this.ended) {
  3188. this.buffering = false;
  3189. return this.emit('ready');
  3190. } else {
  3191. return this.asset.decodePacket();
  3192. }
  3193. }
  3194. };
  3195. Queue.prototype.read = function() {
  3196. if (this.buffers.length === 0) {
  3197. return null;
  3198. }
  3199. this.asset.decodePacket();
  3200. return this.buffers.shift();
  3201. };
  3202. Queue.prototype.reset = function() {
  3203. this.buffers.length = 0;
  3204. this.buffering = true;
  3205. return this.asset.decodePacket();
  3206. };
  3207. return Queue;
  3208. })(EventEmitter);
  3209. module.exports = Queue;
  3210. }).call(this);
  3211. },{"./core/events":8}],29:[function(require,module,exports){
  3212. var AVBuffer, EventEmitter, FileSource,
  3213. __hasProp = {}.hasOwnProperty,
  3214. __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
  3215. EventEmitter = require('../../core/events');
  3216. AVBuffer = require('../../core/buffer');
  3217. FileSource = (function(_super) {
  3218. __extends(FileSource, _super);
  3219. function FileSource(file) {
  3220. this.file = file;
  3221. if (typeof FileReader === "undefined" || FileReader === null) {
  3222. return this.emit('error', 'This browser does not have FileReader support.');
  3223. }
  3224. this.offset = 0;
  3225. this.length = this.file.size;
  3226. this.chunkSize = 1 << 20;
  3227. this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice'];
  3228. }
  3229. FileSource.prototype.start = function() {
  3230. if (this.reader) {
  3231. if (!this.active) {
  3232. return this.loop();
  3233. }
  3234. }
  3235. this.reader = new FileReader;
  3236. this.active = true;
  3237. this.reader.onload = (function(_this) {
  3238. return function(e) {
  3239. var buf;
  3240. buf = new AVBuffer(new Uint8Array(e.target.result));
  3241. _this.offset += buf.length;
  3242. _this.emit('data', buf);
  3243. _this.active = false;
  3244. if (_this.offset < _this.length) {
  3245. return _this.loop();
  3246. }
  3247. };
  3248. })(this);
  3249. this.reader.onloadend = (function(_this) {
  3250. return function() {
  3251. if (_this.offset === _this.length) {
  3252. _this.emit('end');
  3253. return _this.reader = null;
  3254. }
  3255. };
  3256. })(this);
  3257. this.reader.onerror = (function(_this) {
  3258. return function(e) {
  3259. return _this.emit('error', e);
  3260. };
  3261. })(this);
  3262. this.reader.onprogress = (function(_this) {
  3263. return function(e) {
  3264. return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100);
  3265. };
  3266. })(this);
  3267. return this.loop();
  3268. };
  3269. FileSource.prototype.loop = function() {
  3270. var blob, endPos;
  3271. this.active = true;
  3272. endPos = Math.min(this.offset + this.chunkSize, this.length);
  3273. blob = this.file[this.slice](this.offset, endPos);
  3274. return this.reader.readAsArrayBuffer(blob);
  3275. };
  3276. FileSource.prototype.pause = function() {
  3277. var _ref;
  3278. this.active = false;
  3279. try {
  3280. return (_ref = this.reader) != null ? _ref.abort() : void 0;
  3281. } catch (_error) {}
  3282. };
  3283. FileSource.prototype.reset = function() {
  3284. this.pause();
  3285. return this.offset = 0;
  3286. };
  3287. return FileSource;
  3288. })(EventEmitter);
  3289. module.exports = FileSource;
  3290. },{"../../core/buffer":6,"../../core/events":8}],30:[function(require,module,exports){
  3291. var AVBuffer, EventEmitter, HTTPSource,
  3292. __hasProp = {}.hasOwnProperty,
  3293. __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
  3294. EventEmitter = require('../../core/events');
  3295. AVBuffer = require('../../core/buffer');
  3296. HTTPSource = (function(_super) {
  3297. __extends(HTTPSource, _super);
  3298. function HTTPSource(url, opts) {
  3299. this.url = url;
  3300. console.log('url>>>',url)
  3301. this.opts = opts != null ? opts : {};
  3302. this.chunkSize = 1 << 20;
  3303. this.inflight = false;
  3304. if (this.opts.length) {
  3305. this.length = this.opts.length;
  3306. }
  3307. this.reset();
  3308. }
  3309. HTTPSource.prototype.start = function() {
  3310. if (this.length) {
  3311. if (!this.inflight) {
  3312. return this.loop();
  3313. }
  3314. }
  3315. this.inflight = true;
  3316. this.xhr = new XMLHttpRequest();
  3317. this.xhr.onload = (function(_this) {
  3318. return function(event) {
  3319. _this.length = parseInt(_this.xhr.getResponseHeader("Content-Length"));
  3320. _this.inflight = false;
  3321. return _this.loop();
  3322. };
  3323. })(this);
  3324. this.xhr.onerror = (function(_this) {
  3325. return function(err) {
  3326. _this.pause();
  3327. return _this.emit('error', err);
  3328. };
  3329. })(this);
  3330. this.xhr.onabort = (function(_this) {
  3331. return function(event) {
  3332. return _this.inflight = false;
  3333. };
  3334. })(this);
  3335. this.xhr.open("HEAD", this.url, true);
  3336. return this.xhr.send(null);
  3337. };
  3338. HTTPSource.prototype.loop = function() {
  3339. var endPos;
  3340. if (this.inflight || !this.length) {
  3341. return this.emit('error', 'Something is wrong in HTTPSource.loop');
  3342. }
  3343. this.inflight = true;
  3344. this.xhr = new XMLHttpRequest();
  3345. this.xhr.onload = (function(_this) {
  3346. return function(event) {
  3347. var buf, buffer, i, txt, _i, _ref;
  3348. if (_this.xhr.response) {
  3349. buf = new Uint8Array(_this.xhr.response);
  3350. } else {
  3351. txt = _this.xhr.responseText;
  3352. buf = new Uint8Array(txt.length);
  3353. for (i = _i = 0, _ref = txt.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
  3354. buf[i] = txt.charCodeAt(i) & 0xff;
  3355. }
  3356. }
  3357. buffer = new AVBuffer(buf);
  3358. _this.offset += buffer.length;
  3359. _this.emit('data', buffer);
  3360. if (_this.offset >= _this.length) {
  3361. _this.emit('end');
  3362. }
  3363. _this.inflight = false;
  3364. if (!(_this.offset >= _this.length)) {
  3365. return _this.loop();
  3366. }
  3367. };
  3368. })(this);
  3369. this.xhr.onprogress = (function(_this) {
  3370. return function(event) {
  3371. return _this.emit('progress', (_this.offset + event.loaded) / _this.length * 100);
  3372. };
  3373. })(this);
  3374. this.xhr.onerror = (function(_this) {
  3375. return function(err) {
  3376. _this.emit('error', err);
  3377. return _this.pause();
  3378. };
  3379. })(this);
  3380. this.xhr.onabort = (function(_this) {
  3381. return function(event) {
  3382. return _this.inflight = false;
  3383. };
  3384. })(this);
  3385. alert(this.url)
  3386. this.xhr.open("GET", this.url, true);
  3387. this.xhr.responseType = "arraybuffer";
  3388. endPos = Math.min(this.offset + this.chunkSize, this.length - 1);
  3389. this.xhr.setRequestHeader("If-None-Match", "webkit-no-cache");
  3390. this.xhr.setRequestHeader("Range", "bytes=" + this.offset + "-" + endPos);
  3391. this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3392. return this.xhr.send(null);
  3393. };
  3394. HTTPSource.prototype.pause = function() {
  3395. var _ref;
  3396. this.inflight = false;
  3397. return (_ref = this.xhr) != null ? _ref.abort() : void 0;
  3398. };
  3399. HTTPSource.prototype.reset = function() {
  3400. this.pause();
  3401. return this.offset = 0;
  3402. };
  3403. return HTTPSource;
  3404. })(EventEmitter);
  3405. module.exports = HTTPSource;
  3406. },{"../../core/buffer":6,"../../core/events":8}],31:[function(require,module,exports){
  3407. (function (global){
  3408. // Generated by CoffeeScript 1.10.0
  3409. (function() {
  3410. var AVBuffer, BufferList, BufferSource, EventEmitter,
  3411. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  3412. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  3413. hasProp = {}.hasOwnProperty;
  3414. EventEmitter = require('../core/events');
  3415. BufferList = require('../core/bufferlist');
  3416. AVBuffer = require('../core/buffer');
  3417. BufferSource = (function(superClass) {
  3418. var clearImmediate, setImmediate;
  3419. extend(BufferSource, superClass);
  3420. function BufferSource(input) {
  3421. this.loop = bind(this.loop, this);
  3422. if (input instanceof BufferList) {
  3423. this.list = input;
  3424. } else {
  3425. this.list = new BufferList;
  3426. this.list.append(new AVBuffer(input));
  3427. }
  3428. this.paused = true;
  3429. }
  3430. setImmediate = global.setImmediate || function(fn) {
  3431. return global.setTimeout(fn, 0);
  3432. };
  3433. clearImmediate = global.clearImmediate || function(timer) {
  3434. return global.clearTimeout(timer);
  3435. };
  3436. BufferSource.prototype.start = function() {
  3437. this.paused = false;
  3438. return this._timer = setImmediate(this.loop);
  3439. };
  3440. BufferSource.prototype.loop = function() {
  3441. this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0);
  3442. this.emit('data', this.list.first);
  3443. if (this.list.advance()) {
  3444. return setImmediate(this.loop);
  3445. } else {
  3446. return this.emit('end');
  3447. }
  3448. };
  3449. BufferSource.prototype.pause = function() {
  3450. clearImmediate(this._timer);
  3451. return this.paused = true;
  3452. };
  3453. BufferSource.prototype.reset = function() {
  3454. this.pause();
  3455. return this.list.rewind();
  3456. };
  3457. return BufferSource;
  3458. })(EventEmitter);
  3459. module.exports = BufferSource;
  3460. }).call(this);
  3461. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  3462. },{"../core/buffer":6,"../core/bufferlist":7,"../core/events":8}],32:[function(require,module,exports){
  3463. var key, val, _ref;
  3464. _ref = require('./src/aurora');
  3465. for (key in _ref) {
  3466. val = _ref[key];
  3467. exports[key] = val;
  3468. }
  3469. require('./src/devices/webaudio');
  3470. require('./src/devices/mozilla');
  3471. },{"./src/aurora":2,"./src/devices/mozilla":21,"./src/devices/webaudio":23}]},{},[32])(32)
  3472. });
  3473. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYXNzZXQuanMiLCJzcmMvYXVyb3JhLmpzIiwic3JjL2F1cm9yYV9iYXNlLmpzIiwic3JjL2NvcmUvYmFzZS5qcyIsInNyYy9jb3JlL2JpdHN0cmVhbS5qcyIsInNyYy9jb3JlL2J1ZmZlci5qcyIsInNyYy9jb3JlL2J1ZmZlcmxpc3QuanMiLCJzcmMvY29yZS9ldmVudHMuanMiLCJzcmMvY29yZS9zdHJlYW0uanMiLCJzcmMvY29yZS91bmRlcmZsb3cuanMiLCJzcmMvZGVjb2Rlci5qcyIsInNyYy9kZWNvZGVycy9scGNtLmpzIiwic3JjL2RlY29kZXJzL3hsYXcuanMiLCJzcmMvZGVtdXhlci5qcyIsInNyYy9kZW11eGVycy9haWZmLmpzIiwic3JjL2RlbXV4ZXJzL2F1LmpzIiwic3JjL2RlbXV4ZXJzL2NhZi5qcyIsInNyYy9kZW11eGVycy9tNGEuanMiLCJzcmMvZGVtdXhlcnMvd2F2ZS5qcyIsInNyYy9kZXZpY2UuanMiLCJzcmMvZGV2aWNlcy9tb3ppbGxhLmpzIiwic3JjL2RldmljZXMvcmVzYW1wbGVyLmpzIiwic3JjL2RldmljZXMvd2ViYXVkaW8uanMiLCJzcmMvZmlsdGVyLmpzIiwic3JjL2ZpbHRlcnMvYmFsYW5jZS5qcyIsInNyYy9maWx0ZXJzL3ZvbHVtZS5qcyIsInNyYy9wbGF5ZXIuanMiLCJzcmMvcXVldWUuanMiLCIvaG9tZS9kaW0vY29kZS9hdXJvcmEuanMvc3JjL3NvdXJjZXMvYnJvd3Nlci9maWxlLmNvZmZlZSIsIi9ob21lL2RpbS9jb2RlL2F1cm9yYS5qcy9zcmMvc291cmNlcy9icm93c2VyL2h0dHAuY29mZmVlIiwic3JjL3NvdXJjZXMvYnVmZmVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ25PQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3huQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNUpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQSxJQUFBLGtDQUFBO0VBQUE7aVNBQUE7O0FBQUEsWUFBQSxHQUFlLE9BQUEsQ0FBUSxtQkFBUixDQUFmLENBQUE7O0FBQUEsUUFDQSxHQUFXLE9BQUEsQ0FBUSxtQkFBUixDQURYLENBQUE7O0FBQUE7QUFJSSwrQkFBQSxDQUFBOztBQUFhLEVBQUEsb0JBQUUsSUFBRixHQUFBO0FBQ1QsSUFEVSxJQUFDLENBQUEsT0FBQSxJQUNYLENBQUE7QUFBQSxJQUFBLElBQU8sd0RBQVA7QUFDSSxhQUFPLElBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLGdEQUFmLENBQVAsQ0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCxHQUFVLENBSFYsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsSUFBSSxDQUFDLElBSmhCLENBQUE7QUFBQSxJQUtBLElBQUMsQ0FBQSxTQUFELEdBQWEsQ0FBQSxJQUFLLEVBTGxCLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxPQUFULENBQU4sSUFBMkIsSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxHQUFTLGFBQVQsQ0FBakMsSUFBNEQsSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxHQUFTLFVBQVQsQ0FObEUsQ0FEUztFQUFBLENBQWI7O0FBQUEsdUJBU0EsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBRyxJQUFDLENBQUEsTUFBSjtBQUNJLE1BQUEsSUFBQSxDQUFBLElBQXVCLENBQUEsTUFBdkI7QUFBQSxlQUFPLElBQUMsQ0FBQSxJQUFELENBQUEsQ0FBUCxDQUFBO09BREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxHQUFBLENBQUEsVUFIVixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBSlYsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxNQUFSLEdBQWlCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLENBQUQsR0FBQTtBQUNiLFlBQUEsR0FBQTtBQUFBLFFBQUEsR0FBQSxHQUFVLElBQUEsUUFBQSxDQUFhLElBQUEsVUFBQSxDQUFXLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBcEIsQ0FBYixDQUFWLENBQUE7QUFBQSxRQUNBLEtBQUMsQ0FBQSxNQUFELElBQVcsR0FBRyxDQUFDLE1BRGYsQ0FBQTtBQUFBLFFBR0EsS0FBQyxDQUFBLElBQUQsQ0FBTSxNQUFOLEVBQWMsR0FBZCxDQUhBLENBQUE7QUFBQSxRQUlBLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FKVixDQUFBO0FBS0EsUUFBQSxJQUFXLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FBQyxDQUFBLE1BQXRCO2lCQUFBLEtBQUMsQ0FBQSxJQUFELENBQUEsRUFBQTtTQU5hO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FOakIsQ0FBQTtBQUFBLElBY0EsSUFBQyxDQUFBLE1BQU0sQ0FBQyxTQUFSLEdBQW9CLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFBLEdBQUE7QUFDaEIsUUFBQSxJQUFHLEtBQUMsQ0FBQSxNQUFELEtBQVcsS0FBQyxDQUFBLE1BQWY7QUFDSSxVQUFBLEtBQUMsQ0FBQSxJQUFELENBQU0sS0FBTixDQUFBLENBQUE7aUJBQ0EsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUZkO1NBRGdCO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FkcEIsQ0FBQTtBQUFBLElBbUJBLElBQUMsQ0FBQSxNQUFNLENBQUMsT0FBUixHQUFrQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxDQUFELEdBQUE7ZUFDZCxLQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxDQUFmLEVBRGM7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQW5CbEIsQ0FBQTtBQUFBLElBc0JBLElBQUMsQ0FBQSxNQUFNLENBQUMsVUFBUixHQUFxQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxDQUFELEdBQUE7ZUFDakIsS0FBQyxDQUFBLElBQUQsQ0FBTSxVQUFOLEVBQWtCLENBQUMsS0FBQyxDQUFBLE1BQUQsR0FBVSxDQUFDLENBQUMsTUFBYixDQUFBLEdBQXVCLEtBQUMsQ0FBQSxNQUF4QixHQUFpQyxHQUFuRCxFQURpQjtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBdEJyQixDQUFBO1dBeUJBLElBQUMsQ0FBQSxJQUFELENBQUEsRUExQkc7RUFBQSxDQVRQLENBQUE7O0FBQUEsdUJBcUNBLElBQUEsR0FBTSxTQUFBLEdBQUE7QUFDRixRQUFBLFlBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBVixDQUFBO0FBQUEsSUFDQSxNQUFBLEdBQVMsSUFBSSxDQUFDLEdBQUwsQ0FBUyxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxTQUFwQixFQUErQixJQUFDLENBQUEsTUFBaEMsQ0FEVCxDQUFBO0FBQUEsSUFHQSxJQUFBLEdBQU8sSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxDQUFOLENBQWMsSUFBQyxDQUFBLE1BQWYsRUFBdUIsTUFBdkIsQ0FIUCxDQUFBO1dBSUEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxpQkFBUixDQUEwQixJQUExQixFQUxFO0VBQUEsQ0FyQ04sQ0FBQTs7QUFBQSx1QkE0Q0EsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILFFBQUEsSUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxLQUFWLENBQUE7QUFDQTtnREFDUyxDQUFFLEtBQVQsQ0FBQSxXQURGO0tBQUEsa0JBRkc7RUFBQSxDQTVDUCxDQUFBOztBQUFBLHVCQWlEQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFDLENBQUEsS0FBRCxDQUFBLENBQUEsQ0FBQTtXQUNBLElBQUMsQ0FBQSxNQUFELEdBQVUsRUFGUDtFQUFBLENBakRQLENBQUE7O29CQUFBOztHQURxQixhQUh6QixDQUFBOztBQUFBLE1BeURNLENBQUMsT0FBUCxHQUFpQixVQXpEakIsQ0FBQTs7O0FDQUEsSUFBQSxrQ0FBQTtFQUFBO2lTQUFBOztBQUFBLFlBQUEsR0FBZSxPQUFBLENBQVEsbUJBQVIsQ0FBZixDQUFBOztBQUFBLFFBQ0EsR0FBVyxPQUFBLENBQVEsbUJBQVIsQ0FEWCxDQUFBOztBQUFBO0FBSUksK0JBQUEsQ0FBQTs7QUFBYSxFQUFBLG9CQUFFLEdBQUYsRUFBUSxJQUFSLEdBQUE7QUFDVCxJQURVLElBQUMsQ0FBQSxNQUFBLEdBQ1gsQ0FBQTtBQUFBLElBRGdCLElBQUMsQ0FBQSxzQkFBQSxPQUFPLEVBQ3hCLENBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxTQUFELEdBQWEsQ0FBQSxJQUFLLEVBQWxCLENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxRQUFELEdBQVksS0FEWixDQUFBO0FBRUEsSUFBQSxJQUFHLElBQUMsQ0FBQSxJQUFJLENBQUMsTUFBVDtBQUNJLE1BQUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsSUFBSSxDQUFDLE1BQWhCLENBREo7S0FGQTtBQUFBLElBSUEsSUFBQyxDQUFBLEtBQUQsQ0FBQSxDQUpBLENBRFM7RUFBQSxDQUFiOztBQUFBLHVCQU9BLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUcsSUFBQyxDQUFBLE1BQUo7QUFDSSxNQUFBLElBQUEsQ0FBQSxJQUF1QixDQUFBLFFBQXZCO0FBQUEsZUFBTyxJQUFDLENBQUEsSUFBRCxDQUFBLENBQVAsQ0FBQTtPQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxRQUFELEdBQVksSUFIWixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsR0FBRCxHQUFXLElBQUEsY0FBQSxDQUFBLENBSlgsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLEdBQWMsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO0FBQ1YsUUFBQSxLQUFDLENBQUEsTUFBRCxHQUFVLFFBQUEsQ0FBUyxLQUFDLENBQUEsR0FBRyxDQUFDLGlCQUFMLENBQXVCLGdCQUF2QixDQUFULENBQVYsQ0FBQTtBQUFBLFFBQ0EsS0FBQyxDQUFBLFFBQUQsR0FBWSxLQURaLENBQUE7ZUFFQSxLQUFDLENBQUEsSUFBRCxDQUFBLEVBSFU7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQU5kLENBQUE7QUFBQSxJQVdBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEdBQUQsR0FBQTtBQUNYLFFBQUEsS0FBQyxDQUFBLEtBQUQsQ0FBQSxDQUFBLENBQUE7ZUFDQSxLQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxHQUFmLEVBRlc7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQVhmLENBQUE7QUFBQSxJQWVBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtlQUNYLEtBQUMsQ0FBQSxRQUFELEdBQVksTUFERDtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBZmYsQ0FBQTtBQUFBLElBa0JBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLE1BQVYsRUFBa0IsSUFBQyxDQUFBLEdBQW5CLEVBQXdCLElBQXhCLENBbEJBLENBQUE7V0FtQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsSUFBVixFQXBCRztFQUFBLENBUFAsQ0FBQTs7QUFBQSx1QkE2QkEsSUFBQSxHQUFNLFNBQUEsR0FBQTtBQUNGLFFBQUEsTUFBQTtBQUFBLElBQUEsSUFBRyxJQUFDLENBQUEsUUFBRCxJQUFhLENBQUEsSUFBSyxDQUFBLE1BQXJCO0FBQ0ksYUFBTyxJQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSx1Q0FBZixDQUFQLENBREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxJQUhaLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxHQUFELEdBQVcsSUFBQSxjQUFBLENBQUEsQ0FKWCxDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsR0FBRyxDQUFDLE1BQUwsR0FBYyxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7QUFDVixZQUFBLDZCQUFBO0FBQUEsUUFBQSxJQUFHLEtBQUMsQ0FBQSxHQUFHLENBQUMsUUFBUjtBQUNJLFVBQUEsR0FBQSxHQUFVLElBQUEsVUFBQSxDQUFXLEtBQUMsQ0FBQSxHQUFHLENBQUMsUUFBaEIsQ0FBVixDQURKO1NBQUEsTUFBQTtBQUdJLFVBQUEsR0FBQSxHQUFNLEtBQUMsQ0FBQSxHQUFHLENBQUMsWUFBWCxDQUFBO0FBQUEsVUFDQSxHQUFBLEdBQVUsSUFBQSxVQUFBLENBQVcsR0FBRyxDQUFDLE1BQWYsQ0FEVixDQUFBO0FBRUEsZUFBUyw2RkFBVCxHQUFBO0FBQ0ksWUFBQSxHQUFJLENBQUEsQ0FBQSxDQUFKLEdBQVMsR0FBRyxDQUFDLFVBQUosQ0FBZSxDQUFmLENBQUEsR0FBb0IsSUFBN0IsQ0FESjtBQUFBLFdBTEo7U0FBQTtBQUFBLFFBUUEsTUFBQSxHQUFhLElBQUEsUUFBQSxDQUFTLEdBQVQsQ0FSYixDQUFBO0FBQUEsUUFTQSxLQUFDLENBQUEsTUFBRCxJQUFXLE1BQU0sQ0FBQyxNQVRsQixDQUFBO0FBQUEsUUFXQSxLQUFDLENBQUEsSUFBRCxDQUFNLE1BQU4sRUFBYyxNQUFkLENBWEEsQ0FBQTtBQVlBLFFBQUEsSUFBZSxLQUFDLENBQUEsTUFBRCxJQUFXLEtBQUMsQ0FBQSxNQUEzQjtBQUFBLFVBQUEsS0FBQyxDQUFBLElBQUQsQ0FBTSxLQUFOLENBQUEsQ0FBQTtTQVpBO0FBQUEsUUFjQSxLQUFDLENBQUEsUUFBRCxHQUFZLEtBZFosQ0FBQTtBQWVBLFFBQUEsSUFBQSxDQUFBLENBQWUsS0FBQyxDQUFBLE1BQUQsSUFBVyxLQUFDLENBQUEsTUFBM0IsQ0FBQTtpQkFBQSxLQUFDLENBQUEsSUFBRCxDQUFBLEVBQUE7U0FoQlU7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQU5kLENBQUE7QUFBQSxJQXdCQSxJQUFDLENBQUEsR0FBRyxDQUFDLFVBQUwsR0FBa0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO2VBQ2QsS0FBQyxDQUFBLElBQUQsQ0FBTSxVQUFOLEVBQWtCLENBQUMsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUFLLENBQUMsTUFBakIsQ0FBQSxHQUEyQixLQUFDLENBQUEsTUFBNUIsR0FBcUMsR0FBdkQsRUFEYztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBeEJsQixDQUFBO0FBQUEsSUEyQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsR0FBRCxHQUFBO0FBQ1gsUUFBQSxLQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxHQUFmLENBQUEsQ0FBQTtlQUNBLEtBQUMsQ0FBQSxLQUFELENBQUEsRUFGVztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBM0JmLENBQUE7QUFBQSxJQStCQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7ZUFDWCxLQUFDLENBQUEsUUFBRCxHQUFZLE1BREQ7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQS9CZixDQUFBO0FBQUEsSUFrQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsS0FBVixFQUFpQixJQUFDLENBQUEsR0FBbEIsRUFBdUIsSUFBdkIsQ0FsQ0EsQ0FBQTtBQUFBLElBbUNBLElBQUMsQ0FBQSxHQUFHLENBQUMsWUFBTCxHQUFvQixhQW5DcEIsQ0FBQTtBQUFBLElBcUNBLE1BQUEsR0FBUyxJQUFJLENBQUMsR0FBTCxDQUFTLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLFNBQXBCLEVBQStCLElBQUMsQ0FBQSxNQUFELEdBQVUsQ0FBekMsQ0FyQ1QsQ0FBQTtBQUFBLElBc0NBLElBQUMsQ0FBQSxHQUFHLENBQUMsZ0JBQUwsQ0FBc0IsZUFBdEIsRUFBdUMsaUJBQXZDLENBdENBLENBQUE7QUFBQSxJQXVDQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLE9BQXRCLEVBQWdDLFFBQUEsR0FBTyxJQUFDLENBQUEsTUFBUixHQUFnQixHQUFoQixHQUFrQixNQUFsRCxDQXZDQSxDQUFBO0FBQUEsSUF3Q0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxnQkFBTCxDQUFzQixvQ0FBdEIsQ0F4Q0EsQ0FBQTtXQXlDQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxJQUFWLEVBMUNFO0VBQUEsQ0E3Qk4sQ0FBQTs7QUFBQSx1QkF5RUEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILFFBQUEsSUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLFFBQUQsR0FBWSxLQUFaLENBQUE7MkNBQ0ksQ0FBRSxLQUFOLENBQUEsV0FGRztFQUFBLENBekVQLENBQUE7O0FBQUEsdUJBNkVBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUMsQ0FBQSxLQUFELENBQUEsQ0FBQSxDQUFBO1dBQ0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxFQUZQO0VBQUEsQ0E3RVAsQ0FBQTs7b0JBQUE7O0dBRHFCLGFBSHpCLENBQUE7O0FBQUEsTUFxRk0sQ0FBQyxPQUFQLEdBQWlCLFVBckZqQixDQUFBOzs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFzc2V0LCBCdWZmZXJTb3VyY2UsIERlY29kZXIsIERlbXV4ZXIsIEV2ZW50RW1pdHRlciwgRmlsZVNvdXJjZSwgSFRUUFNvdXJjZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBIVFRQU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvaHR0cCcpO1xuXG4gIEZpbGVTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9maWxlJyk7XG5cbiAgQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuL2RlbXV4ZXInKTtcblxuICBEZWNvZGVyID0gcmVxdWlyZSgnLi9kZWNvZGVyJyk7XG5cbiAgQXNzZXQgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChBc3NldCwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBc3NldChzb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlID0gc291cmNlO1xuICAgICAgdGhpcy5fZGVjb2RlID0gYmluZCh0aGlzLl9kZWNvZGUsIHRoaXMpO1xuICAgICAgdGhpcy5maW5kRGVjb2RlciA9IGJpbmQodGhpcy5maW5kRGVjb2RlciwgdGhpcyk7XG4gICAgICB0aGlzLnByb2JlID0gYmluZCh0aGlzLnByb2JlLCB0aGlzKTtcbiAgICAgIHRoaXMuYnVmZmVyZWQgPSAwO1xuICAgICAgdGhpcy5kdXJhdGlvbiA9IG51bGw7XG4gICAgICB0aGlzLmZvcm1hdCA9IG51bGw7XG4gICAgICB0aGlzLm1ldGFkYXRhID0gbnVsbDtcbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBudWxsO1xuICAgICAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc291cmNlLm9uY2UoJ2RhdGEnLCB0aGlzLnByb2JlKTtcbiAgICAgIHRoaXMuc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgX3RoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5zdG9wKCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNvdXJjZS5vbigncHJvZ3Jlc3MnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcmVkKSB7XG4gICAgICAgICAgX3RoaXMuYnVmZmVyZWQgPSBidWZmZXJlZDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnYnVmZmVyJywgX3RoaXMuYnVmZmVyZWQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH1cblxuICAgIEFzc2V0LmZyb21VUkwgPSBmdW5jdGlvbih1cmwsIG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEhUVFBTb3VyY2UodXJsLCBvcHRzKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21GaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgRmlsZVNvdXJjZShmaWxlKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21CdWZmZXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEJ1ZmZlclNvdXJjZShidWZmZXIpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oZGVjb2RlKSB7XG4gICAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGRlY29kZSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2hvdWxkRGVjb2RlID0gZGVjb2RlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc2hvdWxkRGVjb2RlID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zaG91bGREZWNvZGUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5zb3VyY2Uuc3RhcnQoKTtcbiAgICAgIGlmICh0aGlzLmRlY29kZXIgJiYgdGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlLnBhdXNlKCk7XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgIGlmIChldmVudCAhPT0gJ2Zvcm1hdCcgJiYgZXZlbnQgIT09ICdkdXJhdGlvbicgJiYgZXZlbnQgIT09ICdtZXRhZGF0YScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXNbZXZlbnRdICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXNbZXZlbnRdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25jZShldmVudCwgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsdWUpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVBhY2tldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2Rlci5kZWNvZGUoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVRvQnVmZmVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgIHZhciBjaHVua3MsIGRhdGFIYW5kbGVyLCBsZW5ndGg7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgY2h1bmtzID0gW107XG4gICAgICB0aGlzLm9uKCdkYXRhJywgZGF0YUhhbmRsZXIgPSBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICBsZW5ndGggKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICByZXR1cm4gY2h1bmtzLnB1c2goY2h1bmspO1xuICAgICAgfSk7XG4gICAgICB0aGlzLm9uY2UoJ2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYnVmLCBjaHVuaywgaiwgbGVuLCBvZmZzZXQ7XG4gICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChqID0gMCwgbGVuID0gY2h1bmtzLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgY2h1bmsgPSBjaHVua3Nbal07XG4gICAgICAgICAgYnVmLnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICAgICAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2ZmKCdkYXRhJywgZGF0YUhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soYnVmKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgIHZhciBkZW11eGVyO1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBkZW11eGVyID0gRGVtdXhlci5maW5kKGNodW5rKTtcbiAgICAgIGlmICghZGVtdXhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdBIGRlbXV4ZXIgZm9yIHRoaXMgY29udGFpbmVyIHdhcyBub3QgZm91bmQuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBuZXcgZGVtdXhlcih0aGlzLnNvdXJjZSwgY2h1bmspO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdmb3JtYXQnLCB0aGlzLmZpbmREZWNvZGVyKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZHVyYXRpb24nLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgICAgX3RoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZHVyYXRpb24nLCBfdGhpcy5kdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ21ldGFkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgICAgICAgIF90aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ21ldGFkYXRhJywgX3RoaXMubWV0YWRhdGEpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVtdXhlci5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuc3RvcCgpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZmluZERlY29kZXIgPSBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgIHZhciBkZWNvZGVyLCBkaXY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICBkZWNvZGVyID0gRGVjb2Rlci5maW5kKHRoaXMuZm9ybWF0LmZvcm1hdElEKTtcbiAgICAgIGlmICghZGVjb2Rlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiQSBkZWNvZGVyIGZvciBcIiArIHRoaXMuZm9ybWF0LmZvcm1hdElEICsgXCIgd2FzIG5vdCBmb3VuZC5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIgPSBuZXcgZGVjb2Rlcih0aGlzLmRlbXV4ZXIsIHRoaXMuZm9ybWF0KTtcbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50KSB7XG4gICAgICAgIHRoaXMuZGVjb2Rlci5vbignZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXYgPSBNYXRoLnBvdygyLCB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAtIDEpO1xuICAgICAgICB0aGlzLmRlY29kZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgICB2YXIgYnVmLCBpLCBqLCBsZW4sIHNhbXBsZTtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgbGVuID0gYnVmZmVyLmxlbmd0aDsgaiA8IGxlbjsgaSA9ICsraikge1xuICAgICAgICAgICAgICBzYW1wbGUgPSBidWZmZXJbaV07XG4gICAgICAgICAgICAgIGJ1ZltpXSA9IHNhbXBsZSAvIGRpdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZGVjb2Rlci5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZVN0YXJ0Jyk7XG4gICAgICBpZiAodGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgd2hpbGUgKHRoaXMuZGVjb2Rlci5kZWNvZGUoKSAmJiB0aGlzLmFjdGl2ZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGVyLm9uY2UoJ2RhdGEnLCB0aGlzLl9kZWNvZGUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZiwgcmVmMSwgcmVmMjtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRlbXV4ZXIpICE9IG51bGwpIHtcbiAgICAgICAgcmVmLm9mZigpO1xuICAgICAgfVxuICAgICAgaWYgKChyZWYxID0gdGhpcy5kZWNvZGVyKSAhPSBudWxsKSB7XG4gICAgICAgIHJlZjEub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKHJlZjIgPSB0aGlzLnNvdXJjZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYyLm9mZigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBBc3NldDtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXNzZXQ7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIga2V5LCByZWYsIHZhbDtcblxuICByZWYgPSByZXF1aXJlKCcuL2F1cm9yYV9iYXNlJyk7XG4gIGZvciAoa2V5IGluIHJlZikge1xuICAgIHZhbCA9IHJlZltrZXldO1xuICAgIGV4cG9ydHNba2V5XSA9IHZhbDtcbiAgfVxuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvY2FmJyk7XG5cbiAgcmVxdWlyZSgnLi9kZW11eGVycy9tNGEnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2FpZmYnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL3dhdmUnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2F1Jyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy9scGNtJyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy94bGF3Jyk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLkJhc2UgPSByZXF1aXJlKCcuL2NvcmUvYmFzZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyID0gcmVxdWlyZSgnLi9jb3JlL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgZXhwb3J0cy5TdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvc3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5CaXRzdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvYml0c3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgZXhwb3J0cy5VbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBleHBvcnRzLkhUVFBTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9odHRwJyk7XG5cbiAgZXhwb3J0cy5GaWxlU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvZmlsZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuRGVtdXhlciA9IHJlcXVpcmUoJy4vZGVtdXhlcicpO1xuXG4gIGV4cG9ydHMuRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVjb2RlcicpO1xuXG4gIGV4cG9ydHMuQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuL2RldmljZScpO1xuXG4gIGV4cG9ydHMuQXNzZXQgPSByZXF1aXJlKCcuL2Fzc2V0Jyk7XG5cbiAgZXhwb3J0cy5QbGF5ZXIgPSByZXF1aXJlKCcuL3BsYXllcicpO1xuXG4gIGV4cG9ydHMuRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXInKTtcblxuICBleHBvcnRzLlZvbHVtZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy92b2x1bWUnKTtcblxuICBleHBvcnRzLkJhbGFuY2VGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvYmFsYW5jZScpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhc2UsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBpbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgQmFzZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZm5UZXN0O1xuXG4gICAgZnVuY3Rpb24gQmFzZSgpIHt9XG5cbiAgICBmblRlc3QgPSAvXFxiX3N1cGVyXFxiLztcblxuICAgIEJhc2UuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgdmFyIENsYXNzLCBfc3VwZXIsIGZuLCBrZXksIGtleXMsIHJlZjtcbiAgICAgIENsYXNzID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICAgICAgZXh0ZW5kKENsYXNzLCBzdXBlckNsYXNzKTtcblxuICAgICAgICBmdW5jdGlvbiBDbGFzcygpIHtcbiAgICAgICAgICByZXR1cm4gQ2xhc3MuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gQ2xhc3M7XG5cbiAgICAgIH0pKHRoaXMpO1xuICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhDbGFzcy5wcm90b3R5cGUpO1xuICAgICAgICBwcm9wLmNhbGwoQ2xhc3MsIENsYXNzKTtcbiAgICAgICAgcHJvcCA9IHt9O1xuICAgICAgICByZWYgPSBDbGFzcy5wcm90b3R5cGU7XG4gICAgICAgIGZvciAoa2V5IGluIHJlZikge1xuICAgICAgICAgIGZuID0gcmVmW2tleV07XG4gICAgICAgICAgaWYgKGluZGV4T2YuY2FsbChrZXlzLCBrZXkpIDwgMCkge1xuICAgICAgICAgICAgcHJvcFtrZXldID0gZm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBfc3VwZXIgPSBDbGFzcy5fX3N1cGVyX187XG4gICAgICBmb3IgKGtleSBpbiBwcm9wKSB7XG4gICAgICAgIGZuID0gcHJvcFtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIGZuVGVzdC50ZXN0KGZuKSkge1xuICAgICAgICAgIChmdW5jdGlvbihrZXksIGZuKSB7XG4gICAgICAgICAgICByZXR1cm4gQ2xhc3MucHJvdG90eXBlW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIHJldCwgdG1wO1xuICAgICAgICAgICAgICB0bXAgPSB0aGlzLl9zdXBlcjtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSBfc3VwZXJba2V5XTtcbiAgICAgICAgICAgICAgcmV0ID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSB0bXA7XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKGtleSwgZm4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIENsYXNzLnByb3RvdHlwZVtrZXldID0gZm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBDbGFzcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJhc2U7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJhc2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtO1xuXG4gIEJpdHN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCaXRzdHJlYW0oc3RyZWFtKSB7XG4gICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgIHRoaXMuYml0UG9zaXRpb24gPSAwO1xuICAgIH1cblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaXRzdHJlYW0odGhpcy5zdHJlYW0uY29weSgpKTtcbiAgICAgIHJlc3VsdC5iaXRQb3NpdGlvbiA9IHRoaXMuYml0UG9zaXRpb247XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDggKiB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoKGJpdHMgKyA4IC0gdGhpcy5iaXRQb3NpdGlvbikgLyA4KTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gKyBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShwb3MgPj4gMyk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gLSBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0ucmV3aW5kKE1hdGguYWJzKHBvcyA+PiAzKSk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGN1ck9mZnNldDtcbiAgICAgIGN1ck9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgICBpZiAob2Zmc2V0ID4gY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2Uob2Zmc2V0IC0gY3VyT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZChjdXJPZmZzZXQgLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmFsaWduID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5iaXRQb3NpdGlvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmJpdFBvc2l0aW9uID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJpdHMsIHNpZ25lZCkge1xuICAgICAgdmFyIGEsIGEwLCBhMSwgYTIsIGEzLCBhNCwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIG1CaXRzID0gYml0cyArIHRoaXMuYml0UG9zaXRpb247XG4gICAgICBpZiAobUJpdHMgPD0gOCkge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDgoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmYpID4+PiAoOCAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSAxNikge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDE2KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmZmYpID4+PiAoMTYgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMjQpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQyNCgpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmZmYpID4+PiAoMjQgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMzIpIHtcbiAgICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDMyKCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgPj4+ICgzMiAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSA0MCkge1xuICAgICAgICBhMCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgwKSAqIDB4MDEwMDAwMDAwMDtcbiAgICAgICAgYTEgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkgPDwgMjQgPj4+IDA7XG4gICAgICAgIGEyID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDIpIDw8IDE2O1xuICAgICAgICBhMyA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgzKSA8PCA4O1xuICAgICAgICBhNCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KTtcbiAgICAgICAgYSA9IGEwICsgYTEgKyBhMiArIGEzICsgYTQ7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgNDAgLSB0aGlzLmJpdFBvc2l0aW9uKTtcbiAgICAgICAgYSA9IE1hdGguZmxvb3IoYSAvIE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbiAtIGJpdHMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGJpdHMhXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICBpZiAobUJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChhID4+PiAoYml0cyAtIDEpKSB7XG4gICAgICAgICAgICBhID0gKCgxIDw8IGJpdHMgPj4+IDApIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSkgfCAwKSB7XG4gICAgICAgICAgICBhID0gKE1hdGgucG93KDIsIGJpdHMpIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZShiaXRzKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihiaXRzLCBzaWduZWQpIHtcbiAgICAgIHZhciBhLCBhMCwgYTEsIGEyLCBhMywgYTQsIG1CaXRzO1xuICAgICAgaWYgKGJpdHMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzIDw9IDgpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQ4KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmKSA+Pj4gKDggLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMTYpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQxNigpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmKSA+Pj4gKDE2IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDI0KSB7XG4gICAgICAgIGEgPSAoKHRoaXMuc3RyZWFtLnBlZWtVSW50MjQoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmZmZmZmKSA+Pj4gKDI0IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDMyKSB7XG4gICAgICAgIGEgPSAodGhpcy5zdHJlYW0ucGVla1VJbnQzMigpIDw8IHRoaXMuYml0UG9zaXRpb24pID4+PiAoMzIgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gNDApIHtcbiAgICAgICAgYTAgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkgKiAweDAxMDAwMDAwMDA7XG4gICAgICAgIGExID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDEpIDw8IDI0ID4+PiAwO1xuICAgICAgICBhMiA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgyKSA8PCAxNjtcbiAgICAgICAgYTMgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMykgPDwgODtcbiAgICAgICAgYTQgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoNCk7XG4gICAgICAgIGEgPSBhMCArIGExICsgYTIgKyBhMyArIGE0O1xuICAgICAgICBhICU9IE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICAgIGEgPSBNYXRoLmZsb29yKGEgLyBNYXRoLnBvdygyLCA0MCAtIHRoaXMuYml0UG9zaXRpb24gLSBiaXRzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBiaXRzIVwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5yZWFkTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoYml0cyk7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5wZWVrTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJpdHN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQml0c3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyO1xuXG4gIEFWQnVmZmVyID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBCbG9iQnVpbGRlciwgVVJMO1xuXG4gICAgZnVuY3Rpb24gQVZCdWZmZXIoaW5wdXQpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0O1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHwgKChyZWYgPSBnbG9iYWwuQnVmZmVyKSAhPSBudWxsID8gcmVmLmlzQnVmZmVyKGlucHV0KSA6IHZvaWQgMCkpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXQpO1xuICAgICAgfSBlbHNlIGlmIChpbnB1dC5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dC5idWZmZXIsIGlucHV0LmJ5dGVPZmZzZXQsIGlucHV0Lmxlbmd0aCAqIGlucHV0LkJZVEVTX1BFUl9FTEVNRU5UKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQgaW5zdGFuY2VvZiBBVkJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBpbnB1dC5kYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29uc3RydWN0aW5nIGJ1ZmZlciB3aXRoIHVua25vd24gdHlwZS5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XG4gICAgICB0aGlzLm5leHQgPSBudWxsO1xuICAgICAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgICB9XG5cbiAgICBBVkJ1ZmZlci5hbGxvY2F0ZSA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIoc2l6ZSk7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEFWQnVmZmVyKG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YSkpO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihwb3NpdGlvbiwgbGVuZ3RoKSB7XG4gICAgICBpZiAobGVuZ3RoID09IG51bGwpIHtcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICB9XG4gICAgICBpZiAocG9zaXRpb24gPT09IDAgJiYgbGVuZ3RoID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhLnN1YmFycmF5KHBvc2l0aW9uLCBwb3NpdGlvbiArIGxlbmd0aCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCbG9iQnVpbGRlciA9IGdsb2JhbC5CbG9iQnVpbGRlciB8fCBnbG9iYWwuTW96QmxvYkJ1aWxkZXIgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyO1xuXG4gICAgVVJMID0gZ2xvYmFsLlVSTCB8fCBnbG9iYWwud2Via2l0VVJMIHx8IGdsb2JhbC5tb3pVUkw7XG5cbiAgICBBVkJ1ZmZlci5tYWtlQmxvYiA9IGZ1bmN0aW9uKGRhdGEsIHR5cGUpIHtcbiAgICAgIHZhciBiYjtcbiAgICAgIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAgICAgdHlwZSA9ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9iKFtkYXRhXSwge1xuICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoICh1bmRlZmluZWQpIHt9XG4gICAgICBpZiAoQmxvYkJ1aWxkZXIgIT0gbnVsbCkge1xuICAgICAgICBiYiA9IG5ldyBCbG9iQnVpbGRlcjtcbiAgICAgICAgYmIuYXBwZW5kKGRhdGEpO1xuICAgICAgICByZXR1cm4gYmIuZ2V0QmxvYih0eXBlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5tYWtlQmxvYlVSTCA9IGZ1bmN0aW9uKGRhdGEsIHR5cGUpIHtcbiAgICAgIHJldHVybiBVUkwgIT0gbnVsbCA/IFVSTC5jcmVhdGVPYmplY3RVUkwodGhpcy5tYWtlQmxvYihkYXRhLCB0eXBlKSkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnJldm9rZUJsb2JVUkwgPSBmdW5jdGlvbih1cmwpIHtcbiAgICAgIHJldHVybiBVUkwgIT0gbnVsbCA/IFVSTC5yZXZva2VPYmplY3RVUkwodXJsKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucHJvdG90eXBlLnRvQmxvYiA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIEFWQnVmZmVyLm1ha2VCbG9iKHRoaXMuZGF0YS5idWZmZXIpO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUudG9CbG9iVVJMID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gQVZCdWZmZXIubWFrZUJsb2JVUkwodGhpcy5kYXRhLmJ1ZmZlcik7XG4gICAgfTtcblxuICAgIHJldHVybiBBVkJ1ZmZlcjtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQVZCdWZmZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQnVmZmVyTGlzdDtcblxuICBCdWZmZXJMaXN0ID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEJ1ZmZlckxpc3QoKSB7XG4gICAgICB0aGlzLmZpcnN0ID0gbnVsbDtcbiAgICAgIHRoaXMubGFzdCA9IG51bGw7XG4gICAgICB0aGlzLm51bUJ1ZmZlcnMgPSAwO1xuICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyA9IDA7XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMgPSAwO1xuICAgIH1cblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICByZXN1bHQgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIHJlc3VsdC5maXJzdCA9IHRoaXMuZmlyc3Q7XG4gICAgICByZXN1bHQubGFzdCA9IHRoaXMubGFzdDtcbiAgICAgIHJlc3VsdC5udW1CdWZmZXJzID0gdGhpcy5udW1CdWZmZXJzO1xuICAgICAgcmVzdWx0LmF2YWlsYWJsZUJ5dGVzID0gdGhpcy5hdmFpbGFibGVCeXRlcztcbiAgICAgIHJlc3VsdC5hdmFpbGFibGVCdWZmZXJzID0gdGhpcy5hdmFpbGFibGVCdWZmZXJzO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgYnVmZmVyLnByZXYgPSB0aGlzLmxhc3Q7XG4gICAgICBpZiAoKHJlZiA9IHRoaXMubGFzdCkgIT0gbnVsbCkge1xuICAgICAgICByZWYubmV4dCA9IGJ1ZmZlcjtcbiAgICAgIH1cbiAgICAgIHRoaXMubGFzdCA9IGJ1ZmZlcjtcbiAgICAgIGlmICh0aGlzLmZpcnN0ID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5maXJzdCA9IGJ1ZmZlcjtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycysrO1xuICAgICAgcmV0dXJuIHRoaXMubnVtQnVmZmVycysrO1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5maXJzdCkge1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzIC09IHRoaXMuZmlyc3QubGVuZ3RoO1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMtLTtcbiAgICAgICAgdGhpcy5maXJzdCA9IHRoaXMuZmlyc3QubmV4dDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3QgIT0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgaWYgKHRoaXMuZmlyc3QgJiYgIXRoaXMuZmlyc3QucHJldikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLmZpcnN0ID0gKChyZWYgPSB0aGlzLmZpcnN0KSAhPSBudWxsID8gcmVmLnByZXYgOiB2b2lkIDApIHx8IHRoaXMubGFzdDtcbiAgICAgIGlmICh0aGlzLmZpcnN0KSB7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgKz0gdGhpcy5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycysrO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZmlyc3QgIT0gbnVsbDtcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXN1bHRzO1xuICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRoaXMucmV3aW5kKCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlckxpc3Q7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQmFzZSwgRXZlbnRFbWl0dGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgc2xpY2UgPSBbXS5zbGljZTtcblxuICBCYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5cbiAgRXZlbnRFbWl0dGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoRXZlbnRFbWl0dGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgICAgIHJldHVybiBFdmVudEVtaXR0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgICAgdmFyIGJhc2U7XG4gICAgICBpZiAodGhpcy5ldmVudHMgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmV2ZW50cyA9IHt9O1xuICAgICAgfVxuICAgICAgaWYgKChiYXNlID0gdGhpcy5ldmVudHMpW2V2ZW50XSA9PSBudWxsKSB7XG4gICAgICAgIGJhc2VbZXZlbnRdID0gW107XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5ldmVudHNbZXZlbnRdLnB1c2goZm4pO1xuICAgIH07XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgICAgdmFyIGV2ZW50cywgaW5kZXgsIHJlZjtcbiAgICAgIGlmICh0aGlzLmV2ZW50cyA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICgocmVmID0gdGhpcy5ldmVudHMpICE9IG51bGwgPyByZWZbZXZlbnRdIDogdm9pZCAwKSB7XG4gICAgICAgIGlmIChmbiAhPSBudWxsKSB7XG4gICAgICAgICAgaW5kZXggPSB0aGlzLmV2ZW50c1tldmVudF0uaW5kZXhPZihmbik7XG4gICAgICAgICAgaWYgKH5pbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzW2V2ZW50XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHNbZXZlbnRdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGV2ZW50cyA9IHt9O1xuICAgICAgfVxuICAgIH07XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICAgIHZhciBjYjtcbiAgICAgIHJldHVybiB0aGlzLm9uKGV2ZW50LCBjYiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLm9mZihldmVudCwgY2IpO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzLCBldmVudCwgZm4sIGksIGxlbiwgcmVmLCByZWYxO1xuICAgICAgZXZlbnQgPSBhcmd1bWVudHNbMF0sIGFyZ3MgPSAyIDw9IGFyZ3VtZW50cy5sZW5ndGggPyBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkgOiBbXTtcbiAgICAgIGlmICghKChyZWYgPSB0aGlzLmV2ZW50cykgIT0gbnVsbCA/IHJlZltldmVudF0gOiB2b2lkIDApKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlZjEgPSB0aGlzLmV2ZW50c1tldmVudF0uc2xpY2UoKTtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJlZjEubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZm4gPSByZWYxW2ldO1xuICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcblxuICB9KShCYXNlKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVkJ1ZmZlciwgQnVmZmVyTGlzdCwgU3RyZWFtLCBVbmRlcmZsb3dFcnJvcjtcblxuICBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9idWZmZXJsaXN0Jyk7XG5cbiAgQVZCdWZmZXIgPSByZXF1aXJlKCcuL2J1ZmZlcicpO1xuXG4gIFVuZGVyZmxvd0Vycm9yID0gcmVxdWlyZSgnLi91bmRlcmZsb3cnKTtcblxuICBTdHJlYW0gPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ1ZiwgZGVjb2RlU3RyaW5nLCBmbG9hdDMyLCBmbG9hdDY0LCBmbG9hdDY0RmFsbGJhY2ssIGZsb2F0ODAsIGludDE2LCBpbnQzMiwgaW50OCwgbmF0aXZlRW5kaWFuLCB1aW50MTYsIHVpbnQzMiwgdWludDg7XG5cbiAgICBidWYgPSBuZXcgQXJyYXlCdWZmZXIoMTYpO1xuXG4gICAgdWludDggPSBuZXcgVWludDhBcnJheShidWYpO1xuXG4gICAgaW50OCA9IG5ldyBJbnQ4QXJyYXkoYnVmKTtcblxuICAgIHVpbnQxNiA9IG5ldyBVaW50MTZBcnJheShidWYpO1xuXG4gICAgaW50MTYgPSBuZXcgSW50MTZBcnJheShidWYpO1xuXG4gICAgdWludDMyID0gbmV3IFVpbnQzMkFycmF5KGJ1Zik7XG5cbiAgICBpbnQzMiA9IG5ldyBJbnQzMkFycmF5KGJ1Zik7XG5cbiAgICBmbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheShidWYpO1xuXG4gICAgaWYgKHR5cGVvZiBGbG9hdDY0QXJyYXkgIT09IFwidW5kZWZpbmVkXCIgJiYgRmxvYXQ2NEFycmF5ICE9PSBudWxsKSB7XG4gICAgICBmbG9hdDY0ID0gbmV3IEZsb2F0NjRBcnJheShidWYpO1xuICAgIH1cblxuICAgIG5hdGl2ZUVuZGlhbiA9IG5ldyBVaW50MTZBcnJheShuZXcgVWludDhBcnJheShbMHgxMiwgMHgzNF0pLmJ1ZmZlcilbMF0gPT09IDB4MzQxMjtcblxuICAgIGZ1bmN0aW9uIFN0cmVhbShsaXN0MSkge1xuICAgICAgdGhpcy5saXN0ID0gbGlzdDE7XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBTdHJlYW0uZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIGxpc3Q7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChidWZmZXIpO1xuICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obGlzdCk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBTdHJlYW0odGhpcy5saXN0LmNvcHkoKSk7XG4gICAgICByZXN1bHQubG9jYWxPZmZzZXQgPSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgICAgcmVzdWx0Lm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5hdmFpbGFibGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgcmV0dXJuIGJ5dGVzIDw9IHRoaXMubGlzdC5hdmFpbGFibGVCeXRlcyAtIHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVtYWluaW5nQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpc3QuYXZhaWxhYmxlQnl0ZXMgLSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLmFkdmFuY2UgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShieXRlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ICs9IGJ5dGVzO1xuICAgICAgdGhpcy5vZmZzZXQgKz0gYnl0ZXM7XG4gICAgICB3aGlsZSAodGhpcy5saXN0LmZpcnN0ICYmIHRoaXMubG9jYWxPZmZzZXQgPj0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0IC09IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMubGlzdC5hZHZhbmNlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZXdpbmQgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKGJ5dGVzID4gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMubGlzdC5maXJzdCkge1xuICAgICAgICB0aGlzLmxpc3QucmV3aW5kKCk7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2NhbE9mZnNldCAtPSBieXRlcztcbiAgICAgIHRoaXMub2Zmc2V0IC09IGJ5dGVzO1xuICAgICAgd2hpbGUgKHRoaXMubGlzdC5maXJzdC5wcmV2ICYmIHRoaXMubG9jYWxPZmZzZXQgPCAwKSB7XG4gICAgICAgIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICAgICAgdGhpcy5sb2NhbE9mZnNldCArPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHBvc2l0aW9uKSB7XG4gICAgICBpZiAocG9zaXRpb24gPiB0aGlzLm9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlKHBvc2l0aW9uIC0gdGhpcy5vZmZzZXQpO1xuICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA8IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZCh0aGlzLm9mZnNldCAtIHBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhO1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGEgPSB0aGlzLmxpc3QuZmlyc3QuZGF0YVt0aGlzLmxvY2FsT2Zmc2V0XTtcbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgKz0gMTtcbiAgICAgIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICBpZiAodGhpcy5sb2NhbE9mZnNldCA9PT0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy5saXN0LmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGJ1ZmZlcjtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShvZmZzZXQgKyAxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMubG9jYWxPZmZzZXQgKyBvZmZzZXQ7XG4gICAgICBidWZmZXIgPSB0aGlzLmxpc3QuZmlyc3Q7XG4gICAgICB3aGlsZSAoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gb2Zmc2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGJ1ZmZlci5kYXRhW29mZnNldF07XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0IC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5uZXh0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIDA7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzLCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHZhciBpLCBqLCBrLCByZWYsIHJlZjE7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09IG51bGwpIHtcbiAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09PSBuYXRpdmVFbmRpYW4pIHtcbiAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGJ5dGVzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgdWludDhbaV0gPSB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBrID0gcmVmMSA9IGJ5dGVzIC0gMTsgayA+PSAwOyBpID0gayArPSAtMSkge1xuICAgICAgICAgIHVpbnQ4W2ldID0gdGhpcy5yZWFkVUludDgoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihieXRlcywgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHZhciBpLCBqLCBrLCByZWYsIHJlZjE7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09IG51bGwpIHtcbiAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09PSBuYXRpdmVFbmRpYW4pIHtcbiAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGJ5dGVzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgdWludDhbaV0gPSB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyBpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gayA9IDAsIHJlZjEgPSBieXRlczsgayA8IHJlZjE7IGkgPSBrICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtieXRlcyAtIGkgLSAxXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucmVhZCgxKTtcbiAgICAgIHJldHVybiBpbnQ4WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygxLCBvZmZzZXQpO1xuICAgICAgcmV0dXJuIGludDhbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFVJbnQxNiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDIsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50MTYgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMiwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MTYgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCgyLCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygyLCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFVJbnQyNCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVUludDE2KHRydWUpICsgKHRoaXMucmVhZFVJbnQ4KCkgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnJlYWRVSW50MTYoKSA8PCA4KSArIHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQyNCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVla1VJbnQxNihvZmZzZXQsIHRydWUpICsgKHRoaXMucGVla1VJbnQ4KG9mZnNldCArIDIpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5wZWVrVUludDE2KG9mZnNldCkgPDwgOCkgKyB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyAyKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MjQgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFVJbnQxNih0cnVlKSArICh0aGlzLnJlYWRJbnQ4KCkgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnJlYWRJbnQxNigpIDw8IDgpICsgdGhpcy5yZWFkVUludDgoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50MjQgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCB0cnVlKSArICh0aGlzLnBlZWtJbnQ4KG9mZnNldCArIDIpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5wZWVrSW50MTYob2Zmc2V0KSA8PCA4KSArIHRoaXMucGVla1VJbnQ4KG9mZnNldCArIDIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50MzIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrVUludDMyID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDQsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDMyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoNCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50MzIgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoNCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDMyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoNCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtGbG9hdDMyID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDQsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDY0ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoOCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIGlmIChmbG9hdDY0KSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0WzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRGYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmbG9hdDY0RmFsbGJhY2sgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBleHAsIGZyYWMsIGhpZ2gsIGxvdywgb3V0LCBzaWduO1xuICAgICAgbG93ID0gdWludDMyWzBdLCBoaWdoID0gdWludDMyWzFdO1xuICAgICAgaWYgKCFoaWdoIHx8IGhpZ2ggPT09IDB4ODAwMDAwMDApIHtcbiAgICAgICAgcmV0dXJuIDAuMDtcbiAgICAgIH1cbiAgICAgIHNpZ24gPSAxIC0gKGhpZ2ggPj4+IDMxKSAqIDI7XG4gICAgICBleHAgPSAoaGlnaCA+Pj4gMjApICYgMHg3ZmY7XG4gICAgICBmcmFjID0gaGlnaCAmIDB4ZmZmZmY7XG4gICAgICBpZiAoZXhwID09PSAweDdmZikge1xuICAgICAgICBpZiAoZnJhYykge1xuICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNpZ24gKiBJbmZpbml0eTtcbiAgICAgIH1cbiAgICAgIGV4cCAtPSAxMDIzO1xuICAgICAgb3V0ID0gKGZyYWMgfCAweDEwMDAwMCkgKiBNYXRoLnBvdygyLCBleHAgLSAyMCk7XG4gICAgICBvdXQgKz0gbG93ICogTWF0aC5wb3coMiwgZXhwIC0gNTIpO1xuICAgICAgcmV0dXJuIHNpZ24gKiBvdXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0Zsb2F0NjQgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoOCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgaWYgKGZsb2F0NjQpIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NEZhbGxiYWNrKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0ODAgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCgxMCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDgwKCk7XG4gICAgfTtcblxuICAgIGZsb2F0ODAgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhMCwgYTEsIGV4cCwgaGlnaCwgbG93LCBvdXQsIHNpZ247XG4gICAgICBoaWdoID0gdWludDMyWzBdLCBsb3cgPSB1aW50MzJbMV07XG4gICAgICBhMCA9IHVpbnQ4WzldO1xuICAgICAgYTEgPSB1aW50OFs4XTtcbiAgICAgIHNpZ24gPSAxIC0gKGEwID4+PiA3KSAqIDI7XG4gICAgICBleHAgPSAoKGEwICYgMHg3RikgPDwgOCkgfCBhMTtcbiAgICAgIGlmIChleHAgPT09IDAgJiYgbG93ID09PSAwICYmIGhpZ2ggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAoZXhwID09PSAweDdmZmYpIHtcbiAgICAgICAgaWYgKGxvdyA9PT0gMCAmJiBoaWdoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHNpZ24gKiBJbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgfVxuICAgICAgZXhwIC09IDE2MzgzO1xuICAgICAgb3V0ID0gbG93ICogTWF0aC5wb3coMiwgZXhwIC0gMzEpO1xuICAgICAgb3V0ICs9IGhpZ2ggKiBNYXRoLnBvdygyLCBleHAgLSA2Myk7XG4gICAgICByZXR1cm4gc2lnbiAqIG91dDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrRmxvYXQ4MCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygxMCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0ODAoKTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkQnVmZmVyID0gZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmLCByZXN1bHQsIHRvO1xuICAgICAgcmVzdWx0ID0gQVZCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTtcbiAgICAgIHRvID0gcmVzdWx0LmRhdGE7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gbGVuZ3RoOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgIHRvW2ldID0gdGhpcy5yZWFkVUludDgoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0J1ZmZlciA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmLCByZXN1bHQsIHRvO1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBBVkJ1ZmZlci5hbGxvY2F0ZShsZW5ndGgpO1xuICAgICAgdG8gPSByZXN1bHQuZGF0YTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBsZW5ndGg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgdG9baV0gPSB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyBpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFNpbmdsZUJ1ZmZlciA9IGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IHRoaXMubGlzdC5maXJzdC5zbGljZSh0aGlzLmxvY2FsT2Zmc2V0LCBsZW5ndGgpO1xuICAgICAgdGhpcy5hZHZhbmNlKHJlc3VsdC5sZW5ndGgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrU2luZ2xlQnVmZmVyID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICByZXN1bHQgPSB0aGlzLmxpc3QuZmlyc3Quc2xpY2UodGhpcy5sb2NhbE9mZnNldCArIG9mZnNldCwgbGVuZ3RoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFN0cmluZyA9IGZ1bmN0aW9uKGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7XG4gICAgICAgIGVuY29kaW5nID0gJ2FzY2lpJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNvZGVTdHJpbmcuY2FsbCh0aGlzLCAwLCBsZW5ndGgsIGVuY29kaW5nLCB0cnVlKTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7XG4gICAgICAgIGVuY29kaW5nID0gJ2FzY2lpJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNvZGVTdHJpbmcuY2FsbCh0aGlzLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcsIGZhbHNlKTtcbiAgICB9O1xuXG4gICAgZGVjb2RlU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nLCBhZHZhbmNlKSB7XG4gICAgICB2YXIgYjEsIGIyLCBiMywgYjQsIGJvbSwgYywgZW5kLCBsaXR0bGVFbmRpYW4sIG51bGxFbmQsIHB0LCByZXN1bHQsIHcxLCB3MjtcbiAgICAgIGVuY29kaW5nID0gZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtcbiAgICAgIG51bGxFbmQgPSBsZW5ndGggPT09IG51bGwgPyAwIDogLTE7XG4gICAgICBpZiAobGVuZ3RoID09IG51bGwpIHtcbiAgICAgICAgbGVuZ3RoID0gSW5maW5pdHk7XG4gICAgICB9XG4gICAgICBlbmQgPSBvZmZzZXQgKyBsZW5ndGg7XG4gICAgICByZXN1bHQgPSAnJztcbiAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBlbmQgJiYgKGMgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykpICE9PSBudWxsRW5kKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgICAgd2hpbGUgKG9mZnNldCA8IGVuZCAmJiAoYjEgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykpICE9PSBudWxsRW5kKSB7XG4gICAgICAgICAgICBpZiAoKGIxICYgMHg4MCkgPT09IDApIHtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYjEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoYjEgJiAweGUwKSA9PT0gMHhjMCkge1xuICAgICAgICAgICAgICBiMiA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYjEgJiAweDFmKSA8PCA2KSB8IGIyKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGIxICYgMHhmMCkgPT09IDB4ZTApIHtcbiAgICAgICAgICAgICAgYjIgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBiMyA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYjEgJiAweDBmKSA8PCAxMikgfCAoYjIgPDwgNikgfCBiMyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChiMSAmIDB4ZjgpID09PSAweGYwKSB7XG4gICAgICAgICAgICAgIGIyID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgYjMgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBiNCA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIHB0ID0gKCgoYjEgJiAweDBmKSA8PCAxOCkgfCAoYjIgPDwgMTIpIHwgKGIzIDw8IDYpIHwgYjQpIC0gMHgxMDAwMDtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhkODAwICsgKHB0ID4+IDEwKSwgMHhkYzAwICsgKHB0ICYgMHgzZmYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3V0ZjE2LWJlJzpcbiAgICAgICAgY2FzZSAndXRmMTZiZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgICBjYXNlICd1dGYxNi1sZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2Ym9tJzpcbiAgICAgICAgY2FzZSAndXRmMTYtYm9tJzpcbiAgICAgICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICAgICAgICBjYXNlICd1dGYxNmJlJzpcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2LWJlJzpcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAgICAgICBjYXNlICd1dGYxNi1sZSc6XG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndXRmMTZib20nOlxuICAgICAgICAgICAgY2FzZSAndXRmMTYtYm9tJzpcbiAgICAgICAgICAgICAgaWYgKGxlbmd0aCA8IDIgfHwgKGJvbSA9IHRoaXMucGVla1VJbnQxNihvZmZzZXQpKSA9PT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgICAgIGlmIChhZHZhbmNlKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmFkdmFuY2Uob2Zmc2V0ICs9IDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGJvbSA9PT0gMHhmZmZlO1xuICAgICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgd2hpbGUgKG9mZnNldCA8IGVuZCAmJiAodzEgPSB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCBsaXR0bGVFbmRpYW4pKSAhPT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgICBpZiAodzEgPCAweGQ4MDAgfHwgdzEgPiAweGRmZmYpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodzEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKHcxID4gMHhkYmZmKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB1dGYxNiBzZXF1ZW5jZS5cIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdzIgPSB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgICBpZiAodzIgPCAweGRjMDAgfHwgdzIgPiAweGRmZmYpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHV0ZjE2IHNlcXVlbmNlLlwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh3MSwgdzIpO1xuICAgICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHcxID09PSBudWxsRW5kKSB7XG4gICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIgKyBlbmNvZGluZyk7XG4gICAgICB9XG4gICAgICBpZiAoYWR2YW5jZSkge1xuICAgICAgICB0aGlzLmFkdmFuY2Uob2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIHJldHVybiBTdHJlYW07XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFN0cmVhbTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBVbmRlcmZsb3dFcnJvcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIFVuZGVyZmxvd0Vycm9yID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoVW5kZXJmbG93RXJyb3IsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gVW5kZXJmbG93RXJyb3IoKSB7XG4gICAgICBVbmRlcmZsb3dFcnJvci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRoaXMubmFtZSA9ICdVbmRlcmZsb3dFcnJvcic7XG4gICAgICB0aGlzLnN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7XG4gICAgfVxuXG4gICAgcmV0dXJuIFVuZGVyZmxvd0Vycm9yO1xuXG4gIH0pKEVycm9yKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFVuZGVyZmxvd0Vycm9yO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJpdHN0cmVhbSwgQnVmZmVyTGlzdCwgRGVjb2RlciwgRXZlbnRFbWl0dGVyLCBTdHJlYW0sIFVuZGVyZmxvd0Vycm9yLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIFN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9zdHJlYW0nKTtcblxuICBCaXRzdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvYml0c3RyZWFtJyk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL2NvcmUvdW5kZXJmbG93Jyk7XG5cbiAgRGVjb2RlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGNvZGVjcztcblxuICAgIGV4dGVuZChEZWNvZGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIERlY29kZXIoZGVtdXhlciwgZm9ybWF0KSB7XG4gICAgICB2YXIgbGlzdDtcbiAgICAgIHRoaXMuZGVtdXhlciA9IGRlbXV4ZXI7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIHRoaXMuc3RyZWFtID0gbmV3IFN0cmVhbShsaXN0KTtcbiAgICAgIHRoaXMuYml0c3RyZWFtID0gbmV3IEJpdHN0cmVhbSh0aGlzLnN0cmVhbSk7XG4gICAgICB0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMud2FpdGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdjb29raWUnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvb2tpZSkge1xuICAgICAgICAgIHZhciBlcnJvciwgZXJyb3IxO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuc2V0Q29va2llKGNvb2tpZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IxKSB7XG4gICAgICAgICAgICBlcnJvciA9IGVycm9yMTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIF90aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSB0cnVlO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge307XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5zZXRDb29raWUgPSBmdW5jdGlvbihjb29raWUpIHt9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVycm9yLCBlcnJvcjEsIG9mZnNldCwgcGFja2V0O1xuICAgICAgdGhpcy53YWl0aW5nID0gIXRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlcjtcbiAgICAgIG9mZnNldCA9IHRoaXMuYml0c3RyZWFtLm9mZnNldCgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcGFja2V0ID0gdGhpcy5yZWFkQ2h1bmsoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yMSkge1xuICAgICAgICBlcnJvciA9IGVycm9yMTtcbiAgICAgICAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBVbmRlcmZsb3dFcnJvcikpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBhY2tldCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQpO1xuICAgICAgICBpZiAodGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlcikge1xuICAgICAgICB0aGlzLmJpdHN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICAgIHRoaXMud2FpdGluZyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24odGltZXN0YW1wKSB7XG4gICAgICB2YXIgc2Vla1BvaW50O1xuICAgICAgc2Vla1BvaW50ID0gdGhpcy5kZW11eGVyLnNlZWsodGltZXN0YW1wKTtcbiAgICAgIHRoaXMuc3RyZWFtLnNlZWsoc2Vla1BvaW50Lm9mZnNldCk7XG4gICAgICByZXR1cm4gc2Vla1BvaW50LnRpbWVzdGFtcDtcbiAgICB9O1xuXG4gICAgY29kZWNzID0ge307XG5cbiAgICBEZWNvZGVyLnJlZ2lzdGVyID0gZnVuY3Rpb24oaWQsIGRlY29kZXIpIHtcbiAgICAgIHJldHVybiBjb2RlY3NbaWRdID0gZGVjb2RlcjtcbiAgICB9O1xuXG4gICAgRGVjb2Rlci5maW5kID0gZnVuY3Rpb24oaWQpIHtcbiAgICAgIHJldHVybiBjb2RlY3NbaWRdIHx8IG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBEZWNvZGVyO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBEZWNvZGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlY29kZXIsIExQQ01EZWNvZGVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRGVjb2RlciA9IHJlcXVpcmUoJy4uL2RlY29kZXInKTtcblxuICBMUENNRGVjb2RlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKExQQ01EZWNvZGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIExQQ01EZWNvZGVyKCkge1xuICAgICAgdGhpcy5yZWFkQ2h1bmsgPSBiaW5kKHRoaXMucmVhZENodW5rLCB0aGlzKTtcbiAgICAgIHJldHVybiBMUENNRGVjb2Rlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZWNvZGVyLnJlZ2lzdGVyKCdscGNtJywgTFBDTURlY29kZXIpO1xuXG4gICAgTFBDTURlY29kZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNodW5rU2l6ZSwgaSwgaiwgaywgbCwgbGl0dGxlRW5kaWFuLCBtLCBuLCBvLCBvdXRwdXQsIHJlZiwgcmVmMSwgcmVmMiwgcmVmMywgcmVmNCwgcmVmNSwgc2FtcGxlcywgc3RyZWFtO1xuICAgICAgc3RyZWFtID0gdGhpcy5zdHJlYW07XG4gICAgICBsaXR0bGVFbmRpYW4gPSB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW47XG4gICAgICBjaHVua1NpemUgPSBNYXRoLm1pbig0MDk2LCBzdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSk7XG4gICAgICBzYW1wbGVzID0gY2h1bmtTaXplIC8gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgfCAwO1xuICAgICAgaWYgKGNodW5rU2l6ZSA8IHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50KSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwpIHtcbiAgICAgICAgICBjYXNlIDMyOlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEZsb2F0MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBzYW1wbGVzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkRmxvYXQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSA2NDpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGbG9hdDY0QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IHNhbXBsZXM7IGsgPCByZWYxOyBpID0gayArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkRmxvYXQ2NChsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYml0IGRlcHRoLicpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsKSB7XG4gICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDhBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IGwgPSAwLCByZWYyID0gc2FtcGxlczsgbCA8IHJlZjI7IGkgPSBsICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQ4KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDE2OlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDE2QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBtID0gMCwgcmVmMyA9IHNhbXBsZXM7IG0gPCByZWYzOyBpID0gbSArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50MTYobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IG4gPSAwLCByZWY0ID0gc2FtcGxlczsgbiA8IHJlZjQ7IGkgPSBuICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQyNChsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAzMjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQzMkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gbyA9IDAsIHJlZjUgPSBzYW1wbGVzOyBvIDwgcmVmNTsgaSA9IG8gKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEludDMyKGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBiaXQgZGVwdGguJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuICAgIHJldHVybiBMUENNRGVjb2RlcjtcblxuICB9KShEZWNvZGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBYTEFXRGVjb2RlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgWExBV0RlY29kZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIHZhciBCSUFTLCBRVUFOVF9NQVNLLCBTRUdfTUFTSywgU0VHX1NISUZULCBTSUdOX0JJVDtcblxuICAgIGV4dGVuZChYTEFXRGVjb2Rlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBYTEFXRGVjb2RlcigpIHtcbiAgICAgIHRoaXMucmVhZENodW5rID0gYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gWExBV0RlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcigndWxhdycsIFhMQVdEZWNvZGVyKTtcblxuICAgIERlY29kZXIucmVnaXN0ZXIoJ2FsYXcnLCBYTEFXRGVjb2Rlcik7XG5cbiAgICBTSUdOX0JJVCA9IDB4ODA7XG5cbiAgICBRVUFOVF9NQVNLID0gMHhmO1xuXG4gICAgU0VHX1NISUZUID0gNDtcblxuICAgIFNFR19NQVNLID0gMHg3MDtcblxuICAgIEJJQVMgPSAweDg0O1xuXG4gICAgWExBV0RlY29kZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBqLCBrLCBzZWcsIHQsIHRhYmxlLCB2YWw7XG4gICAgICB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IDE2O1xuICAgICAgdGhpcy50YWJsZSA9IHRhYmxlID0gbmV3IEludDE2QXJyYXkoMjU2KTtcbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mb3JtYXRJRCA9PT0gJ3VsYXcnKSB7XG4gICAgICAgIGZvciAoaSA9IGogPSAwOyBqIDwgMjU2OyBpID0gKytqKSB7XG4gICAgICAgICAgdmFsID0gfmk7XG4gICAgICAgICAgdCA9ICgodmFsICYgUVVBTlRfTUFTSykgPDwgMykgKyBCSUFTO1xuICAgICAgICAgIHQgPDw9ICh2YWwgJiBTRUdfTUFTSykgPj4+IFNFR19TSElGVDtcbiAgICAgICAgICB0YWJsZVtpXSA9IHZhbCAmIFNJR05fQklUID8gQklBUyAtIHQgOiB0IC0gQklBUztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gayA9IDA7IGsgPCAyNTY7IGkgPSArK2spIHtcbiAgICAgICAgICB2YWwgPSBpIF4gMHg1NTtcbiAgICAgICAgICB0ID0gdmFsICYgUVVBTlRfTUFTSztcbiAgICAgICAgICBzZWcgPSAodmFsICYgU0VHX01BU0spID4+PiBTRUdfU0hJRlQ7XG4gICAgICAgICAgaWYgKHNlZykge1xuICAgICAgICAgICAgdCA9ICh0ICsgdCArIDEgKyAzMikgPDwgKHNlZyArIDIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ID0gKHQgKyB0ICsgMSkgPDwgMztcbiAgICAgICAgICB9XG4gICAgICAgICAgdGFibGVbaV0gPSB2YWwgJiBTSUdOX0JJVCA/IHQgOiAtdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBYTEFXRGVjb2Rlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgaiwgb3V0cHV0LCByZWYsIHNhbXBsZXMsIHN0cmVhbSwgdGFibGU7XG4gICAgICBzdHJlYW0gPSB0aGlzLnN0cmVhbSwgdGFibGUgPSB0aGlzLnRhYmxlO1xuICAgICAgc2FtcGxlcyA9IE1hdGgubWluKDQwOTYsIHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpO1xuICAgICAgaWYgKHNhbXBsZXMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgb3V0cHV0ID0gbmV3IEludDE2QXJyYXkoc2FtcGxlcyk7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gc2FtcGxlczsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICBvdXRwdXRbaV0gPSB0YWJsZVtzdHJlYW0ucmVhZFVJbnQ4KCldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhMQVdEZWNvZGVyO1xuXG4gIH0pKERlY29kZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJ1ZmZlckxpc3QsIERlbXV4ZXIsIEV2ZW50RW1pdHRlciwgU3RyZWFtLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIFN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9zdHJlYW0nKTtcblxuICBEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgZm9ybWF0cztcblxuICAgIGV4dGVuZChEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIERlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRGVtdXhlcihzb3VyY2UsIGNodW5rKSB7XG4gICAgICB2YXIgbGlzdCwgcmVjZWl2ZWQ7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChjaHVuayk7XG4gICAgICB0aGlzLnN0cmVhbSA9IG5ldyBTdHJlYW0obGlzdCk7XG4gICAgICByZWNlaXZlZCA9IGZhbHNlO1xuICAgICAgc291cmNlLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICAgIHZhciBlLCBlcnJvcjtcbiAgICAgICAgICByZWNlaXZlZCA9IHRydWU7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMucmVhZENodW5rKGNodW5rKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHNvdXJjZS5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoIXJlY2VpdmVkKSB7XG4gICAgICAgICAgICBfdGhpcy5yZWFkQ2h1bmsoY2h1bmspO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNlZWtQb2ludHMgPSBbXTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oY2h1bmspIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuYWRkU2Vla1BvaW50ID0gZnVuY3Rpb24ob2Zmc2V0LCB0aW1lc3RhbXApIHtcbiAgICAgIHZhciBpbmRleDtcbiAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHMuc3BsaWNlKGluZGV4LCAwLCB7XG4gICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnNlYXJjaFRpbWVzdGFtcCA9IGZ1bmN0aW9uKHRpbWVzdGFtcCwgYmFja3dhcmQpIHtcbiAgICAgIHZhciBoaWdoLCBsb3csIG1pZCwgdGltZTtcbiAgICAgIGxvdyA9IDA7XG4gICAgICBoaWdoID0gdGhpcy5zZWVrUG9pbnRzLmxlbmd0aDtcbiAgICAgIGlmIChoaWdoID4gMCAmJiB0aGlzLnNlZWtQb2ludHNbaGlnaCAtIDFdLnRpbWVzdGFtcCA8IHRpbWVzdGFtcCkge1xuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICAgIG1pZCA9IChsb3cgKyBoaWdoKSA+PiAxO1xuICAgICAgICB0aW1lID0gdGhpcy5zZWVrUG9pbnRzW21pZF0udGltZXN0YW1wO1xuICAgICAgICBpZiAodGltZSA8IHRpbWVzdGFtcCkge1xuICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgIH0gZWxzZSBpZiAodGltZSA+PSB0aW1lc3RhbXApIHtcbiAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaGlnaCA+IHRoaXMuc2Vla1BvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgaGlnaCA9IHRoaXMuc2Vla1BvaW50cy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGlnaDtcbiAgICB9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIGluZGV4LCBzZWVrUG9pbnQ7XG4gICAgICBpZiAodGhpcy5mb3JtYXQgJiYgdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0ID4gMCAmJiB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA+IDApIHtcbiAgICAgICAgc2Vla1BvaW50ID0ge1xuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIG9mZnNldDogdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgKiB0aW1lc3RhbXAgLyB0aGlzLmZvcm1hdC5mcmFtZXNQZXJQYWNrZXRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHNlZWtQb2ludDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vla1BvaW50c1tpbmRleF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvcm1hdHMgPSBbXTtcblxuICAgIERlbXV4ZXIucmVnaXN0ZXIgPSBmdW5jdGlvbihkZW11eGVyKSB7XG4gICAgICByZXR1cm4gZm9ybWF0cy5wdXNoKGRlbXV4ZXIpO1xuICAgIH07XG5cbiAgICBEZW11eGVyLmZpbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBlLCBlcnJvciwgZm9ybWF0LCBpLCBsZW4sIG9mZnNldCwgc3RyZWFtO1xuICAgICAgc3RyZWFtID0gU3RyZWFtLmZyb21CdWZmZXIoYnVmZmVyKTtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGZvcm1hdHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZm9ybWF0ID0gZm9ybWF0c1tpXTtcbiAgICAgICAgb2Zmc2V0ID0gc3RyZWFtLm9mZnNldDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoZm9ybWF0LnByb2JlKHN0cmVhbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGUgPSBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBzdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBEZW11eGVyO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBEZW11eGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFJRkZEZW11eGVyLCBEZW11eGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRGVtdXhlciA9IHJlcXVpcmUoJy4uL2RlbXV4ZXInKTtcblxuICBBSUZGRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKEFJRkZEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEFJRkZEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIEFJRkZEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoQUlGRkRlbXV4ZXIpO1xuXG4gICAgQUlGRkRlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdGT1JNJyAmJiAoKHJlZiA9IGJ1ZmZlci5wZWVrU3RyaW5nKDgsIDQpKSA9PT0gJ0FJRkYnIHx8IHJlZiA9PT0gJ0FJRkMnKTtcbiAgICB9O1xuXG4gICAgQUlGRkRlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgZm9ybWF0LCBvZmZzZXQsIHJlZjtcbiAgICAgIGlmICghdGhpcy5yZWFkU3RhcnQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEyKSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ0ZPUk0nKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZmlsZVR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICgocmVmID0gdGhpcy5maWxlVHlwZSkgIT09ICdBSUZGJyAmJiByZWYgIT09ICdBSUZDJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ0ludmFsaWQgQUlGRi4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZEhlYWRlcnMgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDgpKSB7XG4gICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICB0aGlzLmxlbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ0NPTU0nOlxuICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0ge1xuICAgICAgICAgICAgICBmb3JtYXRJRDogJ2xwY20nLFxuICAgICAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCksXG4gICAgICAgICAgICAgIHNhbXBsZUNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgICAgIGJpdHNQZXJDaGFubmVsOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCksXG4gICAgICAgICAgICAgIHNhbXBsZVJhdGU6IHRoaXMuc3RyZWFtLnJlYWRGbG9hdDgwKCksXG4gICAgICAgICAgICAgIGZyYW1lc1BlclBhY2tldDogMSxcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuOiBmYWxzZSxcbiAgICAgICAgICAgICAgZmxvYXRpbmdQb2ludDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9ICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpICogdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmZpbGVUeXBlID09PSAnQUlGQycpIHtcbiAgICAgICAgICAgICAgZm9ybWF0ID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICAgICAgdGhpcy5mb3JtYXQubGl0dGxlRW5kaWFuID0gZm9ybWF0ID09PSAnc293dCcgJiYgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPiA4O1xuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50ID0gZm9ybWF0ID09PSAnZmwzMicgfHwgZm9ybWF0ID09PSAnZmw2NCc7XG4gICAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICd0d29zJyB8fCBmb3JtYXQgPT09ICdzb3d0JyB8fCBmb3JtYXQgPT09ICdmbDMyJyB8fCBmb3JtYXQgPT09ICdmbDY0JyB8fCBmb3JtYXQgPT09ICdOT05FJykge1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9ICdscGNtJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5mb3JtYXRJRCA9IGZvcm1hdDtcbiAgICAgICAgICAgICAgdGhpcy5sZW4gLT0gNDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSAxOCk7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMuZm9ybWF0KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLmZvcm1hdC5zYW1wbGVDb3VudCAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdTU05EJzpcbiAgICAgICAgICAgIGlmICghKHRoaXMucmVhZFNTTkRIZWFkZXIgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDQpKSkge1xuICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2Uob2Zmc2V0KTtcbiAgICAgICAgICAgICAgdGhpcy5yZWFkU1NOREhlYWRlciA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMubGVuKTtcbiAgICAgICAgICAgIHRoaXMubGVuIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gdGhpcy5sZW4gPiAwO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ1NTTkQnKSB7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBBSUZGRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVURlbXV4ZXIsIERlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIEFVRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGJwcywgZm9ybWF0cztcblxuICAgIGV4dGVuZChBVURlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQVVEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIEFVRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKEFVRGVtdXhlcik7XG5cbiAgICBBVURlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJy5zbmQnO1xuICAgIH07XG5cbiAgICBicHMgPSBbOCwgOCwgMTYsIDI0LCAzMiwgMzIsIDY0XTtcblxuICAgIGJwc1syNl0gPSA4O1xuXG4gICAgZm9ybWF0cyA9IHtcbiAgICAgIDE6ICd1bGF3JyxcbiAgICAgIDI3OiAnYWxhdydcbiAgICB9O1xuXG4gICAgQVVEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBieXRlcywgZGF0YVNpemUsIGVuY29kaW5nLCBzaXplO1xuICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXIgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDI0KSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJy5zbmQnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBVSBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGRhdGFTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICBlbmNvZGluZyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgZm9ybWF0SUQ6IGZvcm1hdHNbZW5jb2RpbmddIHx8ICdscGNtJyxcbiAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgIGZsb2F0aW5nUG9pbnQ6IGVuY29kaW5nID09PSA2IHx8IGVuY29kaW5nID09PSA3LFxuICAgICAgICAgIGJpdHNQZXJDaGFubmVsOiBicHNbZW5jb2RpbmcgLSAxXSxcbiAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgY2hhbm5lbHNQZXJGcmFtZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGZyYW1lc1BlclBhY2tldDogMVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vuc3VwcG9ydGVkIGVuY29kaW5nIGluIEFVIGZpbGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPSAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSAqIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWU7XG4gICAgICAgIGlmIChkYXRhU2l6ZSAhPT0gMHhmZmZmZmZmZikge1xuICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCBkYXRhU2l6ZSAvIGJ5dGVzIC8gdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgIHRoaXMucmVhZEhlYWRlciA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5yZWFkSGVhZGVyKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQVVEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIENBRkRlbXV4ZXIsIERlbXV4ZXIsIE00QURlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIE00QURlbXV4ZXIgPSByZXF1aXJlKCcuL200YScpO1xuXG4gIENBRkRlbXV4ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChDQUZEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIENBRkRlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQ0FGRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKENBRkRlbXV4ZXIpO1xuXG4gICAgQ0FGRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDAsIDQpID09PSAnY2FmZic7XG4gICAgfTtcblxuICAgIENBRkRlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgYnl0ZU9mZnNldCwgY29va2llLCBlbnRyaWVzLCBmbGFncywgaSwgaiwgaywga2V5LCBtZXRhZGF0YSwgb2Zmc2V0LCByZWYsIHJlZjEsIHNhbXBsZU9mZnNldCwgdmFsdWU7XG4gICAgICBpZiAoIXRoaXMuZm9ybWF0ICYmIHRoaXMuc3RyZWFtLmF2YWlsYWJsZSg2NCkpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCkgIT09ICdjYWZmJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJJbnZhbGlkIENBRiwgZG9lcyBub3QgYmVnaW4gd2l0aCAnY2FmZidcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCkgIT09ICdkZXNjJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJJbnZhbGlkIENBRiwgJ2NhZmYnIGlzIG5vdCBmb2xsb3dlZCBieSAnZGVzYydcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpID09PSAwICYmIHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSA9PT0gMzIpKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkludmFsaWQgJ2Rlc2MnIHNpemUsIHNob3VsZCBiZSAzMlwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1hdCA9IHt9O1xuICAgICAgICB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlID0gdGhpcy5zdHJlYW0ucmVhZEZsb2F0NjQoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuZm9ybWF0SUQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICBmbGFncyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgaWYgKHRoaXMuZm9ybWF0LmZvcm1hdElEID09PSAnbHBjbScpIHtcbiAgICAgICAgICB0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50ID0gQm9vbGVhbihmbGFncyAmIDEpO1xuICAgICAgICAgIHRoaXMuZm9ybWF0LmxpdHRsZUVuZGlhbiA9IEJvb2xlYW4oZmxhZ3MgJiAyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0ID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5oZWFkZXJDYWNoZSkge1xuICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSB7XG4gICAgICAgICAgICB0eXBlOiB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpLFxuICAgICAgICAgICAgb3ZlcnNpemU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAhPT0gMCxcbiAgICAgICAgICAgIHNpemU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHRoaXMuaGVhZGVyQ2FjaGUub3ZlcnNpemUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJIb2x5IFNoaXQsIGFuIG92ZXJzaXplZCBmaWxlLCBub3Qgc3VwcG9ydGVkIGluIEpTXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMuaGVhZGVyQ2FjaGUudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2t1a2knOlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmZvcm1hdC5mb3JtYXRJRCA9PT0gJ2FhYyAnKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5oZWFkZXJDYWNoZS5zaXplO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWUgPSBNNEFEZW11eGVyLnJlYWRFc2RzKHRoaXMuc3RyZWFtKSkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdjb29raWUnLCBjb29raWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyID0gdGhpcy5zdHJlYW0ucmVhZEJ1ZmZlcih0aGlzLmhlYWRlckNhY2hlLnNpemUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnY29va2llJywgYnVmZmVyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Bha3QnOlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdTaXplcyBncmVhdGVyIHRoYW4gMzIgYml0cyBhcmUgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLm51bVBhY2tldHMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdTaXplcyBncmVhdGVyIHRoYW4gMzIgYml0cyBhcmUgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLm51bUZyYW1lcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5wcmltaW5nRnJhbWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICB0aGlzLnJlbWFpbmRlckZyYW1lcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMubnVtRnJhbWVzIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgICAgdGhpcy5zZW50RHVyYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgICBieXRlT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgc2FtcGxlT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IHRoaXMubnVtUGFja2V0czsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkU2Vla1BvaW50KGJ5dGVPZmZzZXQsIHNhbXBsZU9mZnNldCk7XG4gICAgICAgICAgICAgICAgYnl0ZU9mZnNldCArPSB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgc2FtcGxlT2Zmc2V0ICs9IHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICBtZXRhZGF0YSA9IHt9O1xuICAgICAgICAgICAgZm9yIChpID0gayA9IDAsIHJlZjEgPSBlbnRyaWVzOyAwIDw9IHJlZjEgPyBrIDwgcmVmMSA6IGsgPiByZWYxOyBpID0gMCA8PSByZWYxID8gKytrIDogLS1rKSB7XG4gICAgICAgICAgICAgIGtleSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobnVsbCk7XG4gICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyhudWxsKTtcbiAgICAgICAgICAgICAgbWV0YWRhdGFba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdtZXRhZGF0YScsIG1ldGFkYXRhKTtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VudEZpcnN0RGF0YUNodW5rKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSAtPSA0O1xuICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgIT09IDAgJiYgIXRoaXMuc2VudER1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5udW1GcmFtZXMgPSB0aGlzLmhlYWRlckNhY2hlLnNpemUgLyB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldDtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5udW1GcmFtZXMgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuc2VudEZpcnN0RGF0YUNodW5rID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5oZWFkZXJDYWNoZS5zaXplKTtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSAtPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmhlYWRlckNhY2hlLnNpemUgPD0gMCkge1xuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpO1xuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQ0FGRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZW11eGVyLCBNNEFEZW11eGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgaW5kZXhPZiA9IFtdLmluZGV4T2YgfHwgZnVuY3Rpb24oaXRlbSkgeyBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7IGlmIChpIGluIHRoaXMgJiYgdGhpc1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7IH0gcmV0dXJuIC0xOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgTTRBRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIEJJVFNfUEVSX0NIQU5ORUwsIFRZUEVTLCBhZnRlciwgYXRvbSwgYXRvbXMsIGJvb2wsIGNvbnRhaW5lcnMsIGRpc2tUcmFjaywgZ2VucmVzLCBtZXRhLCBzdHJpbmc7XG5cbiAgICBleHRlbmQoTTRBRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBNNEFEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIE00QURlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihNNEFEZW11eGVyKTtcblxuICAgIFRZUEVTID0gWydNNEEgJywgJ000UCAnLCAnTTRCICcsICdNNFYgJywgJ2lzb20nLCAnbXA0MicsICdxdCAgJ107XG5cbiAgICBNNEFEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDQsIDQpID09PSAnZnR5cCcgJiYgKHJlZiA9IGJ1ZmZlci5wZWVrU3RyaW5nKDgsIDQpLCBpbmRleE9mLmNhbGwoVFlQRVMsIHJlZikgPj0gMCk7XG4gICAgfTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYXRvbXMgPSBbXTtcbiAgICAgIHRoaXMub2Zmc2V0cyA9IFtdO1xuICAgICAgdGhpcy50cmFjayA9IG51bGw7XG4gICAgICByZXR1cm4gdGhpcy50cmFja3MgPSBbXTtcbiAgICB9O1xuXG4gICAgYXRvbXMgPSB7fTtcblxuICAgIGNvbnRhaW5lcnMgPSB7fTtcblxuICAgIGF0b20gPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgdmFyIGMsIGNvbnRhaW5lciwgaywgbGVuMSwgcmVmO1xuICAgICAgYyA9IFtdO1xuICAgICAgcmVmID0gbmFtZS5zcGxpdCgnLicpLnNsaWNlKDAsIC0xKTtcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYubGVuZ3RoOyBrIDwgbGVuMTsgaysrKSB7XG4gICAgICAgIGNvbnRhaW5lciA9IHJlZltrXTtcbiAgICAgICAgYy5wdXNoKGNvbnRhaW5lcik7XG4gICAgICAgIGNvbnRhaW5lcnNbYy5qb2luKCcuJyldID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChhdG9tc1tuYW1lXSA9PSBudWxsKSB7XG4gICAgICAgIGF0b21zW25hbWVdID0ge307XG4gICAgICB9XG4gICAgICByZXR1cm4gYXRvbXNbbmFtZV0uZm4gPSBmbjtcbiAgICB9O1xuXG4gICAgYWZ0ZXIgPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgaWYgKGF0b21zW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgYXRvbXNbbmFtZV0gPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdG9tc1tuYW1lXS5hZnRlciA9IGZuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBoYW5kbGVyLCBwYXRoLCB0eXBlO1xuICAgICAgdGhpc1tcImJyZWFrXCJdID0gZmFsc2U7XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpICYmICF0aGlzW1wiYnJlYWtcIl0pIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXJzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5sZW4gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgLSA4O1xuICAgICAgICAgIHRoaXMudHlwZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgICAgaWYgKHRoaXMubGVuID09PSAwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hdG9tcy5wdXNoKHRoaXMudHlwZSk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnB1c2godGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5sZW4pO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHBhdGggPSB0aGlzLmF0b21zLmpvaW4oJy4nKTtcbiAgICAgICAgaGFuZGxlciA9IGF0b21zW3BhdGhdO1xuICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsID8gaGFuZGxlci5mbiA6IHZvaWQgMCkge1xuICAgICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikgfHwgcGF0aCA9PT0gJ21kYXQnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYW5kbGVyLmZuLmNhbGwodGhpcyk7XG4gICAgICAgICAgaWYgKHBhdGggaW4gY29udGFpbmVycykge1xuICAgICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwYXRoIGluIGNvbnRhaW5lcnMpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4pO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5vZmZzZXQgPj0gdGhpcy5vZmZzZXRzW3RoaXMub2Zmc2V0cy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgIGhhbmRsZXIgPSBhdG9tc1t0aGlzLmF0b21zLmpvaW4oJy4nKV07XG4gICAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCA/IGhhbmRsZXIuYWZ0ZXIgOiB2b2lkIDApIHtcbiAgICAgICAgICAgIGhhbmRsZXIuYWZ0ZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IHRoaXMuYXRvbXMucG9wKCk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnBvcCgpO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBhdG9tKCdmdHlwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgaWYgKHJlZiA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCksIGluZGV4T2YuY2FsbChUWVBFUywgcmVmKSA8IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnTm90IGEgdmFsaWQgTTRBIGZpbGUuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDQpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnRyYWNrID0ge307XG4gICAgICByZXR1cm4gdGhpcy50cmFja3MucHVzaCh0aGlzLnRyYWNrKTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay50a2hkJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg4KTtcbiAgICAgIHRoaXMudHJhY2suaWQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE2KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLmhkbHInLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy50cmFjay50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMTIpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSAyNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5tZGhkJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg4KTtcbiAgICAgIHRoaXMudHJhY2sudGltZVNjYWxlID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5kdXJhdGlvbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgIH0pO1xuXG4gICAgQklUU19QRVJfQ0hBTk5FTCA9IHtcbiAgICAgIHVsYXc6IDgsXG4gICAgICBhbGF3OiA4LFxuICAgICAgaW4yNDogMjQsXG4gICAgICBpbjMyOiAzMixcbiAgICAgIGZsMzI6IDMyLFxuICAgICAgZmw2NDogNjRcbiAgICB9O1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2QnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBmb3JtYXQsIG51bUVudHJpZXMsIHJlZiwgcmVmMSwgdmVyc2lvbjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBudW1FbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgaWYgKHRoaXMudHJhY2sudHlwZSAhPT0gJ3NvdW4nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gOCk7XG4gICAgICB9XG4gICAgICBpZiAobnVtRW50cmllcyAhPT0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiT25seSBleHBlY3Rpbmcgb25lIGVudHJ5IGluIHNhbXBsZSBkZXNjcmlwdGlvbiBhdG9tIVwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBmb3JtYXQgPSB0aGlzLnRyYWNrLmZvcm1hdCA9IHt9O1xuICAgICAgZm9ybWF0LmZvcm1hdElEID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNik7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgdmVyc2lvbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNik7XG4gICAgICBmb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIGZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBmb3JtYXQuc2FtcGxlUmF0ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICBpZiAodmVyc2lvbiA9PT0gMSkge1xuICAgICAgICBmb3JtYXQuZnJhbWVzUGVyUGFja2V0ID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBmb3JtYXQuYnl0ZXNQZXJGcmFtZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIH0gZWxzZSBpZiAodmVyc2lvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vua25vd24gdmVyc2lvbiBpbiBzdHNkIGF0b20nKTtcbiAgICAgIH1cbiAgICAgIGlmIChCSVRTX1BFUl9DSEFOTkVMW2Zvcm1hdC5mb3JtYXRJRF0gIT0gbnVsbCkge1xuICAgICAgICBmb3JtYXQuYml0c1BlckNoYW5uZWwgPSBCSVRTX1BFUl9DSEFOTkVMW2Zvcm1hdC5mb3JtYXRJRF07XG4gICAgICB9XG4gICAgICBmb3JtYXQuZmxvYXRpbmdQb2ludCA9IChyZWYgPSBmb3JtYXQuZm9ybWF0SUQpID09PSAnZmwzMicgfHwgcmVmID09PSAnZmw2NCc7XG4gICAgICBmb3JtYXQubGl0dGxlRW5kaWFuID0gZm9ybWF0LmZvcm1hdElEID09PSAnc293dCcgJiYgZm9ybWF0LmJpdHNQZXJDaGFubmVsID4gODtcbiAgICAgIGlmICgocmVmMSA9IGZvcm1hdC5mb3JtYXRJRCkgPT09ICd0d29zJyB8fCByZWYxID09PSAnc293dCcgfHwgcmVmMSA9PT0gJ2luMjQnIHx8IHJlZjEgPT09ICdpbjMyJyB8fCByZWYxID09PSAnZmwzMicgfHwgcmVmMSA9PT0gJ2ZsNjQnIHx8IHJlZjEgPT09ICdyYXcgJyB8fCByZWYxID09PSAnTk9ORScpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdC5mb3JtYXRJRCA9ICdscGNtJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmFsYWMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICByZXR1cm4gdGhpcy50cmFjay5jb29raWUgPSB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKHRoaXMubGVuIC0gNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZC5lc2RzJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgb2Zmc2V0O1xuICAgICAgb2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5sZW47XG4gICAgICB0aGlzLnRyYWNrLmNvb2tpZSA9IE00QURlbXV4ZXIucmVhZEVzZHModGhpcy5zdHJlYW0pO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLndhdmUuZW5kYScsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudHJhY2suZm9ybWF0LmxpdHRsZUVuZGlhbiA9ICEhdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgIH0pO1xuXG4gICAgTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgIHZhciBjLCBjb3VudCwgbGVuO1xuICAgICAgbGVuID0gMDtcbiAgICAgIGNvdW50ID0gNDtcbiAgICAgIHdoaWxlIChjb3VudC0tKSB7XG4gICAgICAgIGMgPSBzdHJlYW0ucmVhZFVJbnQ4KCk7XG4gICAgICAgIGxlbiA9IChsZW4gPDwgNykgfCAoYyAmIDB4N2YpO1xuICAgICAgICBpZiAoIShjICYgMHg4MCkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGxlbjtcbiAgICB9O1xuXG4gICAgTTRBRGVtdXhlci5yZWFkRXNkcyA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGNvZGVjX2lkLCBmbGFncywgbGVuLCB0YWc7XG4gICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIGxlbiA9IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHN0cmVhbSk7XG4gICAgICBpZiAodGFnID09PSAweDAzKSB7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICBmbGFncyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgaWYgKGZsYWdzICYgMHg4MCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbGFncyAmIDB4NDApIHtcbiAgICAgICAgICBzdHJlYW0uYWR2YW5jZShzdHJlYW0ucmVhZFVJbnQ4KCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbGFncyAmIDB4MjApIHtcbiAgICAgICAgICBzdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICB9XG4gICAgICB0YWcgPSBzdHJlYW0ucmVhZFVJbnQ4KCk7XG4gICAgICBsZW4gPSBNNEFEZW11eGVyLnJlYWREZXNjckxlbihzdHJlYW0pO1xuICAgICAgaWYgKHRhZyA9PT0gMHgwNCkge1xuICAgICAgICBjb2RlY19pZCA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDMpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgbGVuID0gTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4oc3RyZWFtKTtcbiAgICAgICAgaWYgKHRhZyA9PT0gMHgwNSkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW0ucmVhZEJ1ZmZlcihsZW4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0dHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnRyaWVzLCBpLCBrLCByZWY7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHRoaXMudHJhY2suc3R0cyA9IFtdO1xuICAgICAgZm9yIChpID0gayA9IDAsIHJlZiA9IGVudHJpZXM7IGsgPCByZWY7IGkgPSBrICs9IDEpIHtcbiAgICAgICAgdGhpcy50cmFjay5zdHRzW2ldID0ge1xuICAgICAgICAgIGNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgZHVyYXRpb246IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzYycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5zdHNjID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLnN0c2NbaV0gPSB7XG4gICAgICAgICAgZmlyc3Q6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBjb3VudDogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGlkOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKClcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNldHVwU2Vla1BvaW50cygpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c3onLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnRyaWVzLCBpLCBrLCByZWY7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIGlmICh0aGlzLnRyYWNrLnNhbXBsZVNpemUgPT09IDAgJiYgZW50cmllcyA+IDApIHtcbiAgICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplcyA9IFtdO1xuICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgIHRoaXMudHJhY2suc2FtcGxlU2l6ZXNbaV0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNldHVwU2Vla1BvaW50cygpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0Y28nLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbnRyaWVzLCBpLCBrLCByZWY7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHRoaXMudHJhY2suY2h1bmtPZmZzZXRzID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0c1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNldHVwU2Vla1BvaW50cygpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLnRyZWYuY2hhcCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIGVudHJpZXMgPSB0aGlzLmxlbiA+PiAyO1xuICAgICAgdGhpcy50cmFjay5jaGFwdGVyVHJhY2tzID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3NbaV0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5zZXR1cFNlZWtQb2ludHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBqLCBrLCBsLCBsZW4xLCBvZmZzZXQsIHBvc2l0aW9uLCByZWYsIHJlZjEsIHJlc3VsdHMsIHNhbXBsZUluZGV4LCBzaXplLCBzdHNjSW5kZXgsIHN0dHNJbmRleCwgc3R0c1NhbXBsZSwgdGltZXN0YW1wO1xuICAgICAgaWYgKCEoKHRoaXMudHJhY2suY2h1bmtPZmZzZXRzICE9IG51bGwpICYmICh0aGlzLnRyYWNrLnN0c2MgIT0gbnVsbCkgJiYgKHRoaXMudHJhY2suc2FtcGxlU2l6ZSAhPSBudWxsKSAmJiAodGhpcy50cmFjay5zdHRzICE9IG51bGwpKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdHNjSW5kZXggPSAwO1xuICAgICAgc3R0c0luZGV4ID0gMDtcbiAgICAgIHN0dHNJbmRleCA9IDA7XG4gICAgICBzdHRzU2FtcGxlID0gMDtcbiAgICAgIHNhbXBsZUluZGV4ID0gMDtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgICB0aW1lc3RhbXAgPSAwO1xuICAgICAgdGhpcy50cmFjay5zZWVrUG9pbnRzID0gW107XG4gICAgICByZWYgPSB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cztcbiAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCBsZW4xID0gcmVmLmxlbmd0aDsgayA8IGxlbjE7IGkgPSArK2spIHtcbiAgICAgICAgcG9zaXRpb24gPSByZWZbaV07XG4gICAgICAgIGZvciAoaiA9IGwgPSAwLCByZWYxID0gdGhpcy50cmFjay5zdHNjW3N0c2NJbmRleF0uY291bnQ7IGwgPCByZWYxOyBqID0gbCArPSAxKSB7XG4gICAgICAgICAgdGhpcy50cmFjay5zZWVrUG9pbnRzLnB1c2goe1xuICAgICAgICAgICAgb2Zmc2V0OiBvZmZzZXQsXG4gICAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNpemUgPSB0aGlzLnRyYWNrLnNhbXBsZVNpemUgfHwgdGhpcy50cmFjay5zYW1wbGVTaXplc1tzYW1wbGVJbmRleCsrXTtcbiAgICAgICAgICBvZmZzZXQgKz0gc2l6ZTtcbiAgICAgICAgICBwb3NpdGlvbiArPSBzaXplO1xuICAgICAgICAgIHRpbWVzdGFtcCArPSB0aGlzLnRyYWNrLnN0dHNbc3R0c0luZGV4XS5kdXJhdGlvbjtcbiAgICAgICAgICBpZiAoc3R0c0luZGV4ICsgMSA8IHRoaXMudHJhY2suc3R0cy5sZW5ndGggJiYgKytzdHRzU2FtcGxlID09PSB0aGlzLnRyYWNrLnN0dHNbc3R0c0luZGV4XS5jb3VudCkge1xuICAgICAgICAgICAgc3R0c1NhbXBsZSA9IDA7XG4gICAgICAgICAgICBzdHRzSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0c2NJbmRleCArIDEgPCB0aGlzLnRyYWNrLnN0c2MubGVuZ3RoICYmIGkgKyAxID09PSB0aGlzLnRyYWNrLnN0c2Nbc3RzY0luZGV4ICsgMV0uZmlyc3QpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goc3RzY0luZGV4KyspO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCh2b2lkIDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9O1xuXG4gICAgYWZ0ZXIoJ21vb3YnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrLCBsZW4xLCByZWYsIHRyYWNrO1xuICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0IC0gOCk7XG4gICAgICB9XG4gICAgICByZWYgPSB0aGlzLnRyYWNrcztcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYubGVuZ3RoOyBrIDwgbGVuMTsgaysrKSB7XG4gICAgICAgIHRyYWNrID0gcmVmW2tdO1xuICAgICAgICBpZiAoISh0cmFjay50eXBlID09PSAnc291bicpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50cmFjayA9IHRyYWNrO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnRyYWNrLnR5cGUgIT09ICdzb3VuJykge1xuICAgICAgICB0aGlzLnRyYWNrID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnTm8gYXVkaW8gdHJhY2tzIGluIG00YSBmaWxlLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLnRyYWNrLmZvcm1hdCk7XG4gICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy50cmFjay5kdXJhdGlvbiAvIHRoaXMudHJhY2sudGltZVNjYWxlICogMTAwMCB8IDApO1xuICAgICAgaWYgKHRoaXMudHJhY2suY29va2llKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnY29va2llJywgdGhpcy50cmFjay5jb29raWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2Vla1BvaW50cyA9IHRoaXMudHJhY2suc2Vla1BvaW50cztcbiAgICB9KTtcblxuICAgIGF0b20oJ21kYXQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBieXRlcywgY2h1bmtTaXplLCBrLCBsZW5ndGgsIG51bVNhbXBsZXMsIG9mZnNldCwgcmVmLCBzYW1wbGUsIHNpemU7XG4gICAgICBpZiAoIXRoaXMuc3RhcnRlZERhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5tZGF0T2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRyYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBieXRlcyA9IE1hdGgubWluKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCksIHRoaXMubGVuKTtcbiAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKGJ5dGVzKTtcbiAgICAgICAgICB0aGlzLmxlbiAtPSBieXRlcztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaHVua0luZGV4ID0gMDtcbiAgICAgICAgdGhpcy5zdHNjSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnNhbXBsZUluZGV4ID0gMDtcbiAgICAgICAgdGhpcy50YWlsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy50YWlsU2FtcGxlcyA9IDA7XG4gICAgICAgIHRoaXMuc3RhcnRlZERhdGEgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnJlYWRDaGFwdGVycykge1xuICAgICAgICB0aGlzLnJlYWRDaGFwdGVycyA9IHRoaXMucGFyc2VDaGFwdGVycygpO1xuICAgICAgICBpZiAodGhpc1tcImJyZWFrXCJdID0gIXRoaXMucmVhZENoYXB0ZXJzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW3RoaXMuY2h1bmtJbmRleF0gKyB0aGlzLnRhaWxPZmZzZXQ7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUob2Zmc2V0IC0gdGhpcy5zdHJlYW0ub2Zmc2V0KSkge1xuICAgICAgICB0aGlzW1wiYnJlYWtcIl0gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICB3aGlsZSAodGhpcy5jaHVua0luZGV4IDwgdGhpcy50cmFjay5jaHVua09mZnNldHMubGVuZ3RoKSB7XG4gICAgICAgIG51bVNhbXBsZXMgPSB0aGlzLnRyYWNrLnN0c2NbdGhpcy5zdHNjSW5kZXhdLmNvdW50IC0gdGhpcy50YWlsU2FtcGxlcztcbiAgICAgICAgY2h1bmtTaXplID0gMDtcbiAgICAgICAgZm9yIChzYW1wbGUgPSBrID0gMCwgcmVmID0gbnVtU2FtcGxlczsgayA8IHJlZjsgc2FtcGxlID0gayArPSAxKSB7XG4gICAgICAgICAgc2l6ZSA9IHRoaXMudHJhY2suc2FtcGxlU2l6ZSB8fCB0aGlzLnRyYWNrLnNhbXBsZVNpemVzW3RoaXMuc2FtcGxlSW5kZXhdO1xuICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKGxlbmd0aCArIHNpemUpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgbGVuZ3RoICs9IHNpemU7XG4gICAgICAgICAgY2h1bmtTaXplICs9IHNpemU7XG4gICAgICAgICAgdGhpcy5zYW1wbGVJbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzYW1wbGUgPCBudW1TYW1wbGVzKSB7XG4gICAgICAgICAgdGhpcy50YWlsT2Zmc2V0ICs9IGNodW5rU2l6ZTtcbiAgICAgICAgICB0aGlzLnRhaWxTYW1wbGVzICs9IHNhbXBsZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNodW5rSW5kZXgrKztcbiAgICAgICAgICB0aGlzLnRhaWxPZmZzZXQgPSAwO1xuICAgICAgICAgIHRoaXMudGFpbFNhbXBsZXMgPSAwO1xuICAgICAgICAgIGlmICh0aGlzLnN0c2NJbmRleCArIDEgPCB0aGlzLnRyYWNrLnN0c2MubGVuZ3RoICYmIHRoaXMuY2h1bmtJbmRleCArIDEgPT09IHRoaXMudHJhY2suc3RzY1t0aGlzLnN0c2NJbmRleCArIDFdLmZpcnN0KSB7XG4gICAgICAgICAgICB0aGlzLnN0c2NJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAob2Zmc2V0ICsgbGVuZ3RoICE9PSB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0c1t0aGlzLmNodW5rSW5kZXhdKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIobGVuZ3RoKSk7XG4gICAgICAgIHJldHVybiB0aGlzW1wiYnJlYWtcIl0gPSB0aGlzLmNodW5rSW5kZXggPT09IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzW1wiYnJlYWtcIl0gPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgTTRBRGVtdXhlci5wcm90b3R5cGUucGFyc2VDaGFwdGVycyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJvbSwgaWQsIGssIGxlbiwgbGVuMSwgbmV4dFRpbWVzdGFtcCwgcG9pbnQsIHJlZiwgcmVmMSwgcmVmMiwgcmVmMywgdGl0bGUsIHRyYWNrO1xuICAgICAgaWYgKCEoKChyZWYgPSB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3MpICE9IG51bGwgPyByZWYubGVuZ3RoIDogdm9pZCAwKSA+IDApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWQgPSB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3NbMF07XG4gICAgICByZWYxID0gdGhpcy50cmFja3M7XG4gICAgICBmb3IgKGsgPSAwLCBsZW4xID0gcmVmMS5sZW5ndGg7IGsgPCBsZW4xOyBrKyspIHtcbiAgICAgICAgdHJhY2sgPSByZWYxW2tdO1xuICAgICAgICBpZiAodHJhY2suaWQgPT09IGlkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0cmFjay5pZCAhPT0gaWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsICdDaGFwdGVyIHRyYWNrIGRvZXMgbm90IGV4aXN0LicpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2hhcHRlcnMgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmNoYXB0ZXJzID0gW107XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5jaGFwdGVycy5sZW5ndGggPCB0cmFjay5zZWVrUG9pbnRzLmxlbmd0aCkge1xuICAgICAgICBwb2ludCA9IHRyYWNrLnNlZWtQb2ludHNbdGhpcy5jaGFwdGVycy5sZW5ndGhdO1xuICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShwb2ludC5wb3NpdGlvbiAtIHRoaXMuc3RyZWFtLm9mZnNldCArIDMyKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0cmVhbS5zZWVrKHBvaW50LnBvc2l0aW9uKTtcbiAgICAgICAgbGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgICB0aXRsZSA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKGxlbikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICBib20gPSB0aGlzLnN0cmVhbS5wZWVrVUludDE2KCk7XG4gICAgICAgICAgaWYgKGJvbSA9PT0gMHhmZWZmIHx8IGJvbSA9PT0gMHhmZmZlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobGVuLCAndXRmMTYtYm9tJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aXRsZSA9PSBudWxsKSB7XG4gICAgICAgICAgdGl0bGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKGxlbiwgJ3V0ZjgnKTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0VGltZXN0YW1wID0gKHJlZjIgPSAocmVmMyA9IHRyYWNrLnNlZWtQb2ludHNbdGhpcy5jaGFwdGVycy5sZW5ndGggKyAxXSkgIT0gbnVsbCA/IHJlZjMudGltZXN0YW1wIDogdm9pZCAwKSAhPSBudWxsID8gcmVmMiA6IHRyYWNrLmR1cmF0aW9uO1xuICAgICAgICB0aGlzLmNoYXB0ZXJzLnB1c2goe1xuICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICB0aW1lc3RhbXA6IHBvaW50LnRpbWVzdGFtcCAvIHRyYWNrLnRpbWVTY2FsZSAqIDEwMDAgfCAwLFxuICAgICAgICAgIGR1cmF0aW9uOiAobmV4dFRpbWVzdGFtcCAtIHBvaW50LnRpbWVzdGFtcCkgLyB0cmFjay50aW1lU2NhbGUgKiAxMDAwIHwgMFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnY2hhcHRlcnMnLCB0aGlzLmNoYXB0ZXJzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnVkdGEubWV0YScsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5tZXRhZGF0YSA9IHt9O1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgfSk7XG5cbiAgICBhZnRlcignbW9vdi51ZHRhLm1ldGEnLCBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ21ldGFkYXRhJywgdGhpcy5tZXRhZGF0YSk7XG4gICAgfSk7XG5cbiAgICBtZXRhID0gZnVuY3Rpb24oZmllbGQsIG5hbWUsIGZuKSB7XG4gICAgICByZXR1cm4gYXRvbShcIm1vb3YudWR0YS5tZXRhLmlsc3QuXCIgKyBmaWVsZCArIFwiLmRhdGFcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoOCk7XG4gICAgICAgIHRoaXMubGVuIC09IDg7XG4gICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIG5hbWUpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHN0cmluZyA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKHRoaXMubGVuLCAndXRmOCcpO1xuICAgIH07XG5cbiAgICBtZXRhKCfCqWFsYicsICdhbGJ1bScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWFyZycsICdhcnJhbmdlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWFydCcsICdhcnRpc3QnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlBUlQnLCAnYXJ0aXN0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2FBUlQnLCAnYWxidW1BcnRpc3QnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnY2F0ZycsICdjYXRlZ29yeScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWNvbScsICdjb21wb3NlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWNweScsICdjb3B5cmlnaHQnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnY3BydCcsICdjb3B5cmlnaHQnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqljbXQnLCAnY29tbWVudHMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlkYXknLCAncmVsZWFzZURhdGUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnZGVzYycsICdkZXNjcmlwdGlvbicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWdlbicsICdnZW5yZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWdycCcsICdncm91cGluZycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWlzcicsICdJU1JDJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2tleXcnLCAna2V5d29yZHMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlsYWInLCAncmVjb3JkTGFiZWwnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnbGRlcycsICdsb25nRGVzY3JpcHRpb24nLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlseXInLCAnbHlyaWNzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpbmFtJywgJ3RpdGxlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpcGhnJywgJ3JlY29yZGluZ0NvcHlyaWdodCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXByZCcsICdwcm9kdWNlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXByZicsICdwZXJmb3JtZXJzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ3B1cmQnLCAncHVyY2hhc2VEYXRlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ3B1cmwnLCAncG9kY2FzdFVSTCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXN3ZicsICdzb25nd3JpdGVyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpdG9vJywgJ2VuY29kZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwql3cnQnLCAnY29tcG9zZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnY292cicsICdjb3ZlckFydCcsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKHRoaXMubGVuKTtcbiAgICB9KTtcblxuICAgIGdlbnJlcyA9IFtcIkJsdWVzXCIsIFwiQ2xhc3NpYyBSb2NrXCIsIFwiQ291bnRyeVwiLCBcIkRhbmNlXCIsIFwiRGlzY29cIiwgXCJGdW5rXCIsIFwiR3J1bmdlXCIsIFwiSGlwLUhvcFwiLCBcIkphenpcIiwgXCJNZXRhbFwiLCBcIk5ldyBBZ2VcIiwgXCJPbGRpZXNcIiwgXCJPdGhlclwiLCBcIlBvcFwiLCBcIlImQlwiLCBcIlJhcFwiLCBcIlJlZ2dhZVwiLCBcIlJvY2tcIiwgXCJUZWNobm9cIiwgXCJJbmR1c3RyaWFsXCIsIFwiQWx0ZXJuYXRpdmVcIiwgXCJTa2FcIiwgXCJEZWF0aCBNZXRhbFwiLCBcIlByYW5rc1wiLCBcIlNvdW5kdHJhY2tcIiwgXCJFdXJvLVRlY2hub1wiLCBcIkFtYmllbnRcIiwgXCJUcmlwLUhvcFwiLCBcIlZvY2FsXCIsIFwiSmF6eitGdW5rXCIsIFwiRnVzaW9uXCIsIFwiVHJhbmNlXCIsIFwiQ2xhc3NpY2FsXCIsIFwiSW5zdHJ1bWVudGFsXCIsIFwiQWNpZFwiLCBcIkhvdXNlXCIsIFwiR2FtZVwiLCBcIlNvdW5kIENsaXBcIiwgXCJHb3NwZWxcIiwgXCJOb2lzZVwiLCBcIkFsdGVyblJvY2tcIiwgXCJCYXNzXCIsIFwiU291bFwiLCBcIlB1bmtcIiwgXCJTcGFjZVwiLCBcIk1lZGl0YXRpdmVcIiwgXCJJbnN0cnVtZW50YWwgUG9wXCIsIFwiSW5zdHJ1bWVudGFsIFJvY2tcIiwgXCJFdGhuaWNcIiwgXCJHb3RoaWNcIiwgXCJEYXJrd2F2ZVwiLCBcIlRlY2huby1JbmR1c3RyaWFsXCIsIFwiRWxlY3Ryb25pY1wiLCBcIlBvcC1Gb2xrXCIsIFwiRXVyb2RhbmNlXCIsIFwiRHJlYW1cIiwgXCJTb3V0aGVybiBSb2NrXCIsIFwiQ29tZWR5XCIsIFwiQ3VsdFwiLCBcIkdhbmdzdGFcIiwgXCJUb3AgNDBcIiwgXCJDaHJpc3RpYW4gUmFwXCIsIFwiUG9wL0Z1bmtcIiwgXCJKdW5nbGVcIiwgXCJOYXRpdmUgQW1lcmljYW5cIiwgXCJDYWJhcmV0XCIsIFwiTmV3IFdhdmVcIiwgXCJQc3ljaGFkZWxpY1wiLCBcIlJhdmVcIiwgXCJTaG93dHVuZXNcIiwgXCJUcmFpbGVyXCIsIFwiTG8tRmlcIiwgXCJUcmliYWxcIiwgXCJBY2lkIFB1bmtcIiwgXCJBY2lkIEphenpcIiwgXCJQb2xrYVwiLCBcIlJldHJvXCIsIFwiTXVzaWNhbFwiLCBcIlJvY2sgJiBSb2xsXCIsIFwiSGFyZCBSb2NrXCIsIFwiRm9sa1wiLCBcIkZvbGsvUm9ja1wiLCBcIk5hdGlvbmFsIEZvbGtcIiwgXCJTd2luZ1wiLCBcIkZhc3QgRnVzaW9uXCIsIFwiQmVib2JcIiwgXCJMYXRpblwiLCBcIlJldml2YWxcIiwgXCJDZWx0aWNcIiwgXCJCbHVlZ3Jhc3NcIiwgXCJBdmFudGdhcmRlXCIsIFwiR290aGljIFJvY2tcIiwgXCJQcm9ncmVzc2l2ZSBSb2NrXCIsIFwiUHN5Y2hlZGVsaWMgUm9ja1wiLCBcIlN5bXBob25pYyBSb2NrXCIsIFwiU2xvdyBSb2NrXCIsIFwiQmlnIEJhbmRcIiwgXCJDaG9ydXNcIiwgXCJFYXN5IExpc3RlbmluZ1wiLCBcIkFjb3VzdGljXCIsIFwiSHVtb3VyXCIsIFwiU3BlZWNoXCIsIFwiQ2hhbnNvblwiLCBcIk9wZXJhXCIsIFwiQ2hhbWJlciBNdXNpY1wiLCBcIlNvbmF0YVwiLCBcIlN5bXBob255XCIsIFwiQm9vdHkgQmFzc1wiLCBcIlByaW11c1wiLCBcIlBvcm4gR3Jvb3ZlXCIsIFwiU2F0aXJlXCIsIFwiU2xvdyBKYW1cIiwgXCJDbHViXCIsIFwiVGFuZ29cIiwgXCJTYW1iYVwiLCBcIkZvbGtsb3JlXCIsIFwiQmFsbGFkXCIsIFwiUG93ZXIgQmFsbGFkXCIsIFwiUmh5dGhtaWMgU291bFwiLCBcIkZyZWVzdHlsZVwiLCBcIkR1ZXRcIiwgXCJQdW5rIFJvY2tcIiwgXCJEcnVtIFNvbG9cIiwgXCJBIENhcGVsbGFcIiwgXCJFdXJvLUhvdXNlXCIsIFwiRGFuY2UgSGFsbFwiXTtcblxuICAgIG1ldGEoJ2ducmUnLCAnZ2VucmUnLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gZ2VucmVzW3RoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSAtIDFdO1xuICAgIH0pO1xuXG4gICAgbWV0YSgndG1wbycsICd0ZW1wbycsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgfSk7XG5cbiAgICBtZXRhKCdydG5nJywgJ3JhdGluZycsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICB2YXIgcmF0aW5nO1xuICAgICAgcmF0aW5nID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQ4KCk7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSByYXRpbmcgPT09IDIgPyAnQ2xlYW4nIDogcmF0aW5nICE9PSAwID8gJ0V4cGxpY2l0JyA6ICdOb25lJztcbiAgICB9KTtcblxuICAgIGRpc2tUcmFjayA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCkgKyAnIG9mICcgKyB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDYpO1xuICAgIH07XG5cbiAgICBtZXRhKCdkaXNrJywgJ2Rpc2tOdW1iZXInLCBkaXNrVHJhY2spO1xuXG4gICAgbWV0YSgndHJrbicsICd0cmFja051bWJlcicsIGRpc2tUcmFjayk7XG5cbiAgICBib29sID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50OCgpID09PSAxO1xuICAgIH07XG5cbiAgICBtZXRhKCdjcGlsJywgJ2NvbXBpbGF0aW9uJywgYm9vbCk7XG5cbiAgICBtZXRhKCdwY3N0JywgJ3BvZGNhc3QnLCBib29sKTtcblxuICAgIG1ldGEoJ3BnYXAnLCAnZ2FwbGVzcycsIGJvb2wpO1xuXG4gICAgcmV0dXJuIE00QURlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBNNEFEZW11eGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlbXV4ZXIsIFdBVkVEZW11eGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRGVtdXhlciA9IHJlcXVpcmUoJy4uL2RlbXV4ZXInKTtcblxuICBXQVZFRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBleHRlbmQoV0FWRURlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gV0FWRURlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gV0FWRURlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihXQVZFRGVtdXhlcik7XG5cbiAgICBXQVZFRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDAsIDQpID09PSAnUklGRicgJiYgYnVmZmVyLnBlZWtTdHJpbmcoOCwgNCkgPT09ICdXQVZFJztcbiAgICB9O1xuXG4gICAgZm9ybWF0cyA9IHtcbiAgICAgIDB4MDAwMTogJ2xwY20nLFxuICAgICAgMHgwMDAzOiAnbHBjbScsXG4gICAgICAweDAwMDY6ICdhbGF3JyxcbiAgICAgIDB4MDAwNzogJ3VsYXcnXG4gICAgfTtcblxuICAgIFdBVkVEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBidWZmZXIsIGJ5dGVzLCBlbmNvZGluZztcbiAgICAgIGlmICghdGhpcy5yZWFkU3RhcnQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEyKSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ1JJRkYnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBXQVYgZmlsZS4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZpbGVTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKTtcbiAgICAgICAgdGhpcy5yZWFkU3RhcnQgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ1dBVkUnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBXQVYgZmlsZS4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZEhlYWRlcnMgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDgpKSB7XG4gICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICB0aGlzLmxlbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdmbXQgJzpcbiAgICAgICAgICAgIGVuY29kaW5nID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKTtcbiAgICAgICAgICAgIGlmICghKGVuY29kaW5nIGluIGZvcm1hdHMpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vuc3VwcG9ydGVkIGZvcm1hdCBpbiBXQVYgZmlsZS4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0ge1xuICAgICAgICAgICAgICBmb3JtYXRJRDogZm9ybWF0c1tlbmNvZGluZ10sXG4gICAgICAgICAgICAgIGZsb2F0aW5nUG9pbnQ6IGVuY29kaW5nID09PSAweDAwMDMsXG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbjogZm9ybWF0c1tlbmNvZGluZ10gPT09ICdscGNtJyxcbiAgICAgICAgICAgICAgY2hhbm5lbHNQZXJGcmFtZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKSxcbiAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKSxcbiAgICAgICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgICAgICB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9ICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpICogdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE2KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgICAgICAgaWYgKCF0aGlzLnNlbnREdXJhdGlvbikge1xuICAgICAgICAgICAgICBieXRlcyA9IHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gODtcbiAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMubGVuIC8gYnl0ZXMgLyB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgICAgdGhpcy5zZW50RHVyYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnVmZmVyID0gdGhpcy5zdHJlYW0ucmVhZFNpbmdsZUJ1ZmZlcih0aGlzLmxlbik7XG4gICAgICAgICAgICB0aGlzLmxlbiAtPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IHRoaXMubGVuID4gMDtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIGJ1ZmZlcik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09ICdkYXRhJykge1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gV0FWRURlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTAuMFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQXVkaW9EZXZpY2UsIEV2ZW50RW1pdHRlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBBdWRpb0RldmljZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGRldmljZXM7XG5cbiAgICBleHRlbmQoQXVkaW9EZXZpY2UsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQXVkaW9EZXZpY2Uoc2FtcGxlUmF0ZTEsIGNoYW5uZWxzMSkge1xuICAgICAgdGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTE7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gY2hhbm5lbHMxO1xuICAgICAgdGhpcy51cGRhdGVUaW1lID0gYmluZCh0aGlzLnVwZGF0ZVRpbWUsIHRoaXMpO1xuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gMDtcbiAgICB9XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIGlmICh0aGlzLmRldmljZSA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gQXVkaW9EZXZpY2UuY3JlYXRlKHRoaXMuc2FtcGxlUmF0ZSwgdGhpcy5jaGFubmVscyk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZGV2aWNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1cHBvcnRlZCBhdWRpbyBkZXZpY2UgZm91bmQuXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB0aGlzLl90aW1lciA9IHNldEludGVydmFsKHRoaXMudXBkYXRlVGltZSwgMjAwKTtcbiAgICAgIHJldHVybiB0aGlzLmRldmljZS5vbigncmVmaWxsJywgdGhpcy5yZWZpbGwgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdyZWZpbGwnLCBidWZmZXIpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRldmljZS5vZmYoJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIHJldHVybiBjbGVhckludGVydmFsKHRoaXMuX3RpbWVyKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICB0aGlzLnN0b3AoKTtcbiAgICAgIHJldHVybiAocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyByZWYuZGVzdHJveSgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKGN1cnJlbnRUaW1lKSB7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgndGltZVVwZGF0ZScsIHRoaXMuY3VycmVudFRpbWUpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUudXBkYXRlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRpbWU7XG4gICAgICB0aW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSArPSAodGltZSAtIHRoaXMuX2xhc3RUaW1lKSAvIHRoaXMuZGV2aWNlLnNhbXBsZVJhdGUgKiAxMDAwIHwgMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGltZTtcbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3RpbWVVcGRhdGUnLCB0aGlzLmN1cnJlbnRUaW1lKTtcbiAgICB9O1xuXG4gICAgZGV2aWNlcyA9IFtdO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIgPSBmdW5jdGlvbihkZXZpY2UpIHtcbiAgICAgIHJldHVybiBkZXZpY2VzLnB1c2goZGV2aWNlKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UuY3JlYXRlID0gZnVuY3Rpb24oc2FtcGxlUmF0ZSwgY2hhbm5lbHMpIHtcbiAgICAgIHZhciBkZXZpY2UsIGksIGxlbjtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGRldmljZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZGV2aWNlID0gZGV2aWNlc1tpXTtcbiAgICAgICAgaWYgKGRldmljZS5zdXBwb3J0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IGRldmljZShzYW1wbGVSYXRlLCBjaGFubmVscyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICByZXR1cm4gQXVkaW9EZXZpY2U7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEF1ZGlvRGV2aWNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBBdWRpb0RldmljZSwgRXZlbnRFbWl0dGVyLCBNb3ppbGxhQXVkaW9EZXZpY2UsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi4vZGV2aWNlJyk7XG5cbiAgQVZCdWZmZXIgPSByZXF1aXJlKCcuLi9jb3JlL2J1ZmZlcicpO1xuXG4gIE1vemlsbGFBdWRpb0RldmljZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGNyZWF0ZVRpbWVyLCBkZXN0cm95VGltZXI7XG5cbiAgICBleHRlbmQoTW96aWxsYUF1ZGlvRGV2aWNlLCBzdXBlckNsYXNzKTtcblxuICAgIEF1ZGlvRGV2aWNlLnJlZ2lzdGVyKE1vemlsbGFBdWRpb0RldmljZSk7XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2Uuc3VwcG9ydGVkID0gKHR5cGVvZiBBdWRpbyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBBdWRpbyAhPT0gbnVsbCkgJiYgJ21veldyaXRlQXVkaW8nIGluIG5ldyBBdWRpbztcblxuICAgIGZ1bmN0aW9uIE1vemlsbGFBdWRpb0RldmljZShzYW1wbGVSYXRlLCBjaGFubmVscykge1xuICAgICAgdGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICAgIHRoaXMucmVmaWxsID0gYmluZCh0aGlzLnJlZmlsbCwgdGhpcyk7XG4gICAgICB0aGlzLmF1ZGlvID0gbmV3IEF1ZGlvO1xuICAgICAgdGhpcy5hdWRpby5tb3pTZXR1cCh0aGlzLmNoYW5uZWxzLCB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgdGhpcy53cml0ZVBvc2l0aW9uID0gMDtcbiAgICAgIHRoaXMucHJlYnVmZmVyU2l6ZSA9IHRoaXMuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgdGhpcy50aW1lciA9IGNyZWF0ZVRpbWVyKHRoaXMucmVmaWxsLCAxMDApO1xuICAgIH1cblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5wcm90b3R5cGUucmVmaWxsID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXZhaWxhYmxlLCBidWZmZXIsIGN1cnJlbnRQb3NpdGlvbiwgd3JpdHRlbjtcbiAgICAgIGlmICh0aGlzLnRhaWwpIHtcbiAgICAgICAgd3JpdHRlbiA9IHRoaXMuYXVkaW8ubW96V3JpdGVBdWRpbyh0aGlzLnRhaWwpO1xuICAgICAgICB0aGlzLndyaXRlUG9zaXRpb24gKz0gd3JpdHRlbjtcbiAgICAgICAgaWYgKHRoaXMud3JpdGVQb3NpdGlvbiA8IHRoaXMudGFpbC5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnRhaWwgPSB0aGlzLnRhaWwuc3ViYXJyYXkod3JpdHRlbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY3VycmVudFBvc2l0aW9uID0gdGhpcy5hdWRpby5tb3pDdXJyZW50U2FtcGxlT2Zmc2V0KCk7XG4gICAgICBhdmFpbGFibGUgPSBjdXJyZW50UG9zaXRpb24gKyB0aGlzLnByZWJ1ZmZlclNpemUgLSB0aGlzLndyaXRlUG9zaXRpb247XG4gICAgICBpZiAoYXZhaWxhYmxlID4gMCkge1xuICAgICAgICBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGF2YWlsYWJsZSk7XG4gICAgICAgIHRoaXMuZW1pdCgncmVmaWxsJywgYnVmZmVyKTtcbiAgICAgICAgd3JpdHRlbiA9IHRoaXMuYXVkaW8ubW96V3JpdGVBdWRpbyhidWZmZXIpO1xuICAgICAgICBpZiAod3JpdHRlbiA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnRhaWwgPSBidWZmZXIuc3ViYXJyYXkod3JpdHRlbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53cml0ZVBvc2l0aW9uICs9IHdyaXR0ZW47XG4gICAgICB9XG4gICAgfTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlc3Ryb3lUaW1lcih0aGlzLnRpbWVyKTtcbiAgICB9O1xuXG4gICAgTW96aWxsYUF1ZGlvRGV2aWNlLnByb3RvdHlwZS5nZXREZXZpY2VUaW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdWRpby5tb3pDdXJyZW50U2FtcGxlT2Zmc2V0KCkgLyB0aGlzLmNoYW5uZWxzO1xuICAgIH07XG5cbiAgICBjcmVhdGVUaW1lciA9IGZ1bmN0aW9uKGZuLCBpbnRlcnZhbCkge1xuICAgICAgdmFyIHVybCwgd29ya2VyO1xuICAgICAgdXJsID0gQVZCdWZmZXIubWFrZUJsb2JVUkwoXCJzZXRJbnRlcnZhbChmdW5jdGlvbigpIHsgcG9zdE1lc3NhZ2UoJ3BpbmcnKTsgfSwgXCIgKyBpbnRlcnZhbCArIFwiKTtcIik7XG4gICAgICBpZiAodXJsID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHNldEludGVydmFsKGZuLCBpbnRlcnZhbCk7XG4gICAgICB9XG4gICAgICB3b3JrZXIgPSBuZXcgV29ya2VyKHVybCk7XG4gICAgICB3b3JrZXIub25tZXNzYWdlID0gZm47XG4gICAgICB3b3JrZXIudXJsID0gdXJsO1xuICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9O1xuXG4gICAgZGVzdHJveVRpbWVyID0gZnVuY3Rpb24odGltZXIpIHtcbiAgICAgIGlmICh0aW1lci50ZXJtaW5hdGUpIHtcbiAgICAgICAgdGltZXIudGVybWluYXRlKCk7XG4gICAgICAgIHJldHVybiBVUkwucmV2b2tlT2JqZWN0VVJMKHRpbWVyLnVybCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBNb3ppbGxhQXVkaW9EZXZpY2U7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vSmF2YVNjcmlwdCBBdWRpbyBSZXNhbXBsZXJcbi8vQ29weXJpZ2h0IChDKSAyMDExLTIwMTUgR3JhbnQgR2FsaXR6XG4vL1JlbGVhc2VkIHRvIFB1YmxpYyBEb21haW5cbmZ1bmN0aW9uIFJlc2FtcGxlcihmcm9tU2FtcGxlUmF0ZSwgdG9TYW1wbGVSYXRlLCBjaGFubmVscywgaW5wdXRCdWZmZXJMZW5ndGgpIHtcbiAgdGhpcy5mcm9tU2FtcGxlUmF0ZSA9ICtmcm9tU2FtcGxlUmF0ZTtcbiAgdGhpcy50b1NhbXBsZVJhdGUgPSArdG9TYW1wbGVSYXRlO1xuICB0aGlzLmNoYW5uZWxzID0gY2hhbm5lbHMgfCAwO1xuICB0aGlzLmlucHV0QnVmZmVyTGVuZ3RoID0gaW5wdXRCdWZmZXJMZW5ndGg7XG4gIHRoaXMuaW5pdGlhbGl6ZSgpO1xufVxuXG5SZXNhbXBsZXIucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vUGVyZm9ybSBzb21lIGNoZWNrczpcbiAgaWYgKHRoaXMuZnJvbVNhbXBsZVJhdGUgPiAwICYmIHRoaXMudG9TYW1wbGVSYXRlID4gMCAmJiB0aGlzLmNoYW5uZWxzID4gMCkge1xuICAgIGlmICh0aGlzLmZyb21TYW1wbGVSYXRlID09IHRoaXMudG9TYW1wbGVSYXRlKSB7XG4gICAgICAvL1NldHVwIGEgcmVzYW1wbGVyIGJ5cGFzczpcbiAgICAgIHRoaXMucmVzYW1wbGVyID0gdGhpcy5ieXBhc3NSZXNhbXBsZXI7ICAgIC8vUmVzYW1wbGVyIGp1c3QgcmV0dXJucyB3aGF0IHdhcyBwYXNzZWQgdGhyb3VnaC5cbiAgICAgIHRoaXMucmF0aW9XZWlnaHQgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJhdGlvV2VpZ2h0ID0gdGhpcy5mcm9tU2FtcGxlUmF0ZSAvIHRoaXMudG9TYW1wbGVSYXRlO1xuICAgICAgaWYgKHRoaXMuZnJvbVNhbXBsZVJhdGUgPCB0aGlzLnRvU2FtcGxlUmF0ZSkge1xuICAgICAgICAvKlxuICAgICAgICAgIFVzZSBnZW5lcmljIGxpbmVhciBpbnRlcnBvbGF0aW9uIGlmIHVwc2FtcGxpbmcsXG4gICAgICAgICAgYXMgbGluZWFyIGludGVycG9sYXRpb24gcHJvZHVjZXMgYSBncmFkaWVudCB0aGF0IHdlIHdhbnRcbiAgICAgICAgICBhbmQgd29ya3MgZmluZSB3aXRoIHR3byBpbnB1dCBzYW1wbGUgcG9pbnRzIHBlciBvdXRwdXQgaW4gdGhpcyBjYXNlLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmNvbXBpbGVMaW5lYXJJbnRlcnBvbGF0aW9uRnVuY3Rpb24oKTtcbiAgICAgICAgdGhpcy5sYXN0V2VpZ2h0ID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qXG4gICAgICAgICAgQ3VzdG9tIHJlc2FtcGxlciBJIHdyb3RlIHRoYXQgZG9lc24ndCBza2lwIHNhbXBsZXNcbiAgICAgICAgICBsaWtlIHN0YW5kYXJkIGxpbmVhciBpbnRlcnBvbGF0aW9uIGluIGhpZ2ggZG93bnNhbXBsaW5nLlxuICAgICAgICAgIFRoaXMgaXMgbW9yZSBhY2N1cmF0ZSB0aGFuIGxpbmVhciBpbnRlcnBvbGF0aW9uIG9uIGRvd25zYW1wbGluZy5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb21waWxlTXVsdGlUYXBGdW5jdGlvbigpO1xuICAgICAgICB0aGlzLnRhaWxFeGlzdHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5sYXN0V2VpZ2h0ID0gMDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgdmFyIG91dHB1dEJ1ZmZlclNpemUgPSAoTWF0aC5jZWlsKHRoaXMuaW5wdXRCdWZmZXJMZW5ndGggKiB0aGlzLnRvU2FtcGxlUmF0ZSAvIHRoaXMuZnJvbVNhbXBsZVJhdGUgLyB0aGlzLmNoYW5uZWxzICogMS4wMSkgKiB0aGlzLmNoYW5uZWxzKSArIHRoaXMuY2hhbm5lbHM7XG4gICAgICB0aGlzLm91dHB1dEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkob3V0cHV0QnVmZmVyU2l6ZSk7XG4gICAgICB0aGlzLmxhc3RPdXRwdXQgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuY2hhbm5lbHMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyhuZXcgRXJyb3IoXCJJbnZhbGlkIHNldHRpbmdzIHNwZWNpZmllZCBmb3IgdGhlIHJlc2FtcGxlci5cIikpO1xuICB9XG59O1xuXG5SZXNhbXBsZXIucHJvdG90eXBlLmNvbXBpbGVMaW5lYXJJbnRlcnBvbGF0aW9uRnVuY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0b0NvbXBpbGUgPSBcInZhciBvdXRwdXRPZmZzZXQgPSAwO1xcXG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJ1ZmZlci5sZW5ndGg7XFxcbiAgICBpZiAoYnVmZmVyTGVuZ3RoID4gMCkge1xcXG4gICAgICB2YXIgd2VpZ2h0ID0gdGhpcy5sYXN0V2VpZ2h0O1xcXG4gICAgICB2YXIgZmlyc3RXZWlnaHQgPSAwO1xcXG4gICAgICB2YXIgc2Vjb25kV2VpZ2h0ID0gMDtcXFxuICAgICAgdmFyIHNvdXJjZU9mZnNldCA9IDA7XFxcbiAgICAgIHZhciBvdXRwdXRPZmZzZXQgPSAwO1xcXG4gICAgICB2YXIgb3V0cHV0QnVmZmVyID0gdGhpcy5vdXRwdXRCdWZmZXI7XFxcbiAgICAgIGZvciAoOyB3ZWlnaHQgPCAxOyB3ZWlnaHQgKz0gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCIpIHtcXFxuICAgICAgICBzZWNvbmRXZWlnaHQgPSB3ZWlnaHQgJSAxO1xcXG4gICAgICAgIGZpcnN0V2VpZ2h0ID0gMSAtIHNlY29uZFdlaWdodDtcIjtcbiAgICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRCdWZmZXJbb3V0cHV0T2Zmc2V0KytdID0gKHRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl0gKiBmaXJzdFdlaWdodCkgKyAoYnVmZmVyW1wiICsgY2hhbm5lbCArIFwiXSAqIHNlY29uZFdlaWdodCk7XCI7XG4gICAgICAgIH1cbiAgICAgIHRvQ29tcGlsZSArPSBcIn1cXFxuICAgICAgd2VpZ2h0IC09IDE7XFxcbiAgICAgIGZvciAoYnVmZmVyTGVuZ3RoIC09IFwiICsgdGhpcy5jaGFubmVscyArIFwiLCBzb3VyY2VPZmZzZXQgPSBNYXRoLmZsb29yKHdlaWdodCkgKiBcIiArIHRoaXMuY2hhbm5lbHMgKyBcIjsgc291cmNlT2Zmc2V0IDwgYnVmZmVyTGVuZ3RoOykge1xcXG4gICAgICAgIHNlY29uZFdlaWdodCA9IHdlaWdodCAlIDE7XFxcbiAgICAgICAgZmlyc3RXZWlnaHQgPSAxIC0gc2Vjb25kV2VpZ2h0O1wiO1xuICAgICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dEJ1ZmZlcltvdXRwdXRPZmZzZXQrK10gPSAoYnVmZmVyW3NvdXJjZU9mZnNldFwiICsgKChjaGFubmVsID4gMCkgPyAoXCIgKyBcIiArIGNoYW5uZWwpIDogXCJcIikgKyBcIl0gKiBmaXJzdFdlaWdodCkgKyAoYnVmZmVyW3NvdXJjZU9mZnNldCArIFwiICsgKHRoaXMuY2hhbm5lbHMgKyBjaGFubmVsKSArIFwiXSAqIHNlY29uZFdlaWdodCk7XCI7XG4gICAgICAgIH1cbiAgICAgICAgdG9Db21waWxlICs9IFwid2VpZ2h0ICs9IFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiO1xcXG4gICAgICAgIHNvdXJjZU9mZnNldCA9IE1hdGguZmxvb3Iod2VpZ2h0KSAqIFwiICsgdGhpcy5jaGFubmVscyArIFwiO1xcXG4gICAgICB9XCI7XG4gICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdID0gYnVmZmVyW3NvdXJjZU9mZnNldCsrXTtcIjtcbiAgICAgIH1cbiAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMubGFzdFdlaWdodCA9IHdlaWdodCAlIDE7XFxcbiAgICB9XFxcbiAgICByZXR1cm4gdGhpcy5vdXRwdXRCdWZmZXI7XCI7XG4gICAgXG4gIHRoaXMucmVzYW1wbGVyID0gRnVuY3Rpb24oXCJidWZmZXJcIiwgdG9Db21waWxlKTtcbn07XG5cblJlc2FtcGxlci5wcm90b3R5cGUuY29tcGlsZU11bHRpVGFwRnVuY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0b0NvbXBpbGUgPSBcInZhciBvdXRwdXRPZmZzZXQgPSAwO1xcXG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJ1ZmZlci5sZW5ndGg7XFxcbiAgICBpZiAoYnVmZmVyTGVuZ3RoID4gMCkge1xcXG4gICAgICB2YXIgd2VpZ2h0ID0gMDtcIjtcbiAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgIHRvQ29tcGlsZSArPSBcInZhciBvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiA9IDA7XCJcbiAgICAgIH1cbiAgICAgIHRvQ29tcGlsZSArPSBcInZhciBhY3R1YWxQb3NpdGlvbiA9IDA7XFxcbiAgICAgIHZhciBhbW91bnRUb05leHQgPSAwO1xcXG4gICAgICB2YXIgYWxyZWFkeVByb2Nlc3NlZFRhaWwgPSAhdGhpcy50YWlsRXhpc3RzO1xcXG4gICAgICB0aGlzLnRhaWxFeGlzdHMgPSBmYWxzZTtcXFxuICAgICAgdmFyIG91dHB1dEJ1ZmZlciA9IHRoaXMub3V0cHV0QnVmZmVyO1xcXG4gICAgICB2YXIgY3VycmVudFBvc2l0aW9uID0gMDtcXFxuICAgICAgZG8ge1xcXG4gICAgICAgIGlmIChhbHJlYWR5UHJvY2Vzc2VkVGFpbCkge1xcXG4gICAgICAgICAgd2VpZ2h0ID0gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCI7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgPSAwO1wiXG4gICAgICAgICAgfVxuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ9XFxcbiAgICAgICAgZWxzZSB7XFxcbiAgICAgICAgICB3ZWlnaHQgPSB0aGlzLmxhc3RXZWlnaHQ7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgPSB0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdO1wiXG4gICAgICAgICAgfVxuICAgICAgICAgIHRvQ29tcGlsZSArPSBcImFscmVhZHlQcm9jZXNzZWRUYWlsID0gdHJ1ZTtcXFxuICAgICAgICB9XFxcbiAgICAgICAgd2hpbGUgKHdlaWdodCA+IDAgJiYgYWN0dWFsUG9zaXRpb24gPCBidWZmZXJMZW5ndGgpIHtcXFxuICAgICAgICAgIGFtb3VudFRvTmV4dCA9IDEgKyBhY3R1YWxQb3NpdGlvbiAtIGN1cnJlbnRQb3NpdGlvbjtcXFxuICAgICAgICAgIGlmICh3ZWlnaHQgPj0gYW1vdW50VG9OZXh0KSB7XCI7XG4gICAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiICs9IGJ1ZmZlclthY3R1YWxQb3NpdGlvbisrXSAqIGFtb3VudFRvTmV4dDtcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9Db21waWxlICs9IFwiY3VycmVudFBvc2l0aW9uID0gYWN0dWFsUG9zaXRpb247XFxcbiAgICAgICAgICAgIHdlaWdodCAtPSBhbW91bnRUb05leHQ7XFxcbiAgICAgICAgICB9XFxcbiAgICAgICAgICBlbHNlIHtcIjtcbiAgICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgKz0gYnVmZmVyW2FjdHVhbFBvc2l0aW9uXCIgKyAoKGNoYW5uZWwgPiAwKSA/IChcIiArIFwiICsgY2hhbm5lbCkgOiBcIlwiKSArIFwiXSAqIHdlaWdodDtcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9Db21waWxlICs9IFwiY3VycmVudFBvc2l0aW9uICs9IHdlaWdodDtcXFxuICAgICAgICAgICAgd2VpZ2h0ID0gMDtcXFxuICAgICAgICAgICAgYnJlYWs7XFxcbiAgICAgICAgICB9XFxcbiAgICAgICAgfVxcXG4gICAgICAgIGlmICh3ZWlnaHQgPD0gMCkge1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dEJ1ZmZlcltvdXRwdXRPZmZzZXQrK10gPSBvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiAvIFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiO1wiXG4gICAgICAgICAgfVxuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ9XFxcbiAgICAgICAgZWxzZSB7XFxcbiAgICAgICAgICB0aGlzLmxhc3RXZWlnaHQgPSB3ZWlnaHQ7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwidGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXSA9IG91dHB1dFwiICsgY2hhbm5lbCArIFwiO1wiXG4gICAgICAgICAgfVxuICAgICAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMudGFpbEV4aXN0cyA9IHRydWU7XFxcbiAgICAgICAgICBicmVhaztcXFxuICAgICAgICB9XFxcbiAgICAgIH0gd2hpbGUgKGFjdHVhbFBvc2l0aW9uIDwgYnVmZmVyTGVuZ3RoKTtcXFxuICAgIH1cXFxuICAgIHJldHVybiB0aGlzLm91dHB1dEJ1ZmZlcjtcIjtcbiAgXG4gIHRoaXMucmVzYW1wbGVyID0gRnVuY3Rpb24oXCJidWZmZXJcIiwgdG9Db21waWxlKTtcbn07XG5cblJlc2FtcGxlci5wcm90b3R5cGUuYnlwYXNzUmVzYW1wbGVyID0gZnVuY3Rpb24gKGlucHV0QnVmZmVyKSB7XG4gIHJldHVybiBpbnB1dEJ1ZmZlcjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVzYW1wbGVyO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsIFJlc2FtcGxlciwgV2ViQXVkaW9EZXZpY2UsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi4vZGV2aWNlJyk7XG5cbiAgUmVzYW1wbGVyID0gcmVxdWlyZSgnLi9yZXNhbXBsZXInKTtcblxuICBXZWJBdWRpb0RldmljZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIEF1ZGlvQ29udGV4dCwgY3JlYXRlUHJvY2Vzc29yLCBzaGFyZWRDb250ZXh0O1xuXG4gICAgZXh0ZW5kKFdlYkF1ZGlvRGV2aWNlLCBzdXBlckNsYXNzKTtcblxuICAgIEF1ZGlvRGV2aWNlLnJlZ2lzdGVyKFdlYkF1ZGlvRGV2aWNlKTtcblxuICAgIEF1ZGlvQ29udGV4dCA9IGdsb2JhbC5BdWRpb0NvbnRleHQgfHwgZ2xvYmFsLndlYmtpdEF1ZGlvQ29udGV4dDtcblxuICAgIFdlYkF1ZGlvRGV2aWNlLnN1cHBvcnRlZCA9IEF1ZGlvQ29udGV4dCAmJiAodHlwZW9mIEF1ZGlvQ29udGV4dC5wcm90b3R5cGVbY3JlYXRlUHJvY2Vzc29yID0gJ2NyZWF0ZVNjcmlwdFByb2Nlc3NvciddID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBBdWRpb0NvbnRleHQucHJvdG90eXBlW2NyZWF0ZVByb2Nlc3NvciA9ICdjcmVhdGVKYXZhU2NyaXB0Tm9kZSddID09PSAnZnVuY3Rpb24nKTtcblxuICAgIHNoYXJlZENvbnRleHQgPSBudWxsO1xuXG4gICAgZnVuY3Rpb24gV2ViQXVkaW9EZXZpY2Uoc2FtcGxlUmF0ZSwgY2hhbm5lbHMxKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzMTtcbiAgICAgIHRoaXMucmVmaWxsID0gYmluZCh0aGlzLnJlZmlsbCwgdGhpcyk7XG4gICAgICB0aGlzLmNvbnRleHQgPSBzaGFyZWRDb250ZXh0ICE9IG51bGwgPyBzaGFyZWRDb250ZXh0IDogc2hhcmVkQ29udGV4dCA9IG5ldyBBdWRpb0NvbnRleHQ7XG4gICAgICB0aGlzLmRldmljZVNhbXBsZVJhdGUgPSB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgIHRoaXMuYnVmZmVyU2l6ZSA9IE1hdGguY2VpbCg0MDk2IC8gKHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSAvIHRoaXMuc2FtcGxlUmF0ZSkgKiB0aGlzLmNoYW5uZWxzKTtcbiAgICAgIHRoaXMuYnVmZmVyU2l6ZSArPSB0aGlzLmJ1ZmZlclNpemUgJSB0aGlzLmNoYW5uZWxzO1xuICAgICAgaWYgKHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSAhPT0gdGhpcy5zYW1wbGVSYXRlKSB7XG4gICAgICAgIHRoaXMucmVzYW1wbGVyID0gbmV3IFJlc2FtcGxlcih0aGlzLnNhbXBsZVJhdGUsIHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSwgdGhpcy5jaGFubmVscywgdGhpcy5idWZmZXJTaXplKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubm9kZSA9IHRoaXMuY29udGV4dFtjcmVhdGVQcm9jZXNzb3JdKDQwOTYsIHRoaXMuY2hhbm5lbHMsIHRoaXMuY2hhbm5lbHMpO1xuICAgICAgdGhpcy5ub2RlLm9uYXVkaW9wcm9jZXNzID0gdGhpcy5yZWZpbGw7XG4gICAgICB0aGlzLm5vZGUuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgIH1cblxuICAgIFdlYkF1ZGlvRGV2aWNlLnByb3RvdHlwZS5yZWZpbGwgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIGNoYW5uZWxDb3VudCwgY2hhbm5lbHMsIGRhdGEsIGksIGosIGssIGwsIG4sIG91dHB1dEJ1ZmZlciwgcmVmLCByZWYxLCByZWYyO1xuICAgICAgb3V0cHV0QnVmZmVyID0gZXZlbnQub3V0cHV0QnVmZmVyO1xuICAgICAgY2hhbm5lbENvdW50ID0gb3V0cHV0QnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICBjaGFubmVscyA9IG5ldyBBcnJheShjaGFubmVsQ291bnQpO1xuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGNoYW5uZWxDb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICBjaGFubmVsc1tpXSA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgIH1cbiAgICAgIGRhdGEgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYnVmZmVyU2l6ZSk7XG4gICAgICB0aGlzLmVtaXQoJ3JlZmlsbCcsIGRhdGEpO1xuICAgICAgaWYgKHRoaXMucmVzYW1wbGVyKSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLnJlc2FtcGxlci5yZXNhbXBsZXIoZGF0YSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IG91dHB1dEJ1ZmZlci5sZW5ndGg7IGsgPCByZWYxOyBpID0gayArPSAxKSB7XG4gICAgICAgIGZvciAobiA9IGwgPSAwLCByZWYyID0gY2hhbm5lbENvdW50OyBsIDwgcmVmMjsgbiA9IGwgKz0gMSkge1xuICAgICAgICAgIGNoYW5uZWxzW25dW2ldID0gZGF0YVtpICogY2hhbm5lbENvdW50ICsgbl07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgV2ViQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vZGUuZGlzY29ubmVjdCgwKTtcbiAgICB9O1xuXG4gICAgV2ViQXVkaW9EZXZpY2UucHJvdG90eXBlLmdldERldmljZVRpbWUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgKiB0aGlzLnNhbXBsZVJhdGU7XG4gICAgfTtcblxuICAgIHJldHVybiBXZWJBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEZpbHRlcjtcblxuICBGaWx0ZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gRmlsdGVyKGNvbnRleHQsIGtleSkge1xuICAgICAgaWYgKGNvbnRleHQgJiYga2V5KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndmFsdWUnLCB7XG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0W2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHt9O1xuXG4gICAgcmV0dXJuIEZpbHRlcjtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRmlsdGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhbGFuY2VGaWx0ZXIsIEZpbHRlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEZpbHRlciA9IHJlcXVpcmUoJy4uL2ZpbHRlcicpO1xuXG4gIEJhbGFuY2VGaWx0ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChCYWxhbmNlRmlsdGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEJhbGFuY2VGaWx0ZXIoKSB7XG4gICAgICByZXR1cm4gQmFsYW5jZUZpbHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBCYWxhbmNlRmlsdGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgaSwgaiwgcGFuLCByZWY7XG4gICAgICBpZiAodGhpcy52YWx1ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBwYW4gPSBNYXRoLm1heCgtNTAsIE1hdGgubWluKDUwLCB0aGlzLnZhbHVlKSk7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnVmZmVyLmxlbmd0aDsgaiA8IHJlZjsgaSA9IGogKz0gMikge1xuICAgICAgICBidWZmZXJbaV0gKj0gTWF0aC5taW4oMSwgKDUwIC0gcGFuKSAvIDUwKTtcbiAgICAgICAgYnVmZmVyW2kgKyAxXSAqPSBNYXRoLm1pbigxLCAoNTAgKyBwYW4pIC8gNTApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQmFsYW5jZUZpbHRlcjtcblxuICB9KShGaWx0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQmFsYW5jZUZpbHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBGaWx0ZXIsIFZvbHVtZUZpbHRlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEZpbHRlciA9IHJlcXVpcmUoJy4uL2ZpbHRlcicpO1xuXG4gIFZvbHVtZUZpbHRlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFZvbHVtZUZpbHRlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBWb2x1bWVGaWx0ZXIoKSB7XG4gICAgICByZXR1cm4gVm9sdW1lRmlsdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIFZvbHVtZUZpbHRlci5wcm90b3R5cGUucHJvY2VzcyA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIGksIGosIHJlZiwgdm9sO1xuICAgICAgaWYgKHRoaXMudmFsdWUgPj0gMTAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZvbCA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgdGhpcy52YWx1ZSkpIC8gMTAwO1xuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGJ1ZmZlci5sZW5ndGg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgYnVmZmVyW2ldICo9IHZvbDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIFZvbHVtZUZpbHRlcjtcblxuICB9KShGaWx0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gVm9sdW1lRmlsdGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFzc2V0LCBBdWRpb0RldmljZSwgQmFsYW5jZUZpbHRlciwgRXZlbnRFbWl0dGVyLCBQbGF5ZXIsIFF1ZXVlLCBWb2x1bWVGaWx0ZXIsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXNzZXQgPSByZXF1aXJlKCcuL2Fzc2V0Jyk7XG5cbiAgVm9sdW1lRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXJzL3ZvbHVtZScpO1xuXG4gIEJhbGFuY2VGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvYmFsYW5jZScpO1xuXG4gIFF1ZXVlID0gcmVxdWlyZSgnLi9xdWV1ZScpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi9kZXZpY2UnKTtcblxuICBQbGF5ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChQbGF5ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gUGxheWVyKGFzc2V0KSB7XG4gICAgICB0aGlzLmFzc2V0ID0gYXNzZXQ7XG4gICAgICB0aGlzLnN0YXJ0UGxheWluZyA9IGJpbmQodGhpcy5zdGFydFBsYXlpbmcsIHRoaXMpO1xuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmJ1ZmZlcmVkID0gMDtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSAwO1xuICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XG4gICAgICB0aGlzLnZvbHVtZSA9IDEwMDtcbiAgICAgIHRoaXMucGFuID0gMDtcbiAgICAgIHRoaXMubWV0YWRhdGEgPSB7fTtcbiAgICAgIHRoaXMuZmlsdGVycyA9IFtuZXcgVm9sdW1lRmlsdGVyKHRoaXMsICd2b2x1bWUnKSwgbmV3IEJhbGFuY2VGaWx0ZXIodGhpcywgJ3BhbicpXTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2J1ZmZlcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyZWQpIHtcbiAgICAgICAgICBfdGhpcy5idWZmZXJlZCA9IGJ1ZmZlcmVkO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdidWZmZXInLCBfdGhpcy5idWZmZXJlZCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkZWNvZGVTdGFydCcsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgX3RoaXMucXVldWUgPSBuZXcgUXVldWUoX3RoaXMuYXNzZXQpO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5xdWV1ZS5vbmNlKCdyZWFkeScsIF90aGlzLnN0YXJ0UGxheWluZyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdmb3JtYXQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGZvcm1hdCkge1xuICAgICAgICAgIF90aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZm9ybWF0JywgX3RoaXMuZm9ybWF0KTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ21ldGFkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgICAgICAgIF90aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ21ldGFkYXRhJywgX3RoaXMubWV0YWRhdGEpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZHVyYXRpb24nLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgICAgX3RoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZHVyYXRpb24nLCBfdGhpcy5kdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgfVxuXG4gICAgUGxheWVyLmZyb21VUkwgPSBmdW5jdGlvbih1cmwsIG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgUGxheWVyKEFzc2V0LmZyb21VUkwodXJsLCBvcHRzKSk7XG4gICAgfTtcblxuICAgIFBsYXllci5mcm9tRmlsZSA9IGZ1bmN0aW9uKGZpbGUpIHtcbiAgICAgIHJldHVybiBuZXcgUGxheWVyKEFzc2V0LmZyb21GaWxlKGZpbGUpKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLmZyb21CdWZmZXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBuZXcgUGxheWVyKEFzc2V0LmZyb21CdWZmZXIoYnVmZmVyKSk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUucHJlbG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFzc2V0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhcnRlZFByZWxvYWRpbmcgPSB0cnVlO1xuICAgICAgcmV0dXJuIHRoaXMuYXNzZXQuc3RhcnQoZmFsc2UpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnBsYXkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5zdGFydGVkUHJlbG9hZGluZykge1xuICAgICAgICB0aGlzLnByZWxvYWQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxheWluZyA9IHRydWU7XG4gICAgICByZXR1cm4gKHJlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsID8gcmVmLnN0YXJ0KCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAoIXRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHJldHVybiAocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyByZWYuc3RvcCgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnRvZ2dsZVBsYXliYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhdXNlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5wbGF5KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIHRoaXMucGF1c2UoKTtcbiAgICAgIHRoaXMuYXNzZXQuc3RvcCgpO1xuICAgICAgcmV0dXJuIChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZi5kZXN0cm95KCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIGlmICgocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwpIHtcbiAgICAgICAgcmVmLnN0b3AoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucXVldWUub25jZSgncmVhZHknLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciByZWYxLCByZWYyO1xuICAgICAgICAgIGlmICgocmVmMSA9IF90aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVmMS5zZWVrKF90aGlzLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKF90aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiAocmVmMiA9IF90aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZjIuc3RhcnQoKSA6IHZvaWQgMDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aW1lc3RhbXAgPSAodGltZXN0YW1wIC8gMTAwMCkgKiB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlO1xuICAgICAgdGltZXN0YW1wID0gdGhpcy5hc3NldC5kZWNvZGVyLnNlZWsodGltZXN0YW1wKTtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSB0aW1lc3RhbXAgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDA7XG4gICAgICB0aGlzLnF1ZXVlLnJlc2V0KCk7XG4gICAgICByZXR1cm4gdGhpcy5jdXJyZW50VGltZTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5zdGFydFBsYXlpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBmcmFtZSwgZnJhbWVPZmZzZXQ7XG4gICAgICBmcmFtZSA9IHRoaXMucXVldWUucmVhZCgpO1xuICAgICAgZnJhbWVPZmZzZXQgPSAwO1xuICAgICAgdGhpcy5kZXZpY2UgPSBuZXcgQXVkaW9EZXZpY2UodGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSwgdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSk7XG4gICAgICB0aGlzLmRldmljZS5vbigndGltZVVwZGF0ZScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oY3VycmVudFRpbWUpIHtcbiAgICAgICAgICBfdGhpcy5jdXJyZW50VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdwcm9ncmVzcycsIF90aGlzLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMucmVmaWxsID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgICAgICB2YXIgYnVmZmVyT2Zmc2V0LCBmaWx0ZXIsIGksIGosIGssIGxlbiwgbWF4LCByZWYsIHJlZjE7XG4gICAgICAgICAgaWYgKCFfdGhpcy5wbGF5aW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZnJhbWUpIHtcbiAgICAgICAgICAgIGZyYW1lID0gX3RoaXMucXVldWUucmVhZCgpO1xuICAgICAgICAgICAgZnJhbWVPZmZzZXQgPSAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBidWZmZXJPZmZzZXQgPSAwO1xuICAgICAgICAgIHdoaWxlIChmcmFtZSAmJiBidWZmZXJPZmZzZXQgPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICBtYXggPSBNYXRoLm1pbihmcmFtZS5sZW5ndGggLSBmcmFtZU9mZnNldCwgYnVmZmVyLmxlbmd0aCAtIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gbWF4OyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgIGJ1ZmZlcltidWZmZXJPZmZzZXQrK10gPSBmcmFtZVtmcmFtZU9mZnNldCsrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmcmFtZU9mZnNldCA9PT0gZnJhbWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGZyYW1lID0gX3RoaXMucXVldWUucmVhZCgpO1xuICAgICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlZjEgPSBfdGhpcy5maWx0ZXJzO1xuICAgICAgICAgIGZvciAoayA9IDAsIGxlbiA9IHJlZjEubGVuZ3RoOyBrIDwgbGVuOyBrKyspIHtcbiAgICAgICAgICAgIGZpbHRlciA9IHJlZjFba107XG4gICAgICAgICAgICBmaWx0ZXIucHJvY2VzcyhidWZmZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWZyYW1lKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMucXVldWUuZW5kZWQpIHtcbiAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFRpbWUgPSBfdGhpcy5kdXJhdGlvbjtcbiAgICAgICAgICAgICAgX3RoaXMuZW1pdCgncHJvZ3Jlc3MnLCBfdGhpcy5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBfdGhpcy5kZXZpY2Uuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgdGhpcy5kZXZpY2Uub24oJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgdGhpcy5kZXZpY2Uuc3RhcnQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZiwgcmVmMTtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKHJlZjEgPSB0aGlzLmFzc2V0KSAhPSBudWxsKSB7XG4gICAgICAgIHJlZjEuZGVzdHJveSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBQbGF5ZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFBsYXllcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBFdmVudEVtaXR0ZXIsIFF1ZXVlLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIFF1ZXVlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoUXVldWUsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gUXVldWUoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMud3JpdGUgPSBiaW5kKHRoaXMud3JpdGUsIHRoaXMpO1xuICAgICAgdGhpcy5yZWFkeU1hcmsgPSA2NDtcbiAgICAgIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuYnVmZmVyaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuYnVmZmVycyA9IFtdO1xuICAgICAgdGhpcy5hc3NldC5vbignZGF0YScsIHRoaXMud3JpdGUpO1xuICAgICAgdGhpcy5hc3NldC5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW5kZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICB9XG5cbiAgICBRdWV1ZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgdGhpcy5idWZmZXJzLnB1c2goYnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmJ1ZmZlcmluZykge1xuICAgICAgICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA+PSB0aGlzLnJlYWR5TWFyayB8fCB0aGlzLmVuZGVkKSB7XG4gICAgICAgICAgdGhpcy5idWZmZXJpbmcgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFF1ZXVlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXNzZXQuZGVjb2RlUGFja2V0KCk7XG4gICAgICByZXR1cm4gdGhpcy5idWZmZXJzLnNoaWZ0KCk7XG4gICAgfTtcblxuICAgIFF1ZXVlLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5idWZmZXJzLmxlbmd0aCA9IDA7XG4gICAgICB0aGlzLmJ1ZmZlcmluZyA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFF1ZXVlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBRdWV1ZTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIkV2ZW50RW1pdHRlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvZXZlbnRzJ1xuQVZCdWZmZXIgPSByZXF1aXJlICcuLi8uLi9jb3JlL2J1ZmZlcidcblxuY2xhc3MgRmlsZVNvdXJjZSBleHRlbmRzIEV2ZW50RW1pdHRlclxuICAgIGNvbnN0cnVjdG9yOiAoQGZpbGUpIC0+XG4gICAgICAgIGlmIG5vdCBGaWxlUmVhZGVyP1xuICAgICAgICAgICAgcmV0dXJuIEBlbWl0ICdlcnJvcicsICdUaGlzIGJyb3dzZXIgZG9lcyBub3QgaGF2ZSBGaWxlUmVhZGVyIHN1cHBvcnQuJ1xuICAgICAgICBcbiAgICAgICAgQG9mZnNldCA9IDBcbiAgICAgICAgQGxlbmd0aCA9IEBmaWxlLnNpemVcbiAgICAgICAgQGNodW5rU2l6ZSA9IDEgPDwgMjBcbiAgICAgICAgQGZpbGVbQHNsaWNlID0gJ3NsaWNlJ10gb3IgQGZpbGVbQHNsaWNlID0gJ3dlYmtpdFNsaWNlJ10gb3IgQGZpbGVbQHNsaWNlID0gJ21velNsaWNlJ11cbiAgICAgICAgICAgIFxuICAgIHN0YXJ0OiAtPlxuICAgICAgICBpZiBAcmVhZGVyXG4gICAgICAgICAgICByZXR1cm4gQGxvb3AoKSB1bmxlc3MgQGFjdGl2ZVxuICAgICAgICBcbiAgICAgICAgQHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyXG4gICAgICAgIEBhY3RpdmUgPSB0cnVlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyLm9ubG9hZCA9IChlKSA9PlxuICAgICAgICAgICAgYnVmID0gbmV3IEFWQnVmZmVyKG5ldyBVaW50OEFycmF5KGUudGFyZ2V0LnJlc3VsdCkpXG4gICAgICAgICAgICBAb2Zmc2V0ICs9IGJ1Zi5sZW5ndGhcbiAgICAgICAgXG4gICAgICAgICAgICBAZW1pdCAnZGF0YScsIGJ1ZiAgIFxuICAgICAgICAgICAgQGFjdGl2ZSA9IGZhbHNlICAgICBcbiAgICAgICAgICAgIEBsb29wKCkgaWYgQG9mZnNldCA8IEBsZW5ndGhcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25sb2FkZW5kID0gPT5cbiAgICAgICAgICAgIGlmIEBvZmZzZXQgaXMgQGxlbmd0aFxuICAgICAgICAgICAgICAgIEBlbWl0ICdlbmQnXG4gICAgICAgICAgICAgICAgQHJlYWRlciA9IG51bGxcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25lcnJvciA9IChlKSA9PlxuICAgICAgICAgICAgQGVtaXQgJ2Vycm9yJywgZVxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbnByb2dyZXNzID0gKGUpID0+XG4gICAgICAgICAgICBAZW1pdCAncHJvZ3Jlc3MnLCAoQG9mZnNldCArIGUubG9hZGVkKSAvIEBsZW5ndGggKiAxMDBcbiAgICAgICAgXG4gICAgICAgIEBsb29wKClcbiAgICAgICAgXG4gICAgbG9vcDogLT5cbiAgICAgICAgQGFjdGl2ZSA9IHRydWVcbiAgICAgICAgZW5kUG9zID0gTWF0aC5taW4oQG9mZnNldCArIEBjaHVua1NpemUsIEBsZW5ndGgpXG4gICAgICAgIFxuICAgICAgICBibG9iID0gQGZpbGVbQHNsaWNlXShAb2Zmc2V0LCBlbmRQb3MpXG4gICAgICAgIEByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYilcbiAgICAgICAgXG4gICAgcGF1c2U6IC0+XG4gICAgICAgIEBhY3RpdmUgPSBmYWxzZVxuICAgICAgICB0cnlcbiAgICAgICAgICBAcmVhZGVyPy5hYm9ydCgpXG4gICAgICAgIFxuICAgIHJlc2V0OiAtPlxuICAgICAgICBAcGF1c2UoKVxuICAgICAgICBAb2Zmc2V0ID0gMFxuXG5tb2R1bGUuZXhwb3J0cyA9IEZpbGVTb3VyY2VcbiIsIkV2ZW50RW1pdHRlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvZXZlbnRzJ1xuQVZCdWZmZXIgPSByZXF1aXJlICcuLi8uLi9jb3JlL2J1ZmZlcidcblxuY2xhc3MgSFRUUFNvdXJjZSBleHRlbmRzIEV2ZW50RW1pdHRlclxuICAgIGNvbnN0cnVjdG9yOiAoQHVybCwgQG9wdHMgPSB7fSkgLT5cbiAgICAgICAgQGNodW5rU2l6ZSA9IDEgPDwgMjBcbiAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgaWYgQG9wdHMubGVuZ3RoXG4gICAgICAgICAgICBAbGVuZ3RoID0gQG9wdHMubGVuZ3RoXG4gICAgICAgIEByZXNldCgpXG4gICAgICAgIFxuICAgIHN0YXJ0OiAtPlxuICAgICAgICBpZiBAbGVuZ3RoXG4gICAgICAgICAgICByZXR1cm4gQGxvb3AoKSB1bmxlc3MgQGluZmxpZ2h0XG4gICAgICAgIFxuICAgICAgICBAaW5mbGlnaHQgPSB0cnVlXG4gICAgICAgIEB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKVxuICAgICAgICBcbiAgICAgICAgQHhoci5vbmxvYWQgPSAoZXZlbnQpID0+XG4gICAgICAgICAgICBAbGVuZ3RoID0gcGFyc2VJbnQgQHhoci5nZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtTGVuZ3RoXCIpICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgICAgIEBsb29wKClcbiAgICAgICAgXG4gICAgICAgIEB4aHIub25lcnJvciA9IChlcnIpID0+XG4gICAgICAgICAgICBAcGF1c2UoKVxuICAgICAgICAgICAgQGVtaXQgJ2Vycm9yJywgZXJyXG4gICAgICAgICAgICBcbiAgICAgICAgQHhoci5vbmFib3J0ID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgXG4gICAgICAgIEB4aHIub3BlbihcIkhFQURcIiwgQHVybCwgdHJ1ZSlcbiAgICAgICAgQHhoci5zZW5kKG51bGwpXG4gICAgICAgIFxuICAgIGxvb3A6IC0+XG4gICAgICAgIGlmIEBpbmZsaWdodCBvciBub3QgQGxlbmd0aFxuICAgICAgICAgICAgcmV0dXJuIEBlbWl0ICdlcnJvcicsICdTb21ldGhpbmcgaXMgd3JvbmcgaW4gSFRUUFNvdXJjZS5sb29wJ1xuICAgICAgICAgICAgXG4gICAgICAgIEBpbmZsaWdodCA9IHRydWVcbiAgICAgICAgQHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgIFxuICAgICAgICBAeGhyLm9ubG9hZCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIGlmIEB4aHIucmVzcG9uc2VcbiAgICAgICAgICAgICAgICBidWYgPSBuZXcgVWludDhBcnJheShAeGhyLnJlc3BvbnNlKVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHR4dCA9IEB4aHIucmVzcG9uc2VUZXh0XG4gICAgICAgICAgICAgICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkodHh0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgaSBpbiBbMC4uLnR4dC5sZW5ndGhdXG4gICAgICAgICAgICAgICAgICAgIGJ1ZltpXSA9IHR4dC5jaGFyQ29kZUF0KGkpICYgMHhmZlxuXG4gICAgICAgICAgICBidWZmZXIgPSBuZXcgQVZCdWZmZXIoYnVmKVxuICAgICAgICAgICAgQG9mZnNldCArPSBidWZmZXIubGVuZ3RoXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEBlbWl0ICdkYXRhJywgYnVmZmVyXG4gICAgICAgICAgICBAZW1pdCAnZW5kJyBpZiBAb2Zmc2V0ID49IEBsZW5ndGhcblxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcbiAgICAgICAgICAgIEBsb29wKCkgdW5sZXNzIEBvZmZzZXQgPj0gQGxlbmd0aFxuICAgICAgICAgICAgXG4gICAgICAgIEB4aHIub25wcm9ncmVzcyA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBlbWl0ICdwcm9ncmVzcycsIChAb2Zmc2V0ICsgZXZlbnQubG9hZGVkKSAvIEBsZW5ndGggKiAxMDBcblxuICAgICAgICBAeGhyLm9uZXJyb3IgPSAoZXJyKSA9PlxuICAgICAgICAgICAgQGVtaXQgJ2Vycm9yJywgZXJyXG4gICAgICAgICAgICBAcGF1c2UoKVxuXG4gICAgICAgIEB4aHIub25hYm9ydCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBpbmZsaWdodCA9IGZhbHNlXG5cbiAgICAgICAgQHhoci5vcGVuKFwiR0VUXCIsIEB1cmwsIHRydWUpXG4gICAgICAgIEB4aHIucmVzcG9uc2VUeXBlID0gXCJhcnJheWJ1ZmZlclwiXG5cbiAgICAgICAgZW5kUG9zID0gTWF0aC5taW4oQG9mZnNldCArIEBjaHVua1NpemUsIEBsZW5ndGggLSAxKVxuICAgICAgICBAeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJJZi1Ob25lLU1hdGNoXCIsIFwid2Via2l0LW5vLWNhY2hlXCIpXG4gICAgICAgIEB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIlJhbmdlXCIsIFwiYnl0ZXM9I3tAb2Zmc2V0fS0je2VuZFBvc31cIilcbiAgICAgICAgQHhoci5vdmVycmlkZU1pbWVUeXBlKCd0ZXh0L3BsYWluOyBjaGFyc2V0PXgtdXNlci1kZWZpbmVkJylcbiAgICAgICAgQHhoci5zZW5kKG51bGwpXG4gICAgICAgIFxuICAgIHBhdXNlOiAtPlxuICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBAeGhyPy5hYm9ydCgpXG4gICAgICAgIFxuICAgIHJlc2V0OiAtPlxuICAgICAgICBAcGF1c2UoKVxuICAgICAgICBAb2Zmc2V0ID0gMFxuICAgICAgICBcbm1vZHVsZS5leHBvcnRzID0gSFRUUFNvdXJjZVxuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEwLjBcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBCdWZmZXJMaXN0LCBCdWZmZXJTb3VyY2UsIEV2ZW50RW1pdHRlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4uL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIEFWQnVmZmVyID0gcmVxdWlyZSgnLi4vY29yZS9idWZmZXInKTtcblxuICBCdWZmZXJTb3VyY2UgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIHZhciBjbGVhckltbWVkaWF0ZSwgc2V0SW1tZWRpYXRlO1xuXG4gICAgZXh0ZW5kKEJ1ZmZlclNvdXJjZSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBCdWZmZXJTb3VyY2UoaW5wdXQpIHtcbiAgICAgIHRoaXMubG9vcCA9IGJpbmQodGhpcy5sb29wLCB0aGlzKTtcbiAgICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIEJ1ZmZlckxpc3QpIHtcbiAgICAgICAgdGhpcy5saXN0ID0gaW5wdXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgICAgdGhpcy5saXN0LmFwcGVuZChuZXcgQVZCdWZmZXIoaW5wdXQpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGF1c2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBzZXRJbW1lZGlhdGUgPSBnbG9iYWwuc2V0SW1tZWRpYXRlIHx8IGZ1bmN0aW9uKGZuKSB7XG4gICAgICByZXR1cm4gZ2xvYmFsLnNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG5cbiAgICBjbGVhckltbWVkaWF0ZSA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZSB8fCBmdW5jdGlvbih0aW1lcikge1xuICAgICAgcmV0dXJuIGdsb2JhbC5jbGVhclRpbWVvdXQodGltZXIpO1xuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnBhdXNlZCA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuX3RpbWVyID0gc2V0SW1tZWRpYXRlKHRoaXMubG9vcCk7XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUubG9vcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5lbWl0KCdwcm9ncmVzcycsICh0aGlzLmxpc3QubnVtQnVmZmVycyAtIHRoaXMubGlzdC5hdmFpbGFibGVCdWZmZXJzICsgMSkgLyB0aGlzLmxpc3QubnVtQnVmZmVycyAqIDEwMCB8IDApO1xuICAgICAgdGhpcy5lbWl0KCdkYXRhJywgdGhpcy5saXN0LmZpcnN0KTtcbiAgICAgIGlmICh0aGlzLmxpc3QuYWR2YW5jZSgpKSB7XG4gICAgICAgIHJldHVybiBzZXRJbW1lZGlhdGUodGhpcy5sb29wKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgICBjbGVhckltbWVkaWF0ZSh0aGlzLl90aW1lcik7XG4gICAgICByZXR1cm4gdGhpcy5wYXVzZWQgPSB0cnVlO1xuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnBhdXNlKCk7XG4gICAgICByZXR1cm4gdGhpcy5saXN0LnJld2luZCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gQnVmZmVyU291cmNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJTb3VyY2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iXX0=