123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023 |
- //请了解比特流
- (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){
-
- // document.addEventListener('touchstart', function() {
- // console.log("我主动的play()了");
- // // players.play();
- // // players.startPlaying();
- // // var messageData = new Uint8Array(se)
- // // player.decode(messageData);
- // // return this.asset.start(false);
- // this.playing = true;
- // // this.play();
- // console.log("this.playing",this.playing)
- // });
- (function() {
- var Asset, BufferSource, Decoder, Demuxer, EventEmitter, FileSource, HTTPSource,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('./core/events');
- HTTPSource = require('./sources/node/http');
- console.log(HTTPSource)
- FileSource = require('./sources/node/file');
- BufferSource = require('./sources/buffer');
- Demuxer = require('./demuxer');
- Decoder = require('./decoder');
- Asset = (function(superClass) {
- extend(Asset, superClass);
- function Asset(source) {
- this.source = source;
- this._decode = bind(this._decode, this);
- this.findDecoder = bind(this.findDecoder, this);
- this.probe = bind(this.probe, this);
- this.buffered = 0;
- this.duration = null;
- this.format = null;
- this.metadata = null;
- this.active = false;
- this.demuxer = null;
- this.decoder = null;
- this.source.once('data', this.probe);
- this.source.on('error', (function(_this) {
- return function(err) {
- _this.emit('error', err);
- return _this.stop();
- };
- })(this));
- this.source.on('progress', (function(_this) {
- return function(buffered) {
- _this.buffered = buffered;
- return _this.emit('buffer', _this.buffered);
- };
- })(this));
- }
- Asset.fromURL = function(url, opts) {
- return new Asset(new HTTPSource(url, opts));
- };
- Asset.fromFile = function(file) {
- return new Asset(new FileSource(file));
- };
- Asset.fromBuffer = function(buffer) {
- return new Asset(new BufferSource(buffer));
- };
- Asset.prototype.start = function(decode) {
- if (this.active) {
- return;
- }
- if (decode != null) {
- this.shouldDecode = decode;
- }
- if (this.shouldDecode == null) {
- this.shouldDecode = true;
- }
- this.active = true;
- this.source.start();
- if (this.decoder && this.shouldDecode) {
- return this._decode();
- }
- };
- Asset.prototype.stop = function() {
- if (!this.active) {
- return;
- }
- this.active = false;
- return this.source.pause();
- };
- Asset.prototype.get = function(event, callback) {
- if (event !== 'format' && event !== 'duration' && event !== 'metadata') {
- return;
- }
- if (this[event] != null) {
- return callback(this[event]);
- } else {
- this.once(event, (function(_this) {
- return function(value) {
- _this.stop();
- return callback(value);
- };
- })(this));
- return this.start();
- }
- };
- Asset.prototype.decodePacket = function() {
- return this.decoder.decode();
- };
- Asset.prototype.decodeToBuffer = function(callback) {
- var chunks, dataHandler, length;
- length = 0;
- chunks = [];
- this.on('data', dataHandler = function(chunk) {
- length += chunk.length;
- return chunks.push(chunk);
- });
- this.once('end', function() {
- var buf, chunk, j, len, offset;
- buf = new Float32Array(length);
- offset = 0;
- for (j = 0, len = chunks.length; j < len; j++) {
- chunk = chunks[j];
- buf.set(chunk, offset);
- offset += chunk.length;
- }
- this.off('data', dataHandler);
- return callback(buf);
- });
- return this.start();
- };
- Asset.prototype.probe = function(chunk) {
- var demuxer;
- if (!this.active) {
- return;
- }
- demuxer = Demuxer.find(chunk);
- if (!demuxer) {
- return this.emit('error', 'A demuxer for this container was not found.');
- }
- this.demuxer = new demuxer(this.source, chunk);
- this.demuxer.on('format', this.findDecoder);
- this.demuxer.on('duration', (function(_this) {
- return function(duration) {
- _this.duration = duration;
- return _this.emit('duration', _this.duration);
- };
- })(this));
- this.demuxer.on('metadata', (function(_this) {
- return function(metadata) {
- _this.metadata = metadata;
- return _this.emit('metadata', _this.metadata);
- };
- })(this));
- return this.demuxer.on('error', (function(_this) {
- return function(err) {
- _this.emit('error', err);
- return _this.stop();
- };
- })(this));
- };
- Asset.prototype.findDecoder = function(format) {
- var decoder, div;
- this.format = format;
- if (!this.active) {
- return;
- }
- this.emit('format', this.format);
- decoder = Decoder.find(this.format.formatID);
- if (!decoder) {
- return this.emit('error', "A decoder for " + this.format.formatID + " was not found.");
- }
- this.decoder = new decoder(this.demuxer, this.format);
- if (this.format.floatingPoint) {
- this.decoder.on('data', (function(_this) {
- return function(buffer) {
- return _this.emit('data', buffer);
- };
- })(this));
- } else {
- div = Math.pow(2, this.format.bitsPerChannel - 1);
- this.decoder.on('data', (function(_this) {
- return function(buffer) {
- var buf, i, j, len, sample;
- buf = new Float32Array(buffer.length);
- for (i = j = 0, len = buffer.length; j < len; i = ++j) {
- sample = buffer[i];
- buf[i] = sample / div;
- }
- return _this.emit('data', buf);
- };
- })(this));
- }
- this.decoder.on('error', (function(_this) {
- return function(err) {
- _this.emit('error', err);
- return _this.stop();
- };
- })(this));
- this.decoder.on('end', (function(_this) {
- return function() {
- return _this.emit('end');
- };
- })(this));
- this.emit('decodeStart');
- if (this.shouldDecode) {
- return this._decode();
- }
- };
- Asset.prototype._decode = function() {
- while (this.decoder.decode() && this.active) {
- continue;
- }
- if (this.active) {
- return this.decoder.once('data', this._decode);
- }
- };
- Asset.prototype.destroy = function() {
- var ref, ref1, ref2;
- this.stop();
- if ((ref = this.demuxer) != null) {
- ref.off();
- }
- if ((ref1 = this.decoder) != null) {
- ref1.off();
- }
- if ((ref2 = this.source) != null) {
- ref2.off();
- }
- return this.off();
- };
- return Asset;
- })(EventEmitter);
- module.exports = Asset;
- }).call(this);
- },{"./core/events":8,"./decoder":11,"./demuxer":14,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],2:[function(require,module,exports){
- (function() {
- var key, ref, val;
- ref = require('./aurora_base');
- for (key in ref) {
- val = ref[key];
- exports[key] = val;
- }
- require('./demuxers/caf');
- require('./demuxers/m4a');
- require('./demuxers/aiff');
- require('./demuxers/wave');
- require('./demuxers/au');
- require('./decoders/lpcm');
- require('./decoders/xlaw');
- }).call(this);
- },{"./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){
- // 模块生成
- (function() {
- exports.Base = require('./core/base');
- exports.Buffer = require('./core/buffer');
- exports.BufferList = require('./core/bufferlist');
- exports.Stream = require('./core/stream');
- exports.Bitstream = require('./core/bitstream');
- exports.EventEmitter = require('./core/events');
- exports.UnderflowError = require('./core/underflow');
- exports.HTTPSource = require('./sources/node/http');
- exports.FileSource = require('./sources/node/file');
- exports.BufferSource = require('./sources/buffer');
- exports.Demuxer = require('./demuxer');
- exports.Decoder = require('./decoder');
- exports.AudioDevice = require('./device');
- exports.Asset = require('./asset');
- exports.Player = require('./player');
- exports.Filter = require('./filter');
- exports.VolumeFilter = require('./filters/volume');
- exports.BalanceFilter = require('./filters/balance');
- }).call(this);
- },{"./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){
- (function() {
- var Base,
- 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; },
- hasProp = {}.hasOwnProperty,
- 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; };
- Base = (function() {
- var fnTest;
- function Base() {}
- fnTest = /\b_super\b/;
- Base.extend = function(prop) {
- var Class, _super, fn, key, keys, ref;
- Class = (function(superClass) {
- extend(Class, superClass);
- function Class() {
- return Class.__super__.constructor.apply(this, arguments);
- }
- return Class;
- })(this);
- if (typeof prop === 'function') {
- keys = Object.keys(Class.prototype);
- prop.call(Class, Class);
- prop = {};
- ref = Class.prototype;
- for (key in ref) {
- fn = ref[key];
- if (indexOf.call(keys, key) < 0) {
- prop[key] = fn;
- }
- }
- }
- _super = Class.__super__;
- for (key in prop) {
- fn = prop[key];
- if (typeof fn === 'function' && fnTest.test(fn)) {
- (function(key, fn) {
- return Class.prototype[key] = function() {
- var ret, tmp;
- tmp = this._super;
- this._super = _super[key];
- ret = fn.apply(this, arguments);
- this._super = tmp;
- return ret;
- };
- })(key, fn);
- } else {
- Class.prototype[key] = fn;
- }
- }
- return Class;
- };
- return Base;
- })();
- module.exports = Base;
- }).call(this);
- },{}],5:[function(require,module,exports){
- (function() {
- var Bitstream;
- Bitstream = (function() {
- function Bitstream(stream) {
- this.stream = stream;
- this.bitPosition = 0;
- }
- Bitstream.prototype.copy = function() {
- var result;
- result = new Bitstream(this.stream.copy());
- result.bitPosition = this.bitPosition;
- return result;
- };
- Bitstream.prototype.offset = function() {
- return 8 * this.stream.offset + this.bitPosition;
- };
- Bitstream.prototype.available = function(bits) {
- return this.stream.available((bits + 8 - this.bitPosition) / 8);
- };
- Bitstream.prototype.advance = function(bits) {
- var pos;
- pos = this.bitPosition + bits;
- this.stream.advance(pos >> 3);
- return this.bitPosition = pos & 7;
- };
- Bitstream.prototype.rewind = function(bits) {
- var pos;
- pos = this.bitPosition - bits;
- this.stream.rewind(Math.abs(pos >> 3));
- return this.bitPosition = pos & 7;
- };
- Bitstream.prototype.seek = function(offset) {
- var curOffset;
- curOffset = this.offset();
- if (offset > curOffset) {
- return this.advance(offset - curOffset);
- } else if (offset < curOffset) {
- return this.rewind(curOffset - offset);
- }
- };
- Bitstream.prototype.align = function() {
- if (this.bitPosition !== 0) {
- this.bitPosition = 0;
- return this.stream.advance(1);
- }
- };
- //Bitstream原型读取
- Bitstream.prototype.read = function(bits, signed) {
- var a, a0, a1, a2, a3, a4, mBits;
- if (bits === 0) {
- return 0;
- }
- mBits = bits + this.bitPosition;
- if (mBits <= 8) {
- a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
- } else if (mBits <= 16) {
- a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
- } else if (mBits <= 24) {
- a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
- } else if (mBits <= 32) {
- a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
- } else if (mBits <= 40) {
- a0 = this.stream.peekUInt8(0) * 0x0100000000;
- a1 = this.stream.peekUInt8(1) << 24 >>> 0;
- a2 = this.stream.peekUInt8(2) << 16;
- a3 = this.stream.peekUInt8(3) << 8;
- a4 = this.stream.peekUInt8(4);
- a = a0 + a1 + a2 + a3 + a4;
- a %= Math.pow(2, 40 - this.bitPosition);
- a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
- } else {
- throw new Error("Too many bits!");
- }
- if (signed) {
- if (mBits < 32) {
- if (a >>> (bits - 1)) {
- a = ((1 << bits >>> 0) - a) * -1;
- }
- } else {
- if (a / Math.pow(2, bits - 1) | 0) {
- a = (Math.pow(2, bits) - a) * -1;
- }
- }
- }
- this.advance(bits);
- return a;
- };
- // 每一段的查
- Bitstream.prototype.peek = function(bits, signed) {
- var a, a0, a1, a2, a3, a4, mBits;
- if (bits === 0) {
- return 0;
- }
- mBits = bits + this.bitPosition;
- if (mBits <= 8) {
- a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
- } else if (mBits <= 16) {
- a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
- } else if (mBits <= 24) {
- a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
- } else if (mBits <= 32) {
- a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
- } else if (mBits <= 40) {
- a0 = this.stream.peekUInt8(0) * 0x0100000000;
- a1 = this.stream.peekUInt8(1) << 24 >>> 0;
- a2 = this.stream.peekUInt8(2) << 16;
- a3 = this.stream.peekUInt8(3) << 8;
- a4 = this.stream.peekUInt8(4);
- a = a0 + a1 + a2 + a3 + a4;
- a %= Math.pow(2, 40 - this.bitPosition);
- a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
- } else {
- throw new Error("Too many bits!");
- }
- if (signed) {
- if (mBits < 32) {
- if (a >>> (bits - 1)) {
- a = ((1 << bits >>> 0) - a) * -1;
- }
- } else {
- if (a / Math.pow(2, bits - 1) | 0) {
- a = (Math.pow(2, bits) - a) * -1;
- }
- }
- }
- return a;
- };
- //读LSB 8 16 24 32 等
- Bitstream.prototype.readLSB = function(bits, signed) {
- var a, mBits;
- if (bits === 0) {
- return 0;
- }
- if (bits > 40) {
- throw new Error("Too many bits!");
- }
- mBits = bits + this.bitPosition;
- a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
- if (mBits > 8) {
- a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
- }
- if (mBits > 16) {
- a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
- }
- if (mBits > 24) {
- a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
- }
- if (mBits > 32) {
- a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
- }
- if (mBits >= 32) {
- a %= Math.pow(2, bits);
- } else {
- a &= (1 << bits) - 1;
- }
- if (signed) {
- if (mBits < 32) {
- if (a >>> (bits - 1)) {
- a = ((1 << bits >>> 0) - a) * -1;
- }
- } else {
- if (a / Math.pow(2, bits - 1) | 0) {
- a = (Math.pow(2, bits) - a) * -1;
- }
- }
- }
- this.advance(bits);
- return a;
- };
- Bitstream.prototype.peekLSB = function(bits, signed) {
- var a, mBits;
- if (bits === 0) {
- return 0;
- }
- if (bits > 40) {
- throw new Error("Too many bits!");
- }
- mBits = bits + this.bitPosition;
- a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
- if (mBits > 8) {
- a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
- }
- if (mBits > 16) {
- a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
- }
- if (mBits > 24) {
- a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
- }
- if (mBits > 32) {
- a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
- }
- if (mBits >= 32) {
- a %= Math.pow(2, bits);
- } else {
- a &= (1 << bits) - 1;
- }
- if (signed) {
- if (mBits < 32) {
- if (a >>> (bits - 1)) {
- a = ((1 << bits >>> 0) - a) * -1;
- }
- } else {
- if (a / Math.pow(2, bits - 1) | 0) {
- a = (Math.pow(2, bits) - a) * -1;
- }
- }
- }
- return a;
- };
- return Bitstream;
- })();
- module.exports = Bitstream;
- }).call(this);
- },{}],6:[function(require,module,exports){
- (function (global){
- (function() {
- var AVBuffer;
- AVBuffer = (function() {
- var BlobBuilder, URL;
- function AVBuffer(input) {
- var ref;
- if (input instanceof Uint8Array) {
- this.data = input;
- } else if (input instanceof ArrayBuffer || Array.isArray(input) || typeof input === 'number' || ((ref = global.Buffer) != null ? ref.isBuffer(input) : void 0)) {
- this.data = new Uint8Array(input);
- } else if (input.buffer instanceof ArrayBuffer) {
- this.data = new Uint8Array(input.buffer, input.byteOffset, input.length * input.BYTES_PER_ELEMENT);
- } else if (input instanceof AVBuffer) {
- this.data = input.data;
- } else {
- throw new Error("Constructing buffer with unknown type.构造未知类型的缓冲区");
- }
- this.length = this.data.length;
- this.next = null;
- this.prev = null;
- }
- AVBuffer.allocate = function(size) {
- return new AVBuffer(size);
- };
- AVBuffer.prototype.copy = function() {
- return new AVBuffer(new Uint8Array(this.data));
- };
- AVBuffer.prototype.slice = function(position, length) {
- if (length == null) {
- length = this.length;
- }
- if (position === 0 && length >= this.length) {
- return new AVBuffer(this.data);
- } else {
- return new AVBuffer(this.data.subarray(position, position + length));
- }
- };
- BlobBuilder = global.BlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder;
- URL = global.URL || global.webkitURL || global.mozURL;
- AVBuffer.makeBlob = function(data, type) {
- var bb;
- if (type == null) {
- type = 'application/octet-stream';
- }
- try {
- return new Blob([data], {
- type: type
- });
- } catch (undefined) {}
- if (BlobBuilder != null) {
- bb = new BlobBuilder;
- bb.append(data);
- return bb.getBlob(type);
- }
- return null;
- };
- AVBuffer.makeBlobURL = function(data, type) {
- return URL != null ? URL.createObjectURL(this.makeBlob(data, type)) : void 0;
- };
- AVBuffer.revokeBlobURL = function(url) {
- return URL != null ? URL.revokeObjectURL(url) : void 0;
- };
- AVBuffer.prototype.toBlob = function() {
- return AVBuffer.makeBlob(this.data.buffer);
- };
- AVBuffer.prototype.toBlobURL = function() {
- return AVBuffer.makeBlobURL(this.data.buffer);
- };
- return AVBuffer;
- })();
- module.exports = AVBuffer;
- }).call(this);
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{}],7:[function(require,module,exports){
- (function() {
- var BufferList;
- BufferList = (function() {
- function BufferList() {
- this.first = null;
- this.last = null;
- this.numBuffers = 0;
- this.availableBytes = 0;
- this.availableBuffers = 0;
- }
- BufferList.prototype.copy = function() {
- var result;
- result = new BufferList;
- result.first = this.first;
- result.last = this.last;
- result.numBuffers = this.numBuffers;
- result.availableBytes = this.availableBytes;
- result.availableBuffers = this.availableBuffers;
- return result;
- };
- BufferList.prototype.append = function(buffer) {
- var ref;
- buffer.prev = this.last;
- if ((ref = this.last) != null) {
- ref.next = buffer;
- }
- this.last = buffer;
- if (this.first == null) {
- this.first = buffer;
- }
- this.availableBytes += buffer.length;
- this.availableBuffers++;
- return this.numBuffers++;
- };
- BufferList.prototype.advance = function() {
- if (this.first) {
- this.availableBytes -= this.first.length;
- this.availableBuffers--;
- this.first = this.first.next;
- return this.first != null;
- }
- return false;
- };
- BufferList.prototype.rewind = function() {
- var ref;
- if (this.first && !this.first.prev) {
- return false;
- }
- this.first = ((ref = this.first) != null ? ref.prev : void 0) || this.last;
- if (this.first) {
- this.availableBytes += this.first.length;
- this.availableBuffers++;
- }
- return this.first != null;
- };
- BufferList.prototype.reset = function() {
- var results;
- results = [];
- while (this.rewind()) {
- continue;
- }
- return results;
- };
- return BufferList;
- })();
- module.exports = BufferList;
- }).call(this);
- },{}],8:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Base, EventEmitter,
- 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; },
- hasProp = {}.hasOwnProperty,
- slice = [].slice;
- Base = require('./base');
- EventEmitter = (function(superClass) {
- extend(EventEmitter, superClass);
- function EventEmitter() {
- return EventEmitter.__super__.constructor.apply(this, arguments);
- }
- EventEmitter.prototype.on = function(event, fn) {
- var base;
- if (this.events == null) {
- this.events = {};
- }
- if ((base = this.events)[event] == null) {
- base[event] = [];
- }
- return this.events[event].push(fn);
- };
- EventEmitter.prototype.off = function(event, fn) {
- var events, index, ref;
- if (this.events == null) {
- return;
- }
- if ((ref = this.events) != null ? ref[event] : void 0) {
- if (fn != null) {
- index = this.events[event].indexOf(fn);
- if (~index) {
- return this.events[event].splice(index, 1);
- }
- } else {
- return this.events[event];
- }
- } else if (event == null) {
- return events = {};
- }
- };
- EventEmitter.prototype.once = function(event, fn) {
- var cb;
- return this.on(event, cb = function() {
- this.off(event, cb);
- return fn.apply(this, arguments);
- });
- };
- EventEmitter.prototype.emit = function() {
- var args, event, fn, i, len, ref, ref1;
- event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
- if (!((ref = this.events) != null ? ref[event] : void 0)) {
- return;
- }
- ref1 = this.events[event].slice();
- for (i = 0, len = ref1.length; i < len; i++) {
- fn = ref1[i];
- fn.apply(this, args);
- }
- };
- return EventEmitter;
- })(Base);
- module.exports = EventEmitter;
- }).call(this);
- },{"./base":4}],9:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AVBuffer, BufferList, Stream, UnderflowError;
- BufferList = require('./bufferlist');
- AVBuffer = require('./buffer');
- UnderflowError = require('./underflow');
- Stream = (function() {
- var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8;
- buf = new ArrayBuffer(16);
- uint8 = new Uint8Array(buf);
- int8 = new Int8Array(buf);
- uint16 = new Uint16Array(buf);
- int16 = new Int16Array(buf);
- uint32 = new Uint32Array(buf);
- int32 = new Int32Array(buf);
- float32 = new Float32Array(buf);
- if (typeof Float64Array !== "undefined" && Float64Array !== null) {
- float64 = new Float64Array(buf);
- }
- nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
- function Stream(list1) {
- this.list = list1;
- this.localOffset = 0;
- this.offset = 0;
- }
- Stream.fromBuffer = function(buffer) {
- var list;
- list = new BufferList;
- list.append(buffer);
- return new Stream(list);
- };
- Stream.prototype.copy = function() {
- var result;
- result = new Stream(this.list.copy());
- result.localOffset = this.localOffset;
- result.offset = this.offset;
- return result;
- };
- Stream.prototype.available = function(bytes) {
- return bytes <= this.list.availableBytes - this.localOffset;
- };
- Stream.prototype.remainingBytes = function() {
- return this.list.availableBytes - this.localOffset;
- };
- Stream.prototype.advance = function(bytes) {
- if (!this.available(bytes)) {
- throw new UnderflowError();
- }
- this.localOffset += bytes;
- this.offset += bytes;
- while (this.list.first && this.localOffset >= this.list.first.length) {
- this.localOffset -= this.list.first.length;
- this.list.advance();
- }
- return this;
- };
- Stream.prototype.rewind = function(bytes) {
- if (bytes > this.offset) {
- throw new UnderflowError();
- }
- if (!this.list.first) {
- this.list.rewind();
- this.localOffset = this.list.first.length;
- }
- this.localOffset -= bytes;
- this.offset -= bytes;
- while (this.list.first.prev && this.localOffset < 0) {
- this.list.rewind();
- this.localOffset += this.list.first.length;
- }
- return this;
- };
- Stream.prototype.seek = function(position) {
- if (position > this.offset) {
- return this.advance(position - this.offset);
- } else if (position < this.offset) {
- return this.rewind(this.offset - position);
- }
- };
- Stream.prototype.readUInt8 = function() {
- var a;
- if (!this.available(1)) {
- throw new UnderflowError();
- }
- a = this.list.first.data[this.localOffset];
- this.localOffset += 1;
- this.offset += 1;
- if (this.localOffset === this.list.first.length) {
- this.localOffset = 0;
- this.list.advance();
- }
- return a;
- };
- Stream.prototype.peekUInt8 = function(offset) {
- var buffer;
- if (offset == null) {
- offset = 0;
- }
- if (!this.available(offset + 1)) {
- throw new UnderflowError();
- }
- offset = this.localOffset + offset;
- buffer = this.list.first;
- while (buffer) {
- if (buffer.length > offset) {
- return buffer.data[offset];
- }
- offset -= buffer.length;
- buffer = buffer.next;
- }
- return 0;
- };
- Stream.prototype.read = function(bytes, littleEndian) {
- var i, j, k, ref, ref1;
- if (littleEndian == null) {
- littleEndian = false;
- }
- if (littleEndian === nativeEndian) {
- for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
- uint8[i] = this.readUInt8();
- }
- } else {
- for (i = k = ref1 = bytes - 1; k >= 0; i = k += -1) {
- uint8[i] = this.readUInt8();
- }
- }
- };
- Stream.prototype.peek = function(bytes, offset, littleEndian) {
- var i, j, k, ref, ref1;
- if (littleEndian == null) {
- littleEndian = false;
- }
- if (littleEndian === nativeEndian) {
- for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
- uint8[i] = this.peekUInt8(offset + i);
- }
- } else {
- for (i = k = 0, ref1 = bytes; k < ref1; i = k += 1) {
- uint8[bytes - i - 1] = this.peekUInt8(offset + i);
- }
- }
- };
- Stream.prototype.readInt8 = function() {
- this.read(1);
- return int8[0];
- };
- Stream.prototype.peekInt8 = function(offset) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(1, offset);
- return int8[0];
- };
- Stream.prototype.readUInt16 = function(littleEndian) {
- this.read(2, littleEndian);
- return uint16[0];
- };
- Stream.prototype.peekUInt16 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(2, offset, littleEndian);
- return uint16[0];
- };
- Stream.prototype.readInt16 = function(littleEndian) {
- this.read(2, littleEndian);
- return int16[0];
- };
- Stream.prototype.peekInt16 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(2, offset, littleEndian);
- return int16[0];
- };
- Stream.prototype.readUInt24 = function(littleEndian) {
- if (littleEndian) {
- return this.readUInt16(true) + (this.readUInt8() << 16);
- } else {
- return (this.readUInt16() << 8) + this.readUInt8();
- }
- };
- Stream.prototype.peekUInt24 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- if (littleEndian) {
- return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16);
- } else {
- return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2);
- }
- };
- Stream.prototype.readInt24 = function(littleEndian) {
- if (littleEndian) {
- return this.readUInt16(true) + (this.readInt8() << 16);
- } else {
- return (this.readInt16() << 8) + this.readUInt8();
- }
- };
- Stream.prototype.peekInt24 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- if (littleEndian) {
- return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16);
- } else {
- return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2);
- }
- };
- Stream.prototype.readUInt32 = function(littleEndian) {
- this.read(4, littleEndian);
- return uint32[0];
- };
- Stream.prototype.peekUInt32 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(4, offset, littleEndian);
- return uint32[0];
- };
- Stream.prototype.readInt32 = function(littleEndian) {
- this.read(4, littleEndian);
- return int32[0];
- };
- Stream.prototype.peekInt32 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(4, offset, littleEndian);
- return int32[0];
- };
- Stream.prototype.readFloat32 = function(littleEndian) {
- this.read(4, littleEndian);
- return float32[0];
- };
- Stream.prototype.peekFloat32 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(4, offset, littleEndian);
- return float32[0];
- };
- Stream.prototype.readFloat64 = function(littleEndian) {
- this.read(8, littleEndian);
- if (float64) {
- return float64[0];
- } else {
- return float64Fallback();
- }
- };
- float64Fallback = function() {
- var exp, frac, high, low, out, sign;
- low = uint32[0], high = uint32[1];
- if (!high || high === 0x80000000) {
- return 0.0;
- }
- sign = 1 - (high >>> 31) * 2;
- exp = (high >>> 20) & 0x7ff;
- frac = high & 0xfffff;
- if (exp === 0x7ff) {
- if (frac) {
- return NaN;
- }
- return sign * Infinity;
- }
- exp -= 1023;
- out = (frac | 0x100000) * Math.pow(2, exp - 20);
- out += low * Math.pow(2, exp - 52);
- return sign * out;
- };
- Stream.prototype.peekFloat64 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(8, offset, littleEndian);
- if (float64) {
- return float64[0];
- } else {
- return float64Fallback();
- }
- };
- Stream.prototype.readFloat80 = function(littleEndian) {
- this.read(10, littleEndian);
- return float80();
- };
- float80 = function() {
- var a0, a1, exp, high, low, out, sign;
- high = uint32[0], low = uint32[1];
- a0 = uint8[9];
- a1 = uint8[8];
- sign = 1 - (a0 >>> 7) * 2;
- exp = ((a0 & 0x7F) << 8) | a1;
- if (exp === 0 && low === 0 && high === 0) {
- return 0;
- }
- if (exp === 0x7fff) {
- if (low === 0 && high === 0) {
- return sign * Infinity;
- }
- return NaN;
- }
- exp -= 16383;
- out = low * Math.pow(2, exp - 31);
- out += high * Math.pow(2, exp - 63);
- return sign * out;
- };
- Stream.prototype.peekFloat80 = function(offset, littleEndian) {
- if (offset == null) {
- offset = 0;
- }
- this.peek(10, offset, littleEndian);
- return float80();
- };
- Stream.prototype.readBuffer = function(length) {
- var i, j, ref, result, to;
- result = AVBuffer.allocate(length);
- to = result.data;
- for (i = j = 0, ref = length; j < ref; i = j += 1) {
- to[i] = this.readUInt8();
- }
- return result;
- };
- Stream.prototype.peekBuffer = function(offset, length) {
- var i, j, ref, result, to;
- if (offset == null) {
- offset = 0;
- }
- result = AVBuffer.allocate(length);
- to = result.data;
- for (i = j = 0, ref = length; j < ref; i = j += 1) {
- to[i] = this.peekUInt8(offset + i);
- }
- return result;
- };
- Stream.prototype.readSingleBuffer = function(length) {
- var result;
- result = this.list.first.slice(this.localOffset, length);
- this.advance(result.length);
- return result;
- };
- Stream.prototype.peekSingleBuffer = function(offset, length) {
- var result;
- result = this.list.first.slice(this.localOffset + offset, length);
- return result;
- };
- Stream.prototype.readString = function(length, encoding) {
- if (encoding == null) {
- encoding = 'ascii';
- }
- return decodeString.call(this, 0, length, encoding, true);
- };
- Stream.prototype.peekString = function(offset, length, encoding) {
- if (offset == null) {
- offset = 0;
- }
- if (encoding == null) {
- encoding = 'ascii';
- }
- return decodeString.call(this, offset, length, encoding, false);
- };
- decodeString = function(offset, length, encoding, advance) {
- var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2;
- encoding = encoding.toLowerCase();
- nullEnd = length === null ? 0 : -1;
- if (length == null) {
- length = Infinity;
- }
- end = offset + length;
- result = '';
- switch (encoding) {
- case 'ascii':
- case 'latin1':
- while (offset < end && (c = this.peekUInt8(offset++)) !== nullEnd) {
- result += String.fromCharCode(c);
- }
- break;
- case 'utf8':
- case 'utf-8':
- while (offset < end && (b1 = this.peekUInt8(offset++)) !== nullEnd) {
- if ((b1 & 0x80) === 0) {
- result += String.fromCharCode(b1);
- } else if ((b1 & 0xe0) === 0xc0) {
- b2 = this.peekUInt8(offset++) & 0x3f;
- result += String.fromCharCode(((b1 & 0x1f) << 6) | b2);
- } else if ((b1 & 0xf0) === 0xe0) {
- b2 = this.peekUInt8(offset++) & 0x3f;
- b3 = this.peekUInt8(offset++) & 0x3f;
- result += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3);
- } else if ((b1 & 0xf8) === 0xf0) {
- b2 = this.peekUInt8(offset++) & 0x3f;
- b3 = this.peekUInt8(offset++) & 0x3f;
- b4 = this.peekUInt8(offset++) & 0x3f;
- pt = (((b1 & 0x0f) << 18) | (b2 << 12) | (b3 << 6) | b4) - 0x10000;
- result += String.fromCharCode(0xd800 + (pt >> 10), 0xdc00 + (pt & 0x3ff));
- }
- }
- break;
- case 'utf16-be':
- case 'utf16be':
- case 'utf16le':
- case 'utf16-le':
- case 'utf16bom':
- case 'utf16-bom':
- switch (encoding) {
- case 'utf16be':
- case 'utf16-be':
- littleEndian = false;
- break;
- case 'utf16le':
- case 'utf16-le':
- littleEndian = true;
- break;
- case 'utf16bom':
- case 'utf16-bom':
- if (length < 2 || (bom = this.peekUInt16(offset)) === nullEnd) {
- if (advance) {
- this.advance(offset += 2);
- }
- return result;
- }
- littleEndian = bom === 0xfffe;
- offset += 2;
- }
- while (offset < end && (w1 = this.peekUInt16(offset, littleEndian)) !== nullEnd) {
- offset += 2;
- if (w1 < 0xd800 || w1 > 0xdfff) {
- result += String.fromCharCode(w1);
- } else {
- if (w1 > 0xdbff) {
- throw new Error("Invalid utf16 sequence.");
- }
- w2 = this.peekUInt16(offset, littleEndian);
- if (w2 < 0xdc00 || w2 > 0xdfff) {
- throw new Error("Invalid utf16 sequence.");
- }
- result += String.fromCharCode(w1, w2);
- offset += 2;
- }
- }
- if (w1 === nullEnd) {
- offset += 2;
- }
- break;
- default:
- throw new Error("Unknown encoding: " + encoding);
- }
- if (advance) {
- this.advance(offset);
- }
- return result;
- };
- return Stream;
- })();
- module.exports = Stream;
- }).call(this);
- },{"./buffer":6,"./bufferlist":7,"./underflow":10}],10:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var UnderflowError,
- 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; },
- hasProp = {}.hasOwnProperty;
- UnderflowError = (function(superClass) {
- extend(UnderflowError, superClass);
- function UnderflowError() {
- UnderflowError.__super__.constructor.apply(this, arguments);
- this.name = 'UnderflowError';
- this.stack = new Error().stack;
- }
- return UnderflowError;
- })(Error);
- module.exports = UnderflowError;
- }).call(this);
- },{}],11:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError,
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('./core/events');
- BufferList = require('./core/bufferlist');
- Stream = require('./core/stream');
- Bitstream = require('./core/bitstream');
- UnderflowError = require('./core/underflow');
- Decoder = (function(superClass) {
- var codecs;
- extend(Decoder, superClass);
- function Decoder(demuxer, format) {
- var list;
- this.demuxer = demuxer;
- this.format = format;
- list = new BufferList;
- this.stream = new Stream(list);
- this.bitstream = new Bitstream(this.stream);
- this.receivedFinalBuffer = false;
- this.waiting = false;
- this.demuxer.on('cookie', (function(_this) {
- return function(cookie) {
- var error, error1;
- try {
- return _this.setCookie(cookie);
- } catch (error1) {
- error = error1;
- return _this.emit('error', error);
- }
- };
- })(this));
- this.demuxer.on('data', (function(_this) {
- return function(chunk) {
- list.append(chunk);
- if (_this.waiting) {
- return _this.decode();
- }
- };
- })(this));
- this.demuxer.on('end', (function(_this) {
- return function() {
- _this.receivedFinalBuffer = true;
- if (_this.waiting) {
- return _this.decode();
- }
- };
- })(this));
- this.init();
- }
- Decoder.prototype.init = function() {};
- Decoder.prototype.setCookie = function(cookie) {};
- Decoder.prototype.readChunk = function() {};
- Decoder.prototype.decode = function() {
- var error, error1, offset, packet;
- this.waiting = !this.receivedFinalBuffer;
- offset = this.bitstream.offset();
- try {
- packet = this.readChunk();
- } catch (error1) {
- error = error1;
- if (!(error instanceof UnderflowError)) {
- this.emit('error', error);
- return false;
- }
- }
- if (packet) {
- this.emit('data', packet);
- if (this.receivedFinalBuffer) {
- this.emit('end');
- }
- return true;
- } else if (!this.receivedFinalBuffer) {
- this.bitstream.seek(offset);
- this.waiting = true;
- } else {
- this.emit('end');
- }
- return false;
- };
- Decoder.prototype.seek = function(timestamp) {
- var seekPoint;
- seekPoint = this.demuxer.seek(timestamp);
- this.stream.seek(seekPoint.offset);
- return seekPoint.timestamp;
- };
- codecs = {};
- Decoder.register = function(id, decoder) {
- return codecs[id] = decoder;
- };
- Decoder.find = function(id) {
- return codecs[id] || null;
- };
- return Decoder;
- })(EventEmitter);
- module.exports = Decoder;
- }).call(this);
- },{"./core/bitstream":5,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10}],12:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Decoder, LPCMDecoder,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- Decoder = require('../decoder');
- LPCMDecoder = (function(superClass) {
- extend(LPCMDecoder, superClass);
- function LPCMDecoder() {
- this.readChunk = bind(this.readChunk, this);
- return LPCMDecoder.__super__.constructor.apply(this, arguments);
- }
- Decoder.register('lpcm', LPCMDecoder);
- LPCMDecoder.prototype.readChunk = function() {
- var chunkSize, i, j, k, l, littleEndian, m, n, o, output, ref, ref1, ref2, ref3, ref4, ref5, samples, stream;
- stream = this.stream;
- littleEndian = this.format.littleEndian;
- chunkSize = Math.min(4096, stream.remainingBytes());
- samples = chunkSize / (this.format.bitsPerChannel / 8) | 0;
- if (chunkSize < this.format.bitsPerChannel / 8) {
- return null;
- }
- if (this.format.floatingPoint) {
- switch (this.format.bitsPerChannel) {
- case 32:
- output = new Float32Array(samples);
- for (i = j = 0, ref = samples; j < ref; i = j += 1) {
- output[i] = stream.readFloat32(littleEndian);
- }
- break;
- case 64:
- output = new Float64Array(samples);
- for (i = k = 0, ref1 = samples; k < ref1; i = k += 1) {
- output[i] = stream.readFloat64(littleEndian);
- }
- break;
- default:
- throw new Error('Unsupported bit depth.不支持的位深度');
- }
- } else {
- switch (this.format.bitsPerChannel) {
- case 8:
- output = new Int8Array(samples);
- for (i = l = 0, ref2 = samples; l < ref2; i = l += 1) {
- output[i] = stream.readInt8();
- }
- break;
- case 16:
- output = new Int16Array(samples);
- for (i = m = 0, ref3 = samples; m < ref3; i = m += 1) {
- output[i] = stream.readInt16(littleEndian);
- }
- break;
- case 24:
- output = new Int32Array(samples);
- for (i = n = 0, ref4 = samples; n < ref4; i = n += 1) {
- output[i] = stream.readInt24(littleEndian);
- }
- break;
- case 32:
- output = new Int32Array(samples);
- for (i = o = 0, ref5 = samples; o < ref5; i = o += 1) {
- output[i] = stream.readInt32(littleEndian);
- }
- break;
- default:
- throw new Error('Unsupported bit depth.');
- }
- }
- return output;
- };
- return LPCMDecoder;
- })(Decoder);
- }).call(this);
- },{"../decoder":11}],13:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Decoder, XLAWDecoder,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- Decoder = require('../decoder');
- XLAWDecoder = (function(superClass) {
- var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT;
- extend(XLAWDecoder, superClass);
- function XLAWDecoder() {
- this.readChunk = bind(this.readChunk, this);
- return XLAWDecoder.__super__.constructor.apply(this, arguments);
- }
- Decoder.register('ulaw', XLAWDecoder);
- Decoder.register('alaw', XLAWDecoder);
- SIGN_BIT = 0x80;
- QUANT_MASK = 0xf;
- SEG_SHIFT = 4;
- SEG_MASK = 0x70;
- BIAS = 0x84;
- XLAWDecoder.prototype.init = function() {
- var i, j, k, seg, t, table, val;
- this.format.bitsPerChannel = 16;
- this.table = table = new Int16Array(256);
- if (this.format.formatID === 'ulaw') {
- for (i = j = 0; j < 256; i = ++j) {
- val = ~i;
- t = ((val & QUANT_MASK) << 3) + BIAS;
- t <<= (val & SEG_MASK) >>> SEG_SHIFT;
- table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS;
- }
- } else {
- for (i = k = 0; k < 256; i = ++k) {
- val = i ^ 0x55;
- t = val & QUANT_MASK;
- seg = (val & SEG_MASK) >>> SEG_SHIFT;
- if (seg) {
- t = (t + t + 1 + 32) << (seg + 2);
- } else {
- t = (t + t + 1) << 3;
- }
- table[i] = val & SIGN_BIT ? t : -t;
- }
- }
- };
- XLAWDecoder.prototype.readChunk = function() {
- var i, j, output, ref, samples, stream, table;
- stream = this.stream, table = this.table;
- samples = Math.min(4096, this.stream.remainingBytes());
- if (samples === 0) {
- return;
- }
- output = new Int16Array(samples);
- for (i = j = 0, ref = samples; j < ref; i = j += 1) {
- output[i] = table[stream.readUInt8()];
- }
- return output;
- };
- return XLAWDecoder;
- })(Decoder);
- }).call(this);
- },{"../decoder":11}],14:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var BufferList, Demuxer, EventEmitter, Stream,
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('./core/events');
- BufferList = require('./core/bufferlist');
- Stream = require('./core/stream');
- Demuxer = (function(superClass) {
- var formats;
- extend(Demuxer, superClass);
- Demuxer.probe = function(buffer) {
- return false;
- };
- function Demuxer(source, chunk) {
- var list, received;
- list = new BufferList;
- list.append(chunk);
- this.stream = new Stream(list);
- received = false;
- source.on('data', (function(_this) {
- return function(chunk) {
- var e, error;
- received = true;
- list.append(chunk);
- try {
- return _this.readChunk(chunk);
- } catch (error) {
- e = error;
- return _this.emit('error', e);
- }
- };
- })(this));
- source.on('error', (function(_this) {
- return function(err) {
- return _this.emit('error', err);
- };
- })(this));
- source.on('end', (function(_this) {
- return function() {
- if (!received) {
- _this.readChunk(chunk);
- }
- return _this.emit('end');
- };
- })(this));
- this.seekPoints = [];
- this.init();
- }
- Demuxer.prototype.init = function() {};
- Demuxer.prototype.readChunk = function(chunk) {};
- Demuxer.prototype.addSeekPoint = function(offset, timestamp) {
- var index;
- index = this.searchTimestamp(timestamp);
- return this.seekPoints.splice(index, 0, {
- offset: offset,
- timestamp: timestamp
- });
- };
- Demuxer.prototype.searchTimestamp = function(timestamp, backward) {
- var high, low, mid, time;
- low = 0;
- high = this.seekPoints.length;
- if (high > 0 && this.seekPoints[high - 1].timestamp < timestamp) {
- return high;
- }
- while (low < high) {
- mid = (low + high) >> 1;
- time = this.seekPoints[mid].timestamp;
- if (time < timestamp) {
- low = mid + 1;
- } else if (time >= timestamp) {
- high = mid;
- }
- }
- if (high > this.seekPoints.length) {
- high = this.seekPoints.length;
- }
- return high;
- };
- Demuxer.prototype.seek = function(timestamp) {
- var index, seekPoint;
- if (this.format && this.format.framesPerPacket > 0 && this.format.bytesPerPacket > 0) {
- seekPoint = {
- timestamp: timestamp,
- offset: this.format.bytesPerPacket * timestamp / this.format.framesPerPacket
- };
- return seekPoint;
- } else {
- index = this.searchTimestamp(timestamp);
- return this.seekPoints[index];
- }
- };
- formats = [];
- Demuxer.register = function(demuxer) {
- return formats.push(demuxer);
- };
- Demuxer.find = function(buffer) {
- var e, error, format, i, len, offset, stream;
- stream = Stream.fromBuffer(buffer);
- for (i = 0, len = formats.length; i < len; i++) {
- format = formats[i];
- offset = stream.offset;
- try {
- if (format.probe(stream)) {
- return format;
- }
- } catch (error) {
- e = error;
- }
- stream.seek(offset);
- }
- return null;
- };
- return Demuxer;
- })(EventEmitter);
- module.exports = Demuxer;
- }).call(this);
- },{"./core/bufferlist":7,"./core/events":8,"./core/stream":9}],15:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AIFFDemuxer, Demuxer,
- 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; },
- hasProp = {}.hasOwnProperty;
- Demuxer = require('../demuxer');
- AIFFDemuxer = (function(superClass) {
- extend(AIFFDemuxer, superClass);
- function AIFFDemuxer() {
- return AIFFDemuxer.__super__.constructor.apply(this, arguments);
- }
- Demuxer.register(AIFFDemuxer);
- AIFFDemuxer.probe = function(buffer) {
- var ref;
- return buffer.peekString(0, 4) === 'FORM' && ((ref = buffer.peekString(8, 4)) === 'AIFF' || ref === 'AIFC');
- };
- AIFFDemuxer.prototype.readChunk = function() {
- var buffer, format, offset, ref;
- if (!this.readStart && this.stream.available(12)) {
- if (this.stream.readString(4) !== 'FORM') {
- return this.emit('error', 'Invalid AIFF.');
- }
- this.fileSize = this.stream.readUInt32();
- this.fileType = this.stream.readString(4);
- this.readStart = true;
- if ((ref = this.fileType) !== 'AIFF' && ref !== 'AIFC') {
- return this.emit('error', 'Invalid AIFF.');
- }
- }
- while (this.stream.available(1)) {
- if (!this.readHeaders && this.stream.available(8)) {
- this.type = this.stream.readString(4);
- this.len = this.stream.readUInt32();
- }
- switch (this.type) {
- case 'COMM':
- if (!this.stream.available(this.len)) {
- return;
- }
- this.format = {
- formatID: 'lpcm',
- channelsPerFrame: this.stream.readUInt16(),
- sampleCount: this.stream.readUInt32(),
- bitsPerChannel: this.stream.readUInt16(),
- sampleRate: this.stream.readFloat80(),
- framesPerPacket: 1,
- littleEndian: false,
- floatingPoint: false
- };
- this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
- if (this.fileType === 'AIFC') {
- format = this.stream.readString(4);
- this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8;
- this.format.floatingPoint = format === 'fl32' || format === 'fl64';
- if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') {
- format = 'lpcm';
- }
- this.format.formatID = format;
- this.len -= 4;
- }
- this.stream.advance(this.len - 18);
- this.emit('format', this.format);
- this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0);
- break;
- case 'SSND':
- if (!(this.readSSNDHeader && this.stream.available(4))) {
- offset = this.stream.readUInt32();
- this.stream.advance(4);
- this.stream.advance(offset);
- this.readSSNDHeader = true;
- }
- buffer = this.stream.readSingleBuffer(this.len);
- this.len -= buffer.length;
- this.readHeaders = this.len > 0;
- this.emit('data', buffer);
- break;
- default:
- if (!this.stream.available(this.len)) {
- return;
- }
- this.stream.advance(this.len);
- }
- if (this.type !== 'SSND') {
- this.readHeaders = false;
- }
- }
- };
- return AIFFDemuxer;
- })(Demuxer);
- }).call(this);
- },{"../demuxer":14}],16:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AUDemuxer, Demuxer,
- 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; },
- hasProp = {}.hasOwnProperty;
- Demuxer = require('../demuxer');
- AUDemuxer = (function(superClass) {
- var bps, formats;
- extend(AUDemuxer, superClass);
- function AUDemuxer() {
- return AUDemuxer.__super__.constructor.apply(this, arguments);
- }
- Demuxer.register(AUDemuxer);
- AUDemuxer.probe = function(buffer) {
- return buffer.peekString(0, 4) === '.snd';
- };
- bps = [8, 8, 16, 24, 32, 32, 64];
- bps[26] = 8;
- formats = {
- 1: 'ulaw',
- 27: 'alaw'
- };
- AUDemuxer.prototype.readChunk = function() {
- var bytes, dataSize, encoding, size;
- if (!this.readHeader && this.stream.available(24)) {
- if (this.stream.readString(4) !== '.snd') {
- return this.emit('error', 'Invalid AU file.');
- }
- size = this.stream.readUInt32();
- dataSize = this.stream.readUInt32();
- encoding = this.stream.readUInt32();
- this.format = {
- formatID: formats[encoding] || 'lpcm',
- littleEndian: false,
- floatingPoint: encoding === 6 || encoding === 7,
- bitsPerChannel: bps[encoding - 1],
- sampleRate: this.stream.readUInt32(),
- channelsPerFrame: this.stream.readUInt32(),
- framesPerPacket: 1
- };
- if (this.format.bitsPerChannel == null) {
- return this.emit('error', 'Unsupported encoding in AU file.');
- }
- this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
- if (dataSize !== 0xffffffff) {
- bytes = this.format.bitsPerChannel / 8;
- this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
- }
- this.emit('format', this.format);
- this.readHeader = true;
- }
- if (this.readHeader) {
- while (this.stream.available(1)) {
- this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes()));
- }
- }
- };
- return AUDemuxer;
- })(Demuxer);
- }).call(this);
- },{"../demuxer":14}],17:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var CAFDemuxer, Demuxer, M4ADemuxer,
- 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; },
- hasProp = {}.hasOwnProperty;
- Demuxer = require('../demuxer');
- M4ADemuxer = require('./m4a');
- CAFDemuxer = (function(superClass) {
- extend(CAFDemuxer, superClass);
- function CAFDemuxer() {
- return CAFDemuxer.__super__.constructor.apply(this, arguments);
- }
- Demuxer.register(CAFDemuxer);
- CAFDemuxer.probe = function(buffer) {
- return buffer.peekString(0, 4) === 'caff';
- };
- CAFDemuxer.prototype.readChunk = function() {
- var buffer, byteOffset, cookie, entries, flags, i, j, k, key, metadata, offset, ref, ref1, sampleOffset, value;
- if (!this.format && this.stream.available(64)) {
- if (this.stream.readString(4) !== 'caff') {
- return this.emit('error', "Invalid CAF, does not begin with 'caff'");
- }
- this.stream.advance(4);
- if (this.stream.readString(4) !== 'desc') {
- return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'");
- }
- if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) {
- return this.emit('error', "Invalid 'desc' size, should be 32");
- }
- this.format = {};
- this.format.sampleRate = this.stream.readFloat64();
- this.format.formatID = this.stream.readString(4);
- flags = this.stream.readUInt32();
- if (this.format.formatID === 'lpcm') {
- this.format.floatingPoint = Boolean(flags & 1);
- this.format.littleEndian = Boolean(flags & 2);
- }
- this.format.bytesPerPacket = this.stream.readUInt32();
- this.format.framesPerPacket = this.stream.readUInt32();
- this.format.channelsPerFrame = this.stream.readUInt32();
- this.format.bitsPerChannel = this.stream.readUInt32();
- this.emit('format', this.format);
- }
- while (this.stream.available(1)) {
- if (!this.headerCache) {
- this.headerCache = {
- type: this.stream.readString(4),
- oversize: this.stream.readUInt32() !== 0,
- size: this.stream.readUInt32()
- };
- if (this.headerCache.oversize) {
- return this.emit('error', "Holy Shit, an oversized file, not supported in JS");
- }
- }
- switch (this.headerCache.type) {
- case 'kuki':
- if (this.stream.available(this.headerCache.size)) {
- if (this.format.formatID === 'aac ') {
- console.log('aac')
- offset = this.stream.offset + this.headerCache.size;
- if (cookie = M4ADemuxer.readEsds(this.stream)) {
- this.emit('cookie', cookie);
- }
- this.stream.seek(offset);
- } else {
- buffer = this.stream.readBuffer(this.headerCache.size);
- this.emit('cookie', buffer);
- }
- this.headerCache = null;
- }
- break;
- case 'pakt':
- if (this.stream.available(this.headerCache.size)) {
- if (this.stream.readUInt32() !== 0) {
- return this.emit('error', 'Sizes greater than 32 bits are not supported.');
- }
- this.numPackets = this.stream.readUInt32();
- if (this.stream.readUInt32() !== 0) {
- return this.emit('error', 'Sizes greater than 32 bits are not supported.');
- }
- this.numFrames = this.stream.readUInt32();
- this.primingFrames = this.stream.readUInt32();
- this.remainderFrames = this.stream.readUInt32();
- this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
- this.sentDuration = true;
- byteOffset = 0;
- sampleOffset = 0;
- for (i = j = 0, ref = this.numPackets; j < ref; i = j += 1) {
- this.addSeekPoint(byteOffset, sampleOffset);
- byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream);
- sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream);
- }
- this.headerCache = null;
- }
- break;
- case 'info':
- entries = this.stream.readUInt32();
- metadata = {};
- for (i = k = 0, ref1 = entries; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) {
- key = this.stream.readString(null);
- value = this.stream.readString(null);
- metadata[key] = value;
- }
- this.emit('metadata', metadata);
- this.headerCache = null;
- break;
- case 'data':
- if (!this.sentFirstDataChunk) {
- this.stream.advance(4);
- this.headerCache.size -= 4;
- if (this.format.bytesPerPacket !== 0 && !this.sentDuration) {
- this.numFrames = this.headerCache.size / this.format.bytesPerPacket;
- this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
- }
- this.sentFirstDataChunk = true;
- }
- buffer = this.stream.readSingleBuffer(this.headerCache.size);
- this.headerCache.size -= buffer.length;
- this.emit('data', buffer);
- if (this.headerCache.size <= 0) {
- this.headerCache = null;
- }
- break;
- default:
- if (this.stream.available(this.headerCache.size)) {
- this.stream.advance(this.headerCache.size);
- this.headerCache = null;
- }
- }
- }
- };
- return CAFDemuxer;
- })(Demuxer);
- }).call(this);
- },{"../demuxer":14,"./m4a":18}],18:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Demuxer, M4ADemuxer,
- 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; },
- hasProp = {}.hasOwnProperty,
- 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; };
- Demuxer = require('../demuxer');
- M4ADemuxer = (function(superClass) {
- var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string;
- extend(M4ADemuxer, superClass);
- function M4ADemuxer() {
- return M4ADemuxer.__super__.constructor.apply(this, arguments);
- }
- Demuxer.register(M4ADemuxer);
- TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt '];
- M4ADemuxer.probe = function(buffer) {
- var ref;
- return buffer.peekString(4, 4) === 'ftyp' && (ref = buffer.peekString(8, 4), indexOf.call(TYPES, ref) >= 0);
- };
- M4ADemuxer.prototype.init = function() {
- this.atoms = [];
- this.offsets = [];
- this.track = null;
- return this.tracks = [];
- };
- atoms = {};
- containers = {};
- atom = function(name, fn) {
- var c, container, k, len1, ref;
- c = [];
- ref = name.split('.').slice(0, -1);
- for (k = 0, len1 = ref.length; k < len1; k++) {
- container = ref[k];
- c.push(container);
- containers[c.join('.')] = true;
- }
- if (atoms[name] == null) {
- atoms[name] = {};
- }
- return atoms[name].fn = fn;
- };
- after = function(name, fn) {
- if (atoms[name] == null) {
- atoms[name] = {};
- }
- return atoms[name].after = fn;
- };
- M4ADemuxer.prototype.readChunk = function() {
- var handler, path, type;
- this["break"] = false;
- while (this.stream.available(1) && !this["break"]) {
- if (!this.readHeaders) {
- if (!this.stream.available(8)) {
- return;
- }
- this.len = this.stream.readUInt32() - 8;
- this.type = this.stream.readString(4);
- if (this.len === 0) {
- continue;
- }
- this.atoms.push(this.type);
- this.offsets.push(this.stream.offset + this.len);
- this.readHeaders = true;
- }
- path = this.atoms.join('.');
- handler = atoms[path];
- if (handler != null ? handler.fn : void 0) {
- if (!(this.stream.available(this.len) || path === 'mdat')) {
- return;
- }
- handler.fn.call(this);
- if (path in containers) {
- this.readHeaders = false;
- }
- } else if (path in containers) {
- this.readHeaders = false;
- } else {
- if (!this.stream.available(this.len)) {
- return;
- }
- this.stream.advance(this.len);
- }
- while (this.stream.offset >= this.offsets[this.offsets.length - 1]) {
- handler = atoms[this.atoms.join('.')];
- if (handler != null ? handler.after : void 0) {
- handler.after.call(this);
- }
- type = this.atoms.pop();
- this.offsets.pop();
- this.readHeaders = false;
- }
- }
- };
- atom('ftyp', function() {
- var ref;
- if (ref = this.stream.readString(4), indexOf.call(TYPES, ref) < 0) {
- return this.emit('error', 'Not a valid M4A file.');
- }
- return this.stream.advance(this.len - 4);
- });
- atom('moov.trak', function() {
- this.track = {};
- return this.tracks.push(this.track);
- });
- atom('moov.trak.tkhd', function() {
- this.stream.advance(4);
- this.stream.advance(8);
- this.track.id = this.stream.readUInt32();
- return this.stream.advance(this.len - 16);
- });
- atom('moov.trak.mdia.hdlr', function() {
- this.stream.advance(4);
- this.stream.advance(4);
- this.track.type = this.stream.readString(4);
- this.stream.advance(12);
- return this.stream.advance(this.len - 24);
- });
- atom('moov.trak.mdia.mdhd', function() {
- this.stream.advance(4);
- this.stream.advance(8);
- this.track.timeScale = this.stream.readUInt32();
- this.track.duration = this.stream.readUInt32();
- return this.stream.advance(4);
- });
- BITS_PER_CHANNEL = {
- ulaw: 8,
- alaw: 8,
- in24: 24,
- in32: 32,
- fl32: 32,
- fl64: 64
- };
- atom('moov.trak.mdia.minf.stbl.stsd', function() {
- var format, numEntries, ref, ref1, version;
- this.stream.advance(4);
- numEntries = this.stream.readUInt32();
- if (this.track.type !== 'soun') {
- return this.stream.advance(this.len - 8);
- }
- if (numEntries !== 1) {
- return this.emit('error', "Only expecting one entry in sample description atom!");
- }
- this.stream.advance(4);
- format = this.track.format = {};
- format.formatID = this.stream.readString(4);
- this.stream.advance(6);
- this.stream.advance(2);
- version = this.stream.readUInt16();
- this.stream.advance(6);
- format.channelsPerFrame = this.stream.readUInt16();
- format.bitsPerChannel = this.stream.readUInt16();
- this.stream.advance(4);
- format.sampleRate = this.stream.readUInt16();
- this.stream.advance(2);
- if (version === 1) {
- format.framesPerPacket = this.stream.readUInt32();
- this.stream.advance(4);
- format.bytesPerFrame = this.stream.readUInt32();
- this.stream.advance(4);
- } else if (version !== 0) {
- this.emit('error', 'Unknown version in stsd atom');
- }
- if (BITS_PER_CHANNEL[format.formatID] != null) {
- format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID];
- }
- format.floatingPoint = (ref = format.formatID) === 'fl32' || ref === 'fl64';
- format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8;
- if ((ref1 = format.formatID) === 'twos' || ref1 === 'sowt' || ref1 === 'in24' || ref1 === 'in32' || ref1 === 'fl32' || ref1 === 'fl64' || ref1 === 'raw ' || ref1 === 'NONE') {
- return format.formatID = 'lpcm';
- }
- });
- atom('moov.trak.mdia.minf.stbl.stsd.alac', function() {
- this.stream.advance(4);
- return this.track.cookie = this.stream.readBuffer(this.len - 4);
- });
- atom('moov.trak.mdia.minf.stbl.stsd.esds', function() {
- var offset;
- offset = this.stream.offset + this.len;
- this.track.cookie = M4ADemuxer.readEsds(this.stream);
- return this.stream.seek(offset);
- });
- atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() {
- return this.track.format.littleEndian = !!this.stream.readUInt16();
- });
- M4ADemuxer.readDescrLen = function(stream) {
- var c, count, len;
- len = 0;
- count = 4;
- while (count--) {
- c = stream.readUInt8();
- len = (len << 7) | (c & 0x7f);
- if (!(c & 0x80)) {
- break;
- }
- }
- return len;
- };
- M4ADemuxer.readEsds = function(stream) {
- var codec_id, flags, len, tag;
- stream.advance(4);
- tag = stream.readUInt8();
- len = M4ADemuxer.readDescrLen(stream);
- if (tag === 0x03) {
- stream.advance(2);
- flags = stream.readUInt8();
- if (flags & 0x80) {
- stream.advance(2);
- }
- if (flags & 0x40) {
- stream.advance(stream.readUInt8());
- }
- if (flags & 0x20) {
- stream.advance(2);
- }
- } else {
- stream.advance(2);
- }
- tag = stream.readUInt8();
- len = M4ADemuxer.readDescrLen(stream);
- if (tag === 0x04) {
- codec_id = stream.readUInt8();
- stream.advance(1);
- stream.advance(3);
- stream.advance(4);
- stream.advance(4);
- tag = stream.readUInt8();
- len = M4ADemuxer.readDescrLen(stream);
- if (tag === 0x05) {
- return stream.readBuffer(len);
- }
- }
- return null;
- };
- atom('moov.trak.mdia.minf.stbl.stts', function() {
- var entries, i, k, ref;
- this.stream.advance(4);
- entries = this.stream.readUInt32();
- this.track.stts = [];
- for (i = k = 0, ref = entries; k < ref; i = k += 1) {
- this.track.stts[i] = {
- count: this.stream.readUInt32(),
- duration: this.stream.readUInt32()
- };
- }
- return this.setupSeekPoints();
- });
- atom('moov.trak.mdia.minf.stbl.stsc', function() {
- var entries, i, k, ref;
- this.stream.advance(4);
- entries = this.stream.readUInt32();
- this.track.stsc = [];
- for (i = k = 0, ref = entries; k < ref; i = k += 1) {
- this.track.stsc[i] = {
- first: this.stream.readUInt32(),
- count: this.stream.readUInt32(),
- id: this.stream.readUInt32()
- };
- }
- return this.setupSeekPoints();
- });
- atom('moov.trak.mdia.minf.stbl.stsz', function() {
- var entries, i, k, ref;
- this.stream.advance(4);
- this.track.sampleSize = this.stream.readUInt32();
- entries = this.stream.readUInt32();
- if (this.track.sampleSize === 0 && entries > 0) {
- this.track.sampleSizes = [];
- for (i = k = 0, ref = entries; k < ref; i = k += 1) {
- this.track.sampleSizes[i] = this.stream.readUInt32();
- }
- }
- return this.setupSeekPoints();
- });
- atom('moov.trak.mdia.minf.stbl.stco', function() {
- var entries, i, k, ref;
- this.stream.advance(4);
- entries = this.stream.readUInt32();
- this.track.chunkOffsets = [];
- for (i = k = 0, ref = entries; k < ref; i = k += 1) {
- this.track.chunkOffsets[i] = this.stream.readUInt32();
- }
- return this.setupSeekPoints();
- });
- atom('moov.trak.tref.chap', function() {
- var entries, i, k, ref;
- entries = this.len >> 2;
- this.track.chapterTracks = [];
- for (i = k = 0, ref = entries; k < ref; i = k += 1) {
- this.track.chapterTracks[i] = this.stream.readUInt32();
- }
- });
- M4ADemuxer.prototype.setupSeekPoints = function() {
- var i, j, k, l, len1, offset, position, ref, ref1, results, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp;
- if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) {
- return;
- }
- stscIndex = 0;
- sttsIndex = 0;
- sttsIndex = 0;
- sttsSample = 0;
- sampleIndex = 0;
- offset = 0;
- timestamp = 0;
- this.track.seekPoints = [];
- ref = this.track.chunkOffsets;
- results = [];
- for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
- position = ref[i];
- for (j = l = 0, ref1 = this.track.stsc[stscIndex].count; l < ref1; j = l += 1) {
- this.track.seekPoints.push({
- offset: offset,
- position: position,
- timestamp: timestamp
- });
- size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++];
- offset += size;
- position += size;
- timestamp += this.track.stts[sttsIndex].duration;
- if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) {
- sttsSample = 0;
- sttsIndex++;
- }
- }
- if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) {
- results.push(stscIndex++);
- } else {
- results.push(void 0);
- }
- }
- return results;
- };
- after('moov', function() {
- var k, len1, ref, track;
- if (this.mdatOffset != null) {
- this.stream.seek(this.mdatOffset - 8);
- }
- ref = this.tracks;
- for (k = 0, len1 = ref.length; k < len1; k++) {
- track = ref[k];
- if (!(track.type === 'soun')) {
- continue;
- }
- this.track = track;
- break;
- }
- if (this.track.type !== 'soun') {
- this.track = null;
- return this.emit('error', 'No audio tracks in m4a file.');
- }
- this.emit('format', this.track.format);
- this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0);
- if (this.track.cookie) {
- this.emit('cookie', this.track.cookie);
- }
- return this.seekPoints = this.track.seekPoints;
- });
- atom('mdat', function() {
- var bytes, chunkSize, k, length, numSamples, offset, ref, sample, size;
- if (!this.startedData) {
- if (this.mdatOffset == null) {
- this.mdatOffset = this.stream.offset;
- }
- if (this.tracks.length === 0) {
- bytes = Math.min(this.stream.remainingBytes(), this.len);
- this.stream.advance(bytes);
- this.len -= bytes;
- return;
- }
- this.chunkIndex = 0;
- this.stscIndex = 0;
- this.sampleIndex = 0;
- this.tailOffset = 0;
- this.tailSamples = 0;
- this.startedData = true;
- }
- if (!this.readChapters) {
- this.readChapters = this.parseChapters();
- if (this["break"] = !this.readChapters) {
- return;
- }
- this.stream.seek(this.mdatOffset);
- }
- offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset;
- length = 0;
- if (!this.stream.available(offset - this.stream.offset)) {
- this["break"] = true;
- return;
- }
- this.stream.seek(offset);
- while (this.chunkIndex < this.track.chunkOffsets.length) {
- numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples;
- chunkSize = 0;
- for (sample = k = 0, ref = numSamples; k < ref; sample = k += 1) {
- size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex];
- if (!this.stream.available(length + size)) {
- break;
- }
- length += size;
- chunkSize += size;
- this.sampleIndex++;
- }
- if (sample < numSamples) {
- this.tailOffset += chunkSize;
- this.tailSamples += sample;
- break;
- } else {
- this.chunkIndex++;
- this.tailOffset = 0;
- this.tailSamples = 0;
- if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) {
- this.stscIndex++;
- }
- if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) {
- break;
- }
- }
- }
- if (length > 0) {
- this.emit('data', this.stream.readBuffer(length));
- return this["break"] = this.chunkIndex === this.track.chunkOffsets.length;
- } else {
- return this["break"] = true;
- }
- });
- M4ADemuxer.prototype.parseChapters = function() {
- var bom, id, k, len, len1, nextTimestamp, point, ref, ref1, ref2, ref3, title, track;
- if (!(((ref = this.track.chapterTracks) != null ? ref.length : void 0) > 0)) {
- return true;
- }
- id = this.track.chapterTracks[0];
- ref1 = this.tracks;
- for (k = 0, len1 = ref1.length; k < len1; k++) {
- track = ref1[k];
- if (track.id === id) {
- break;
- }
- }
- if (track.id !== id) {
- this.emit('error', 'Chapter track does not exist.');
- }
- if (this.chapters == null) {
- this.chapters = [];
- }
- while (this.chapters.length < track.seekPoints.length) {
- point = track.seekPoints[this.chapters.length];
- if (!this.stream.available(point.position - this.stream.offset + 32)) {
- return false;
- }
- this.stream.seek(point.position);
- len = this.stream.readUInt16();
- title = null;
- if (!this.stream.available(len)) {
- return false;
- }
- if (len > 2) {
- bom = this.stream.peekUInt16();
- if (bom === 0xfeff || bom === 0xfffe) {
- title = this.stream.readString(len, 'utf16-bom');
- }
- }
- if (title == null) {
- title = this.stream.readString(len, 'utf8');
- }
- nextTimestamp = (ref2 = (ref3 = track.seekPoints[this.chapters.length + 1]) != null ? ref3.timestamp : void 0) != null ? ref2 : track.duration;
- this.chapters.push({
- title: title,
- timestamp: point.timestamp / track.timeScale * 1000 | 0,
- duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0
- });
- }
- this.emit('chapters', this.chapters);
- return true;
- };
- atom('moov.udta.meta', function() {
- this.metadata = {};
- return this.stream.advance(4);
- });
- after('moov.udta.meta', function() {
- return this.emit('metadata', this.metadata);
- });
- meta = function(field, name, fn) {
- return atom("moov.udta.meta.ilst." + field + ".data", function() {
- this.stream.advance(8);
- this.len -= 8;
- return fn.call(this, name);
- });
- };
- string = function(field) {
- return this.metadata[field] = this.stream.readString(this.len, 'utf8');
- };
- meta('©alb', 'album', string);
- meta('©arg', 'arranger', string);
- meta('©art', 'artist', string);
- meta('©ART', 'artist', string);
- meta('aART', 'albumArtist', string);
- meta('catg', 'category', string);
- meta('©com', 'composer', string);
- meta('©cpy', 'copyright', string);
- meta('cprt', 'copyright', string);
- meta('©cmt', 'comments', string);
- meta('©day', 'releaseDate', string);
- meta('desc', 'description', string);
- meta('©gen', 'genre', string);
- meta('©grp', 'grouping', string);
- meta('©isr', 'ISRC', string);
- meta('keyw', 'keywords', string);
- meta('©lab', 'recordLabel', string);
- meta('ldes', 'longDescription', string);
- meta('©lyr', 'lyrics', string);
- meta('©nam', 'title', string);
- meta('©phg', 'recordingCopyright', string);
- meta('©prd', 'producer', string);
- meta('©prf', 'performers', string);
- meta('purd', 'purchaseDate', string);
- meta('purl', 'podcastURL', string);
- meta('©swf', 'songwriter', string);
- meta('©too', 'encoder', string);
- meta('©wrt', 'composer', string);
- meta('covr', 'coverArt', function(field) {
- return this.metadata[field] = this.stream.readBuffer(this.len);
- });
- 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"];
- meta('gnre', 'genre', function(field) {
- return this.metadata[field] = genres[this.stream.readUInt16() - 1];
- });
- meta('tmpo', 'tempo', function(field) {
- return this.metadata[field] = this.stream.readUInt16();
- });
- meta('rtng', 'rating', function(field) {
- var rating;
- rating = this.stream.readUInt8();
- return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None';
- });
- diskTrack = function(field) {
- this.stream.advance(2);
- this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16();
- return this.stream.advance(this.len - 6);
- };
- meta('disk', 'diskNumber', diskTrack);
- meta('trkn', 'trackNumber', diskTrack);
- bool = function(field) {
- return this.metadata[field] = this.stream.readUInt8() === 1;
- };
- meta('cpil', 'compilation', bool);
- meta('pcst', 'podcast', bool);
- meta('pgap', 'gapless', bool);
- return M4ADemuxer;
- })(Demuxer);
- module.exports = M4ADemuxer;
- }).call(this);
- },{"../demuxer":14}],19:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Demuxer, WAVEDemuxer,
- 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; },
- hasProp = {}.hasOwnProperty;
- Demuxer = require('../demuxer');
- WAVEDemuxer = (function(superClass) {
- var formats;
- extend(WAVEDemuxer, superClass);
- function WAVEDemuxer() {
- return WAVEDemuxer.__super__.constructor.apply(this, arguments);
- }
- Demuxer.register(WAVEDemuxer);
- WAVEDemuxer.probe = function(buffer) {
- return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE';
- };
- formats = {
- 0x0001: 'lpcm',
- 0x0003: 'lpcm',
- 0x0006: 'alaw',
- 0x0007: 'ulaw'
- };
- WAVEDemuxer.prototype.readChunk = function() {
- var buffer, bytes, encoding;
- if (!this.readStart && this.stream.available(12)) {
- if (this.stream.readString(4) !== 'RIFF') {
- return this.emit('error', 'Invalid WAV file.');
- }
- this.fileSize = this.stream.readUInt32(true);
- this.readStart = true;
- if (this.stream.readString(4) !== 'WAVE') {
- return this.emit('error', 'Invalid WAV file.');
- }
- }
- while (this.stream.available(1)) {
- if (!this.readHeaders && this.stream.available(8)) {
- this.type = this.stream.readString(4);
- this.len = this.stream.readUInt32(true);
- }
- switch (this.type) {
- case 'fmt ':
- encoding = this.stream.readUInt16(true);
- if (!(encoding in formats)) {
- return this.emit('error', 'Unsupported format in WAV file.');
- }
- this.format = {
- formatID: formats[encoding],
- floatingPoint: encoding === 0x0003,
- littleEndian: formats[encoding] === 'lpcm',
- channelsPerFrame: this.stream.readUInt16(true),
- sampleRate: this.stream.readUInt32(true),
- framesPerPacket: 1
- };
- this.stream.advance(4);
- this.stream.advance(2);
- this.format.bitsPerChannel = this.stream.readUInt16(true);
- this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
- this.emit('format', this.format);
- this.stream.advance(this.len - 16);
- break;
- case 'data':
- if (!this.sentDuration) {
- bytes = this.format.bitsPerChannel / 8;
- this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
- this.sentDuration = true;
- }
- buffer = this.stream.readSingleBuffer(this.len);
- this.len -= buffer.length;
- this.readHeaders = this.len > 0;
- this.emit('data', buffer);
- break;
- default:
- if (!this.stream.available(this.len)) {
- return;
- }
- this.stream.advance(this.len);
- }
- if (this.type !== 'data') {
- this.readHeaders = false;
- }
- }
- };
- return WAVEDemuxer;
- })(Demuxer);
- }).call(this);
- },{"../demuxer":14}],20:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AudioDevice, EventEmitter,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('./core/events');
- AudioDevice = (function(superClass) {
- var devices;
- extend(AudioDevice, superClass);
- function AudioDevice(sampleRate1, channels1) {
- this.sampleRate = sampleRate1;
- this.channels = channels1;
- this.updateTime = bind(this.updateTime, this);
- this.playing = false;
- this.currentTime = 0;
- this._lastTime = 0;
- }
- AudioDevice.prototype.start = function() {
- if (this.playing) {
- return;
- }
- this.playing = true;
- if (this.device == null) {
- this.device = AudioDevice.create(this.sampleRate, this.channels);
- }
- if (!this.device) {
- throw new Error("No supported audio device found.");
- }
- this._lastTime = this.device.getDeviceTime();
- this._timer = setInterval(this.updateTime, 200);
- return this.device.on('refill', this.refill = (function(_this) {
- return function(buffer) {
- return _this.emit('refill', buffer);
- };
- })(this));
- };
- AudioDevice.prototype.stop = function() {
- if (!this.playing) {
- return;
- }
- this.playing = false;
- this.device.off('refill', this.refill);
- return clearInterval(this._timer);
- };
- AudioDevice.prototype.destroy = function() {
- var ref;
- this.stop();
- return (ref = this.device) != null ? ref.destroy() : void 0;
- };
- AudioDevice.prototype.seek = function(currentTime) {
- this.currentTime = currentTime;
- if (this.playing) {
- this._lastTime = this.device.getDeviceTime();
- }
- return this.emit('timeUpdate', this.currentTime);
- };
- AudioDevice.prototype.updateTime = function() {
- var time;
- time = this.device.getDeviceTime();
- this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0;
- this._lastTime = time;
- return this.emit('timeUpdate', this.currentTime);
- };
- devices = [];
- AudioDevice.register = function(device) {
- return devices.push(device);
- };
- AudioDevice.create = function(sampleRate, channels) {
- var device, i, len;
- for (i = 0, len = devices.length; i < len; i++) {
- device = devices[i];
- if (device.supported) {
- return new device(sampleRate, channels);
- }
- }
- return null;
- };
- return AudioDevice;
- })(EventEmitter);
- module.exports = AudioDevice;
- }).call(this);
- },{"./core/events":8}],21:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('../core/events');
- AudioDevice = require('../device');
- AVBuffer = require('../core/buffer');
- MozillaAudioDevice = (function(superClass) {
- var createTimer, destroyTimer;
- extend(MozillaAudioDevice, superClass);
- AudioDevice.register(MozillaAudioDevice);
- MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio;
- function MozillaAudioDevice(sampleRate, channels) {
- this.sampleRate = sampleRate;
- this.channels = channels;
- this.refill = bind(this.refill, this);
- this.audio = new Audio;
- this.audio.mozSetup(this.channels, this.sampleRate);
- this.writePosition = 0;
- this.prebufferSize = this.sampleRate / 2;
- this.tail = null;
- this.timer = createTimer(this.refill, 100);
- console.log('createTimer>>>',createTimer)
- }
- MozillaAudioDevice.prototype.refill = function() {
- var available, buffer, currentPosition, written;
- if (this.tail) {
- written = this.audio.mozWriteAudio(this.tail);
- this.writePosition += written;
- if (this.writePosition < this.tail.length) {
- this.tail = this.tail.subarray(written);
- } else {
- this.tail = null;
- }
- }
- currentPosition = this.audio.mozCurrentSampleOffset();
- available = currentPosition + this.prebufferSize - this.writePosition;
- if (available > 0) {
- buffer = new Float32Array(available);
- this.emit('refill', buffer);
- written = this.audio.mozWriteAudio(buffer);
- if (written < buffer.length) {
- this.tail = buffer.subarray(written);
- }
- this.writePosition += written;
- }
- };
- MozillaAudioDevice.prototype.destroy = function() {
- return destroyTimer(this.timer);
- };
- MozillaAudioDevice.prototype.getDeviceTime = function() {
- return this.audio.mozCurrentSampleOffset() / this.channels;
- };
- createTimer = function(fn, interval) {
- var url, worker;
- url = AVBuffer.makeBlobURL("setInterval(function() { postMessage('ping'); }, " + interval + ");");
- if (url == null) {
- return setInterval(fn, interval);
- }
- worker = new Worker(url);
- worker.onmessage = fn;
- worker.url = url;
- return worker;
- };
- destroyTimer = function(timer) {
- if (timer.terminate) {
- timer.terminate();
- return URL.revokeObjectURL(timer.url);
- } else {
- return clearInterval(timer);
- }
- };
- return MozillaAudioDevice;
- })(EventEmitter);
- }).call(this);
- },{"../core/buffer":6,"../core/events":8,"../device":20}],22:[function(require,module,exports){
- //JavaScript Audio Resampler
- //Copyright (C) 2011-2015 Grant Galitz
- //Released to Public Domain
- function Resampler(fromSampleRate, toSampleRate, channels, inputBufferLength) {
- this.fromSampleRate = +fromSampleRate;
- this.toSampleRate = +toSampleRate;
- this.channels = channels | 0;
- this.inputBufferLength = inputBufferLength;
- this.initialize();
- }
- Resampler.prototype.initialize = function () {
- //Perform some checks:
- if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) {
- if (this.fromSampleRate == this.toSampleRate) {
- //Setup a resampler bypass:
- this.resampler = this.bypassResampler; //Resampler just returns what was passed through.
- this.ratioWeight = 1;
- } else {
- this.ratioWeight = this.fromSampleRate / this.toSampleRate;
- if (this.fromSampleRate < this.toSampleRate) {
- /*
- Use generic linear interpolation if upsampling,
- as linear interpolation produces a gradient that we want
- and works fine with two input sample points per output in this case.
- */
- this.compileLinearInterpolationFunction();
- this.lastWeight = 1;
- } else {
- /*
- Custom resampler I wrote that doesn't skip samples
- like standard linear interpolation in high downsampling.
- This is more accurate than linear interpolation on downsampling.
- */
- this.compileMultiTapFunction();
- this.tailExists = false;
- this.lastWeight = 0;
- }
-
- var outputBufferSize = (Math.ceil(this.inputBufferLength * this.toSampleRate / this.fromSampleRate / this.channels * 1.01) * this.channels) + this.channels;
- this.outputBuffer = new Float32Array(outputBufferSize);
- this.lastOutput = new Float32Array(this.channels);
- }
- } else {
- throw(new Error("Invalid settings specified for the resampler."));
- }
- };
- Resampler.prototype.compileLinearInterpolationFunction = function () {
- var toCompile = "var outputOffset = 0;\
- var bufferLength = buffer.length;\
- if (bufferLength > 0) {\
- var weight = this.lastWeight;\
- var firstWeight = 0;\
- var secondWeight = 0;\
- var sourceOffset = 0;\
- var outputOffset = 0;\
- var outputBuffer = this.outputBuffer;\
- for (; weight < 1; weight += " + this.ratioWeight + ") {\
- secondWeight = weight % 1;\
- firstWeight = 1 - secondWeight;";
- for (var channel = 0; channel < this.channels; ++channel) {
- toCompile += "outputBuffer[outputOffset++] = (this.lastOutput[" + channel + "] * firstWeight) + (buffer[" + channel + "] * secondWeight);";
- }
- toCompile += "}\
- weight -= 1;\
- for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; sourceOffset < bufferLength;) {\
- secondWeight = weight % 1;\
- firstWeight = 1 - secondWeight;";
- for (var channel = 0; channel < this.channels; ++channel) {
- toCompile += "outputBuffer[outputOffset++] = (buffer[sourceOffset" + ((channel > 0) ? (" + " + channel) : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + channel) + "] * secondWeight);";
- }
- toCompile += "weight += " + this.ratioWeight + ";\
- sourceOffset = Math.floor(weight) * " + this.channels + ";\
- }";
- for (var channel = 0; channel < this.channels; ++channel) {
- toCompile += "this.lastOutput[" + channel + "] = buffer[sourceOffset++];";
- }
- toCompile += "this.lastWeight = weight % 1;\
- }\
- return this.outputBuffer;";
-
- this.resampler = Function("buffer", toCompile);
- };
- Resampler.prototype.compileMultiTapFunction = function () {
- var toCompile = "var outputOffset = 0;\
- var bufferLength = buffer.length;\
- if (bufferLength > 0) {\
- var weight = 0;";
- for (var channel = 0; channel < this.channels; ++channel) {
- toCompile += "var output" + channel + " = 0;"
- }
- toCompile += "var actualPosition = 0;\
- var amountToNext = 0;\
- var alreadyProcessedTail = !this.tailExists;\
- this.tailExists = false;\
- var outputBuffer = this.outputBuffer;\
- var currentPosition = 0;\
- do {\
- if (alreadyProcessedTail) {\
- weight = " + this.ratioWeight + ";";
- for (channel = 0; channel < this.channels; ++channel) {
- toCompile += "output" + channel + " = 0;"
- }
- toCompile += "}\
- else {\
- weight = this.lastWeight;";
- for (channel = 0; channel < this.channels; ++channel) {
- toCompile += "output" + channel + " = this.lastOutput[" + channel + "];"
- }
- toCompile += "alreadyProcessedTail = true;\
- }\
- while (weight > 0 && actualPosition < bufferLength) {\
- amountToNext = 1 + actualPosition - currentPosition;\
- if (weight >= amountToNext) {";
- for (channel = 0; channel < this.channels; ++channel) {
- toCompile += "output" + channel + " += buffer[actualPosition++] * amountToNext;"
- }
- toCompile += "currentPosition = actualPosition;\
- weight -= amountToNext;\
- }\
- else {";
- for (channel = 0; channel < this.channels; ++channel) {
- toCompile += "output" + channel + " += buffer[actualPosition" + ((channel > 0) ? (" + " + channel) : "") + "] * weight;"
- }
- toCompile += "currentPosition += weight;\
- weight = 0;\
- break;\
- }\
- }\
- if (weight <= 0) {";
- for (channel = 0; channel < this.channels; ++channel) {
- toCompile += "outputBuffer[outputOffset++] = output" + channel + " / " + this.ratioWeight + ";"
- }
- toCompile += "}\
- else {\
- this.lastWeight = weight;";
- for (channel = 0; channel < this.channels; ++channel) {
- toCompile += "this.lastOutput[" + channel + "] = output" + channel + ";"
- }
- toCompile += "this.tailExists = true;\
- break;\
- }\
- } while (actualPosition < bufferLength);\
- }\
- return this.outputBuffer;";
-
- this.resampler = Function("buffer", toCompile);
- };
- Resampler.prototype.bypassResampler = function (inputBuffer) {
- return inputBuffer;
- };
- module.exports = Resampler;
- },{}],23:[function(require,module,exports){
- (function (global){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AudioDevice, EventEmitter, Resampler, WebAudioDevice,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('../core/events');
- AudioDevice = require('../device');
- Resampler = require('./resampler');
- WebAudioDevice = (function(superClass) {
- var AudioContext, createProcessor, sharedContext;
-
- extend(WebAudioDevice, superClass);
- AudioDevice.register(WebAudioDevice);
- // TEED 生成音频上下文
- AudioContext = global.AudioContext || global.webkitAudioContext;
- console.log("AudioContext>>>>>",AudioContext)
- WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function');
- sharedContext = null;
- // 网络音频设备
- function WebAudioDevice(sampleRate, channels1) {
- this.sampleRate = sampleRate;
- this.channels = channels1;
- this.refill = bind(this.refill, this);
- this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext;
- this.deviceSampleRate = this.context.sampleRate;
- this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels);
- this.bufferSize += this.bufferSize % this.channels;
- if (this.deviceSampleRate !== this.sampleRate) {
- this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, this.bufferSize);
- }
- this.node = this.context[createProcessor](4096, this.channels, this.channels);
- this.node.onaudioprocess = this.refill;
- this.node.connect(this.context.destination);
- }
- WebAudioDevice.prototype.refill = function(event) {
- var channelCount, channels, data, i, j, k, l, n, outputBuffer, ref, ref1, ref2;
- outputBuffer = event.outputBuffer;
- channelCount = outputBuffer.numberOfChannels;
- channels = new Array(channelCount);
- for (i = j = 0, ref = channelCount; j < ref; i = j += 1) {
- channels[i] = outputBuffer.getChannelData(i);
- }
- data = new Float32Array(this.bufferSize);
- this.emit('refill', data);
- if (this.resampler) {
- data = this.resampler.resampler(data);
- }
- for (i = k = 0, ref1 = outputBuffer.length; k < ref1; i = k += 1) {
- for (n = l = 0, ref2 = channelCount; l < ref2; n = l += 1) {
- channels[n][i] = data[i * channelCount + n];
- }
- }
- };
- WebAudioDevice.prototype.destroy = function() {
- return this.node.disconnect(0);
- };
- WebAudioDevice.prototype.getDeviceTime = function() {
- return this.context.currentTime * this.sampleRate;
- };
- return WebAudioDevice;
- })(EventEmitter);
- }).call(this);
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{"../core/events":8,"../device":20,"./resampler":22}],24:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Filter;
- Filter = (function() {
- function Filter(context, key) {
- if (context && key) {
- Object.defineProperty(this, 'value', {
- get: function() {
- return context[key];
- }
- });
- }
- }
- Filter.prototype.process = function(buffer) {};
- return Filter;
- })();
- module.exports = Filter;
- }).call(this);
- },{}],25:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var BalanceFilter, Filter,
- 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; },
- hasProp = {}.hasOwnProperty;
- Filter = require('../filter');
- BalanceFilter = (function(superClass) {
- extend(BalanceFilter, superClass);
- function BalanceFilter() {
- return BalanceFilter.__super__.constructor.apply(this, arguments);
- }
- BalanceFilter.prototype.process = function(buffer) {
- var i, j, pan, ref;
- if (this.value === 0) {
- return;
- }
- pan = Math.max(-50, Math.min(50, this.value));
- for (i = j = 0, ref = buffer.length; j < ref; i = j += 2) {
- buffer[i] *= Math.min(1, (50 - pan) / 50);
- buffer[i + 1] *= Math.min(1, (50 + pan) / 50);
- }
- };
- return BalanceFilter;
- })(Filter);
- module.exports = BalanceFilter;
- }).call(this);
- },{"../filter":24}],26:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Filter, VolumeFilter,
- 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; },
- hasProp = {}.hasOwnProperty;
- Filter = require('../filter');
- VolumeFilter = (function(superClass) {
- extend(VolumeFilter, superClass);
- function VolumeFilter() {
- return VolumeFilter.__super__.constructor.apply(this, arguments);
- }
- VolumeFilter.prototype.process = function(buffer) {
- var i, j, ref, vol;
- if (this.value >= 100) {
- return;
- }
- vol = Math.max(0, Math.min(100, this.value)) / 100;
- for (i = j = 0, ref = buffer.length; j < ref; i = j += 1) {
- buffer[i] *= vol;
- }
- };
- return VolumeFilter;
- })(Filter);
- module.exports = VolumeFilter;
- }).call(this);
- },{"../filter":24}],27:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('./core/events');
- Asset = require('./asset');
- VolumeFilter = require('./filters/volume');
- BalanceFilter = require('./filters/balance');
- Queue = require('./queue');
- AudioDevice = require('./device');
- Player = (function(superClass) {
- extend(Player, superClass);
- // 请看音频上下文的文档 了解 这个作用是 播放音频 TDDE
- function Player(asset) {
- console.log("asset",asset);
- this.asset = asset;
- this.startPlaying = bind(this.startPlaying, this);
- this.playing = false;
- this.buffered = 0;
- this.currentTime = 0;
- this.duration = 0;
- this.volume = 100;
- this.pan = 0;
- this.metadata = {};
- this.filters = [new VolumeFilter(this, 'volume'), new BalanceFilter(this, 'pan')];
- this.asset.on('buffer', (function(_this) {
- return function(buffered) {
- _this.buffered = buffered;
- return _this.emit('buffer', _this.buffered);
- };
- })(this));
- this.asset.on('decodeStart', (function(_this) {
- return function() {
- _this.queue = new Queue(_this.asset);
- return _this.queue.once('ready', _this.startPlaying);
- };
- })(this));
- this.asset.on('format', (function(_this) {
- return function(format) {
- _this.format = format;
- return _this.emit('format', _this.format);
- };
- })(this));
- this.asset.on('metadata', (function(_this) {
- return function(metadata) {
- _this.metadata = metadata;
- return _this.emit('metadata', _this.metadata);
- };
- })(this));
- this.asset.on('duration', (function(_this) {
- return function(duration) {
- _this.duration = duration;
- return _this.emit('duration', _this.duration);
- };
- })(this));
- this.asset.on('error', (function(_this) {
- return function(error) {
- return _this.emit('error', error);
- };
- })(this));
- }
- //来自URL
- Player.fromURL = function(url, opts) {
- return new Player(Asset.fromURL(url, opts));
- };
- //来自文件 封装 可以读取 aac 本地文件
- Player.fromFile = function(file) {
- return new Player(Asset.fromFile(file));
- };
- //每一块
- Player.fromBuffer = function(buffer) {
- return new Player(Asset.fromBuffer(buffer));
- };
- //预载
- Player.prototype.preload = function() {
- if (!this.asset) {
- return;
- }
- this.startedPreloading = true;
- return this.asset.start(false);
- console.log("!this.asset==========",!this.asset,this.asset);
- };
- Player.prototype.play = function() {
- var ref;
- if (this.playing) {
- return;
- }
- if (!this.startedPreloading) {
- this.preload();
- console.log("!this.startedPreloading",!this.startedPreloading);
- }
-
- // this.playing = true;
- return (ref = this.device) != null ? ref.start() : void 0;
- };
- Player.prototype.pause = function() {
- var ref;
- if (!this.playing) {
- return;
- }
- this.playing = false;
- return (ref = this.device) != null ? ref.stop() : void 0;
- };
- Player.prototype.togglePlayback = function() {
- if (this.playing) {
- return this.pause();
- } else {
- return this.play();
- }
- };
- Player.prototype.stop = function() {
- var ref;
- this.pause();
- this.asset.stop();
- return (ref = this.device) != null ? ref.destroy() : void 0;
- };
- Player.prototype.seek = function(timestamp) {
- var ref;
- if ((ref = this.device) != null) {
- ref.stop();
- }
- this.queue.once('ready', (function(_this) {
- return function() {
- var ref1, ref2;
- if ((ref1 = _this.device) != null) {
- ref1.seek(_this.currentTime);
- }
- if (_this.playing) {
- return (ref2 = _this.device) != null ? ref2.start() : void 0;
- }
- };
- })(this));
- timestamp = (timestamp / 1000) * this.format.sampleRate;
- timestamp = this.asset.decoder.seek(timestamp);
- this.currentTime = timestamp / this.format.sampleRate * 1000 | 0;
- this.queue.reset();
- return this.currentTime;
- };
- Player.prototype.startPlaying = function() {
- var frame, frameOffset;
- frame = this.queue.read();
- frameOffset = 0;
- this.device = new AudioDevice(this.format.sampleRate, this.format.channelsPerFrame);
- this.device.on('timeUpdate', (function(_this) {
- return function(currentTime) {
- _this.currentTime = currentTime;
- return _this.emit('progress', _this.currentTime);
- };
- })(this));
- this.refill = (function(_this) {
- return function(buffer) {
- var bufferOffset, filter, i, j, k, len, max, ref, ref1;
- if (!_this.playing) {
- return;
- }
- if (!frame) {
- frame = _this.queue.read();
- frameOffset = 0;
- }
- bufferOffset = 0;
- while (frame && bufferOffset < buffer.length) {
- max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset);
- for (i = j = 0, ref = max; j < ref; i = j += 1) {
- buffer[bufferOffset++] = frame[frameOffset++];
- }
- if (frameOffset === frame.length) {
- frame = _this.queue.read();
- frameOffset = 0;
- }
- }
- ref1 = _this.filters;
- for (k = 0, len = ref1.length; k < len; k++) {
- filter = ref1[k];
- filter.process(buffer);
- }
- if (!frame) {
- if (_this.queue.ended) {
- _this.currentTime = _this.duration;
- _this.emit('progress', _this.currentTime);
- _this.emit('end');
- _this.stop();
- } else {
- _this.device.stop();
- }
- }
- };
- })(this);
- this.device.on('refill', this.refill);
- if (this.playing) {
- this.device.start();
- }
- return this.emit('ready');
- };
- Player.prototype.destroy = function() {
- var ref, ref1;
- this.stop();
- if ((ref = this.device) != null) {
- ref.off();
- }
- if ((ref1 = this.asset) != null) {
- ref1.destroy();
- }
- return this.off();
- };
- return Player;
- })(EventEmitter);
- module.exports = Player;
- }).call(this);
- },{"./asset":1,"./core/events":8,"./device":20,"./filters/balance":25,"./filters/volume":26,"./queue":28}],28:[function(require,module,exports){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var EventEmitter, Queue,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('./core/events');
- Queue = (function(superClass) {
- extend(Queue, superClass);
- function Queue(asset) {
- this.asset = asset;
- this.write = bind(this.write, this);
- this.readyMark = 64;
- this.finished = false;
- this.buffering = true;
- this.ended = false;
- this.buffers = [];
- this.asset.on('data', this.write);
- this.asset.on('end', (function(_this) {
- return function() {
- return _this.ended = true;
- };
- })(this));
- this.asset.decodePacket();
- }
- Queue.prototype.write = function(buffer) {
- if (buffer) {
- this.buffers.push(buffer);
- }
- if (this.buffering) {
- if (this.buffers.length >= this.readyMark || this.ended) {
- this.buffering = false;
- return this.emit('ready');
- } else {
- return this.asset.decodePacket();
- }
- }
- };
- Queue.prototype.read = function() {
- if (this.buffers.length === 0) {
- return null;
- }
- this.asset.decodePacket();
- return this.buffers.shift();
- };
- Queue.prototype.reset = function() {
- this.buffers.length = 0;
- this.buffering = true;
- return this.asset.decodePacket();
- };
- return Queue;
- })(EventEmitter);
- module.exports = Queue;
- }).call(this);
- },{"./core/events":8}],29:[function(require,module,exports){
- var AVBuffer, EventEmitter, FileSource,
- __hasProp = {}.hasOwnProperty,
- __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; };
- EventEmitter = require('../../core/events');
- AVBuffer = require('../../core/buffer');
- FileSource = (function(_super) {
- __extends(FileSource, _super);
- function FileSource(file) {
- this.file = file;
- if (typeof FileReader === "undefined" || FileReader === null) {
- return this.emit('error', 'This browser does not have FileReader support.');
- }
- this.offset = 0;
- this.length = this.file.size;
- this.chunkSize = 1 << 20;
- this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice'];
- }
- FileSource.prototype.start = function() {
- if (this.reader) {
- if (!this.active) {
- return this.loop();
- }
- }
- this.reader = new FileReader;
- this.active = true;
- this.reader.onload = (function(_this) {
- return function(e) {
- var buf;
- buf = new AVBuffer(new Uint8Array(e.target.result));
- _this.offset += buf.length;
- _this.emit('data', buf);
- _this.active = false;
- if (_this.offset < _this.length) {
- return _this.loop();
- }
- };
- })(this);
- this.reader.onloadend = (function(_this) {
- return function() {
- if (_this.offset === _this.length) {
- _this.emit('end');
- return _this.reader = null;
- }
- };
- })(this);
- this.reader.onerror = (function(_this) {
- return function(e) {
- return _this.emit('error', e);
- };
- })(this);
- this.reader.onprogress = (function(_this) {
- return function(e) {
- return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100);
- };
- })(this);
- return this.loop();
- };
- FileSource.prototype.loop = function() {
- var blob, endPos;
- this.active = true;
- endPos = Math.min(this.offset + this.chunkSize, this.length);
- blob = this.file[this.slice](this.offset, endPos);
- return this.reader.readAsArrayBuffer(blob);
- };
- FileSource.prototype.pause = function() {
- var _ref;
- this.active = false;
- try {
- return (_ref = this.reader) != null ? _ref.abort() : void 0;
- } catch (_error) {}
- };
- FileSource.prototype.reset = function() {
- this.pause();
- return this.offset = 0;
- };
- return FileSource;
- })(EventEmitter);
- module.exports = FileSource;
- },{"../../core/buffer":6,"../../core/events":8}],30:[function(require,module,exports){
- var AVBuffer, EventEmitter, HTTPSource,
- __hasProp = {}.hasOwnProperty,
- __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; };
- EventEmitter = require('../../core/events');
- AVBuffer = require('../../core/buffer');
- HTTPSource = (function(_super) {
- __extends(HTTPSource, _super);
- function HTTPSource(url, opts) {
- this.url = url;
- console.log('url>>>',url)
- this.opts = opts != null ? opts : {};
- this.chunkSize = 1 << 20;
- this.inflight = false;
- if (this.opts.length) {
- this.length = this.opts.length;
- }
- this.reset();
- }
- HTTPSource.prototype.start = function() {
- if (this.length) {
- if (!this.inflight) {
- return this.loop();
- }
- }
- this.inflight = true;
- this.xhr = new XMLHttpRequest();
- this.xhr.onload = (function(_this) {
- return function(event) {
- _this.length = parseInt(_this.xhr.getResponseHeader("Content-Length"));
- _this.inflight = false;
- return _this.loop();
- };
- })(this);
- this.xhr.onerror = (function(_this) {
- return function(err) {
- _this.pause();
- return _this.emit('error', err);
- };
- })(this);
- this.xhr.onabort = (function(_this) {
- return function(event) {
- return _this.inflight = false;
- };
- })(this);
- this.xhr.open("HEAD", this.url, true);
- return this.xhr.send(null);
- };
- HTTPSource.prototype.loop = function() {
- var endPos;
- if (this.inflight || !this.length) {
- return this.emit('error', 'Something is wrong in HTTPSource.loop');
- }
- this.inflight = true;
- this.xhr = new XMLHttpRequest();
- this.xhr.onload = (function(_this) {
- return function(event) {
- var buf, buffer, i, txt, _i, _ref;
- if (_this.xhr.response) {
- buf = new Uint8Array(_this.xhr.response);
- } else {
- txt = _this.xhr.responseText;
- buf = new Uint8Array(txt.length);
- for (i = _i = 0, _ref = txt.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
- buf[i] = txt.charCodeAt(i) & 0xff;
- }
- }
- buffer = new AVBuffer(buf);
- _this.offset += buffer.length;
- _this.emit('data', buffer);
- if (_this.offset >= _this.length) {
- _this.emit('end');
- }
- _this.inflight = false;
- if (!(_this.offset >= _this.length)) {
- return _this.loop();
- }
- };
- })(this);
- this.xhr.onprogress = (function(_this) {
- return function(event) {
- return _this.emit('progress', (_this.offset + event.loaded) / _this.length * 100);
- };
- })(this);
- this.xhr.onerror = (function(_this) {
- return function(err) {
- _this.emit('error', err);
- return _this.pause();
- };
- })(this);
- this.xhr.onabort = (function(_this) {
- return function(event) {
- return _this.inflight = false;
- };
- })(this);
- alert(this.url)
- this.xhr.open("GET", this.url, true);
- this.xhr.responseType = "arraybuffer";
- endPos = Math.min(this.offset + this.chunkSize, this.length - 1);
- this.xhr.setRequestHeader("If-None-Match", "webkit-no-cache");
- this.xhr.setRequestHeader("Range", "bytes=" + this.offset + "-" + endPos);
- this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
- return this.xhr.send(null);
- };
- HTTPSource.prototype.pause = function() {
- var _ref;
- this.inflight = false;
- return (_ref = this.xhr) != null ? _ref.abort() : void 0;
- };
- HTTPSource.prototype.reset = function() {
- this.pause();
- return this.offset = 0;
- };
- return HTTPSource;
- })(EventEmitter);
- module.exports = HTTPSource;
- },{"../../core/buffer":6,"../../core/events":8}],31:[function(require,module,exports){
- (function (global){
- // Generated by CoffeeScript 1.10.0
- (function() {
- var AVBuffer, BufferList, BufferSource, EventEmitter,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- 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; },
- hasProp = {}.hasOwnProperty;
- EventEmitter = require('../core/events');
- BufferList = require('../core/bufferlist');
- AVBuffer = require('../core/buffer');
- BufferSource = (function(superClass) {
- var clearImmediate, setImmediate;
- extend(BufferSource, superClass);
- function BufferSource(input) {
- this.loop = bind(this.loop, this);
- if (input instanceof BufferList) {
- this.list = input;
- } else {
- this.list = new BufferList;
- this.list.append(new AVBuffer(input));
- }
- this.paused = true;
- }
- setImmediate = global.setImmediate || function(fn) {
- return global.setTimeout(fn, 0);
- };
- clearImmediate = global.clearImmediate || function(timer) {
- return global.clearTimeout(timer);
- };
- BufferSource.prototype.start = function() {
- this.paused = false;
- return this._timer = setImmediate(this.loop);
- };
- BufferSource.prototype.loop = function() {
- this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0);
- this.emit('data', this.list.first);
- if (this.list.advance()) {
- return setImmediate(this.loop);
- } else {
- return this.emit('end');
- }
- };
- BufferSource.prototype.pause = function() {
- clearImmediate(this._timer);
- return this.paused = true;
- };
- BufferSource.prototype.reset = function() {
- this.pause();
- return this.list.rewind();
- };
- return BufferSource;
- })(EventEmitter);
- module.exports = BufferSource;
- }).call(this);
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{"../core/buffer":6,"../core/bufferlist":7,"../core/events":8}],32:[function(require,module,exports){
- var key, val, _ref;
- _ref = require('./src/aurora');
- for (key in _ref) {
- val = _ref[key];
- exports[key] = val;
- }
- require('./src/devices/webaudio');
- require('./src/devices/mozilla');
- },{"./src/aurora":2,"./src/devices/mozilla":21,"./src/devices/webaudio":23}]},{},[32])(32)
- });
- //# 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=
|